fix(admin): name records by translatable (mltext) fields

The record heading, breadcrumb crumb and document title took the first
plain text field only, so records named by an mltext field fell back to
the generic update message. A shared recordDisplayName helper now takes
the first text or ML field and reads its default locale, then the first
non-empty one.
This commit is contained in:
Jakub Zych
2026-10-07 19:05:47 +02:00
parent 7554241e9d
commit a714bb4629
6 changed files with 105 additions and 13 deletions

View File

@@ -217,6 +217,35 @@ export function mergeMLValue(incoming: unknown, enabledLocales: readonly string[
return { ...seeded, ...localeRecord(incoming) }
}
/** The record's display name: the value of the first text-like field (plain
* `text` or an ML type) in schema order. An ML value reads the default (first
* enabled) locale, then the first non-empty locale; '' when nothing is set. */
export function recordDisplayName(
fields: readonly FormField[] | undefined,
values: AdminRecord,
enabledLocales: readonly string[],
): string {
const first = fields?.find((field) => field.type === 'text' || isMLFieldType(field.type))
const value = first ? values[first.name] : undefined
if (typeof value === 'string' || typeof value === 'number') {
return String(value).trim()
}
if (!first || !isMLFieldType(first.type)) {
return ''
}
const texts = localeRecord(value)
const preferred = enabledLocales[0] !== undefined ? (texts[enabledLocales[0]] ?? '').trim() : ''
if (preferred !== '') {
return preferred
}
for (const text of Object.values(texts)) {
if (text.trim() !== '') {
return text.trim()
}
}
return ''
}
/** D-10 422 details (field -> messages) as a string-list map. */
export function fieldErrors(details: ErrorBody['details'] | undefined): Record<string, string[]> {
const out: Record<string, string[]> = {}