import { TransitionState } from '@wix/bex-core'; import { reaction } from 'mobx'; import { Column } from '../model'; import { CustomColumnsActionName } from './CustomColumnsState'; import { SidePanelsState } from './SidePanelsState'; import { CustomColumnsPanelStateBase } from './CustomColumnsPanelStateBase'; import { SchemaFieldsState } from './SchemaCard/SchemaFieldsState'; import type { CustomColumnsDragAndDrop } from '../components/CustomColumns/CustomColumnsDragAndDrop'; import type { CustomColumnsDragAndDropState } from './CustomColumnsDragAndDropState'; import type { Field, SchemaConfig } from '../types/SchemaConfig'; export interface CustomColumnsEntityPageStateParams { panels: SidePanelsState; container: import('@wix/bex-core').WixPatternsContainer; fieldsState: SchemaFieldsState; schema: SchemaConfig; showFieldTypeIcons?: boolean; dragAndDrop?: typeof CustomColumnsDragAndDrop; modalsContainerRef: { current: HTMLElement | null | undefined; }; } function fieldToColumn( field: Field & { isPii?: boolean; isSystem?: boolean; isPrimary?: boolean }, hideable: boolean, ): Column { return { id: field.id, name: field.displayName, title: field.displayName, render: () => null, fieldType: field.type as Column['fieldType'], hideable, isPii: field.isPii, isSystem: field.isSystem, isPrimary: field.isPrimary, validation: field.validation?.required ? [{ type: 'required' as const, message: '' }] : undefined, }; } export class CustomColumnsEntityPageState extends CustomColumnsPanelStateBase { readonly panels: SidePanelsState; readonly fieldsState: SchemaFieldsState; readonly _showFieldTypeIcons: boolean; readonly _schema: SchemaConfig; readonly _dragAndDrop?: CustomColumnsDragAndDropState; constructor(params: CustomColumnsEntityPageStateParams) { super({ container: params.container, queryName: 'entity-page-custom-columns', }); this.panels = params.panels; this.fieldsState = params.fieldsState; this._showFieldTypeIcons = params.showFieldTypeIcons ?? true; this._schema = params.schema; if (params.dragAndDrop) { const { fieldsState } = params; // eslint-disable-next-line @typescript-eslint/no-this-alias const self = this; const { CustomColumnsDragAndDropState: DnDState } = params.dragAndDrop; this._dragAndDrop = new DnDState({ customColumns: this, dataSource: { get columns() { return self.orderedColumns; }, selectedColumns: { get value() { return fieldsState.orderedFields.map((f) => ({ id: f.id, isSelected: fieldsState.isFieldVisible(f.id), })); }, refresh(reordered) { fieldsState.setFieldOrder( reordered.map((s) => ({ id: s.id, isVisible: s.isSelected ?? true, })), ); }, }, }, components: params.dragAndDrop, modalsContainerRef: params.modalsContainerRef, }); } this.initBaseObservables(); } get orderedColumns(): Column[] { const { fields } = this._schema; return this.fieldsState.orderedFields .map((viewConfig) => { const field = fields[viewConfig.id]; if (!field) { return null; } const isRequired = field.validation?.required === true; const hideable = !isRequired; return fieldToColumn(field, hideable); }) .filter(Boolean) as Column[]; } get showFieldTypeIcons() { return this._showFieldTypeIcons; } get collectionFieldsSource() { return null; } get sidePanelTransition(): TransitionState | undefined { return this.panels.sidePanel.transition; } get dragAndDrop() { return this._dragAndDrop; } customizeColumnsInSidePanelBi(_params: { actionName: CustomColumnsActionName; }) { // BI reporting — to be wired } onClose() { this.panels.closeSidePanel(); } init() { const disposers = [ reaction( () => this.fieldsState.orderedFields, async () => { const fields = this.fieldsState.orderedFields; this.select.clear(); this.select.forceSetMany( fields.map((field) => ({ value: { id: field.id }, status: this.fieldsState.isFieldVisible(field.id) ? this.select.finalStatus : this.select.startStatus, })), ); await this.columnsCollection.refreshAllPages(); }, { fireImmediately: true }, ), reaction( () => this.select.selectedValues, () => { const fields = this.fieldsState.orderedFields; for (const field of fields) { const isChecked = this.select.isChecked(field.id); const isCurrentlyVisible = this.fieldsState.isFieldVisible( field.id, ); if (isChecked !== isCurrentlyVisible) { this.fieldsState.setFieldVisibility(field.id, isChecked); } } }, ), this.columnsCollection.init(), this._dragAndDrop?.init(), ]; return () => { disposers.forEach((d) => d?.()); }; } }