Grid filter input hardening and async bulk document updates (QA)
Executive summary
This release promotes two frontend changes to QA: numeric grid-filter inputs (mail and admin) now reject characters that produced confusing or wrong filter values, and the document grid now correctly recognizes when a bulk update is processed in the background instead of treating it as instantly finished. No new end-user features; this is a quality and correctness pass on existing grid filtering and bulk-edit flows.
Why this was needed
QA reported that the Batches Overview "Total Mails" filter accepted invalid input. A native numeric input allows scientific notation (e/E) and signs (+/-): typing a lone e left a stray character visible while the value read empty (looked broken), and 12e5 was silently treated as 1,200,000 — a value the user never intended. Separately, the backend moved document bulk updates to a set-based engine that can return 202 Accepted and finish the work in a background job; the frontend was treating that as a completed synchronous update, so grids could refresh before the job actually finished.
Client / user impact
- Count/numeric column filters in the mail and admin grids only accept valid digits (and a single decimal for float columns), so filtered results match what the user typed.
- The broken-looking "stray character" state on filter inputs is eliminated.
- Bulk document edits that the backend runs asynchronously no longer trigger a premature grid refresh; results are picked up when the job completes, reducing stale or empty views after a large edit.
Technical scope
Batch promotes dev → qa (9 commits across 2 PRs).
#1069 — Numeric grid-filter input guards
- New shared module
packages/ui/src/grid-filters/numeric-input-guards.tsexportingisDisallowedNumericKey,handleNumericKeyDown,handleNumericPaste(re-exported fromgrid-filters/index.ts). - Keydown blocks
e/E/+/-(and.on integer columns) while leaving editing/navigation keys and Ctrl/Cmd/Alt shortcuts intact; float columns reject a second decimal via a selection-aware check wrapped in try/catch for the Chrometype="number"selectionDOMException. - Paste is whitelist-validated (
INTEGER_PASTE_PATTERN/FLOAT_PASTE_PATTERN). - Guards wired (memoized) into both
apps/mailandapps/admincolumn-filter-popover.tsx; existingsanitizeNumericFilterBoundclamping unchanged.
#1068 — Async document bulk updates
isBulkJobAcceptedmoved totypes/bulk-operations.types.ts(re-exported frommail.services.tsfor back-compat);BulkMailJobAcceptedResponserenamed toBulkJobAcceptedResponse(legacy alias kept) with newqueued_count/async/operationfields.- Document mutation
onSuccesshandlers now skip query invalidation when the response is an accepted async job. document.services.tsupdate methods now return a sync-or-async union type; addedDocumentBulkUpdatePhaseand nullablefailed_detailstowebsocket.types.ts.- Hardened document-type list updates in two metadata views with
Array.isArray+ type-guardfilterbefore mapping.
Risk & mitigation
Low to moderate, scoped to grids and bulk edits. The filter guards are additive and could in theory block a legitimate keystroke, but named/navigation keys and clipboard shortcuts are explicitly preserved and value clamping is unchanged. The async-update change depends on the backend's 202/queued contract; if the backend returns an unexpected shape, the type guard's fallbacks (status optional, count fallbacks) reduce the chance of misclassification. Mitigation: validate against the live QA backend and confirm grid refresh on job completion. Note: Batches Overview column sorting is a separate backend issue (DSM_Backend#202) and is not addressed here.
QA validation focus
- Mail and admin grid numeric filters: confirm
e,E,+,-are rejected by typing and by paste; integer columns reject., float columns allow exactly one.. - Select-all then type/paste a new decimal in a float filter should be accepted; pasting letters/symbols/scientific notation should be rejected.
- Verify filtered results match the entered value (no silent
12e5-> 1,200,000). - Bulk document update / status change on a large selection: confirm the success toast, that the grid does not refresh prematurely, and that it updates once the background job completes.
- Test in Chrome specifically (selection
DOMExceptionpath) and at least one other browser.