RecordViewHeader passed actionEntries={hasCustomActionsMenu || availableProcesses.length > 0 ? actionEntries : []} to the desktop RecordActions. Tables with no processes and no custom VIEW_SCREEN_ACTIONS menu therefore got no Actions dropdown, losing Developer Mode, Audit and the New/Copy/Delete menu items, even though DEFAULT_ACTIONS_MENU already resolves them with the permission/capability checks. Separately, the desktop and phone Actions controls were gated on canEdit || canInsert || canDelete || processes || metadata actions, which hid them entirely for read-only tables that still offer Developer Mode (and Audit).
Fix
Always pass the resolved actionEntries to RecordActions.
Gate the desktop and phone Actions controls on hasMenuItems(actionEntries) in addition to the existing conditions (renamed hasMobileActions to hasRecordActions, since it gates both).
RecordActions keeps de-duplicating through menuOffersAction: when the menu offers Copy/Delete, they are not also rendered as buttons. This matches Material, which grouped secondary actions in the menu (see VIS-003).
defaultPhoneMenuExtras was already correct: it keeps New/Developer Mode/Audit/downloads and leaves CRUD and processes to the sheet's own buttons. No change was needed there.
Keyboard shortcuts (n/e/c/d/a) are unchanged. They never depended on the menu.
A custom VIEW_SCREEN_ACTIONS menu that resolves to nothing for a read-only user still shows no Actions control.
Tests
RecordViewHeader.test.tsx covers these cases:
A table without processes or a custom menu gets an Actions menu with New, Copy, Edit, Delete, Developer Mode, and Developer Mode navigates to /dev.
Audit is added when auditSource is set.
Copy and Delete each appear once, in the menu, with no standalone buttons.
A read-only table gets a desktop menu with only Developer Mode, and the phone sheet has Developer Mode and Audit but no write actions.
An empty custom menu shows no control.
With processes, the menu is New, Copy, Edit, Delete, Tag Records, Developer Mode.
The 5 new #45 cases fail on main and pass with the fix. The old "keeps standalone secondary actions when there is no process menu" test encoded the bug and is replaced.
Acceptance specs that asserted the missing menu now assert the new behavior:
PRC-050 (qryBin record: the menu exists, with Delete and Developer Mode and without the omitted process).
REC-046 (read-only persona: the menu or phone sheet offers Developer Mode and no New/Edit/Copy/Delete).
The matrix wording is updated to match.
Local results:
pnpm typecheck passes.
pnpm lint reports 0 errors (5 existing warnings).
pnpm test passes 2158/2160. The 2 failures are pre-existing and Windows-only (path-separator checks in tests/standalone/acceptance-stage.test.ts and tests/acceptance/support/standalone-variant.test.ts). They fail identically on clean main.
I didn't run the real-backend Playwright acceptance locally because it needs the Java sample backend, so I relied on the Acceptance workflow.
The first run passed 619/621 on each desktop browser and 1152/1152 on mobile+tablet, including REC-046.
The only failures were my updated PRC-050 assertion: it expected Developer Mode to be the last item, but Audit follows it for users who can read audits.
Follow-up commit 3ceed91 changes PRC-050 to check that Developer Mode and Audit are both present.
## Root cause
`RecordViewHeader` passed `actionEntries={hasCustomActionsMenu || availableProcesses.length > 0 ? actionEntries : []}` to the desktop `RecordActions`. Tables with no processes and no custom `VIEW_SCREEN_ACTIONS` menu therefore got no Actions dropdown, losing Developer Mode, Audit and the New/Copy/Delete menu items, even though `DEFAULT_ACTIONS_MENU` already resolves them with the permission/capability checks. Separately, the desktop and phone Actions controls were gated on `canEdit || canInsert || canDelete || processes || metadata actions`, which hid them entirely for read-only tables that still offer Developer Mode (and Audit).
## Fix
- Always pass the resolved `actionEntries` to `RecordActions`.
- Gate the desktop and phone Actions controls on `hasMenuItems(actionEntries)` in addition to the existing conditions (renamed `hasMobileActions` to `hasRecordActions`, since it gates both).
- `RecordActions` keeps de-duplicating through `menuOffersAction`: when the menu offers Copy/Delete, they are not also rendered as buttons. This matches Material, which grouped secondary actions in the menu (see VIS-003).
- `defaultPhoneMenuExtras` was already correct: it keeps New/Developer Mode/Audit/downloads and leaves CRUD and processes to the sheet's own buttons. No change was needed there.
- Keyboard shortcuts (`n/e/c/d/a`) are unchanged. They never depended on the menu.
- A custom `VIEW_SCREEN_ACTIONS` menu that resolves to nothing for a read-only user still shows no Actions control.
## Tests
- `RecordViewHeader.test.tsx` covers these cases:
- A table without processes or a custom menu gets an Actions menu with `New, Copy, Edit, Delete, Developer Mode`, and Developer Mode navigates to `/dev`.
- Audit is added when `auditSource` is set.
- Copy and Delete each appear once, in the menu, with no standalone buttons.
- A read-only table gets a desktop menu with only Developer Mode, and the phone sheet has Developer Mode and Audit but no write actions.
- An empty custom menu shows no control.
- With processes, the menu is `New, Copy, Edit, Delete, Tag Records, Developer Mode`.
The 5 new #45 cases fail on `main` and pass with the fix. The old "keeps standalone secondary actions when there is no process menu" test encoded the bug and is replaced.
- Acceptance specs that asserted the missing menu now assert the new behavior:
- PRC-050 (qryBin record: the menu exists, with Delete and Developer Mode and without the omitted process).
- REC-046 (read-only persona: the menu or phone sheet offers Developer Mode and no New/Edit/Copy/Delete).
- The matrix wording is updated to match.
- Local results:
- `pnpm typecheck` passes.
- `pnpm lint` reports 0 errors (5 existing warnings).
- `pnpm test` passes 2158/2160. The 2 failures are pre-existing and Windows-only (path-separator checks in `tests/standalone/acceptance-stage.test.ts` and `tests/acceptance/support/standalone-variant.test.ts`). They fail identically on clean `main`.
- I didn't run the real-backend Playwright acceptance locally because it needs the Java sample backend, so I relied on the Acceptance workflow.
- The first run passed 619/621 on each desktop browser and 1152/1152 on mobile+tablet, including REC-046.
- The only failures were my updated PRC-050 assertion: it expected Developer Mode to be the last item, but Audit follows it for users who can read audits.
- Follow-up commit `3ceed91` changes PRC-050 to check that Developer Mode and Audit are both present.
Closes #45
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Root cause
RecordViewHeaderpassedactionEntries={hasCustomActionsMenu || availableProcesses.length > 0 ? actionEntries : []}to the desktopRecordActions. Tables with no processes and no customVIEW_SCREEN_ACTIONSmenu therefore got no Actions dropdown, losing Developer Mode, Audit and the New/Copy/Delete menu items, even thoughDEFAULT_ACTIONS_MENUalready resolves them with the permission/capability checks. Separately, the desktop and phone Actions controls were gated oncanEdit || canInsert || canDelete || processes || metadata actions, which hid them entirely for read-only tables that still offer Developer Mode (and Audit).Fix
actionEntriestoRecordActions.hasMenuItems(actionEntries)in addition to the existing conditions (renamedhasMobileActionstohasRecordActions, since it gates both).RecordActionskeeps de-duplicating throughmenuOffersAction: when the menu offers Copy/Delete, they are not also rendered as buttons. This matches Material, which grouped secondary actions in the menu (see VIS-003).defaultPhoneMenuExtraswas already correct: it keeps New/Developer Mode/Audit/downloads and leaves CRUD and processes to the sheet's own buttons. No change was needed there.n/e/c/d/a) are unchanged. They never depended on the menu.VIEW_SCREEN_ACTIONSmenu that resolves to nothing for a read-only user still shows no Actions control.Tests
RecordViewHeader.test.tsxcovers these cases:New, Copy, Edit, Delete, Developer Mode, and Developer Mode navigates to/dev.auditSourceis set.New, Copy, Edit, Delete, Tag Records, Developer Mode.The 5 new #45 cases fail on
mainand pass with the fix. The old "keeps standalone secondary actions when there is no process menu" test encoded the bug and is replaced.Acceptance specs that asserted the missing menu now assert the new behavior:
Local results:
pnpm typecheckpasses.pnpm lintreports 0 errors (5 existing warnings).pnpm testpasses 2158/2160. The 2 failures are pre-existing and Windows-only (path-separator checks intests/standalone/acceptance-stage.test.tsandtests/acceptance/support/standalone-variant.test.ts). They fail identically on cleanmain.I didn't run the real-backend Playwright acceptance locally because it needs the Java sample backend, so I relied on the Acceptance workflow.
3ceed91changes PRC-050 to check that Developer Mode and Audit are both present.Closes #45
🤖 Generated with Claude Code