import { CollectionOptimisticActions, FiltersMap } from '@wix/bex-core'; import { arrayMove } from '@wix/wix-style-react-incubator/dnd-kit/sortable'; import { addEventListener } from '@wix/bex-core/util'; import type { CustomColumnsDragAndDrop } from '../components/CustomColumns/CustomColumnsDragAndDrop'; import { CollectionDragAndDropState } from '../components/DragAndDrop'; import { Column } from '../model'; import { action, computed, makeObservable } from 'mobx'; import { RectState } from './RectState'; import { indexOfCompareFn } from './indexOfCompareFn'; import { CustomColumnsPanelStateBase } from './CustomColumnsPanelStateBase'; export interface DragAndDropColumnsDataSource { readonly columns: Column[]; readonly selectedColumns: { readonly value: { id: string; isSelected?: boolean }[]; refresh(value: { id: string; isSelected?: boolean }[]): void; }; } export interface CustomColumnsDragAndDropStateParams { readonly customColumns: CustomColumnsPanelStateBase; readonly dataSource: DragAndDropColumnsDataSource; readonly components: typeof CustomColumnsDragAndDrop; readonly modalsContainerRef: { current: HTMLElement | null | undefined; }; } export class CustomColumnsDragAndDropState { readonly container; readonly customColumns; readonly dataSource; readonly columnsActions; readonly components; get _dnd() { return this.collectionDragAndDropState?.dnd; } collectionDragAndDropState: CollectionDragAndDropState | null = null; forceRenderIndexes: number[] | undefined = undefined; reportBi = () => { // report columns re-order BI here }; readonly listRect; constructor(params: CustomColumnsDragAndDropStateParams) { const { customColumns, dataSource, components } = params; this.components = components; this.container = customColumns.container; this.listRect = new RectState({ container: customColumns.container, }); this.customColumns = customColumns; this.dataSource = dataSource; this.columnsActions = new CollectionOptimisticActions({ container: this.container, collection: this.customColumns.columnsCollection, }); this.collectionDragAndDropState = new CollectionDragAndDropState({ state: this, a11yContainer: params.modalsContainerRef, container: this.container, }); makeObservable(this, { _onCustomColumnsReorder: action.bound, containerRect: computed, orderedColumns: computed, orderedColumnsByReorderDisabled: computed, }); } get orderedColumnsByReorderDisabled() { return this.dataSource.columns.reduce( (state, column) => { column.reorderDisabled ? state.reorderDisabled.push(column) : state.regular.push(column); return state; }, { regular: [] as Column[], reorderDisabled: [] as Column[] }, ); } get orderedColumns(): Column[] { const { dataSource } = this; const { selectedColumns: { value: selectedColumns }, } = dataSource; const { reorderDisabled, regular } = this.orderedColumnsByReorderDisabled; return [ ...reorderDisabled, ...regular.sort( indexOfCompareFn(selectedColumns as { id: string }[], (c) => c.id), ), ]; } get collection() { return this.customColumns.columnsCollection; } get containerRect() { const { listRect } = this; if (listRect.rect.left) { return { ...listRect.rect, }; } return undefined; } _onCustomColumnsReorder(columnId: string, overColumnId: string) { const { dataSource: { selectedColumns }, } = this; const columnsArray = selectedColumns.value; const reorderedColumnsArray = arrayMove( columnsArray, columnsArray.findIndex((c) => c.id === columnId), columnsArray.findIndex((c) => c.id === overColumnId), ); selectedColumns.refresh(reorderedColumnsArray); } init() { const { columnsActions } = this; const disposers = [ columnsActions.init(), addEventListener(columnsActions.events, 'updated', async () => { const { customColumns: { columnsCollection }, } = this; await columnsCollection.refreshAllPages(); }), ]; return () => { disposers.forEach((disposer) => disposer?.()); }; } }