import { CollectionOptimisticActions, FiltersMap, TypedEmitter, addEventListener, withoutDefaults, } from '@wix/bex-core'; import { cairoReorderingSortColumns } from '@wix/bex-core/bi'; import { arrayMove } from '@wix/wix-style-react-incubator/dnd-kit/sortable'; import EventEmitter from 'events'; import { MultiLevelSortingState, SortableColumn, } from './MultiLevelSortingState'; import { CollectionDragAndDropState } from '../components/DragAndDrop'; import { makeObservable, observable } from 'mobx'; export interface MultiLevelSortingStateDragAndDropParams< T, F extends FiltersMap, > { readonly multiLevelSortingState: MultiLevelSortingState; readonly modalsContainerRef: { current: HTMLElement | null | undefined; }; } export class MultiLevelSortingStateDragAndDrop { readonly multiLevelSortingState; readonly multiLevelSortingActions: CollectionOptimisticActions< SortableColumn, {} >; readonly collectionDragAndDropState: CollectionDragAndDropState< SortableColumn, {} > | null = null; forceRenderIndexes = undefined as number[] | undefined; events = new EventEmitter() as TypedEmitter<{ beforeReorder: () => unknown; afterReorder: (params: { indexBefore: number; indexAfter: number; columnId: string; }) => unknown; }>; constructor(params: MultiLevelSortingStateDragAndDropParams) { const { multiLevelSortingState } = params; this.multiLevelSortingState = multiLevelSortingState; this.multiLevelSortingActions = new CollectionOptimisticActions< SortableColumn, {} >({ container: this.container, collection: this.collection, }); this.collectionDragAndDropState = new CollectionDragAndDropState({ state: this, a11yContainer: params.modalsContainerRef, container: this.multiLevelSortingState.container, }); makeObservable(this, { forceRenderIndexes: observable.ref, }); } get _dnd() { return this.collectionDragAndDropState?.dnd; } get reportBi() { return this.multiLevelSortingState.table.reportBi; } get container() { return this.multiLevelSortingState.container; } get collection() { return this.multiLevelSortingState.sortingCollection; } _onSortReorder(fromColumnId: string, overColumnId: string) { const { orderedSortableColumns } = this.multiLevelSortingState; const indexBefore = orderedSortableColumns.findIndex( ({ columnId }) => columnId === fromColumnId, ); const indexAfter = orderedSortableColumns.findIndex( ({ columnId }) => columnId === overColumnId, ); const newOrder = arrayMove(orderedSortableColumns, indexBefore, indexAfter); this.events.emit('beforeReorder'); orderedSortableColumns.replace(newOrder); this.events.emit('afterReorder', { indexBefore, indexAfter, columnId: fromColumnId, }); } init() { const { reportBi, events, multiLevelSortingState } = this; const disposers = [ this.multiLevelSortingActions.init(), addEventListener(events, 'beforeReorder', () => { const prevSortOrder = JSON.stringify( multiLevelSortingState.currentSortOrder, ); events.once('afterReorder', ({ indexBefore, indexAfter, columnId }) => { const newSortOrder = JSON.stringify( multiLevelSortingState.currentSortOrder, ); const numSortingColumns = multiLevelSortingState.orderedSortableColumns.length; reportBi( withoutDefaults(cairoReorderingSortColumns)({ columnIndexBefore: indexBefore, columnIndexAfter: indexAfter, numSortingColumns, sortingColumn: columnId, newSortOrder, prevSortOrder, }), ); }); }), ]; return () => { disposers.forEach((disposer) => disposer?.()); }; } }