Skip to content

fix(web): render empty-state in sidebar when no projects configured - #1549

Merged
ashish921998 merged 4 commits into
mainfrom
session/ao-155
May 4, 2026
Merged

ashish921998 merged 4 commits into
mainfrom
session/ao-155

Conversation

@harsh-batheja

Copy link
Copy Markdown
Contributor

Summary

  • A fresh-install user with zero projects sees no sidebar content and no way to open AddProjectModal — the outer ProjectSidebar wrapper returns null when projects.length === 0.
  • Replace that null with a small ProjectSidebarEmpty sibling that reuses the existing header + + button, shows a one-line explainer, and keeps only the ThemeToggle in the footer.
  • Add three test cases covering the empty state and update the previous "renders nothing" assertion.

Context

UX decision

The empty-state mirrors the populated sidebar's chrome (so the + button stays in the same spot a returning user would look) and drops the show-killed / show-done / settings buttons because they have no meaning with zero projects. The body uses var(--color-text-tertiary) and the existing project-sidebar__empty class — no new tokens, no inline styles.

Constraints honored

  • No inline style= attributes (C-02). All styling via existing classes (project-sidebar, project-sidebar__compact-hdr, project-sidebar__sect-label, project-sidebar__add-btn, project-sidebar__empty, project-sidebar__footer, project-sidebar__theme-toggle) and Tailwind utilities.
  • No new design tokens.
  • ProjectSidebarInner (the populated path) is untouched.
  • Empty-state factored into a sibling component to keep the file from drifting toward the 400-line cap (C-04).

Test plan

  • pnpm --filter @aoagents/ao-web typecheck — clean.
  • pnpm --filter @aoagents/ao-web test ProjectSidebar — 17/17 pass (14 existing + 3 new).
  • pnpm lint — 0 errors (45 pre-existing warnings, none from this change).
  • Other test failures observed in the wider suite (api-routes.test.ts, serialize.test.ts, sessions/[id]/page.test.tsx) reproduce on main — unrelated to this change.

@greptile-apps

greptile-apps Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR replaces the null early-return in ProjectSidebar when projects.length === 0 with a new ProjectSidebarEmpty component that renders the sidebar chrome (header, + button, ThemeToggle footer) and a one-line explainer, giving fresh-install users a clear call to action. Three new tests cover the empty-state render, modal interaction, and footer toggle.

Confidence Score: 5/5

Safe to merge — the change is narrowly scoped to the zero-projects path, leaves ProjectSidebarInner untouched, and is well-covered by the updated test suite.

The only finding is a P2 style suggestion (missing aria-hidden on a decorative SVG inside a fully labelled button). No logic errors, data issues, or security concerns were identified.

No files require special attention.

Important Files Changed

Filename Overview
packages/web/src/components/ProjectSidebar.tsx Replaces the null early-return with a new ProjectSidebarEmpty sibling that renders the header + button, empty-state body, and footer ThemeToggle; ProjectSidebarInner is untouched. Minor: decorative SVG in the new component lacks aria-hidden.
packages/web/src/components/tests/ProjectSidebar.test.tsx Replaces the old "renders nothing" assertion with three focused tests covering empty-state header/button presence, modal opening, and ThemeToggle rendering; existing tests are unmodified.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["ProjectSidebar (props)"] --> B{projects.length === 0?}
    B -- Yes --> C["ProjectSidebarEmpty"]
    B -- No --> D["ProjectSidebarInner"]
    C --> E["Header: 'Projects' label + '+' button"]
    C --> F["Body: 'No projects yet' text"]
    C --> G["Footer: ThemeToggle"]
    C --> H["AddProjectModal (controlled by addProjectOpen state)"]
    E -->|click '+'| H
Loading

Reviews (1): Last reviewed commit: "fix(web): render empty-state in sidebar ..." | Re-trigger Greptile

@github-actions

Copy link
Copy Markdown
Contributor

