import { observer } from "mobx-react"; // helpers import { cn } from "@/helpers/common.helper"; import { getDate, renderFormattedPayloadDate } from "@/helpers/date-time.helper"; // hooks import { useIssueDetail } from "@/hooks/store"; import { TSelectionHelper } from "@/hooks/use-multiple-select"; // constants import { BLOCK_HEIGHT } from "../constants"; // components import { ChartAddBlock, ChartDraggable } from "../helpers"; import { useGanttChart } from "../hooks"; import { ChartDataType, IBlockUpdateData, IGanttBlock } from "../types"; type Props = { blockId: string; getBlockById: (id: string, currentViewData?: ChartDataType | undefined) => IGanttBlock; showAllBlocks: boolean; blockToRender: (data: any) => React.ReactNode; blockUpdateHandler: (block: any, payload: IBlockUpdateData) => void; enableBlockLeftResize: boolean; enableBlockRightResize: boolean; enableBlockMove: boolean; enableAddBlock: boolean; ganttContainerRef: React.RefObject; selectionHelpers: TSelectionHelper; }; export const GanttChartBlock: React.FC = observer((props) => { const { blockId, getBlockById, showAllBlocks, blockToRender, blockUpdateHandler, enableBlockLeftResize, enableBlockRightResize, enableBlockMove, enableAddBlock, ganttContainerRef, selectionHelpers, } = props; // store hooks const { currentViewData, updateActiveBlockId, isBlockActive } = useGanttChart(); const { getIsIssuePeeked } = useIssueDetail(); const block = getBlockById(blockId, currentViewData); // hide the block if it doesn't have start and target dates and showAllBlocks is false if (!block || (!showAllBlocks && !(block.start_date && block.target_date))) return null; const isBlockVisibleOnChart = block.start_date && block.target_date; const handleChartBlockPosition = ( block: IGanttBlock, totalBlockShifts: number, dragDirection: "left" | "right" | "move" ) => { const originalStartDate = getDate(block.start_date); const originalTargetDate = getDate(block.target_date); if (!originalStartDate || !originalTargetDate) return; const updatedStartDate = new Date(originalStartDate); const updatedTargetDate = new Date(originalTargetDate); // update the start date on left resize if (dragDirection === "left") updatedStartDate.setDate(originalStartDate.getDate() - totalBlockShifts); // update the target date on right resize else if (dragDirection === "right") updatedTargetDate.setDate(originalTargetDate.getDate() + totalBlockShifts); // update both the dates on x-axis move else if (dragDirection === "move") { updatedStartDate.setDate(originalStartDate.getDate() + totalBlockShifts); updatedTargetDate.setDate(originalTargetDate.getDate() + totalBlockShifts); } // call the block update handler with the updated dates blockUpdateHandler(block.data, { start_date: renderFormattedPayloadDate(updatedStartDate) ?? undefined, target_date: renderFormattedPayloadDate(updatedTargetDate) ?? undefined, }); }; if (!block.data) return null; const isBlockSelected = selectionHelpers.getIsEntitySelected(block.id); const isBlockFocused = selectionHelpers.getIsEntityActive(block.id); const isBlockHoveredOn = isBlockActive(block.id); return (
updateActiveBlockId(blockId)} onMouseLeave={() => updateActiveBlockId(null)} > {isBlockVisibleOnChart ? ( handleChartBlockPosition(block, ...args)} enableBlockLeftResize={enableBlockLeftResize} enableBlockRightResize={enableBlockRightResize} enableBlockMove={enableBlockMove} ganttContainerRef={ganttContainerRef} /> ) : ( enableAddBlock && )}
); });