Appearance
Виджет
По умолчанию рендерер ячейки получает из snapshot только rendererId и ссылку на объект — ничего живого. Чтобы виджет в ячейке показывал реальные данные, host-приложение поднимает оркестратор и кладёт его в cellRendererContext. Эта страница описывает паттерн.
Оркестратор
Поднимает живые данные для набора объектов и переиспользуется одновременно страницей онлайн-объектов и table-view рендереры.
Компонент-потребитель получает services — стабильный объект функций, который можно переиспользовать.
ts
interface UseWidgetOrchestratorParams {
/** Список объектов, для которых оркестратор поддерживает живые данные. */
objects: MaybeRefOrGetter<ConcreteObjectInstance[]>;
/** Input: текущий портал/проект — нужен для построения URL WebSocket и accidentAlarm. Ячейке не виден. Принимает union: на портале это IRootPortal, в проекте — IRootProject. */
root: IRootProject | IRootPortal;
/** Опциональный колбэк для логов (виджет-группа передаёт `emit("logEvent", ...)`). */
onLog?: (log: IWidgetLogItem) => void;
}
interface UseWidgetOrchestratorResult {
/** Стабильный объект сервисов — кладётся в `cellRendererContext` напрямую. */
services: ComputedRef<WidgetServices>;
/** UI-state: для каждого объекта — раскрыта ли у него доп. панель. */
objectIsShowAdditionalPanel: Ref<Record<string, boolean>>;
/** Готовит пропсы для display-виджета (используется WidgetGroup'ом). */
getObjectWidgetProps: (object: ConcreteObjectInstance) => Record<string, unknown>;
/** Открывает диалог квитирования аларма (один на host-компонент). */
openAcknowledgeDialog: (alarm: IAlarmWidget) => void;
/** Реактивный текст комментария диалога квитирования — биндится к `<TextArea>`. */
dialogComment: Ref<string>;
}Контекст рендерера
ts
/**
* Сервисы оркестратора — то, что рендерер ячейки читает из `props.context`.
* Передаётся host-приложением через `cellRendererContext` и доезжает до каждой
* ячейки как `props.context`. Содержит только функции доступа к живым данным —
* никакой информации о текущем портале (`root`): это внутренний input оркестратора,
* ячейке он не нужен.
*/
export interface WidgetServices {
/** Реактивно возвращает состояние объекта или `null`, если состояния ещё нет. */
getState: (objectId: string) => unknown | null;
/** Реактивно возвращает список алармов объекта (пустой массив, если алармов нет). */
getAlarms: (objectId: string) => IAlarmWidget[];
/** Возвращает commandService для объекта по его типу и типу display-виджета. */
getCommandService: (objectType: EObjectType, displayType: ObjectDisplayType) => unknown;
/** Текущие права доступа: WRITE для управления, READ для превью. */
accessRights: AccessRights;
/**
* Открывает диалог квитирования аларма (один на всю таблицу, рендерится
* в host-компоненте). Вызывается рендерером по `@onAcknowledge` от виджета.
* Сетевой вызов `accidentAlarm` делается внутри, после подтверждения юзером.
*/
acknowledgeAlarm: (alarm: IAlarmWidget) => void;
/** Тост-сервис: нужен виджетам для показа сообщений об ошибках команд. */
toastService: TToast;
}
/**
* Контекст виджет-рендерера ячейки. Равен `WidgetServices` — объекту функций
* оркестратора. Host кладёт `orchestrator.services.value` в `cellRendererContext`.
*/
export type TableViewWidgetRendererContext = WidgetServices;