[scanner] fix: add loading states to async button handlers - #21295
Conversation
- NamespaceAccessPanel: add per-entry revokingBindingName state to handleRevokeAccess; disable and show spinner on revoke button during the DELETE rolebinding call to prevent double-submission - UserManagementModal: change DeleteUserConfirmModal.onConfirm type to Promise<void>, add isDeleting state, pass isLoading to ConfirmDialog so the confirm button is disabled while the delete is in flight - UserManagementList: remove premature setDeleteConfirmUserId(null) so the modal stays open until the async delete resolves/rejects - UserManagement.types: update onDeleteUser signature to Promise<void> Fixes #21293 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Scanner <scanner@kubestellar.io>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
✅ Deploy Preview for kubestellarconsole ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
👋 Hey @clubanderson — thanks for opening this PR!
This is an automated message. |
|
🐝 Hi @clubanderson! I'm Trusted users — org members and contributors with write access — can mention Automation may take a moment to start, and follow-up happens through workflow activity rather than chat replies. |
✅ Test Coverage CheckAll new source files in this PR have corresponding test files. Checked |
Auto Test GeneratorThe following new files have no corresponding test file:
Please add tests or apply the |
♿ Accessibility Audit (WCAG 2.1 AA)✅ No WCAG 2.1 AA violations detected in audited routes. Powered by axe-core. Target: WCAG 2.1 AA compliance. |
There was a problem hiding this comment.
Pull request overview
Adds in-flight UX feedback (loading + disabled states) for destructive async actions so users get clear progress indication and double-submissions are avoided across namespace access revocation and console user deletion flows.
Changes:
NamespaceAccessPanel: disables the revoke button and shows a spinner while the DELETE rolebinding request is in flight.UserManagementModal/UserManagementList: makes delete confirmation async-aware and wiresisLoadingthroughConfirmDialogto disable buttons during deletion.- Updates
onDeleteUsertyping to returnPromise<void>to match the async delete implementation.
Note: build/lint are validated by CI on the PR (per AGENTS.md).
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| web/src/components/namespaces/NamespaceAccessPanel.tsx | Adds revoke-button loading/disabled state while RBAC revocation runs. |
| web/src/components/cards/UserManagementModal.tsx | Adds isDeleting state and passes isLoading to ConfirmDialog while awaiting async confirm. |
| web/src/components/cards/UserManagementList.tsx | Keeps delete confirm modal open until the async delete finishes by awaiting onConfirm. |
| web/src/components/cards/UserManagement.types.ts | Updates onDeleteUser to return Promise<void> to reflect async behavior. |
| setRevokingBindingName(binding.bindingName) | ||
| try { | ||
| const params = new URLSearchParams({ |
| if (!window.confirm(`Revoke access for ${binding.subjectName}?`)) { | ||
| return |
| console.error('Failed to revoke access:', err) | ||
| showToast('Failed to revoke access', 'error') |
|
Thank you for your contribution! Your PR has been merged. Check out what's new:
Stay connected: Slack #kubestellar-dev | Multi-Cluster Survey |
|
Post-merge build verification passed ✅ Both Go and frontend builds compiled successfully against merge commit |
✅ Post-Merge Verification: passedCommit: |
Fixes #21293
Changes
Add missing
isLoading/disabled states to three async button handlers that lacked visual feedback during in-flight operations:NamespaceAccessPanel— revoke access buttonrevokingBindingNamestate (per-entry) tohandleRevokeAccessLoader2spinner while the DELETE rolebinding call is in flightUserManagementModal— delete user confirmationonConfirmtype to(userId: string) => Promise<void>isDeletingstate; passisLoading={isDeleting}toConfirmDialogUserManagementList+UserManagement.typesonDeleteUsertype toPromise<void>to match the asynchandleDeleteUserimplementationsetDeleteConfirmUserId(null)so the modal stays open until the operation completes