import { FC, useEffect, useState } from "react"; // icons import { Bars4Icon, XMarkIcon, ArrowsPointingInIcon, ArrowsPointingOutIcon, } from "@heroicons/react/20/solid"; // components import { GanttChartBlocks } from "../blocks"; // 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"; // views import { // generateHourChart, // generateDayChart, generateWeekChart, generateBiWeekChart, generateMonthChart, generateQuarterChart, generateYearChart, getNumberOfDaysBetweenTwoDatesInMonth, getNumberOfDaysBetweenTwoDatesInQuarter, getNumberOfDaysBetweenTwoDatesInYear, getMonthChartItemPositionWidthInMonth, } from "../views"; // types import { ChartDataType } from "../types"; // data import { datePreview, currentViewDataWithView } from "../data"; // context import { useChart } from "../hooks"; type ChartViewRootProps = { title: null | string; loaderTitle: string; blocks: any; blockUpdateHandler: (data: any) => void; sidebarBlockRender: FC; blockRender: FC; }; export const ChartViewRoot: FC = ({ title, blocks = null, loaderTitle, blockUpdateHandler, sidebarBlockRender, blockRender, }) => { const { currentView, currentViewData, renderView, dispatch, allViews } = useChart(); const [itemsContainerWidth, setItemsContainerWidth] = useState(0); const [fullScreenMode, setFullScreenMode] = useState(false); const [blocksSidebarView, setBlocksSidebarView] = useState(false); // blocks state management starts const [chartBlocks, setChartBlocks] = useState(null); const renderBlockStructure = (view: any, blocks: any) => blocks && blocks.length > 0 ? blocks.map((_block: any) => ({ ..._block, position: getMonthChartItemPositionWidthInMonth(view, _block), })) : []; useEffect(() => { if (currentViewData && blocks && blocks.length > 0) setChartBlocks(() => renderBlockStructure(currentViewData, blocks)); }, [currentViewData, blocks]); // blocks state management ends const handleChartView = (key: string) => updateCurrentViewRenderPayload(null, key); const updateCurrentViewRenderPayload = (side: null | "left" | "right", view: string) => { const selectedCurrentView = 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(); }, []); const updatingCurrentLeftScrollPosition = (width: number) => { const scrollContainer = document.getElementById("scroll-container") as HTMLElement; 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; 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); }; useEffect(() => { const scrollContainer = document.getElementById("scroll-container") as HTMLElement; scrollContainer.addEventListener("scroll", onScroll); return () => { scrollContainer.removeEventListener("scroll", onScroll); }; }, [renderView]); return (
{/* chart title */}
{title && (
{title}
Gantt View Beta
)} {blocks === null ? (
Loading...
) : (
{blocks.length} {loaderTitle}
)}
{/* chart header */}
{/*
setBlocksSidebarView(() => !blocksSidebarView)} > {blocksSidebarView ? ( ) : ( )}
*/}
{`${datePreview(currentViewData?.data?.startDate)} - ${datePreview( currentViewData?.data?.endDate )}`}
{allViews && allViews.length > 0 && allViews.map((_chatView: any, _idx: any) => (
handleChartView(_chatView?.key)} > {_chatView?.title}
))}
Today
setFullScreenMode(() => !fullScreenMode)} > {fullScreenMode ? ( ) : ( )}
{/* content */}
{/* blocks components */} {currentView && currentViewData && ( )} {/* chart */} {/* {currentView && currentView === "hours" && } */} {/* {currentView && currentView === "day" && } */} {/* {currentView && currentView === "week" && } */} {/* {currentView && currentView === "bi_week" && } */} {currentView && currentView === "month" && } {/* {currentView && currentView === "quarter" && } */} {/* {currentView && currentView === "year" && } */}
); };