feat(frontend): add Roles & Permissions admin UI (EVO-1061)#55
Conversation
Reviewer's GuideImplements a Roles & Permissions admin UI with list and detail pages wired to a new roles service, adds navigation and i18n wiring for the new section, gates access via permissions, and removes outdated environment warnings from SMTP and storage settings. Sequence diagram for loading and saving role permissions in RoleDetailsequenceDiagram
actor AdminUser
participant AppRouter
participant PermissionRoute
participant RoleDetail
participant rolesService
participant permissionsService
participant apiAuth
AdminUser->>AppRouter: navigate /settings/roles/:id
AppRouter->>PermissionRoute: render resource=roles action=read
PermissionRoute-->>AppRouter: [authorized]
AppRouter-->>RoleDetail: mount
RoleDetail->>rolesService: get(id)
rolesService->>apiAuth: get /roles/:id
apiAuth-->>rolesService: ApiResponse<Role>
rolesService-->>RoleDetail: Role
RoleDetail->>permissionsService: getResourceActions()
permissionsService->>apiAuth: get /permissions/resource_actions
apiAuth-->>permissionsService: ResourceActionsData
permissionsService-->>RoleDetail: ResourceActionsData
RoleDetail-->>RoleDetail: build selected permissions Set
AdminUser->>RoleDetail: click savePermissions
RoleDetail->>rolesService: bulkUpdatePermissions(role.id, permissionKeys)
rolesService->>apiAuth: put /roles/:id/bulk_update_permissions
apiAuth-->>rolesService: ApiResponse<Role>
rolesService-->>RoleDetail: updated Role
Sequence diagram for listing, creating, and deleting roles in RolesListsequenceDiagram
actor AdminUser
participant AppRouter
participant PermissionRoute
participant RolesList
participant rolesService
participant apiAuth
AdminUser->>AppRouter: navigate /settings/roles
AppRouter->>PermissionRoute: render resource=roles action=read
PermissionRoute-->>AppRouter: [authorized]
AppRouter-->>RolesList: mount
RolesList->>rolesService: list()
rolesService->>apiAuth: get /roles
apiAuth-->>rolesService: ApiResponse<Role[]>
rolesService-->>RolesList: Role[]
AdminUser->>RolesList: click addRole
RolesList-->>RolesList: open create dialog
AdminUser->>RolesList: confirm create
RolesList->>rolesService: create(RoleFormData)
rolesService->>apiAuth: post /roles
apiAuth-->>rolesService: ApiResponse<Role>
rolesService-->>RolesList: Role
RolesList-->>AppRouter: navigate /settings/roles/:id
AdminUser->>RolesList: click deleteRole
RolesList-->>RolesList: open delete dialog
AdminUser->>RolesList: confirm delete
RolesList->>rolesService: destroy(role.id)
rolesService->>apiAuth: delete /roles/:id
apiAuth-->>rolesService: {}
rolesService-->>RolesList: void
RolesList-->>RolesList: remove role from list
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've left some high level feedback:
- The Suspense fallback spinner markup for the new roles routes is duplicated; consider extracting this into a small reusable loading component to keep the router config DRY and easier to tweak later.
- The
updatemethod inrolesServiceis currently unused; if there is no immediate use planned, consider removing it to avoid dead code and keep the service surface minimal.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The Suspense fallback spinner markup for the new roles routes is duplicated; consider extracting this into a small reusable loading component to keep the router config DRY and easier to tweak later.
- The `update` method in `rolesService` is currently unused; if there is no immediate use planned, consider removing it to avoid dead code and keep the service surface minimal.Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
- Add /settings/roles list page with search, create modal, delete confirmation - Add /settings/roles/:id detail page with permission tree grouped by resource - Wire to existing roles API (index/show/create/destroy/bulk_update_permissions) - Gate routes via PermissionRoute resource=roles action=read - Add Roles & Permissions sidebar entry (visible to super_admin and account_owner) - Register roles i18n namespace for all 6 locales (pt-BR, pt, en, es, fr, it) - Remove outdated envWarning banners from SmtpConfig and StorageConfig (EVO-1049/EVO-1050 pending) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add inline rename/edit UI for custom roles in RoleDetail (H2) - Clear permissions cache after bulk_update_permissions save and after role deletion in RolesList (H3) - Translate es/fr/it roles.json from English copies (H4) - Add menu.settings.roles key to es/fr/it/pt layout.json (H5) - Restore SMTP/Storage env warning banners and email.envWarning i18n keys across all 6 locales (H6) - Add saveChanges i18n key to all 6 roles.json locales Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…n roles UI (EVO-1061) - RoleDetail: filter selected keys against known resourceActions before calling bulkUpdatePermissions, preventing 422 on orphan keys (M1) - RolesList: extract API error message from response when create fails, showing specific validation feedback instead of a generic toast (M2) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- handleSave extracts apiErr.message from 403 before falling back to generic toast - handleSaveMeta and handleDeleteConfirm follow the same pattern Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
c4619cc to
701519e
Compare
dpaes
left a comment
There was a problem hiding this comment.
Approved.
Rebased cleanly onto develop (menuItems.ts conflict resolved keeping Products, Templates, and Roles). API error surfacing in handleSave, handleSaveMeta, and handleDeleteConfirm is correct — generic toasts replaced with the backend message and validation details fallback.
One medium-priority UX bug noted in RoleDetail.tsx#handleSaveMeta: clearing an existing description is a silent no-op because metaForm.description.trim() || undefined drops the key during JSON serialization, so the backend never sees the change. Non-blocking for this merge; tracked in the Linear card.
Merging with --delete-branch.
Summary
develop(resolves merge conflict inmenuItems.ts— keeps Products, Templates, and Roles all present)handleSave,handleSaveMeta, andhandleDeleteConfirminstead of generic toastsValidation
evo-ai-frontend-community: pnpm exec tsc -b --noEmit→ OKevo-ai-frontend-community: pnpm lint→ 879 pre-existing errors, zero new introducedChanged Files
src/pages/Admin/Roles/RoleDetail.tsxsrc/pages/Admin/Roles/RolesList.tsxsrc/services/roles/rolesService.tssrc/components/layout/config/menuItems.tssrc/routes/index.tsxsrc/i18n/config.tssrc/i18n/locales/*/roles.json(6 locales — new)src/i18n/locales/*/layout.json(6 locales)Related PRs
Linked Issue