Repository navigation
fix(frontend): hide Edit and Delete on system-managed groups - #1392
Conversation
The API refuses edits and deletes of system-managed groups (seeded by migrations: Administrators, Purchaser, RI Exchanger, Standard Users, Read-Only Users, ...) with ErrSystemManagedGroup / 403, but every group card offered Edit and Delete, so admins were handed actions that always fail. When Delete failed, the toast also dropped the server's reason and only said "Failed to delete group", while Edit already shows it. Cards for groups with system_managed: true now show a muted "System group" badge (tooltip plus screen-reader text explaining it cannot be edited or deleted, and that membership is changed from the Users list) in place of Edit and Delete. Duplicate stays, since it makes a separate, editable copy. deleteGroup refuses such a group up front instead of asking for confirmation, and a failed delete now reads "Failed to delete group: <server reason>". The list endpoint does not serialize system_managed yet (auth.APIGroup has no such field), so the cards only change once the backend sends it; the Delete message fix works today. Refs LeanerCloud#919 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reached
This review includes 5 billable files and costs up to $1.25. Or wait 59 minutes for your next included review. View limit details
Comment |
|
Independent review (IAmJSD's agent, fresh context, given only the diff, the issue and the PR text): APPROVE Blocking:
|
|
Local verification at
|
|
Marked ready and merged by IAmJSD's agent, at IAmJSD's request (IAmJSD reviewed the before/after screenshots; cristim is traveling), after the independent review and local verification above, all at |
Conflicts: - frontend/src/groups/groupList.ts: combined. Main (LeanerCloud#1392) hides Edit and Delete on system-managed groups and shows a "System group" badge instead; this branch turned Edit / Duplicate / Delete into icon buttons in a .row-actions group. Result: the badge replaces the pencil Edit button for locked groups, Delete (trash) is omitted for them, and Duplicate (copy) always shows, all inside .row-actions. Imports keep both iconSvg and main's systemGroups helpers. - frontend/src/groups/groupModals.ts: import block. Kept iconSvg (used by the trash Remove-permission button) and main's groupFormValidation and permissionOptions imports; dropped ALL_ACTIONS/ALL_RESOURCES/Action/ Resource, which main moved into permissionOptions.ts with the option builders. - frontend/src/history.ts: imports keep both iconSvg and main's history-queue-link helpers. Retry button and retry lineage badge keep this branch's alert-triangle / rotate-cw icons with main's Number(p.retry_attempt_n) || 0 coercion (LeanerCloud#1318 escaping hardening). - frontend/src/lib/history-filter-popover.ts: filter button keeps main's data-filter-scope attribute (LeanerCloud#1342) with this branch's filter icon in place of the ⛛ glyph. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…1513) The dashboard hides Edit and Delete on a group whose system_managed flag is true (#1392), but auth.APIGroup never carried the field, so the badge never showed. groupToAPIGroup now copies it as `system_managed` (omitted when false), matching frontend/src/api/types.ts. Service.UpdateGroup relied on its only caller, UpdateGroupAPI, to refuse a system-managed group. It now reads the stored row and refuses with ErrSystemManagedGroup (403 at the handler) itself, sharing the check with DeleteGroup via refuseSystemManagedGroup. Refs #919 Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Every group card offered Edit and Delete, including the seeded system-managed groups (Administrators, Purchaser, RI Exchanger, Standard Users, Read-Only Users), which the API always refuses with a 403. A refused Delete also showed only "Failed to delete group" and dropped the server's reason. This PR replaces Edit and Delete with a "System group" badge on those cards and includes the server's reason in the Delete error toast.
Refs #919
Partial: the cards only change once the API sends
system_managed(auth.APIGrouphas no such field on main yet), and the suggested guard onService.UpdateGroupis backend work not done here. The Delete error message works today.What changed
frontend/src/groups/systemGroups.tswithisSystemManagedGroupandSYSTEM_GROUP_NOTE.frontend/src/groups/groupList.ts: whengroup.system_managedis true, Edit and Delete are replaced by a muted "System group" badge with atitletooltip and screen-reader text ("Built-in group maintained by CUDly. It cannot be edited or deleted; change its members from the Users list."). Duplicate is kept.frontend/src/groups/groupActions.ts:deleteGrouprefuses a system-managed group before the confirm dialog, and a failed delete shows "Failed to delete group: ".src/__tests__/groups-system-managed-919.test.tsandtests-e2e/system-managed-groups.spec.ts.Why this approach
The buttons are hidden rather than disabled because disabled buttons cannot be focused and their tooltips do not show reliably; the badge explains why on hover and to screen readers and keeps the card uncluttered. Duplicate stays because copying a seeded group into an editable custom one is the legitimate way to start from it. The state comes from the API's
system_managedflag rather than a hardcoded list of seeded UUIDs, which would drift each time a migration locks another group (000059, 000096 and 000125 all changed the set). The helpers live in their own module sogroupListandgroupActionsdo not import each other.Screenshots
Before is main (
a14dc8f2), after is this branch. Both are headless Chromium at 1440x900 against the repo's mocked e2e API, withsystem_managed: trueon Administrators and Purchaser in the mocked/api/groupsand a 403 onDELETEfor the toast.Verification
Run on this branch's head
53bdb80fon top of maina14dc8f2:npm run lint: 0 errors (142 pre-existing warnings). Typecheck and build pass.groups-system-managed-919.test.ts(system card has no Edit/Delete, keeps Duplicate, badge tooltip and sr-only text; custom cards unchanged; a false or missing flag means custom;deleteGrouprefuses a system group without confirm or API call; server reason shown on a refused delete; generic fallback for an empty message) passes with--randomize.e2e-local.sh: 158 passed, including the newsystem-managed-groups.spec.ts.scripts/test-git-secrets-allowlist.sh: 137 PASS.Notes for review
system_managedtoday.internal/auth/service_api.goAPIGrouphas noSystemManagedfield andgroupToAPIGroupdoes not copy it, so in production the cards stay unchanged until a small backend change addsSystemManaged bool `json:"system_managed,omitempty"`toAPIGroupand sets it ingroupToAPIGroup. The frontend type inapi/types.tsalready declares the field.Service.UpdateGroup(internal/auth/service_group.go:30) is backend work and is not touched here.badge-muted) and its tooltip text.openEditGroupModalis shared with fix(frontend): a group holding a blank permission resource cannot be saved at all, with no explanation #213.Overlaps
groups/groupList.ts(empty-state line only, no conflict expected).groups/groupModals.tsandhandlers.ts(different files).Note for the UI owner
This changes UI code that @cristim owns. IAmJSD reviewed the before/after screenshots and asked for it to be merged; any design point you disagree with can be a follow-up.
🤖 Generated with Claude Code