feat(dict): таблица справочника — все scalar поля схемы в pool колонок

This commit is contained in:
Александр Зимин
2026-06-02 11:50:16 +00:00
parent 4510d7cc6f
commit 65f5dbd48b
@@ -586,26 +586,31 @@ function DictionaryDetail() {
) )
} }
// Schema-driven extra columns: enum + reference поля — самые info-dense // Schema-driven extra columns: ВСЕ scalar non-localized поля schema'ы
// не-локализованные scalar'ы. Skip name/code/businessKey (уже показаны), // редактируемые в drawer'е — те же что и в edit-form. Юзер сам через
// всё нескалярное (object/array/localized). // ColumnVisibilityMenu выбирает что показывать (стейт persisted в
// localStorage per dict).
// //
// Раньше cap = 2, чтобы строка comfortably fits на 1280px. Сейчас cap // Skip: name/code/businessKey (primary identifier уже отдельной колонкой),
// снят — все eligible колонки в pool, юзер выбирает через // localized (требует locale-aware рендер, не подходит для compact pill),
// ColumnVisibilityMenu (стейт persisted в localStorage per dict). // array/object (рендеримся как [object Object] — бесполезно в строке).
// Soft cap 8 — защита от absurd schemas (50+ enum полей сломали бы //
// toolbar layout до того как user успел зайти в menu). // Cap 30 — soft защита от absurd schemas. На практике справочники ЦУОД
// имеют 5-15 полей, drawer показывает их все — таблица теперь
// паритетна. FK маркеры (x-references) подсвечиваются accent цветом
// в строке row, остальные — нейтральный ink pill.
const extraColumns = useMemo<{ key: string; label: string; isFk: boolean }[]>(() => { const extraColumns = useMemo<{ key: string; label: string; isFk: boolean }[]>(() => {
const props = detailQuery.data?.schemaJson?.properties ?? {} const props = detailQuery.data?.schemaJson?.properties ?? {}
const interesting: { key: string; label: string; isFk: boolean }[] = [] const interesting: { key: string; label: string; isFk: boolean }[] = []
for (const [key, prop] of Object.entries(props)) { for (const [key, prop] of Object.entries(props)) {
if (interesting.length >= 8) break if (interesting.length >= 30) break
if (key === 'name' || key === 'code' || key === 'businessKey') continue if (key === 'name' || key === 'code' || key === 'businessKey') continue
const isLocalized = Boolean(prop['x-localized']) if (Boolean(prop['x-localized'])) continue
if (isLocalized) continue const type = prop.type
const isEnum = Array.isArray(prop.enum) && prop.enum.length > 0 // Array / object не рендерятся в pill — String([1,2,3]) = "1,2,3"
// ОК, но String({...}) = "[object Object]". Пропускаем оба.
if (type === 'array' || type === 'object') continue
const isFk = typeof prop['x-references'] === 'string' && Boolean(prop['x-references']) const isFk = typeof prop['x-references'] === 'string' && Boolean(prop['x-references'])
if (!isEnum && !isFk) continue
interesting.push({ key, label: humanize(key), isFk }) interesting.push({ key, label: humanize(key), isFk })
} }
return interesting return interesting