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
// не-локализованные scalar'ы. Skip name/code/businessKey (уже показаны),
// всё нескалярное (object/array/localized).
// Schema-driven extra columns: ВСЕ scalar non-localized поля schema'ы
// редактируемые в drawer'е — те же что и в edit-form. Юзер сам через
// ColumnVisibilityMenu выбирает что показывать (стейт persisted в
// localStorage per dict).
//
// Раньше cap = 2, чтобы строка comfortably fits на 1280px. Сейчас cap
// снят — все eligible колонки в pool, юзер выбирает через
// ColumnVisibilityMenu (стейт persisted в localStorage per dict).
// Soft cap 8 — защита от absurd schemas (50+ enum полей сломали бы
// toolbar layout до того как user успел зайти в menu).
// Skip: name/code/businessKey (primary identifier уже отдельной колонкой),
// localized (требует locale-aware рендер, не подходит для compact pill),
// array/object (рендеримся как [object Object] — бесполезно в строке).
//
// 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 props = detailQuery.data?.schemaJson?.properties ?? {}
const interesting: { key: string; label: string; isFk: boolean }[] = []
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
const isLocalized = Boolean(prop['x-localized'])
if (isLocalized) continue
const isEnum = Array.isArray(prop.enum) && prop.enum.length > 0
if (Boolean(prop['x-localized'])) continue
const type = prop.type
// 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'])
if (!isEnum && !isFk) continue
interesting.push({ key, label: humanize(key), isFk })
}
return interesting