import React, { ReactElement, Suspense, useEffect, useMemo } from 'react'; import { FiltersMap } from '@wix/bex-core'; import { observer } from 'mobx-react-lite'; import { Table, TableProps } from '../Table'; import { Grid, GridProps } from '../Grid'; import type { EditableTableProps } from '../EditableTable'; import { InitialLoader } from '../InitialLoader'; import { LayoutSwitchButton } from '../LayoutSwitchButton'; import type { ILayoutSwitchState } from '../../state/ILayoutSwitchState'; const LazyEditableTable = React.lazy(() => import('../EditableTable').then((m) => ({ default: m.EditableTable as React.ComponentType, })), ); export interface LayoutSwitchProps { state: ILayoutSwitchState; /** * An `` element added to the toolbar of whichever layout is * shown. Set it here once instead of repeating it in each layout's props. A * layout's own `importButton` (in `tableProps`/`gridProps`/`spreadsheetProps`) * takes precedence over this one. */ importButton?: ReactElement; tableProps?: Omit, 'tableGridSwitchButton'>; gridProps?: Omit, 'tableGridSwitchButton'>; spreadsheetProps?: Omit, 'tableGridSwitchButton'>; } function _LayoutSwitch({ state, importButton, tableProps, gridProps, spreadsheetProps, }: LayoutSwitchProps) { const { viewTypeState, initTask, toolbar } = state; const isLoading = initTask.status.isIdle || initTask.status.isLoading; // Recompute only when a prop flips between defined and undefined. const availableOptions = useMemo( () => viewTypeState.options.filter((option) => { if (option === 'table') { return !!tableProps; } if (option === 'grid') { return !!gridProps; } if (option === 'spreadsheet') { return !!spreadsheetProps; } return false; }), // eslint-disable-next-line react-hooks/exhaustive-deps [!!tableProps, !!gridProps, !!spreadsheetProps], ); useEffect(() => state.init(), []); // If the stored viewType is not among the available options (e.g. 'grid' was // persisted but gridProps is not provided), persist the correction so the next // load starts from a valid value. changeViewType also updates dataCapsule. useEffect(() => { if ( availableOptions.length > 0 && !availableOptions.includes(viewTypeState.viewType) ) { viewTypeState.changeViewType(availableOptions[0]!); } }, [availableOptions, viewTypeState.viewType]); if (!availableOptions.length) { console.error( '[LayoutSwitch] At least one of tableProps, gridProps, or spreadsheetProps must be provided.', ); return null; } const layoutSwitchButton = ( ); if (isLoading) { return ; } // If viewType is not yet available (loaded from storage but xProp absent), // fall back locally without waiting for the correction effect to fire. const activeView = availableOptions.includes(viewTypeState.viewType) ? viewTypeState.viewType : availableOptions[0]; if (activeView === 'table') { return (
); } if (activeView === 'grid') { return (
); } if (activeView === 'spreadsheet') { return (
} >
); } return null; } export const LayoutSwitch = observer(_LayoutSwitch);