Mail & Admin Frontend Batch: Live Bulk-Action Progress, Failure Details, and Loading Polish (QA)
Executive summary
A batch of seven frontend fixes was promoted from dev to the QA environment. It makes bulk mail actions report progress over the live notifications connection (with a reliable fallback), surfaces exactly which items failed in a partial bulk operation, stabilizes loading skeletons and PDF thumbnail rendering, and tightens several mail/admin UI details. No new end-user feature is introduced beyond these improvements; this is a quality and reliability pass now entering QA testing.
Why this was needed
Bulk mail operations (bulk assign, bulk update) previously leaned on immediate HTTP polling and could show jumpy or incomplete progress, and a partially failed bulk action gave no indication of which items failed. Separately, the frontend's real-time WebSocket types had drifted from the backend's actual message contracts, the socket could churn (disconnect/reconnect) when navigating between sections, table/grid loading states caused layout jumps, and a few smaller issues (missing tenant labels on users, mis-handled deleted-user references, dropdowns unscrollable inside dialogs) degraded the experience.
Client / user impact
- Bulk mail actions now prefer the live notifications connection for progress, with a graceful HTTP fallback only when the socket is slow or quiet, giving smoother and more accurate progress.
- When some items in a bulk action fail, the bottom-right progress panel now shows a clear summary (e.g. "X/Y updated, Z failed") plus an expandable list of the specific failures.
- Loading states for admin tables and mail grids no longer jump around, and PDF thumbnails render more reliably.
- Users now show their tenant badge when assigning to folders; deleted users display consistently as "Deleted User"; large user-pick lists load page-by-page as you scroll; and dropdowns inside dialogs scroll correctly.
Technical scope
Promotion of origin/dev into qa; no code added on top of dev. Notable included PRs:
- #954 socket-first bulk progress:
BulkOperationProgressnow enables HTTP polling only after grace windows (connect 2s, first-event 10s, stale 5s); adds successful/failed counts andfailedDetails, a newBulkOperationProgressFailureDetailspanel, and a guarded single-fire completion path. - #952 loading stabilization: new
data-table-skeleton-row/data-grid-skeleton-rowwith shimmer + staggered fade; tables lock cached column widths during load;PdfThumbnailGridrender-safety fixes. - #950 WS contract alignment: rewrites
packages/types/websocket.types.tsand the comments/upload/download/job socket hooks to match backend envelopes; adds close-code 1013 to skip-reconnect. - #948 socket lifecycle: hoists
NotificationsSocketProviderto the mail root layout via a newAuthenticatedSocketProvider, adds bfcache pagehide/pageshow handling and telemetry. - #949 tenant badges + paginated multi-select:
AdminMultiSelectgainsonPaginatedSearchinfinite scroll (cached, 20/page);UserMultiSelectadopts it; folder modals mapentity_name. - #947 deleted-user sentinel: new
user.constants.ts; activity logs/comments map sentineldeleted_userto "Deleted User" and keep "System" for null. - #946 review-bug fixes: numeric-id guard in user modals, infinite-retry break in MailForm label resolver, async-select label priority.
- #950/#949 popover-in-dialog: combobox/multi-select portal into the dialog container.
Risk & mitigation
Moderate, touching real-time progress and shared UI primitives. The socket-first progress path is timing-dependent: if the grace windows are mis-tuned, progress could stall before HTTP fallback kicks in, or briefly double-poll. WebSocket type changes are broad and could surface mismatches if backend contracts differ from the documented ones in QA. Mitigations: HTTP polling fallback still guarantees terminal completion; completion is single-fire guarded against duplicate signals; changes are additive UI improvements with existing flows preserved; QA is the intended gate before production.
QA validation focus
- Run bulk mail update/assign over a large selection: confirm live progress updates, accurate percentage, and timely terminal state with the socket connected and (force) when it is not.
- Trigger a bulk action with some items failing: verify the "X/Y updated, Z failed" summary and the expandable failure-details list show correct items.
- Navigate between dashboard and batches mid-operation: progress should persist without socket reconnect churn; check bfcache (back/forward) behavior.
- Verify admin tables and mail grids show stable skeletons (no layout jump) and that PDF thumbnails render without flicker/errors.
- Confirm tenant badges on users in folder assign modals, "Deleted User" display in activity logs/comments, infinite-scroll user lists, and that combobox/multi-select dropdowns scroll inside dialogs.