feat(records): bulk close — multi-select toolbar + per-record транзакция
Backend POST /api/v1/dictionaries/{name}/records/bulk-close принимает
businessKeys[] (1..500) + reason. BulkRecordService крутит цикл через
inject'ed DictionaryRecordService — каждый close в своей транзакции
(SERIALIZABLE), partial success возможен. Result: closed[] / skipped[]
(already_closed, not_found) / errors[].
Frontend: checkbox column + sticky toolbar когда selection.size > 0.
Header checkbox с indeterminate state для partial select. selectAll
включает все ВИДИМЫЕ ключи (не игнорирует фильтры). При изменении
фильтра — useEffect выкидывает невидимые ключи из selection (WYSIWYG).
Bulk close dialog: count + reason input → confirm → результат панель
"Закрыто N, пропущено M, ошибок K" с детальным списком skipped/errors.
После успеха selection остаётся для skipped/errors — юзер видит что
ещё не сделано.
Лимит 500: защита от случайного огромного селекта или бага UI.
Дедупликация внутри batch'а silent skip — не error.
This commit is contained in:
@@ -113,6 +113,18 @@ export type CreateRecordRequest = {
|
||||
validTo?: string
|
||||
}
|
||||
|
||||
export type BulkCloseRequest = {
|
||||
businessKeys: string[]
|
||||
at?: string
|
||||
reason?: string
|
||||
}
|
||||
|
||||
export type BulkCloseResponse = {
|
||||
closed: string[]
|
||||
skipped: { businessKey: string; reason: string }[]
|
||||
errors: { businessKey: string; reason: string }[]
|
||||
}
|
||||
|
||||
export type AuditAction = 'CREATE' | 'UPDATE' | 'CLOSE'
|
||||
|
||||
export type AuditEntry = {
|
||||
|
||||
Reference in New Issue
Block a user