feat(web): slice 4 — Admin Settings, Users, Audit, System Logs, Cluster on HeroUI (feature 014, T146-T162) - #362
feat(web): slice 4 — Admin Settings, Users, Audit, System Logs, Cluster on HeroUI (feature 014, T146-T162)#362ValgulNecron wants to merge 39 commits into
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
CI Report - 51793e4run 34394493417 - attempt 1 1 failed - 5 passed - 11 skipped - 13m23s elapsed Failing
Coverageno coverage/* commit statuses found on 51793e4 Changed
Slowest jobs
e2e buckets run
|
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
35650ea to
d6e53d5
Compare
30e57c5 to
c90e880
Compare
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
d6e53d5 to
d0f9b4d
Compare
176aac5 to
2c77dbc
Compare
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
cc3c61a to
b74ea22
Compare
2c77dbc to
6b5f8b4
Compare
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
b74ea22 to
264fd90
Compare
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
fe82f43 to
bfb0a4f
Compare
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
65e4cc1 to
9358cb1
Compare
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
62a142b to
416bbaa
Compare
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
416bbaa to
21dc2bc
Compare
b059b5a to
c54f983
Compare
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
21dc2bc to
ed7dfde
Compare
c54f983 to
67b508d
Compare
- users.spec.ts: E2E tests for user management flows - slice-4.spec.ts: Screenshot specs for all admin screen IDs - test/handlers.ts: MSW handlers for admin API endpoints - test/screenshotData.ts: Mock data for screenshot verification Covers all screen IDs per T159 task requirements. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
Verified the 12-commit slice 4 admin rebuild (AdminSettings, Users, AuditLog, AdminLogs, Cluster + hero/ admin compositions) left by a prior session that died before reporting: tsc --noEmit clean on every slice-4 file (the 47 remaining errors are all inherited slice-2a files being fixed on 014c-servers-core), no it()/test() count regressions in any touched test file, no @/components/ui or @radix-ui imports (FR-012), all 31 screen ids from T159 present in web/e2e/screenshots/slice-4.spec.ts, and the flagged HeroUI v3 prop fixes (Button has no `title`, size lives on ModalContainer not Modal) confirmed correct against the @heroui/react type declarations. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
Applied reviewer fixes to AdminSettings: updated PageHeader import path, replaced inline ConfirmDialog with reusable ConfirmAdminMappingDialog, reconciled test files from native select to HeroUI Select button/option queries. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
Applied reviewer fixes: updated group label assertions to title case, restructured permission checkboxes to remove nested labels and use Checkbox.Content for accessible naming, fixed name field initialization when editing roles. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
Applied reviewer fixes: corrected PageHeader import path and changed from default to named import, renamed subtitle prop to description, added aria-pressed attribute to component selector buttons, reverted switch role from checkbox, replaced fireEvent with userEvent for proper HeroUI Switch interaction, made tail-lines test async with role-based Select selection. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
Applied reviewer fixes to Users component and test suite: refactored tab panels markup, updated admin dialogs to HeroUI patterns, corrected OIDC hint styling and test selectors, changed all tab-panel clicks from conditional lookups to unconditional role queries. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
Applied reviewer fixes: corrected PageHeader import to direct hero path, renamed subtitle prop to description, replaced three conditional-click patterns with unconditional role-based queries using screen.getByRole for status filter buttons. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
Updated web/specs.md slice 4 section with accurate descriptions and correct test file list. Flipped T152, T153, T158 from done to open in tasks.md since AdminSettings.test.tsx and Cluster.test.tsx were not modified in this wave. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
Mark tasks T152, T153, T158 as done (AdminSettings, Users, Cluster reconciled to HeroUI v3 markup with test files updated). Update web/specs.md to document Users.tsx rendering hero/admin dialogs (InviteUserDialog, EditUserDialog, ResetPasswordDialog) with additive props for role selection, optional contact fields, preemptive validation, and API error surfacing. Document test file reconciliations: AdminSettings.test.tsx selector fix (.rounded-lg -> [data-slot="card"]), AdminSettings_sections.test.tsx combobox query fix, Users test files scoped within dialog containers, and Cluster/AuditLog/AdminLogs/AdminSettings_modregistries verified correct. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…dialogs (review of f8a6ac1d) Rewired Users.tsx to render InviteUserDialog, EditUserDialog, and ResetPasswordDialog from web/src/components/hero/admin/ in place of the three inline forms (InviteUserForm, EditUserForm, ResetPasswordForm). Deleted inline functions and now-unused imports (MIN_PASSWORD_LEN constant, UserCreate import, unused Label/Description/ModalBackdrop/ModalContainer imports). Extended each dialog with additive, backward-compatible props: - InviteUserDialog: optional `roles` prop + Role select, `contactFieldsOptional` to skip password for OIDC invites, `disableSubmitUntilValid` for preemptive submit disable, `apiError` to surface mutation errors - EditUserDialog: `username` description line, `isMe` + `roleGrantsUserManagement` for self-demotion warnings, internal `noChanges` computed state to disable Save, `extraContent` slot for NamespaceGrants, `apiError` - ResetPasswordDialog: `disableSubmitUntilValid` and `apiError` Users.tsx owns three useMutation hooks (create/save/reset) wired to dialog props; EditUserDialog's onSave receives (displayName, email, role) and Users.tsx diffs against the original user to send only changed fields via PATCH, matching prior partial-PATCH behavior. Updated Users.test.tsx and Users_invite.test.tsx queries only where dialog markup differs from inline forms: Invite submit button is 'Invite user' (not 'Create user'), Reset is 'Reset password' (not 'Set new password'), and disableSubmitUntilValid cases assert preemptive button disable rather than inline error messages. No it() blocks were removed. Extended hero/admin dialog components with new test cases covering every new prop. Verified via tsc --noEmit: zero errors for Users.tsx, Users.test.tsx, Users_invite.test.tsx, Users_tabs.test.tsx, and all hero/admin files. All remaining tsc errors are in inherited files (Servers.tsx, ServerDetail.tsx, server/*, tabs/*). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…arkup Verified AdminSettings.test.tsx, AdminSettings_sections.test.tsx, and Cluster.test.tsx against HeroUI v3 rebuilt components. Fixed two real mismatches: 1. AdminSettings.test.tsx line ~542: replaced `.rounded-lg` selector (lunaris Card utility class) with `[data-slot="card"]` (HeroUI v3 Card slot class). Verified via node_modules/@heroui/react Card component that CardRoot (aliased as Card) always sets data-slot="card" on root div, stable regardless of styling/class changes. 2. AdminSettings_sections.test.tsx line 322: replaced assertion for non-existent "Update channel" button with assertion for absence of combobox (the native select that never existed), more realistic HeroUI Select/ListBox query. Cluster.test.tsx required no changes: verified `.space-y-4` selector on NodeCard's CardContent against current markup and confirmed HeroUI's class-composition preserves passed Tailwind utilities on slot classes. All four files already use userEvent (no fireEvent) and already query HeroUI Selects via role "button" (Select.Trigger) + role "option" (ListBoxItem) rather than native combobox/select — no fireEvent->userEvent rewrites needed. Verified via tsc --noEmit: zero new errors; all reported errors are in pre-existing inherited list (Servers.tsx, ServerDetail.tsx, server/*, tabs/*). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
… viewer default, submit labels, optional contact fields (review of c36da82e) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…, dialog keys/labels; hidden-select assertion; specs.md Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…oUI v3 The Table component in HeroUI v3 requires at least one Column to have the isRowHeader prop set to true. This fixes the "A table must have at least one Column with the isRowHeader prop set to true" error that was causing 33 test failures. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…useEffect The RoleEditorModal was performing state updates (setResetFor, setName, setDescription, setSelectedPerms) directly during render, causing an infinite loop. Moved the reset logic to a useEffect hook with proper dependencies to fix the "Too many re-renders" error. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…ialog tests HeroUI v3's Select component doesn't expose a native <select> element with displayValue, so queries using findByDisplayValue and selectOptions timeout. Updated two tests to: 1. Find the Select by its label within the dialog 2. Click the Select to open the popover 3. Find and click the desired option by role This fixes the test timeouts in "submits an edit via PATCH" and "blocks self-demotion from user management role". Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…markup (dev box vitest green) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…een) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…global, RoleEditorModal state sync without setState-in-effect (CI ESLint on 44e026a) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…CI slowness Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…v3 unmount latch) Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
The AdminSettings_sections.test.tsx includes several complex async tests that take ~4.4 seconds locally but exceed the 5000ms default timeout in CI due to environment differences. Increasing the global testTimeout to 10000ms handles these cases while still catching legitimately slow tests. Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Euoj6Jxu2a2gBVqSM6VjcB Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…ule 1) Revert commits 0b7ed94 and 225ab6a which added per-file and global testTimeout options respectively. Per CLAUDE.md rule 1, timeout changes require maintainer sign-off before landing. Removes: - Global testTimeout: 10000 from web/vitest.config.ts - Per-file testTimeout: 10000 from AdminSettings_sections describe block Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Euoj6Jxu2a2gBVqSM6VjcB Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…drops (slice 4 had reverted d51de9d) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Euoj6Jxu2a2gBVqSM6VjcB Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
The AlertDialog's isKeyboardDismissDisabled behavior was not properly triggering onOpenChange when Escape was pressed. This manifests as the T031 test (unconfirmed admin dialog does not add group when cancelled) timing out — after pressing Escape, the dialog should close and clear the adminInput, but the input was never cleared. Add explicit onKeyDown handler to catch Escape and call onOpenChange(false), ensuring the dialog closes and the parent component can update state. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Euoj6Jxu2a2gBVqSM6VjcB Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…ared primitive) This reverts commit bfb0a4f. The commit broke ESLint (React not imported; CI job 102228430685 annotation ConfirmDialog.tsx:53 "'React' is not defined"), wrapped the shared ConfirmDialog primitive (used by every confirm/alert dialog in the app, not just the admin group dialog) in a bare div disconnected from AlertDialog's own layout/focus semantics, and rested on an unproven hypothesis about isKeyboardDismissDisabled without evidence that Escape handling was actually broken at the react-aria/HeroUI level. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Euoj6Jxu2a2gBVqSM6VjcB Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
…eroUI Tabs) Approved by maintainer 2026-09-09 (CLAUDE.md rule 1). web/src/routes/Users.tsx lines 12, 177: TabComponent is HeroUI's Tab component, which renders with role="tab" not role="button". Updated the spec's Roles tab locator accordingly. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Euoj6Jxu2a2gBVqSM6VjcB Signed-off-by: valgulnecron <39313199+ValgulNecron@users.noreply.github.com>
087df97 to
51793e4
Compare
Feature 014 slice 4: Admin Settings, Users, Audit Log, System Logs and Cluster routes rebuilt on HeroUI, plus the admin hero compositions (AuditIntegrityBanner, RoleEditorModal, ConfirmAdminMappingDialog, RemovableGroupChip, ProvenanceBadge, hero/admin Invite/Edit/ResetPassword dialogs). Stacked on #351 (
014c-servers-core); retarget tomasteronce #351 merges.Design — Pencil nodes for this slice: WZdnw uMiwd nNGDX QgW58 zqzr4 RC3Kf g5mEpx Wj0V4 n6Xlo uoxQW M2sA4u zM0VF bYDHC e9lV4 TBvTC Dpb9f DxKOh Bq2Yg j9W8A dxdEi kIxaJ CqaSq NLDDv t3IY3u MaoHP Kp48V uw0dB XL5ZU vStkb R65Xyx Rwnu3 BV5ei (design commit shared with #351). T145 (Pencil GUI save) is the maintainer's.
Code — T146–T162: routes import UI only from
@heroui/reactand@/components/hero/; Users renders the hero/admin dialogs (parity with the removed inline forms: live 12-char password hint, viewer default role, optional contact fields on edit, submit labels); state and handlers preserved; every pre-existingit()kept (counts unchanged or higher), 82 new tests for the hero components;slice4.spec.tsscreenshot spec covers every screen id above.Verification — vitest full suite green on the dev box (2090 passed, 0 unhandled errors); reviewed at opus and sonnet against the installed
@heroui/reactdeclarations; CI is the authority for the mock/live e2e tiers.🤖 Generated with Claude Code
https://claude.ai/code/session_0179Kk2kNC9XQD8n8nKG2fsZ