Appearance
Контракт данных представлений
Данные хранятся одновременно в двух формах. preset — живая конфигурация: фильтры, обе оси и вид ячейки по умолчанию. snapshot — зафиксированный результат генерации: готовые строки, столбцы и ячейки. Это даёт два режима работы — быстрый предпросмотр по фильтрам и ручная доводка зафиксированной таблицы.
Контракт общий для builder и портала — сохранённое представление открывается одинаково в обоих приложениях.
Структура представления
ts
/**
* Объект прав доступа для компонента-фасада LibMenuFolderView.
* Определяет, какие интерактивные действия разрешены в представлении.
*/
export interface MenuFolderViewPermissions {
/** Разрешить приём внешнего перетаскивания (D&D из дерева). */
canDropExternal?: boolean;
/** Разрешить ручную перестановку строк (осей). */
canReorderRows?: boolean;
/** Разрешить ручную перестановку столбцов (осей). */
canReorderColumns?: boolean;
/** Режим только для чтения: скрывает элементы управления и блокирует правки. */
readonly?: boolean;
}
export interface MenuFolderTableView {
/**
* Версия схемы сохранённого представления. Растёт при любом несовместимом
* изменении структуры `preset`/`snapshot`. Точка входа миграций: при
* десериализации (import, загрузка из БД) значение прогоняется через
* `migrateMenuFolderTableView` до `MENU_FOLDER_TABLE_VIEW_VERSION`.
* Свежесозданные представления всегда получают текущую версию.
*/
version: number;
/** Live-конфигурация таблицы: фильтры, обе оси и вид ячеек для генерации. */
preset: TableViewPreset;
/** Зафиксированный результат генерации или `null`, если snapshot ещё не создан. */
snapshot: TableViewSnapshot | null;
/**
* Выбранный источник данных превью (онлайн/snapshot). При `snapshot`, если сам
* snapshot ещё не сгенерирован, фактически показывается `preset`.
*/
displaySource: MenuFolderTableViewSource;
/**
* Режим отрисовки представления: `list` (сгруппированный список) или `table`
* (таблица). Не меняет структуру данных — те же `preset` и `snapshot`
* используются в обоих режимах, отличается только рендер. В режиме `list` ось
* столбцов скрывается, но её настройки сохраняются.
*/
displayMode: MenuFolderViewDisplayMode;
}
/**
* @description Текущая версия схемы `MenuFolderTableView`. Любое несовместимое
* изменение структуры preset/snapshot требует увеличения этого значения и
* регистрации соответствующего migrator'а в `migrateMenuFolderTableView`.
* Начальное значение — `0`.
*/
export const MENU_FOLDER_TABLE_VIEW_VERSION = 0;Preset: живая конфигурация
preset — живая конфигурация представления. Описывает, из каких объектов и каких полей собирать таблицу. Состоит из двух одинаковых по структуре осей rows/columns и вида ячейки по умолчанию.
Каждая ось — это набор "признаков" объекта. Для каждой оси через фильтр отбираются объекты. Таблица строится на пересечении "признаков". Объекты, полученные после фильтрации имеют множество "признаков". valuePath - путь до "признака" объекта. При наличии этого поля ось таблицы принимает все возможные значения этого "признака". Есть возомжность использовать для построения осей только их уникальные значения. Если у объекта одновременно встречается оба "признака" - строковый и столцевой, то этот объект отображается на пересечении строки и столбца. Если таких объектов несколько, отображается первый попавшийся.
ts
export interface TableViewAxisPreset {
/** Пресет {@link_doc object-filter}: отбирает объекты, участвующие в оси. */
filter: TableViewObjectFilterPreset;
/** Путь к полю объекта, значение которого становится ключом и подписью элемента оси (например `name`, `objectType`). */
valuePath: string;
/** Если `true` — одинаковые значения по `valuePath` схлопываются в один элемент оси; `false` оставляет каждое значение отдельным элементом. */
unique: boolean;
/**
* @description
* Словарь ручных подписей для значений оси. Ключом остаётся исходное
* значение, полученное по `valuePath`, потому что именно оно участвует в
* поиске пересечений таблицы и в повторной генерации snapshot. Значение
* словаря влияет только на отображаемый label строки, столбца или элемента
* списка.
*/
labelOverrides: Record<string, string>;
}
export interface TableViewPreset {
/** Конфигурация оси строк: фильтр, путь значения и подписи. */
rows: TableViewAxisPreset;
/** Конфигурация оси столбцов: фильтр, путь значения и подписи. В режиме `list` скрывается, но сохраняется. */
columns: TableViewAxisPreset;
/** Вид ячейки по умолчанию для свежесгенерированных ячеек таблицы. */
defaultCellView: TableViewCellView;
}Snapshot: зафиксированный результат
snapshot — зафиксированный результат генерации. Содержит готовые строки, столбцы и ячейки, собранные из preset. После генерации snapshot становится самостоятельным: его элементы переименовывают, переставляют, удаляют и переопределяют по отдельности, связь с preset разрывается. Это даёт ручную доводку первоначально выстроеной черзе preset таблицы.
ts
export interface TableViewSnapshot {
/** Зафиксированные строки оси на момент генерации. */
rows: TableViewAxisItem[];
/** Зафиксированные столбцы оси на момент генерации. В режиме `list` не отображаются, но сохраняются. */
columns: TableViewAxisItem[];
/** Зафиксированные ячейки таблицы — пересечения строк и столбцов. */
cells: TableViewCell[];
/** ISO-метка времени генерации snapshot. */
generatedAt: string;
}Строки, столбцы и ячейки
ts
export interface TableViewAxisItem {
/** Стабильный идентификатор элемента оси; используется в ссылках ячеек snapshot. */
id: string;
/** Исходное значение, полученное из объекта по `valuePath` пресета оси. */
value: string;
/** Отображаемый текст — значение или ручная подпись из `labelOverrides`. */
label: string;
}
export interface TableViewCell {
/** id строки, на пересечении которой стоит ячейка. */
rowId: string;
/** id столбца, на пересечении которого стоит ячейка. */
columnId: string;
/** id объекта портала в ячейке или `null`, если ячейка пуста. */
objectId: string | null;
/** Сохранённый вид ячейки (рендерер); если не задан — берётся `defaultCellView`. */
view?: TableViewCellView;
}