Skip to content

feat(desktop): add per-project workspace sorting - #5993

Closed
Roshvan wants to merge 3 commits into
ParadevAI:mainfrom
Roshvan:sort-order-agents
Closed

Roshvan wants to merge 3 commits into
ParadevAI:mainfrom
Roshvan:sort-order-agents

Conversation

@Roshvan

@Roshvan Roshvan commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor

What changed

  • add a per-project workspace sort menu with Manual, Agent status, Newest first, Oldest first, and Name modes
  • keep local main pinned and preserve section boundaries while sorting workspaces inside each group
  • persist each project's selected view order locally without rewriting its manual drag order
  • disable workspace and section dragging while an automatic order is active, then restore the exact manual order when switched back
  • aggregate existing agent status cache data so actionable and working workspaces can move to the top without extra requests per workspace

Why

Projects can accumulate many concurrent agent workspaces. A small project-level control makes it easy to find the oldest or newest work, scan alphabetically, or bring work needing attention forward while preserving the user's hand-arranged order.

Verification

  • rebased onto current main and resolved the new project sorting/filtering and workspace pinning integrations
  • bun install --frozen-lockfile
  • bun run lint:fix
  • bun run lint (0 warnings)
  • bun run typecheck in apps/desktop
  • 62 focused desktop tests across workspace/project sorting, filtering, persistence, data building, navigation, deletion, and ports
  • git diff --check
  • exact-worktree Electron E2E at renderer http://localhost:3125 with CDP on 9342
    • created a disposable project plus four workspaces through visible UI input
    • verified Manual, Agent status, Newest first, and Oldest first ordering
    • marked a workspace unread through its visible context menu and confirmed status ordering
    • verified the project-level controls landed on main coexist with the per-project workspace control
    • reloaded the renderer after the rebase and confirmed both the selected sort and resulting order persisted
    • restarted the full Electron process and confirmed the selected sort and resulting order persisted
    • captured visual and numeric DOM-order evidence
  • addressed both concrete CodeRabbit cache-subscription findings; the final incremental review produced no actionable comments

Screenshots

Sort menu

Per-project workspace sort menu

Agent status

Actionable workspace moves ahead of newer idle work while local main remains pinned.

Agent-status workspace order

Oldest first

Oldest-first workspace order

Summary by CodeRabbit

  • New Features

    • Added workspace sorting options in the dashboard sidebar (manual, status, created date, and name).
    • Sorting is now notification/activity-aware when using the status mode.
    • Added per-project workspace sort controls, including disabling drag-and-drop when automatic sorting is selected.
  • Bug Fixes

    • Fixed dragged project selection when filters are active.
    • Automatic sorting now preserves pinned workspaces and keeps grouped layouts stable (while maintaining manual order when selected).
  • Tests

    • Expanded coverage for sort modes, pinned placement, default settings, and workspace sort schema behavior.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

The dashboard sidebar now stores per-project workspace sort modes, derives workspace notification statuses from cached terminal data, and orders workspace entries by manual order, status, creation time, or name. Automatic modes disable workspace reordering.

Changes

Workspace sorting

