All updates
QAFrontend

Role permission saves and bulk download counts fixed (QA)

PR #972pixbox-supportApr 15, 2026 · 09:53 UTC
QAApr 15, 2026

Executive summary

Promotes two correctness fixes from development into the QA environment. The first stops the admin Roles screen from silently discarding a role's permissions when its permission list spans multiple pages, and makes the Roles grid refresh immediately after any change. The second corrects the bulk-download progress counter, which was showing "NaN files updated" instead of the actual count of files downloaded.

Why this was needed

Two distinct defects reached users on development. In Admin, editing a role with more than one page of assigned permissions rebuilt the permission list from only the visible page and sent it as a full replacement, so every permission on other pages was silently dropped on save; separately, the Roles grid kept showing stale rows after a save until a hard page refresh. In Mail, the bulk ZIP download progress panel displayed "NaN files updated" on success because the completion event omits count fields and the copy always said "updated" regardless of operation.

Client / user impact

  • Admin users can edit roles with many permissions across multiple pages without accidentally losing assignments on pages they did not view.
  • The Roles grid now reflects create, edit, delete, and permission changes immediately, no manual refresh needed.
  • The bulk download progress panel shows an accurate count with the correct wording ("N files downloaded"), instead of the confusing "NaN files updated".
  • Bulk status updates and batch uploads continue to read "updated" and "processed" respectively.

Technical scope

Scope is small and frontend-only (8 files, +89/-45), covering two feature PRs:

PR #974 — admin role permissions + grid staleness:

  • RoleFormDialog now sends the backend's incremental { add_permission_ids, remove_permission_ids } payload instead of reconstructing a full permission_ids list from one paginated page.
  • AssignRolePermissionsRequest type and the Zod schema were narrowed to the incremental shape so the unsafe full-replacement payload is no longer representable.
  • Introduced a 2-segment ROLES_LIST_KEY (["admin", "roles-list"]) prefix and routed all role mutations (create/update/delete/assign) through it, fixing a TanStack Query key mismatch ("roles" vs "roles-list") that left the grid stale; removed the dialog's redundant invalidation calls.
  • Removed an unused export and refreshed stale JSDoc/route comments.

PR #971 — bulk ZIP download count:

  • useJobProgressSocket now guards count fields so only finite numeric values overwrite state, preventing a partial WebSocket completion event from caching NaN.
  • BulkOperationProgress derives an explicit actionVerb per operation type (downloaded / processed / updated) for both the counter and the minimized summary.

Risk & mitigation

Low. Changes are confined to the admin Roles dialog/mutations and the Mail bulk-progress UI; no backend or shared-package changes. The permission payload switch depends on the backend supporting the incremental add/remove fields (verified against the dev API per the commit notes). A separate, unrelated backend issue (DSM_Backend_dev#144) — the bulk ZIP endpoint not honoring the workspace-tenant header for enterprise-filtered downloads — is out of scope and unaffected by this UI fix.

QA validation focus

  • Roles (Admin): Edit a role with permissions spanning more than one page, toggle some on/off across pages, save; confirm no page's assignments are silently dropped and the count is correct.
  • Confirm the Roles grid updates without a hard refresh after edit, create, delete, and permission changes.
  • Confirm the "cannot remove admin access if no other admin role exists" guard still triggers.
  • Bulk download (Mail): On /inbox apply an Enterprise filter, select-all, Download; confirm the counter reads "N files downloaded" (not "NaN files updated") and the minimized summary reads "Download complete — file downloaded".
  • Regression: bulk status update still reads "N mails updated"; batch upload still reads "N files processed".