import { Box, Divider, PopoverMenuProps, TableToolbar, Text, TextButton, } from '@wix/design-system'; import React, { cloneElement, useEffect, useState } from 'react'; import { observer } from 'mobx-react-lite'; import { useToolbarCollectionContext } from '../ToolbarCollectionContext'; import { st, classes } from './MultiBulkActionToolbar.st.css.js'; import { ActionControl, ActionPopover, ActionSubitem } from '../ActionControl'; import { useWixPatternsContainer } from '@wix/bex-core/react'; import { MultiBulkActionToolbarState } from './MultiBulkActionToolbarState'; import { useExtensionMenuItems } from '../../hooks/useExtensionMenuItems'; import { BulkActionContainer } from './BulkActionContainer'; import { useIsMobile } from '../../hooks/useIsMobile'; import { useBulkActionMobileGroups } from '../../hooks/useBulkActionMobileGroups'; import { useBmHarmonyTheme } from '../../hooks/useBmHarmonyTheme'; export interface MultiBulkActionToolbarProps { /** * List of primary actions. Primary actions are displayed as individual buttons. * @overrideType [ActionSubitem[]](./?path=/story/common-types--actionsubitem) * @external */ primaryActionItems?: ActionSubitem[]; /** * List of secondary actions. Secondary actions are displayed when clicking the More Actions menu. * Secondary actions can be grouped by using an array of arrays, and a divider will be added between each group. * @external * @overrideType [ActionSubitem[]](./?path=/story/common-types--actionsubitem) | [ActionSubitem[][]](./?path=/story/common-types--actionsubitem) */ secondaryActionItems?: ActionSubitem[] | ActionSubitem[][]; /** * [PopoverMenu](https://www.docs.wixdesignsystem.com/?path=/story/components-overlays--popovermenu) props to pass to the 'More Action' popover menu. * @external */ secondaryActionsPopoverMenuProps?: Partial; /** * This ID is used to specify the target container for [dashboard menu plugin](./?path=/story/features-enrich-slots-and-plugins--slots-and-plugins) items. */ containerId?: string; /** * This prop is used to pass additional properties that can be used on the onClick of the container's extensions menu items. */ containerProps?: Record; } function _MultiBulkActionToolbar(props: MultiBulkActionToolbarProps) { const { primaryActionItems, secondaryActionItems, secondaryActionsPopoverMenuProps, containerId, containerProps, } = props; const toolbarCollectionState = useToolbarCollectionContext(); const extensionMenuItems = useExtensionMenuItems({ containerId, containerProps, }); const isMobile = useIsMobile(); const isBmHarmonyTheme = useBmHarmonyTheme(); const [state] = useState( () => new MultiBulkActionToolbarState({ extensionMenuItems, collection: toolbarCollectionState.collection, }), ); useEffect(() => { state.setActions({ primaryActionItems, secondaryActionItems, }); }, [primaryActionItems, secondaryActionItems]); const { collection, hasToolbarTabs, featuredComponents, bulk } = toolbarCollectionState; const { maxSelection, total, selectedCountOrTotal, allSelected } = bulk; const { value: exportButton } = featuredComponents.exportButton; const TagsAssignButton = toolbarCollectionState.tagsCollectionState?.components.AssignButton; const { translate: t } = useWixPatternsContainer(); const withBi = (item: ActionSubitem, ctaIndex: number): ActionSubitem => { return { ...item, onClick: () => { toolbarCollectionState.toolbarBIReporter.ctaClicked({ itemId: bulk.selectedIds.join(','), location: 'multiBulkActionToolbar', ctaName: item.biName ?? '', ctaIndex, componentId: (item as any).componentId, appId: (item as any).appId, numCtas: state.primaryActionItems.length + state.secondaryActionItemsCount, }); item?.onClick(); }, }; }; const mobileBulkActionGroups = useBulkActionMobileGroups({ primaryActionItems: state.primaryActionItems, secondaryActionItems: state.secondaryActionItems, moreActionsLabel: t('cairo.moreActions'), }); const mobileBulkActionGroupsWithBi = mobileBulkActionGroups?.map((group) => group.map((item, itemIndex) => withBi(item, itemIndex + 1)), ); const bulkActionButtonsDesktop = ( <> {TagsAssignButton && ( )} {exportButton && ( {cloneElement(exportButton, { toolbarType: 'bulkActionToolbar', })} )} {state.primaryActionItems .filter((x) => !!x) .map((actionItem, index) => ( subItemsGroup?.map((subItem, subIndex) => ({ ...subItem, onClick: () => { toolbarCollectionState.toolbarBIReporter.ctaClicked({ itemId: bulk.selectedIds.join(','), location: 'multiBulkActionToolbar', ctaName: subItem.biName ?? '', ctaIndex: subIndex + 1, // Missing BI requirements https://jira.wixpress.com/browse/CAIRO-600?focusedCommentId=9989131 moreActionsIndex: subIndex + 1, componentId: (subItem as any).componentId, appId: (subItem as any).appId, numCtas: state.primaryActionItems.length + state.secondaryActionItemsCount, }); subItem.onClick?.(); }, })), ), onClick: () => { toolbarCollectionState.toolbarBIReporter.ctaClicked({ itemId: bulk.selectedIds.join(','), location: 'multiBulkActionToolbar', ctaName: actionItem.biName ?? '', ctaIndex: 1, // Missing BI requirements https://jira.wixpress.com/browse/CAIRO-600?focusedCommentId=9989131 moreActionsIndex: 0, componentId: (actionItem as any).componentId, appId: (actionItem as any).appId, numCtas: state.primaryActionItems.length + state.secondaryActionItemsCount, }); actionItem.onClick?.(); }, }} /> ))} {state.secondaryActionItems.filter( (secondaryActionItemsGroup) => secondaryActionItemsGroup.length > 0, ).length > 0 && ( { let index = 0; return state.secondaryActionItems.map((subItemGroup) => subItemGroup.map((subItem) => { const subItemIndex = index; index++; const _subItem = { ...subItem, onClick: () => { toolbarCollectionState.toolbarBIReporter.ctaClicked({ itemId: bulk.selectedIds.join(','), location: 'multiBulkActionToolbar', ctaName: subItem.biName ?? '', ctaIndex: subItemIndex + 3, moreActionsIndex: subItemIndex + 1, componentId: (subItem as any).componentId, appId: (subItem as any).appId, numCtas: state.primaryActionItems.length + state.secondaryActionItemsCount, }); subItem.onClick?.(); }, }; return _subItem; }), ); })(), popoverMenuProps: secondaryActionsPopoverMenuProps, label: t('cairo.moreActions'), }} /> )} ); const bulkActionButtonsMobile = ( ); return ( {maxSelection !== undefined ? t('cairo.bulkActions.max.selection', { max: maxSelection, total: selectedCountOrTotal, }) : collection.result.supportTotal && collection.result.totalStatus === 'success' ? t('cairo.bulkSelectedWithTotal', { num: selectedCountOrTotal, total, }) : allSelected ? '' : t('cairo.bulkSelected', { num: selectedCountOrTotal, })} {collection.result.supportTotal && ( bulk.toggleSelectAll({ location: 'TableToolbar CTA' }) } > {bulk.hasClickableRows ? t('cairo.selectAll') : t('cairo.deselectAll')} )} {!isMobile && bulkActionButtonsDesktop} {isMobile && ( {bulkActionButtonsMobile} )} ); } export const MultiBulkActionToolbar = observer(_MultiBulkActionToolbar);