Layer / File(s) Summary
Sort contract and persisted state
apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/dashboardSidebarLocal/schema.ts, .../useDashboardSidebarState.ts, .../DashboardSidebarData/*, .../DashboardSidebar/types.ts
Adds validated workspace sort modes, defaults to manual, persists the setting per project, and propagates it into sidebar project data.
Notification aggregation and child sorting
apps/desktop/src/renderer/hooks/host-service/useV2NotificationStatus/*, .../DashboardSidebar/utils/sortProjectChildren/*
Aggregates unread and terminal-derived statuses per workspace and sorts top-level and grouped workspaces using the selected mode.
Sort controls and reorder behavior
.../DashboardSidebarProjectSection/*, .../DashboardSidebarProjectRow/*, .../SortableSectionHeader/*, .../DashboardSidebarSectionHeader/*
Adds the workspace sort menu and disables drag interactions and reorder affordances when automatic sorting is selected.
Sidebar ordering integration
.../DashboardSidebar/DashboardSidebar.tsx
Applies workspace sorting before project ordering and resolves drag-start projects from the filtered displayed groups.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant DashboardSidebarWorkspaceSortMenu
  participant useDashboardSidebarState
  participant DashboardSidebar
  participant useV2WorkspaceNotificationStatuses
  participant sortProjectChildren
  User->>DashboardSidebarWorkspaceSortMenu: select sort mode
  DashboardSidebarWorkspaceSortMenu->>useDashboardSidebarState: update project workspaceSortOrder
  useDashboardSidebarState-->>DashboardSidebar: updated sidebar project state
  DashboardSidebar->>useV2WorkspaceNotificationStatuses: request workspace statuses
  useV2WorkspaceNotificationStatuses-->>DashboardSidebar: return status map
  DashboardSidebar->>sortProjectChildren: sort project children
  sortProjectChildren-->>DashboardSidebar: ordered workspace children
Loading

Possibly related PRs

Suggested reviewers: kitenite

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.64% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title is concise, conventional, and accurately summarizes the main change: per-project workspace sorting.
Description check ✅ Passed The description covers what changed, why, and verification well, but it does not include the template's Checklist section.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@ghost

ghost commented Jul 27, 2026 •

Copy link
Copy Markdown

@Roshvan
Roshvan force-pushed the sort-order-agents branch from cfc3d2e to cb4911a Compare July 27, 2026 19:10
@Roshvan

Roshvan commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
apps/desktop/src/renderer/hooks/host-service/useV2NotificationStatus/useV2NotificationStatus.ts (1)

78-141: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract shared cache-subscription logic; verify the event.type filter divergence from useV2AttentionWorkspaceCount.

This hook duplicates the query-cache subscription, manualUnread/terminalSeenAt reads, and cacheVersion bump pattern already used by useV2AttentionWorkspaceCount below (lines 180-219). Additionally, this hook's subscribe callback checks event.type === "updated" (line 96) while the sibling hook's callback has no event.type check at all (line 190) — same queryKey, different filter. If this divergence isn't intentional, it risks the two hooks becoming stale in different ways as the cache emits other event types (e.g. added, removed).

Consider extracting a small shared hook (e.g. useTerminalAgentBindingsCacheVersion()) that both call, so the subscription/filter logic has one source of truth.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@apps/desktop/src/renderer/hooks/host-service/useV2NotificationStatus/useV2NotificationStatus.ts`
around lines 78 - 141, Extract the duplicated query-cache version subscription
into a shared hook such as useTerminalAgentBindingsCacheVersion, and use it from
both useV2WorkspaceNotificationStatuses and useV2AttentionWorkspaceCount.
Centralize the terminal-agent-bindings query-key handling and event-type filter
there, deciding whether updated-only or all relevant cache events are intended,
so both consumers invalidate consistently. Remove each hook’s local cacheVersion
state and subscription while preserving their existing manualUnread and
terminalSeenAt behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@apps/desktop/src/renderer/hooks/host-service/useV2NotificationStatus/useV2NotificationStatus.ts`:
- Around line 78-141: Extract the duplicated query-cache version subscription
into a shared hook such as useTerminalAgentBindingsCacheVersion, and use it from
both useV2WorkspaceNotificationStatuses and useV2AttentionWorkspaceCount.
Centralize the terminal-agent-bindings query-key handling and event-type filter
there, deciding whether updated-only or all relevant cache events are intended,
so both consumers invalidate consistently. Remove each hook’s local cacheVersion
state and subscription while preserving their existing manualUnread and
terminalSeenAt behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: e8f0777d-4acd-4f53-8a37-5ffbd2031a4c

📥 Commits

Reviewing files that changed from the base of the PR and between 97e0446 and cb4911a.

📒 Files selected for processing (23)
  • apps/desktop/src/renderer/hooks/host-service/useV2NotificationStatus/index.ts
  • apps/desktop/src/renderer/hooks/host-service/useV2NotificationStatus/useV2NotificationStatus.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/DashboardSidebar.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarProjectSection/DashboardSidebarProjectSection.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarProjectSection/components/DashboardSidebarCollapsedProjectContent/DashboardSidebarCollapsedProjectContent.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarProjectSection/components/DashboardSidebarExpandedProjectContent/DashboardSidebarExpandedProjectContent.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarProjectSection/components/DashboardSidebarProjectRow/DashboardSidebarProjectRow.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarProjectSection/components/DashboardSidebarProjectRow/components/DashboardSidebarWorkspaceSortMenu/DashboardSidebarWorkspaceSortMenu.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarProjectSection/components/DashboardSidebarProjectRow/components/DashboardSidebarWorkspaceSortMenu/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarProjectSection/hooks/useDashboardSidebarProjectSectionActions/useDashboardSidebarProjectSectionActions.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/DashboardSidebarSection/components/DashboardSidebarSectionHeader/DashboardSidebarSectionHeader.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/components/SortableSectionHeader/SortableSectionHeader.tsx
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/buildDashboardSidebarProjects.test.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/buildDashboardSidebarProjects.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/useDashboardSidebarData.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/types.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/utils/sortProjectChildren/index.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/utils/sortProjectChildren/sortProjectChildren.test.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/utils/sortProjectChildren/sortProjectChildren.ts
  • apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/utils/testProjectFixtures.ts
  • apps/desktop/src/renderer/routes/_authenticated/hooks/useDashboardSidebarState/useDashboardSidebarState.ts
  • apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/dashboardSidebarLocal/schema.test.ts
  • apps/desktop/src/renderer/routes/_authenticated/providers/CollectionsProvider/dashboardSidebarLocal/schema.ts

@Roshvan

Roshvan commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@apps/desktop/src/renderer/hooks/host-service/useV2NotificationStatus/useV2NotificationStatus.ts`:
- Around line 27-41: Replace the useState/useEffect subscription in
useTerminalAgentBindingsCacheVersion with a React-integrated external-store
observer such as useSyncExternalStore or useQuery, using the
terminal-agent-bindings query cache as the source. Ensure updates occurring
before passive effects are observed during render/commit so
useV2WorkspaceNotificationStatuses and useV2AttentionWorkspaceCount receive
current summaries.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 5d67ef01-a75b-4ee7-b7b4-0fb2b3529f40

📥 Commits

Reviewing files that changed from the base of the PR and between cb4911a and b08359e.

📒 Files selected for processing (1)
  • apps/desktop/src/renderer/hooks/host-service/useV2NotificationStatus/useV2NotificationStatus.ts

@Roshvan

Roshvan commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@Roshvan
Roshvan marked this pull request as ready for review July 27, 2026 19:41

Roshvan commented Jul 27, 2026

Copy link
Copy Markdown
Contributor Author

@kiet @satyan Once a project has lots of workspaces, it gets difficult to spot what’s new, old, or waiting for attention. This adds a simple sorting menu for each project while keeping the user’s manual order safe—would love your feedback.

@Roshvan Roshvan closed this Aug 21, 2026
@Roshvan
Roshvan deleted the sort-order-agents branch August 21, 2026 05:47
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.

1 participant