Test Coverage Report

Changed files have no coverage data (not instrumented or no tests ran).

@ashish921998

Copy link
Copy Markdown
Contributor

Review finding

[P1] Empty sidebar never renders on fresh installs

The new ProjectSidebarEmpty path is still unreachable from the main dashboard because the parent only mounts ProjectSidebar when projects.length >= 1. With zero projects, the dashboard skips the sidebar entirely, so users still see no sidebar chrome and no + button. The component-level tests pass because they render ProjectSidebar directly; add/update a dashboard-level test and let the dashboard mount the sidebar for the zero-project case.

Location: packages/web/src/components/Dashboard.tsx:200

@ashish921998

Copy link
Copy Markdown
Contributor

P2 Honor collapsed state in empty sidebar

Dashboard now always renders ProjectSidebar and passes collapsed={sidebarCollapsed}, but the zero-project branch drops those props and always renders a full-width .project-sidebar. On a fresh install, clicking the header sidebar toggle applies .dashboard-shell--sidebar-collapsed so the wrapper shrinks to 44px, while the child sidebar remains 224px wide and can overlap the main dashboard instead of collapsing like the populated sidebar path. The empty branch should either render a collapsed variant when props.collapsed is true or avoid enabling the desktop collapse path for the zero-project sidebar.

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).
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.
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.
@ashish921998

Copy link
Copy Markdown
Contributor

Respect collapsed state in empty sidebar

Dashboard now always renders the sidebar toggle and passes collapsed={sidebarCollapsed}, including when projects is empty. But this branch discards the prop and always renders the full-width empty sidebar. On a fresh install, clicking the desktop sidebar toggle shrinks only .sidebar-wrapper to 44px while the inner .project-sidebar remains 224px, so the empty-state sidebar protrudes/overlaps the main content instead of collapsing like the populated path. Pass collapsed into the empty component or render a collapsed empty rail for this state.

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.
@ashish921998
ashish921998 merged commit eb06a4d into main May 4, 2026
14 checks passed
@AgentWrapper AgentWrapper mentioned this pull request May 6, 2026
4 tasks
@OrcInc OrcInc mentioned this pull request May 6, 2026
4 tasks
AgentWrapper pushed a commit that referenced this pull request May 6, 2026
- Add changesets for #1643 (orchestrator worktree adoption), #1549
  (sidebar empty-state), and #1608 (terminal attach + mux routing).
- Update agent-codex package-version.test.ts expectation from 0.4.0
  to 0.5.0 so the test no longer fails after the upcoming version bump.
AgentWrapper pushed a commit that referenced this pull request May 6, 2026
* chore(release): add changesets for 0.5.0 and bump codex version test

- Add changesets for #1643 (orchestrator worktree adoption), #1549
  (sidebar empty-state), and #1608 (terminal attach + mux routing).
- Update agent-codex package-version.test.ts expectation from 0.4.0
  to 0.5.0 so the test no longer fails after the upcoming version bump.

* chore: release 0.5.0

---------

Co-authored-by: i-trytoohard <[email protected]>
alerios pushed a commit to AIMagicFlow/agent-orchestrator that referenced this pull request Oct 14, 2026
…rchestratorInc#1549)

* 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 (OrchestratorInc#381), softened to === 0 in OrchestratorInc#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.
alerios pushed a commit to AIMagicFlow/agent-orchestrator that referenced this pull request Oct 14, 2026
* chore(release): add changesets for 0.5.0 and bump codex version test

- Add changesets for OrchestratorInc#1643 (orchestrator worktree adoption), OrchestratorInc#1549
  (sidebar empty-state), and OrchestratorInc#1608 (terminal attach + mux routing).
- Update agent-codex package-version.test.ts expectation from 0.4.0
  to 0.5.0 so the test no longer fails after the upcoming version bump.

* chore: release 0.5.0

---------

Co-authored-by: i-trytoohard <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants