import { FC, useEffect, useState } from "react"; // next import { useRouter } from "next/router"; // icons // components import { GanttChartBlocks } from "components/gantt-chart"; import { GanttSidebar } from "../sidebar"; // import { HourChartView } from "./hours"; // import { DayChartView } from "./day"; // import { WeekChartView } from "./week"; // import { BiWeekChartView } from "./bi-week"; import { MonthChartView } from "./month"; // import { QuarterChartView } from "./quarter"; // import { YearChartView } from "./year"; // icons import { Expand, PlusIcon, Shrink } from "lucide-react"; // views import { // generateHourChart, // generateDayChart, // generateWeekChart, // generateBiWeekChart, generateMonthChart, // generateQuarterChart, // generateYearChart, getNumberOfDaysBetweenTwoDatesInMonth, // getNumberOfDaysBetweenTwoDatesInQuarter, // getNumberOfDaysBetweenTwoDatesInYear, getMonthChartItemPositionWidthInMonth, } from "../views"; // import { GanttInlineCreateIssueForm } from "components/core/views/gantt-chart-view/inline-create-issue-form"; // types import { ChartDataType, IBlockUpdateData, IGanttBlock, TGanttViews } from "../types"; // data import { currentViewDataWithView } from "../data"; // context import { useChart } from "../hooks"; type ChartViewRootProps = { border: boolean; title: string; loaderTitle: string; blocks: IGanttBlock[] | null; blockUpdateHandler: (block: any, payload: IBlockUpdateData) => void; SidebarBlockRender: React.FC; BlockRender: React.FC; enableBlockLeftResize: boolean; enableBlockRightResize: boolean; enableBlockMove: boolean; enableReorder: boolean; bottomSpacing: boolean; }; export const ChartViewRoot: FC = ({ border, title, blocks = null, loaderTitle, blockUpdateHandler, SidebarBlockRender, BlockRender, enableBlockLeftResize, enableBlockRightResize, enableBlockMove, enableReorder, bottomSpacing, }) => { // router const router = useRouter(); const { cycleId, moduleId } = router.query; const isCyclePage = router.pathname.split("/")[4] === "cycles" && !cycleId; const isModulePage = router.pathname.split("/")[4] === "modules" && !moduleId; // states const [itemsContainerWidth, setItemsContainerWidth] = useState(0); const [fullScreenMode, setFullScreenMode] = useState(false); const [isCreateIssueFormOpen, setIsCreateIssueFormOpen] = useState(false); const [chartBlocks, setChartBlocks] = useState(null); // blocks state management starts // hooks const { currentView, currentViewData, renderView, dispatch, allViews, updateScrollLeft } = useChart(); const renderBlockStructure = (view: any, blocks: IGanttBlock[] | null) => blocks && blocks.length > 0 ? blocks.map((block: any) => ({ ...block, position: getMonthChartItemPositionWidthInMonth(view, block), })) : []; useEffect(() => { if (currentViewData && blocks) setChartBlocks(() => renderBlockStructure(currentViewData, blocks)); }, [currentViewData, blocks]); // blocks state management ends const handleChartView = (key: TGanttViews) => updateCurrentViewRenderPayload(null, key); const updateCurrentViewRenderPayload = (side: null | "left" | "right", view: TGanttViews) => { const selectedCurrentView: TGanttViews = view; const selectedCurrentViewData: ChartDataType | undefined = selectedCurrentView && selectedCurrentView === currentViewData?.key ? currentViewData : currentViewDataWithView(view); if (selectedCurrentViewData === undefined) return; let currentRender: any; // if (view === "hours") currentRender = generateHourChart(selectedCurrentViewData, side); // if (view === "day") currentRender = generateDayChart(selectedCurrentViewData, side); // if (view === "week") currentRender = generateWeekChart(selectedCurrentViewData, side); // if (view === "bi_week") currentRender = generateBiWeekChart(selectedCurrentViewData, side); if (selectedCurrentView === "month") currentRender = generateMonthChart(selectedCurrentViewData, side); // if (view === "quarter") currentRender = generateQuarterChart(selectedCurrentViewData, side); // if (selectedCurrentView === "year") // currentRender = generateYearChart(selectedCurrentViewData, side); // updating the prevData, currentData and nextData if (currentRender.payload.length > 0) { if (side === "left") { dispatch({ type: "PARTIAL_UPDATE", payload: { currentView: selectedCurrentView, currentViewData: currentRender.state, renderView: [...currentRender.payload, ...renderView], }, }); updatingCurrentLeftScrollPosition(currentRender.scrollWidth); setItemsContainerWidth(itemsContainerWidth + currentRender.scrollWidth); } else if (side === "right") { dispatch({ type: "PARTIAL_UPDATE", payload: { currentView: view, currentViewData: currentRender.state, renderView: [...renderView, ...currentRender.payload], }, }); setItemsContainerWidth(itemsContainerWidth + currentRender.scrollWidth); } else { dispatch({ type: "PARTIAL_UPDATE", payload: { currentView: view, currentViewData: currentRender.state, renderView: [...currentRender.payload], }, }); setItemsContainerWidth(currentRender.scrollWidth); setTimeout(() => { handleScrollToCurrentSelectedDate(currentRender.state, currentRender.state.data.currentDate); }, 50); } } }; const handleToday = () => updateCurrentViewRenderPayload(null, currentView); // handling the scroll positioning from left and right useEffect(() => { handleToday(); // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const updatingCurrentLeftScrollPosition = (width: number) => { const scrollContainer = document.getElementById("scroll-container") as HTMLElement; if (!scrollContainer) return; scrollContainer.scrollLeft = width + scrollContainer?.scrollLeft; setItemsContainerWidth(width + scrollContainer?.scrollLeft); }; const handleScrollToCurrentSelectedDate = (currentState: ChartDataType, date: Date) => { const scrollContainer = document.getElementById("scroll-container") as HTMLElement; const clientVisibleWidth: number = scrollContainer?.clientWidth; let scrollWidth: number = 0; let daysDifference: number = 0; // if (currentView === "hours") // daysDifference = getNumberOfDaysBetweenTwoDatesInMonth(currentState.data.startDate, date); // if (currentView === "day") // daysDifference = getNumberOfDaysBetweenTwoDatesInMonth(currentState.data.startDate, date); // if (currentView === "week") // daysDifference = getNumberOfDaysBetweenTwoDatesInMonth(currentState.data.startDate, date); // if (currentView === "bi_week") // daysDifference = getNumberOfDaysBetweenTwoDatesInMonth(currentState.data.startDate, date); if (currentView === "month") daysDifference = getNumberOfDaysBetweenTwoDatesInMonth(currentState.data.startDate, date); // if (currentView === "quarter") // daysDifference = getNumberOfDaysBetweenTwoDatesInQuarter(currentState.data.startDate, date); // if (currentView === "year") // daysDifference = getNumberOfDaysBetweenTwoDatesInYear(currentState.data.startDate, date); scrollWidth = daysDifference * currentState.data.width - (clientVisibleWidth / 2 - currentState.data.width); scrollContainer.scrollLeft = scrollWidth; }; // handling scroll functionality const onScroll = () => { const scrollContainer = document.getElementById("scroll-container") as HTMLElement; const scrollWidth: number = scrollContainer?.scrollWidth; const clientVisibleWidth: number = scrollContainer?.clientWidth; const currentScrollPosition: number = scrollContainer?.scrollLeft; updateScrollLeft(currentScrollPosition); const approxRangeLeft: number = scrollWidth >= clientVisibleWidth + 1000 ? 1000 : scrollWidth - clientVisibleWidth; const approxRangeRight: number = scrollWidth - (approxRangeLeft + clientVisibleWidth); if (currentScrollPosition >= approxRangeRight) updateCurrentViewRenderPayload("right", currentView); if (currentScrollPosition <= approxRangeLeft) updateCurrentViewRenderPayload("left", currentView); }; return (
{/* chart header */}
{title && (
{title}
{/*
Gantt View Beta
*/}
)}
{blocks === null ? (
Loading...
) : (
{blocks.length} {loaderTitle}
)}
{allViews && allViews.length > 0 && // eslint-disable-next-line @typescript-eslint/no-unused-vars allViews.map((_chatView: any, _idx: any) => (
handleChartView(_chatView?.key)} > {_chatView?.title}
))}
Today
setFullScreenMode((prevData) => !prevData)} > {fullScreenMode ? : }
{/* content */}
{title}
Duration
{chartBlocks && !(isCyclePage || isModulePage) && (
{/* setIsCreateIssueFormOpen(false)} onSuccess={() => { const ganttSidebar = document.getElementById(`gantt-sidebar-${cycleId}`); const timeoutId = setTimeout(() => { if (ganttSidebar) ganttSidebar.scrollBy({ top: ganttSidebar.scrollHeight, left: 0, behavior: "smooth", }); clearTimeout(timeoutId); }, 10); }} prePopulatedData={{ start_date: new Date(Date.now()).toISOString().split("T")[0], target_date: new Date(Date.now() + 86400000).toISOString().split("T")[0], ...(cycleId && { cycle: cycleId.toString() }), ...(moduleId && { module: moduleId.toString() }), }} /> */} {!isCreateIssueFormOpen && ( )}
)}
{/* {currentView && currentView === "hours" && } */} {/* {currentView && currentView === "day" && } */} {/* {currentView && currentView === "week" && } */} {/* {currentView && currentView === "bi_week" && } */} {currentView && currentView === "month" && } {/* {currentView && currentView === "quarter" && } */} {/* {currentView && currentView === "year" && } */} {/* blocks */} {currentView && currentViewData && ( )}
); };