import * as React from 'react'; import { AddItem, Box, CounterBadge, Text } from '@wix/design-system'; import { FiltersMap, KeyedItem } from '@wix/bex-core'; import { observer } from 'mobx-react-lite'; import { CardComponent, KanbanCardProps } from './Card'; import { KanbanBaseProps } from './KanbanProps'; import { KanbanCardDragAndDrop } from '../KanbanDragAndDropDndKit/KanbanCardDragAndDrop'; import { ItemActionsState } from '../../state'; import { useDroppable } from '@wix/wix-style-react-incubator/dnd-kit/core'; import { KanbanState } from '../../state/KanbanState'; import { action } from 'mobx'; import { CardsSkeleton } from './CardsSkeleton'; import { useEffect } from 'react'; import { StageActions } from './StageActions'; interface StageComponentProps { dataHook: string; state: KanbanState; stageSummary?: KanbanBaseProps['stageSummary']; renderItem?: KanbanBaseProps['renderItem']; noResultsState?: KanbanBaseProps['noResultsState']; actionCell?: KanbanBaseProps['actionCell']; dataExtension?: KanbanBaseProps['dataExtension']; tags?: KanbanBaseProps['tags']; activeStageKey?: string | null; // Active source stage key stageActionCell?: KanbanBaseProps['stageActionCell']; stageKey: string; } function _StageComponent({ dataHook, state, stageSummary, activeStageKey, stageKey, stageActionCell, ...props }: StageComponentProps) { const stageState = state.kanbanStageStates[stageKey]; const { events } = state; const handleScroll = (e: React.UIEvent) => { const { scrollTop, scrollHeight, clientHeight } = e.currentTarget; if ( scrollHeight - scrollTop <= clientHeight + 10 && !stageState.itemsCollectionState.fetchedLastPage && !stageState.itemsCollectionState.result.status.isFetching ) { stageState.fetchMore(); } }; const { result: { keyedItems }, status, } = stageState.itemsCollectionState; useEffect(() => { if (stageState.hasError) { stageState.showErrorToast(status.error); } }, [stageState.hasError]); const scrollToCardInStage = ({ stageKey: _stageKey, cardKey, }: { stageKey: string; cardKey: string; }) => { if (stageKey !== stageState.stageKey) { return; } const cardElement = document.querySelector( `[data-hook="kanban-card-container-${_stageKey}-${cardKey}"]`, ); if (cardElement) { cardElement.scrollIntoView?.({ behavior: 'smooth', block: 'nearest', inline: 'nearest', }); } }; useEffect(() => { events.on('scrollToCardInStage', scrollToCardInStage); return () => { events.off('scrollToCardInStage', scrollToCardInStage); }; }, [events, stageKey]); // Make the stage droppable const { isOver, setNodeRef: setDroppableRef } = useDroppable({ id: stageState.stageKey, }); // Check if this stage is the source stage (where drag originated) const isDndSourceStage = activeStageKey === stageState.stageKey; const items: KanbanCardProps[] = React.useMemo(() => { return keyedItems.map((keyedItem: KeyedItem, index: number) => { const itemActionsState = new ItemActionsState({ fade: 'static', keyedItem, collection: stageState.itemsCollectionState, reportBi: state.toolbar.reportBi, }); return { keyedItem, stageKey: stageState.stageKey, originalItem: keyedItem.item, itemIndex: index, itemActionsState, item: { ...props.renderItem?.({ stage: stageState.stage, item: keyedItem.item, }), key: keyedItem.key, }, actionCell: props.actionCell, state, }; }); }, [keyedItems, keyedItems.length]); const { DraggableCard } = KanbanCardDragAndDrop; const isInSearchMode = state.isInSearchMode(); const isInFilterMode = state.isInFilterMode(); const isStageLoading = stageState.isLoading; const isChangingFiltersValue = state.getIsChangingFiltersValue(); const shouldShowStageSummary = !isChangingFiltersValue && !isStageLoading; return (
{ if (state.dragAndDropState.activeId) { state.dragAndDropState.handleDragEnd({ over: { id: stageState.stageKey }, active: { id: state.dragAndDropState.activeId }, } as any); } }), })} >
{stageState.stageName} {shouldShowStageSummary && ( {stageState.totalItems} )} {stageActionCell && ( )} {shouldShowStageSummary ? ( {stageSummary?.({ stage: stageState.stage })} ) : null} {shouldShowStageSummary && state.items.create?.title ? ( { state.items.create?.navigateToEntityPage?.({ stage: stageState.stage, }); state.kanbanStateBIReporter.reportStageCTAClicked({ ctaName: 'Add Card', ctaType: 'Primary Button', stageId: stageState.stageKey, stageIndex: state.getStageIndexByKey(stageState.stageKey), stageName: stageState.stageName, }); }} > {state.items.create?.title} ) : null} {state.isRefetching || isStageLoading || isChangingFiltersValue ? ( ) : (
{(isInSearchMode || isInFilterMode) && items.length === 0 ? ( {props.noResultsState} ) : ( items?.map((item) => ( {CardComponent} )) )} {stageState.itemsCollectionState.status.isLoading && (
Loading more...
)}
)}
); } export const StageComponent = observer(_StageComponent);