You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit e929bcf
Browse filesBrowse the repository at this point in the historyBrowse files
fix(menus): build every separator guard from its items' exact conditions
Review caught two places where the grouping rule and the code disagreed.
The tables row menu guarded its rule on `onMove` while the Move submenu
needs a non-empty `moveOptions`, so a table whose other actions were all
absent and whose move list was empty would draw the rule with nothing
above it — the exact looseness the rule warns about.
The logs row menu puts its one rule after Retry and Cancel Run rather
than before a destructive group, which the rule as written did not
cover. Retry is the primary action on a failed run and belongs at the
top; the rule now describes the separator as fencing the consequential
group at whichever end it sits, and names the logs menu as the one place
that group leads.
Also aligns three empty-space menu labels with the header chips they
mirror: "Add document" and "Create chunk" were the only create actions
not matching their toolbar, and the files menu said "Upload file" where
its header says "Upload".
Run order in the two column run menus now matches the action bar and the
row menu — incomplete before all, not all before incomplete.
Platform-only entries (desktop **Browser** and **Terminal**) trail the shared set rather than interleaving, so the common prefix is identical on every platform.
28
28
29
-
## Grouping: one rule, before the destructive action
29
+
## Grouping: one rule, against the consequential group
30
30
31
31
Order is governed above. **Separators are governed here** — and the answer is: use at most one.
32
32
33
-
Put a single `DropdownMenuSeparator` immediately before the destructive group (Delete, Leave,
34
-
Close, Hide) and nowhere else. Everything above it runs uninterrupted in toolbar-mirroring order.
33
+
Put a single `DropdownMenuSeparator` against the **consequential group** — the actions that
34
+
delete, detach, or change a run — and nowhere else. Everything on the other side of it runs
35
+
uninterrupted in toolbar-mirroring order.
36
+
37
+
That group trails in almost every menu, so in practice the rule reads "one rule immediately
38
+
before Delete / Leave / Close / Hide". It leads in exactly one place: the **logs row menu**,
39
+
where `Retry` and `Cancel Run` are the primary actions on a failed run and sit at the top, with
40
+
the rule beneath them. Ordering follows the surface (see "The rule" above); the separator simply
41
+
fences whichever end the consequential group occupies. A menu whose consequential actions are
42
+
merely *disabled* still gets no extra rule — `disabled` is not a group.
35
43
36
44
```tsx
37
45
// ✗ Bad — four semantic bands the user meets nowhere else
Copy file name to clipboardExpand all lines: CLAUDE.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -388,7 +388,7 @@ A list orders itself the way the user already reads the same things somewhere el
388
388
389
389
Encode the order in ONE exported constant and sort by it — never a hand-maintained literal per menu (`RESOURCE_MENU_ORDER` / `byResourceMenuOrder` in `home/components/mothership-view/components/resource-registry`). Render mixed item kinds in a single ordered pass; emitting all submenu-backed families and then all flat ones silently pins every submenu to the top no matter what the constant says. Divergence is allowed only for search ranking, user-controlled ordering, and recency.
390
390
391
-
**Grouping**: at most ONE `DropdownMenuSeparator` per menu, immediately before the destructive group (Delete/Leave/Close/Hide). No toolbar in the app renders a divider, so multi-band menus teach a taxonomy that exists on no other surface. Build each separator's guard from the EXACT render conditions of the items on both sides — a looser guard is what leaves a dangling rule when its group is conditional. Never add a prop to move a rule. Full rule in `.claude/rules/sim-list-ordering.md`.
391
+
**Grouping**: at most ONE `DropdownMenuSeparator` per menu, fencing the consequential group — immediately before Delete/Leave/Close/Hide in almost every menu, and immediately after Retry/Cancel Run in the logs row menu, where those lead. No toolbar in the app renders a divider, so multi-band menus teach a taxonomy that exists on no other surface. Build each separator's guard from the EXACT render conditions of the items on both sides — a looser guard is what leaves a dangling rule when its group is conditional. Never add a prop to move a rule. Full rule in `.claude/rules/sim-list-ordering.md`.
Copy file name to clipboardExpand all lines: apps/sim/app/workspace/[workspaceId]/knowledge/[id]/[documentId]/components/chunk-context-menu/chunk-context-menu.tsx
Copy file name to clipboardExpand all lines: apps/sim/app/workspace/[workspaceId]/knowledge/[id]/components/document-context-menu/document-context-menu.tsx
+1-1Lines changed: 1 addition & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -141,7 +141,7 @@ export function DocumentContextMenu({
Copy file name to clipboardExpand all lines: apps/sim/app/workspace/[workspaceId]/tables/[tableId]/components/table-grid/headers/workflow-group-meta-cell.tsx
Copy file name to clipboardExpand all lines: apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workflow-list/components/context-menu/context-menu.tsx
+3Lines changed: 3 additions & 0 deletions
Original file line number
Diff line number
Diff line change
@@ -185,6 +185,9 @@ export function ContextMenu({
185
185
* rendered a trailing rule under the last item.
186
186
*/
187
187
consthasActionsAboveDestructive=
188
+
/* No `openInNewTabPosition` term: the item renders in the 'first' slot or the
189
+
'last' one, and the prop is a closed two-value union, so `showOpenInNewTab &&
190
+
onOpenInNewTab` already means exactly "the nav item renders somewhere above". */
0 commit comments