cmux-next sidebar: workspaces marked Done fold into one Done (N) row

Merged
TE
15d ago
+486-52

This is slice S4 of Leo's sidebar-organization ask (item A, the "Done (N)" fold).

What changes

Workspaces you marked Done (Mark as Done, Set Workspace Status โ†’ Done) leave their place and list behind one "Done (N)" row at the end of their group, or at the end of the loose rows. Click the row to show them below it; click again to fold them.

  • Order: nothing reorders the model. The other rows keep their manual order, and the Done ones keep theirs behind the fold.
  • Kept in place: the active workspace, even when it is Done. While filtering, every match shows where it is. With the session tree on, nothing folds (the tree nests rows under others).
  • What redraws: marking a workspace Done (or not) is now a structural change, so the list lays out again instead of patching the row (SidebarModel.movesRows). A group holding Done workspaces folds and opens by a full layout instead of the splice.
  • The row: a chevron and "Done (N)" in the folder header's quiet style, one line high, indented with the group's members. It is no drop target, has no rename, and right-click shows its group's or section's menu. VoiceOver reads it as a disclosure triangle.
  • While a drag runs, every Done workspace shows in its place (drops resolve by the drawn rows), and the fold comes back after the drop.
  • Selected from elsewhere: a Done workspace chosen from the palette, Cmd-number or the socket shows in its place (the selection patch hands over to a layout). After you leave a Done workspace by a click, it stays drawn until the next layout, as a collapsed group keeps the member you left, so nothing moves under the pointer.
  • State: which Done rows are open is view state of the list (SidebarListView.openDoneFolds), not saved.
  • Toggle: Debug toggle sidebar.doneFold, on by default.
  • Strings: one new string, "Done (%lld)", in all 21 locales.
  • Size: SidebarLayout.swift shrinks (474 โ†’ 461 lines): its row helpers visible, listsTabs and disclosure moved onto SidebarLayoutOptions, and the filter's path-to-match onto a static helper.

Tests

Tests/CmuxNextAppTests/SidebarDoneFoldTests.swift (committed first):

  • Done workspaces fold into one row at the end, in a group and in the loose rows;
  • the row counts its workspaces;
  • an open fold lists them in their order;
  • the active workspace keeps its place;
  • off, and while filtering, every row is in place;
  • a group with Done workspaces is not spliced;
  • marking Done is a structural change;
  • the string carries the count;
  • a Done workspace selected elsewhere shows.

Capture

Three workspaces marked Done (with the app's Mark as Done action) fold into one closed "Done (3)" row under the others.

Capture steps-386849ff85 at 7c19da8f8742 (fleet build, capture mini, text checked for private data)

LightDark
lightdark

Review

  • BLOCK at d5b9dd3: drops near a closed Done row, the drop gap, and a Done workspace selected elsewhere. Fixed in 87531eb, with a test.
  • SHIP at 87531eb. Follow-ups from it: the first event of a drag from outside the sidebar can name the wrong row until the next move; rows jump when a drag starts while Done rows are folded; a dragged group's slot is taller than its card.
  • After it: the chevron sat over the count (moved before it), and turning sidebar.doneFold on or off now lays the list out again. Fleet compile passed at 7c19da8.

Changelog

  • Added: Workspaces marked Done fold into one "Done (N)" row at the end of their group or list.
    Agent session: cosmic-gray

๐Ÿค– Generated with Claude Code