fix: confirm admin role toggle and keep the checkbox controlled
The admin checkbox fired an immediate, irreversible privilege change with no confirmation, and on cancel/failure the optimistic DOM flip stuck while the server state was unchanged. Add a confirm() gate (like Delete) and make the checkbox controlled by u.is_admin: onchange reverts the DOM immediately and it only flips once the server confirms — so a cancelled or failed toggle never misrepresents the real role. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -51,12 +51,19 @@
|
||||
}
|
||||
|
||||
async function onToggleAdmin(id: string, next: boolean) {
|
||||
// Privilege changes are one-click and consequential — confirm first,
|
||||
// like Delete. The checkbox is kept controlled by `u.is_admin` (see the
|
||||
// onchange handler), so a cancel here leaves it showing the true state.
|
||||
const verb = next ? 'grant admin rights to' : 'revoke admin rights from';
|
||||
if (!confirm(`Are you sure you want to ${verb} this user?`)) return;
|
||||
busyId = id;
|
||||
try {
|
||||
await setUserAdmin(id, next);
|
||||
await load();
|
||||
} catch (e) {
|
||||
error = e instanceof ApiError ? e.message : 'update failed';
|
||||
// The checkbox was reverted in onchange and `u.is_admin` is
|
||||
// unchanged, so it correctly still reflects the server state.
|
||||
} finally {
|
||||
busyId = null;
|
||||
}
|
||||
@@ -187,7 +194,15 @@
|
||||
type="checkbox"
|
||||
checked={u.is_admin}
|
||||
disabled={busyId === u.id || isSelf}
|
||||
onchange={(e) => onToggleAdmin(u.id, e.currentTarget.checked)}
|
||||
onchange={(e) => {
|
||||
const desired = e.currentTarget.checked;
|
||||
// Keep the box controlled by `u.is_admin`: undo the
|
||||
// optimistic flip so it only changes once the server
|
||||
// confirms — and never lies if the change is
|
||||
// cancelled or the request fails.
|
||||
e.currentTarget.checked = u.is_admin;
|
||||
onToggleAdmin(u.id, desired);
|
||||
}}
|
||||
aria-label="admin"
|
||||
/>
|
||||
</td>
|
||||
|
||||
Reference in New Issue
Block a user