361f3b431c
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.
Ordinis Admin UI
React 19 + Vite 7 + TanStack Router + TanStack Query + Tailwind v4 + i18next.
Локально
cd ordinis-admin-ui
pnpm install
# .env.local: VITE_API_PROXY=http://localhost:8081 (port-forward read-api)
pnpm dev
Контракт API
GET /api/v1/dictionaries(read-api) — список справочниковGET /api/v1/{dictionaryName}/records(read-api) — записи с локализациейPOST /api/v1/dictionaries(writer) — создание справочника (TODO в UI)POST /api/v1/dictionaries/{name}/records(writer) — создание записи (TODO в UI)
Сборка / Docker
docker build -t repo.nstart.cloud/terravault/ordinis-admin-ui:dev .
docker run --rm -p 8088:80 repo.nstart.cloud/terravault/ordinis-admin-ui:dev
# → http://localhost:8088
В кластере nginx проксирует /api/v1/* в ordinis-read-api (GET) и
ordinis-app (POST/PUT/PATCH/DELETE).