Files
mdm-ordinis/ordinis-admin-ui/src
Zimin A.N. 361f3b431c feat(approval): bulk approve/reject в /reviews queue (Phase 4 polish)
Phase 4 last optional UX из design doc — bulk operations:

- Multi-select column в reviewer queue (Checkbox per row + select-all
  header). Set<draftId> selection state, persisted между refetch'ами.
- "Approve выбранные" — confirm dialog → parallel approveDraft mutations
  через Promise.all. Каждая mutation independent: если одна fail
  (409 self_approve_forbidden / draft_not_pending race), остальные
  продолжают.
- "Reject выбранные" — Modal с TextArea для shared reason (required,
  matches backend reject_reason_required validation). Reason одинаковый
  для всех — bulk обычно "duplicate registration" / "wrong scope" / etc.
- Bulk result Alert: approved count / rejected count / failed list с
  per-draft reason'ами (err code из 409). User видит точно что прошло
  и что нет.
- Auto-clear selection после bulk operation. Queue refetch'ит через
  refetchInterval=30s, плюс mutation onSuccess invalidate'ит ['drafts'].

i18n RU/EN: 22 keys (selectAll/selectRow/selectedCount/approveSelected/
rejectSelected/clear/confirmApprove/rejectModal*/confirmReject/cancel/
resultTitle/approvedCount/rejectedCount/failedCount). Pluralization
через i18next plurals.

Why ship without soak data:
- Implementation не зависит от queue depth — это просто loop'ит над
  выбранными drafts.
- Reviewer на любом dict с queue >5 уже выгадывает время.
- Если queue staying small после soak — feature не bothering нас (UI
  toolbar показывается только когда anySelected).

Tests: vitest 89/89, tsc clean, prod build clean.
2026-05-10 12:12:57 +03:00
..