From eb06a4d090fd5d9e09ae7ae204c68ab1dcc9aba0 Mon Sep 17 00:00:00 2001
From: Harsh Batheja <40922251+harsh-batheja@users.noreply.github.com>
Date: Mon, 4 May 2026 20:13:11 +0530
Subject: [PATCH] fix(web): render empty-state in sidebar when no projects
configured (#1549)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* fix(web): render empty-state in sidebar when no projects configured
A fresh-install user with zero projects saw a blank sidebar and had no
way to open AddProjectModal from it. The early-return was originally
projects.length <= 1 (#381), softened to === 0 in #927, but no empty-
state UI was added at the same time.
Replace the null branch with a small ProjectSidebarEmpty sibling that
reuses the existing header (with the + button wired to AddProjectModal),
shows a one-line explainer, and renders only the ThemeToggle in the
footer (the show-killed/show-done/settings buttons are meaningless with
zero projects).
* fix(web): mark sidebar + button SVGs aria-hidden
The decorative SVG inside the labeled + buttons (empty-state and
populated sidebar) should not be announced — screen readers should rely
on the button's aria-label. Adds aria-hidden="true" to both for
consistency.
* fix(web): always mount sidebar so empty-state renders on fresh installs
Dashboard previously gated the sidebar on projects.length >= 1, leaving
ProjectSidebarEmpty unreachable. ProjectSidebar handles both cases now,
so drop the gate and add a dashboard-level test for the zero-project
path.
* fix(web): honor collapsed prop in empty sidebar branch
ProjectSidebarEmpty discarded the collapsed prop, so on a fresh install
the wrapper shrank to 44px while the inner sidebar stayed 224px and
overlapped the main content. Render a 44px-wide rail with just the +
button when collapsed, matching the populated sidebar's collapse path.
---
packages/web/src/components/Dashboard.tsx | 101 +++++++++---------
.../web/src/components/ProjectSidebar.tsx | 71 +++++++++++-
.../__tests__/Dashboard.emptyState.test.tsx | 11 ++
.../__tests__/ProjectSidebar.test.tsx | 66 +++++++++++-
4 files changed, 191 insertions(+), 58 deletions(-)
diff --git a/packages/web/src/components/Dashboard.tsx b/packages/web/src/components/Dashboard.tsx
index b66f7dc00..f9dd25245 100644
--- a/packages/web/src/components/Dashboard.tsx
+++ b/packages/web/src/components/Dashboard.tsx
@@ -197,13 +197,12 @@ function DashboardInner({
const showDebugBundleButton =
!isMobile &&
(process.env.NODE_ENV === "development" || debugParam === "1" || debugParam === "true");
- const showSidebar = projects.length >= 1;
const { showToast } = useToast();
const [doneExpanded, setDoneExpanded] = useState(false);
const sessionsRef = useRef(sessions);
sessionsRef.current = sessions;
- const allProjectsView = projects.length > 1 && showSidebar && projectId === undefined;
+ const allProjectsView = projects.length > 1 && projectId === undefined;
const currentProjectOrchestrator = useMemo(
() =>
projectId
@@ -495,41 +494,39 @@ function DashboardInner({