feat(admin-ui): record CRUD with json-schema-driven form

POST/PUT/DELETE формы для записей справочников. Schema-driven рендер полей
из definition.schemaJson — i18n-aware (x-localized → input на каждый supportedLocale),
enum → select, type → text/number/checkbox/array. Валидация через ajv (Draft-07,
match backend networknt validator).

- new: api/mutations.ts с Idempotency-Key (crypto.randomUUID) и query invalidation
- new: SchemaDrivenForm — react-hook-form + ajv compile per-schema, errors через
  setError по ajv instancePath
- new: Modal (Esc + backdrop click) и confirm dialog для close-операции
- nginx: regex location ^/api/v1/dictionaries/[^/]+$ → writer (admin schema fetch)
- queries: dictionaryDetailQuery возвращает full def с schemaJson
- i18n: RU/EN ключи для CRUD (create/edit/close, validFrom/validTo, confirm)
This commit is contained in:
Zimin A.N.
2026-05-04 01:49:08 +03:00
parent d5a747616a
commit b1b1f05e3c
11 changed files with 3137 additions and 36 deletions
+34
View File
@@ -20,7 +20,24 @@ i18n
'dict.col.scope': 'Scope',
'dict.col.validFrom': 'Действует с',
'dict.col.locale': 'Локаль',
'dict.col.actions': 'Действия',
'dict.list.records': 'записей',
'dict.action.create': 'Создать запись',
'dict.action.edit': 'Изменить',
'dict.action.close': 'Закрыть',
'dict.confirmClose.title': 'Закрыть запись?',
'dict.confirmClose.body':
'Запись «{{key}}» будет помечена как закрытая (valid_to = now). Действие обратимо через создание новой версии.',
'dict.confirmClose.reason': 'Причина (опционально)',
'dict.confirmClose.reasonPlaceholder': 'например, «дубликат» или «выведено из эксплуатации»',
'form.businessKey': 'Бизнес-ключ',
'form.validFrom': 'Действует с',
'form.validTo': 'Действует до',
'form.dataFields': 'Поля записи',
'form.cancel': 'Отмена',
'form.save': 'Сохранить',
'form.saving': 'Сохранение...',
'form.error.required': 'Обязательное поле',
'loading': 'Загрузка...',
'error.failed': 'Не удалось загрузить данные',
},
@@ -35,7 +52,24 @@ i18n
'dict.col.scope': 'Scope',
'dict.col.validFrom': 'Valid from',
'dict.col.locale': 'Locale',
'dict.col.actions': 'Actions',
'dict.list.records': 'records',
'dict.action.create': 'Create record',
'dict.action.edit': 'Edit',
'dict.action.close': 'Close',
'dict.confirmClose.title': 'Close record?',
'dict.confirmClose.body':
'Record "{{key}}" will be marked as closed (valid_to = now). Reversible by creating a new version.',
'dict.confirmClose.reason': 'Reason (optional)',
'dict.confirmClose.reasonPlaceholder': 'e.g., "duplicate" or "decommissioned"',
'form.businessKey': 'Business key',
'form.validFrom': 'Valid from',
'form.validTo': 'Valid to',
'form.dataFields': 'Record fields',
'form.cancel': 'Cancel',
'form.save': 'Save',
'form.saving': 'Saving...',
'form.error.required': 'Required field',
'loading': 'Loading...',
'error.failed': 'Failed to load data',
},