fix(admin-ui): запись не сохранялась при пустом optional x-localized поле
Симптом: «Сохранить» (create и edit) ничего не делал, ошибок не видно.
Причина: x-localized поле рендерит Controller на каждую локаль
(data.<field>.<locale>). RHF при сабмите реконструирует values из имён
зарегистрированных полей и материализует родительский объект даже когда
исходное значение было null/отсутствовало → optional поле (например
mission) превращалось в { "ru-RU": undefined, "en-US": undefined }.
AJV отвергал undefined-локали ("must be string"), submit() делал return
до onSubmit — запрос не уходил. Ошибка ложилась через setError на
data.<field>.<locale>, а FieldError читает data.<field> → невидима.
Фикс: pruneEmpty() в submit() рекурсивно убирает undefined и опустевшие
объекты из data перед AJV-валидацией и отправкой — нетронутое
optional-поле снова валидируется как «отсутствует». Не трогает
null/''/0/false.
Откат временной диагностики [ordinis-diag] из MR !251.
Regression-тест падает без фикса, проходит с фиксом.
This commit is contained in:
@@ -578,12 +578,6 @@ function DictionaryDetail() {
|
||||
const rawRecordQuery = useRecordRaw(name, editingKey)
|
||||
|
||||
const handleSubmit = (req: CreateRecordRequest) => {
|
||||
// [ordinis-diag] DIAGNOSTIC BUILD — удалить после диагностики.
|
||||
console.warn('[ordinis-diag] route.handleSubmit(): получен req от формы', {
|
||||
editKind: edit.kind,
|
||||
approvalRequired,
|
||||
businessKey: req.businessKey,
|
||||
})
|
||||
// Fill validFrom at submit (review #5): defaultValues в RHF берётся
|
||||
// ТОЛЬКО при mount. Если user открыл modal в 12:00 и submit в 12:05 —
|
||||
// `validFrom` в req это значение из 12:00. Backend check `validFrom >
|
||||
@@ -637,20 +631,14 @@ function DictionaryDetail() {
|
||||
)
|
||||
return
|
||||
}
|
||||
console.warn('[ordinis-diag] route: вызываю createMut.mutate() — POST /records')
|
||||
createMut.mutate(
|
||||
{ payload: submitReq, idempotencyKey: recordIdempotencyKey },
|
||||
{
|
||||
onSuccess: () => {
|
||||
console.warn('[ordinis-diag] createMut onSuccess — запись создана')
|
||||
setEdit({ kind: 'closed' })
|
||||
resetRecordIdempotencyKey()
|
||||
},
|
||||
onError: (err) => {
|
||||
console.warn('[ordinis-diag] createMut onError', {
|
||||
status: (err as { response?: { status?: number } })?.response?.status,
|
||||
data: (err as { response?: { data?: unknown } })?.response?.data,
|
||||
})
|
||||
// Create rarely conflicts (no prior record to lock), но если backend
|
||||
// вернёт 409 по уникальному ключу — businessKey возьмём из payload.
|
||||
handleSaveError(err, submitReq.businessKey ?? '')
|
||||
@@ -681,7 +669,6 @@ function DictionaryDetail() {
|
||||
)
|
||||
return
|
||||
}
|
||||
console.warn('[ordinis-diag] route: вызываю updateMut.mutate() — PUT /records/' + edit.record.businessKey)
|
||||
updateMut.mutate(
|
||||
{
|
||||
businessKey: edit.record.businessKey,
|
||||
@@ -690,17 +677,10 @@ function DictionaryDetail() {
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
console.warn('[ordinis-diag] updateMut onSuccess — запись обновлена')
|
||||
setEdit({ kind: 'closed' })
|
||||
resetRecordIdempotencyKey()
|
||||
},
|
||||
onError: (err) => {
|
||||
console.warn('[ordinis-diag] updateMut onError', {
|
||||
status: (err as { response?: { status?: number } })?.response?.status,
|
||||
data: (err as { response?: { data?: unknown } })?.response?.data,
|
||||
})
|
||||
handleSaveError(err, edit.record.businessKey)
|
||||
},
|
||||
onError: (err) => handleSaveError(err, edit.record.businessKey),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user