import { CollectionState, FiltersMap, SortOrder, WixPatternsContainer, } from '@wix/bex-core'; import { ToolbarCollectionState, ToolbarCollectionStateParamsInitParams, } from './ToolbarCollectionState'; import { TableVirtualState } from './TableVirtualState'; import { DragAndDropState } from '../components/DragAndDrop'; import { ICollectionComponentState } from './ICollectionComponentState'; import { LoadingRowState } from '../components/LoadingRow/LoadingRowState'; export interface TableStateParams { readonly collection: CollectionState; readonly container: WixPatternsContainer; readonly toolbar?: ToolbarCollectionState; } interface TableDragAndDropStateBase { getStickyColumnsCount: (params: { stickyColumns: number }) => number; init: () => void; dnd: DragAndDropState; } export interface TableStateInitParams extends ToolbarCollectionStateParamsInitParams { hasMultiLevelSorting?: boolean; } export interface TableStatePublicAPI { /** * Underlying [CollectionState](./?path=/story/common-state--collectionstate) instance * @external */ readonly collection: CollectionState; /** * Underlying [ToolbarCollectionState](./?path=/story/common-state--toolbarcollectionstate) instance * @external */ readonly toolbar: ToolbarCollectionState; /** * Reset active filters & sorting and adds new items to the collection. * @external * @param items - new items to add to the collection */ onAddItemActionComplete(items: T[]): void; /** * Visible columns as selected via [CustomColumns](./?path=/story/features-display--customcolumns) * @external */ readonly visibleColumns: { id: string }[]; /** * Sorts the collection by a specified column and optional sort direction. * @external */ sort: (columnId: string, params: { forceDirection?: SortOrder }) => void; } export class TableState implements ICollectionComponentState, TableStatePublicAPI { readonly toolbar; readonly virtual; readonly loadingRowState; tableDragAndDropState: TableDragAndDropStateBase | null = null; /** The sticky table header element (column headers row) */ headerElement: HTMLElement | null = null; constructor(params: TableStateParams) { this.toolbar = params.toolbar ?? new ToolbarCollectionState({ collection: params.collection, container: params.container, componentType: 'Table', }); this.virtual = new TableVirtualState({ table: this, }); this.loadingRowState = new LoadingRowState(); } get visibleColumns() { return this.toolbar.selectedOrderedColumnsOrAll; } // backwards compat get table() { return this.toolbar; } get collection() { return this.table.collection; } get tableState() { return this; } get itemsContentWidth() { return this.toolbar.itemsContentRect.rect.width ?? 0; } get itemsToRenderCount() { return this.collection.result.size; } init(params: TableStateInitParams) { return this.table.init(params); } get keyedItems() { return this.collection.result.keyedItems; } getStickyColumnsCount(params: { stickyColumns?: number; horizontalScroll?: boolean; showSelection?: boolean; stickySelectionColumn?: boolean; }) { const { horizontalScroll } = params; if (!horizontalScroll) { return params.stickyColumns; } const { tableDragAndDropState, toolbar } = this; const { customColumnsState, customColumnsProps, customColumnsStateInitialized, } = toolbar; const { stickySelectionColumn, showSelection } = params; let stickyColumns = params.stickyColumns ?? 0; const customColumnsIsEffective = customColumnsProps && customColumnsState && customColumnsStateInitialized; const reorderDisabledColumnsIsEffective = !!customColumnsState?.dragAndDrop?.orderedColumnsByReorderDisabled .reorderDisabled?.length; if (customColumnsIsEffective) { stickyColumns = customColumnsState.getStickyColumnsCount({ ...params, stickyColumns, }); } if (tableDragAndDropState) { stickyColumns = tableDragAndDropState.getStickyColumnsCount({ ...params, stickyColumns, }); } const checkboxColumnStickyCompat = reorderDisabledColumnsIsEffective || stickySelectionColumn || tableDragAndDropState != null; if (showSelection && checkboxColumnStickyCompat) { stickyColumns += 1; } return stickyColumns; } get showEmptyState() { return this.toolbar.multi.showEmptyState; } get hasAvailableItems() { return this.toolbar.multi.hasAvailableItems; } get resultOriginQuerySearch() { return this.toolbar.multi.resultOriginQuerySearch; } get hasNonPersistentActiveFilters() { return this.toolbar.multi.hasNonPersistentActiveFilters; } get showErrorState() { return this.toolbar.multi.showErrorState; } get errorStatus() { return this.toolbar.multi.errorStatus; } get showLoadingState() { const { initTask, toolbar } = this; return ( initTask.status.isIdle || initTask.status.isLoading || toolbar.multi.showLoadingState ); } get initTask() { return this.toolbar.initTask; } retryErrorState = () => this.toolbar.retryErrorState(); onAddItemActionComplete = async (items: T[]) => { return this.toolbar.onAddItemActionComplete(items); }; sort = ( columnId: string, { forceDirection }: { forceDirection?: SortOrder } = {}, ) => { this.collection.sort({ id: columnId }, { forceDirection }); }; }