import { ArchiveFieldModalState, CustomFieldModalState, CustomFieldOrigin, DeleteFieldModalState, FieldsSource, ReportBI, WixPatternsContainer, } from '@wix/bex-core'; import { makeAutoObservable } from 'mobx'; import type { FieldActionsMenuConfig } from '../../components/FieldActions'; /** Builds the per-field action popover (edit / archive / delete …) for a field. */ export type FieldActionsMenuBuilder = (args: { fieldId: string; origin: CustomFieldOrigin; location: string; }) => FieldActionsMenuConfig | null; export interface CustomFieldsPanelStateParams { readonly reportBi: ReportBI; readonly closeSidePanel: () => unknown; readonly fieldsSource: FieldsSource; readonly container: WixPatternsContainer; /** * The source's per-field menu, as a factory over the panel it belongs to (its * handlers call back into this panel's modals). Built once in the constructor. */ readonly createFieldActionsMenu: ( panel: CustomFieldsPanelState, ) => FieldActionsMenuBuilder; } export class CustomFieldsPanelState { readonly reportBi; readonly closeSidePanel; readonly fieldsSource; readonly container; readonly customFieldModal; readonly archiveFieldModal?: ArchiveFieldModalState; readonly deleteFieldModal: DeleteFieldModalState; /** The per-field action popover. The source supplies it; CustomFieldItem reads it. */ readonly fieldActionsMenu: FieldActionsMenuBuilder; constructor(params: CustomFieldsPanelStateParams) { this.reportBi = params.reportBi; this.closeSidePanel = params.closeSidePanel; this.fieldsSource = params.fieldsSource; this.container = params.container; if (params.fieldsSource.archive) { this.archiveFieldModal = new ArchiveFieldModalState({ reportBi: this.reportBi, archiver: params.fieldsSource.archive, }); } this.customFieldModal = new CustomFieldModalState({ reportBi: this.reportBi, fieldManagement: params.fieldsSource.fieldManagement!, container: params.container, fieldCount: () => params.fieldsSource.manageableFields.length, }); // The delete runs through the source's own deleteField (which reports its // own toast) and reconciles the archived-items list when archiving exists. this.deleteFieldModal = new DeleteFieldModalState({ reportBi: this.reportBi, fieldManagement: { deleteField: (id, origin) => params.fieldsSource.fieldManagement!.deleteField(id, origin), }, archive: params.fieldsSource.archive ?? { items: [], closePanel: () => undefined, }, }); this.fieldActionsMenu = params.createFieldActionsMenu(this); makeAutoObservable(this, { // A function that builds (doesn't mutate) the popover — not an action. It's // set once here and never reassigned, so it needn't be observable either. fieldActionsMenu: false, }); } get fieldManagement() { return this.fieldsSource.fieldManagement; } get manageableFields() { return this.fieldsSource.manageableFields; } get archive() { return this.fieldsSource.archive; } openCustomFieldModal(params: { fieldId?: string; origin: CustomFieldOrigin; customOrigin?: string; }) { const { customFieldModal } = this; const { customFieldModalBiReporter } = customFieldModal; customFieldModal.reset(); customFieldModal.mode = params.fieldId ? 'edit' : 'new'; customFieldModal.origin = params.origin; customFieldModal.customOrigin = params.customOrigin; !params.fieldId && customFieldModalBiReporter.reportAddCustomField({ origin: params.origin, customOrigin: params.customOrigin, }); customFieldModalBiReporter.formSnapshot = null; customFieldModal.setDefaultPermissions(); if (params.fieldId) { const formValues = this.fieldsSource.fieldManagement?.getFieldDraft( params.fieldId, ); if (!formValues) { return; } customFieldModal.setFormValues(formValues, { disablePermissionCheckboxes: true, }); customFieldModalBiReporter.formSnapshot = formValues; } customFieldModal.modalState.modal.open(); } }