import React, { cloneElement, FunctionComponent, ReactElement, useEffect, useMemo, useState, } from 'react'; import { observer } from 'mobx-react-lite'; import { Box, Divider, TableToolbar } from '@wix/design-system'; import { FiltersMap } from '@wix/bex-core'; import { CollectionProvider } from '../CollectionContext'; import { ToolbarCollectionState } from '../../state'; import { PartialFunctionComponent } from '../PartialFunctionComponent'; import type { CollectionSearchElement, MultiLevelSortingElement, } from '../assertComponentType'; import { assertComponentType } from '../assertComponentType'; import { ToolbarItemBox } from '../ToolbarItemBox'; import { classes, st } from './CollectionToolbar.st.css.js'; import { InitialLoadingConditional } from '../InitialLoadingConditional'; import { ToolbarBaseProps, ToolbarCollectionBaseProps, } from '../ToolbarCollection'; import { useBmHarmonyTheme } from '../../hooks/useBmHarmonyTheme'; import { useCollectionToolbarSyncedProps } from './useCollectionToolbarSyncedProps'; import { useIsCollectionToolbarExists } from './useIsCollectionToolbarExists'; import { CollectionToolbarActionsToolbarItemsGroup } from './CollectionToolbarActionsToolbarItemsGroup'; import { MoreActions } from '../MoreActions'; import { CollectionToolbarSkeletonItem } from './CollectionToolbarSkeletonItem'; import { useIsMobile } from '../../hooks/useIsMobile'; import { isValidElement } from '../isValidElement'; import { CollectionSearch } from '../CollectionSearch'; import { CollectionToolbarLeftGroup } from './CollectionToolbarLeftGroup'; import { CollectionToolbarActionsGroupResponsiveLayout } from './CollectionToolbarActionsGroupResponsiveLayout'; import { getToolbarMode } from './toolbarModeUtils'; import { TableGridSwitchButtonProps } from '../TableGridSwitchButton/TableGridSwitchButton'; export interface CollectionToolbarProps { state: ToolbarCollectionState; title?: ToolbarCollectionBaseProps['title']; tabs?: ToolbarCollectionBaseProps['tabs']; customColumns?: ToolbarCollectionBaseProps['customColumns']; multiLevelSorting?: MultiLevelSortingElement; views?: ToolbarCollectionBaseProps['views']; search?: ToolbarBaseProps['search']; dataHook?: string; filters?: ToolbarCollectionBaseProps['filters']; tableGridSwitchButton?: ToolbarCollectionBaseProps< T, F >['tableGridSwitchButton']; exportButton?: ToolbarCollectionBaseProps['exportButton']; importButton?: ToolbarCollectionBaseProps['importButton']; primaryActionButton?: ToolbarCollectionBaseProps['primaryActionButton']; dragAndDropReorderModeToolbar?: ToolbarCollectionBaseProps< T, F >['dragAndDropReorderModeToolbar']; secondaryActions?: ToolbarCollectionBaseProps['secondaryActions']; moreActions?: ToolbarCollectionBaseProps['moreActions']; } function _CollectionToolbar( props: CollectionToolbarProps, ) { const { state, search = true, title, tabs, customColumns, multiLevelSorting, views, dataHook, filters: filtersProp, tableGridSwitchButton, exportButton, importButton, dragAndDropReorderModeToolbar, primaryActionButton, secondaryActions, moreActions, } = props; const isMobile = useIsMobile(); const hasOtherToolbarFeatures = useIsCollectionToolbarExists(props, { excludeSearch: true, isMobile, }); const searchIsExpandable = isMobile ? hasOtherToolbarFeatures : undefined; assertComponentType( primaryActionButton, 'PrimaryActionButton', 'PrimaryActionButton', ); const { collection, featuredComponents, toolbar: { responsive }, container: { isPanelLayout }, } = state; const SourceCustomColumns = state.collectionFieldsSource?.components.CustomColumns; const effectiveCustomColumns = customColumns ?? (SourceCustomColumns ? : undefined); const addDataHookToMoreActions = () => { return ( ); }; const searchElement = isPanelLayout ? undefined : isValidElement(search) ? ( cloneElement(search as CollectionSearchElement, { expandable: searchIsExpandable ?? (search as CollectionSearchElement).props.expandable, }) ) : search ? ( ) : ( search ); const MoreFiltersButton = featuredComponents.moreFiltersButton .value as PartialFunctionComponent as FunctionComponent | null; const viewsToolbarItem = isPanelLayout ? undefined : views && ( {views} ); const ToolbarFilters = state.tagsCollectionState?.components.CollectionToolbarFilters ?? state.collectionFieldsSource?.components.CollectionToolbarFilters; const filtersElement = useMemo(() => { if (!state.container.initTask.status.isSuccess) { return; } if (isMobile) { return undefined; } if (filtersProp) { return filtersProp; } const featureFilters = [ ...(state.collectionFieldsSource?.buildFilters() || []), state.tagsCollectionState?.buildTagsFilterWrapper(), ].filter(Boolean); return ( filtersProp ?? (ToolbarFilters && ( {featureFilters} )) ); }, [filtersProp, isMobile, state.container.initTask.status]); let left: ReactElement | undefined; if (tabs) { left = ( {tabs} ); } else if (title && !isMobile) { left = title; } useCollectionToolbarSyncedProps({ left, filtersElement, viewsToolbarItem, state, }); /* checking if something is rendered in the .left TableToolbar.ItemGroup (not empty) */ const [rendersStart, setRendersStart] = useState(); useEffect(() => { setRendersStart( !!left || !!viewsToolbarItem || (state.toolbarFiltersState?.totalInlineFilters.value !== undefined && state.toolbarFiltersState?.totalInlineFilters.value !== null && state.toolbarFiltersState?.totalInlineFilters.value > 0), ); }, [left, viewsToolbarItem, state.toolbarFiltersStateInitialized]); const isLayoutToggleRedesignEnabled = state.container.internalExperiments?.enabled( 'specs.cairo.layout-toggle.redesign', ); const isBmHarmonyTheme = useBmHarmonyTheme(); const shouldAddDivider = !isBmHarmonyTheme && !isLayoutToggleRedesignEnabled && tableGridSwitchButton && (searchElement || MoreFiltersButton); const analyticsCustomColumnsDiscoverability = state.container.experiments?.get( 'specs.analytics.CustomColumnsWithLabelAndNewIcon', ); const showCustomColumnsOnTheLeft = analyticsCustomColumnsDiscoverability === 'b' || analyticsCustomColumnsDiscoverability === 'c'; const immidiatelyInteractWithToolbarsEnabled = state.container.internalExperiments?.enabled( 'specs.cairo.ImmidiatelyInteractWithToolbars', ); const CollectionToolbarActionsGroup = isMobile || responsive.responsiveDisabled ? CollectionToolbarActionsToolbarItemsGroup : CollectionToolbarActionsGroupResponsiveLayout; const responsiveMode = getToolbarMode({ isDisabled: responsive.responsiveDisabled, hasTabs: !!tabs, hasTitle: !!left && !viewsToolbarItem, hasViews: !!viewsToolbarItem, }); const toolbarElement = ( <> )?.props?.state : undefined } /> {primaryActionButton && ( {primaryActionButton} )} {moreActions && ( {addDataHookToMoreActions()} )} {secondaryActions && ( {secondaryActions} )} {shouldAddDivider && ( )} {!isLayoutToggleRedesignEnabled && tableGridSwitchButton && ( {tableGridSwitchButton} )} ); const toolbarWithSkeleton = ( } hideLoadingElement={immidiatelyInteractWithToolbarsEnabled} > {toolbarElement} ); return ( {state.isReorderModeToolbarVisible ? ( dragAndDropReorderModeToolbar ) : ( {toolbarWithSkeleton} )} ); } export const CollectionToolbar = observer(_CollectionToolbar);