import { WixPatternsContainer, CollectionState, FiltersMap, KeyedItem, } from '@wix/bex-core'; import { computed, makeObservable } from 'mobx'; import { ToolbarCollectionState } from './ToolbarCollectionState'; import { FoldersAndItemsCollectionsState, FoldersAndItemsCollectionsStateInitParams, PartialAllFilters, } from './FoldersAndItemsCollectionsState'; import { TableState } from './TableState'; import { TableVirtualState } from './TableVirtualState'; import { ICollectionComponentState } from './ICollectionComponentState'; export interface TableFoldersStateParams< T1, F1 extends FiltersMap, T2, F2 extends FiltersMap, > { readonly items: CollectionState; readonly folders: CollectionState; readonly container: WixPatternsContainer; readonly toolbar?: ToolbarCollectionState>; } interface Item { _tag: 'item'; originalKeyedItem: KeyedItem; } interface Folder { _tag: 'folder'; originalKeyedItem: KeyedItem; } export type RowItem = Item | Folder; export type RowKeyedItem = KeyedItem>; export function isItemKeyedItem( keyedItem: RowKeyedItem, ): keyedItem is KeyedItem> { return keyedItem.item._tag === 'item'; } export function isFolderKeyedItem( keyedItem: RowKeyedItem, ): keyedItem is KeyedItem> { return keyedItem.item._tag === 'folder'; } interface TableFoldersStateInitParams extends FoldersAndItemsCollectionsStateInitParams {} export interface TableFoldersStatePublicAPI< T1, F1 extends FiltersMap, T2, F2 extends FiltersMap, > { /** * Underlying [ToolbarCollectionState](./?path=/story/common-state--toolbarcollectionstate) instance */ readonly toolbar: ToolbarCollectionState; /** * Underlying [TableState](./?path=/story/base-components-collections-table-tablestate--tablestate) instance */ readonly tableState: TableState; /** * Underlying [CollectionState](./?path=/story/common-state--collectionstate) instances for folders and items */ readonly collections: { readonly folders: CollectionState; readonly items: CollectionState; }; } export class TableFoldersState< T1, F1 extends FiltersMap, T2, F2 extends FiltersMap, > implements ICollectionComponentState, TableFoldersStatePublicAPI { readonly container; readonly table; readonly toolbar; readonly virtual; readonly collections; constructor(params: TableFoldersStateParams) { this.container = params.container; this.virtual = new TableVirtualState({ table: this, }); this.toolbar = params.toolbar ?? new ToolbarCollectionState({ collection: params.items as CollectionState as CollectionState< T1, PartialAllFilters >, container: params.container, componentType: 'TableFolders', }); this.collections = new FoldersAndItemsCollectionsState({ ...params, toolbar: this.toolbar, }); this.table = new TableState({ container: this.container, collection: params.items, toolbar: this.toolbar as ToolbarCollectionState, }); makeObservable(this, { showItemsSection: computed, showFoldersSection: computed, keyedItems: computed, }); this.toolbar.bulk.shouldIncludeCollection = (collection) => { if (collection === this.collections.folders) { // Only exclude folders if they're explicitly hidden due to filters return !this.collections.hasItemsOnlyActiveFilters; } if (collection === this.collections.items) { // Only exclude items if they're explicitly hidden due to filters return !this.collections.hasFoldersOnlyActiveFilters; } return true; }; } get showItemsSection() { return ( !this.collections.items.result.isEmptyAndNotFetching && !this.collections.hasFoldersOnlyActiveFilters && (!this.showFoldersSection || this.collections.folders.fetchedLastPage) ); } get showFoldersSection() { return ( !this.collections.folders.result.isEmptyAndNotFetching && !this.collections.hasItemsOnlyActiveFilters ); } get tableState() { return this.table; } get showEmptyState() { return this.collections.showEmptyState; } get hasAvailableItems() { return this.collections.hasAvailableItems; } get resultOriginQuerySearch() { return this.collections.resultOriginQuerySearch; } get hasNonPersistentActiveFilters() { return this.collections.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(); get keyedItems(): RowKeyedItem[] { const { showFoldersSection, showItemsSection, collections: { folders, items }, } = this; return [ ...(showFoldersSection ? folders.result.keyedItems.map((keyedItem) => ({ ...keyedItem, item: { _tag: 'folder' as const, originalKeyedItem: keyedItem, }, })) : []), ...(showItemsSection ? items.result.keyedItems.map((keyedItem) => ({ ...keyedItem, item: { _tag: 'item' as const, originalKeyedItem: keyedItem, }, originalKeyedItem: keyedItem, })) : []), ]; } init(params: TableFoldersStateInitParams) { const disposers = [this.collections.init(params)]; return () => { disposers.forEach((d) => d()); }; } }