diff --git a/web/components/gantt-chart/blocks/blocks-display.tsx b/web/components/gantt-chart/blocks/blocks-list.tsx similarity index 98% rename from web/components/gantt-chart/blocks/blocks-display.tsx rename to web/components/gantt-chart/blocks/blocks-list.tsx index 78b2607d9..8372d4ecc 100644 --- a/web/components/gantt-chart/blocks/blocks-display.tsx +++ b/web/components/gantt-chart/blocks/blocks-list.tsx @@ -20,7 +20,7 @@ export type GanttChartBlocksProps = { showAllBlocks: boolean; }; -export const GanttChartBlocks: FC = (props) => { +export const GanttChartBlocksList: FC = (props) => { const { itemsContainerWidth, blocks, diff --git a/web/components/gantt-chart/blocks/index.ts b/web/components/gantt-chart/blocks/index.ts index 18ca5da9e..c99f8af32 100644 --- a/web/components/gantt-chart/blocks/index.ts +++ b/web/components/gantt-chart/blocks/index.ts @@ -1 +1 @@ -export * from "./blocks-display"; +export * from "./blocks-list"; diff --git a/web/components/gantt-chart/chart/header.tsx b/web/components/gantt-chart/chart/header.tsx new file mode 100644 index 000000000..a98c5d883 --- /dev/null +++ b/web/components/gantt-chart/chart/header.tsx @@ -0,0 +1,64 @@ +// hooks +import { Expand, Shrink } from "lucide-react"; +import { useChart } from "../hooks"; +// types +import { IGanttBlock, TGanttViews } from "../types"; + +type Props = { + blocks: IGanttBlock[] | null; + fullScreenMode: boolean; + handleChartView: (view: TGanttViews) => void; + handleToday: () => void; + loaderTitle: string; + title: string; + toggleFullScreenMode: () => void; +}; + +export const GanttChartHeader: React.FC = (props) => { + const { blocks, fullScreenMode, handleChartView, handleToday, loaderTitle, title, toggleFullScreenMode } = props; + // chart hook + const { currentView, allViews } = useChart(); + + return ( +
+
{title}
+ +
+
{blocks ? `${blocks.length} ${loaderTitle}` : "Loading..."}
+
+ +
+ {allViews && + allViews.map((_chatView: any) => ( +
handleChartView(_chatView?.key)} + > + {_chatView?.title} +
+ ))} +
+ +
+ +
+ + +
+ ); +}; diff --git a/web/components/gantt-chart/chart/index.ts b/web/components/gantt-chart/chart/index.ts new file mode 100644 index 000000000..68b20b89a --- /dev/null +++ b/web/components/gantt-chart/chart/index.ts @@ -0,0 +1,4 @@ +export * from "./views"; +export * from "./header"; +export * from "./main-content"; +export * from "./root"; diff --git a/web/components/gantt-chart/chart/index.tsx b/web/components/gantt-chart/chart/index.tsx deleted file mode 100644 index 44f630970..000000000 --- a/web/components/gantt-chart/chart/index.tsx +++ /dev/null @@ -1,334 +0,0 @@ -import { FC, useEffect, useRef, useState } from "react"; -// 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, Shrink } from "lucide-react"; -// views -import { - // generateHourChart, - // generateDayChart, - // generateWeekChart, - // generateBiWeekChart, - generateMonthChart, - // generateQuarterChart, - // generateYearChart, - getNumberOfDaysBetweenTwoDatesInMonth, - // getNumberOfDaysBetweenTwoDatesInQuarter, - // getNumberOfDaysBetweenTwoDatesInYear, - getMonthChartItemPositionWidthInMonth, -} from "../views"; -// 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; - blockToRender: (data: any, textDisplacement: number) => React.ReactNode; - sidebarToRender: (props: any) => React.ReactNode; - enableBlockLeftResize: boolean; - enableBlockRightResize: boolean; - enableBlockMove: boolean; - enableReorder: boolean; - bottomSpacing: boolean; - showAllBlocks: boolean; -}; - -export const ChartViewRoot: FC = (props) => { - const { - border, - title, - blocks = null, - loaderTitle, - blockUpdateHandler, - sidebarToRender, - blockToRender, - enableBlockLeftResize, - enableBlockRightResize, - enableBlockMove, - enableReorder, - bottomSpacing, - showAllBlocks, - } = props; - // states - const [itemsContainerWidth, setItemsContainerWidth] = useState(0); - const [fullScreenMode, setFullScreenMode] = useState(false); - const [chartBlocks, setChartBlocks] = useState(null); // blocks state management starts - // refs - const sidebarRef = useRef(null); - // hooks - const { currentView, currentViewData, renderView, dispatch, allViews, updateScrollLeft, updateScrollTop } = - 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 scrollContainer = document.getElementById("scroll-container") as HTMLDivElement; - - const updatingCurrentLeftScrollPosition = (width: number) => { - if (!scrollContainer) return; - - scrollContainer.scrollLeft = width + scrollContainer?.scrollLeft; - setItemsContainerWidth(width + scrollContainer?.scrollLeft); - }; - - const handleScrollToCurrentSelectedDate = (currentState: ChartDataType, date: Date) => { - if (!scrollContainer) return; - - 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 = (e: React.UIEvent) => { - const { clientWidth: clientVisibleWidth, scrollLeft: currentLeftScrollPosition, scrollWidth } = e.currentTarget; - - updateScrollLeft(currentLeftScrollPosition); - - const approxRangeLeft = scrollWidth >= clientVisibleWidth + 1000 ? 1000 : scrollWidth - clientVisibleWidth; - const approxRangeRight = scrollWidth - (approxRangeLeft + clientVisibleWidth); - - if (currentLeftScrollPosition >= approxRangeRight) updateCurrentViewRenderPayload("right", currentView); - if (currentLeftScrollPosition <= approxRangeLeft) updateCurrentViewRenderPayload("left", currentView); - }; - - const onSidebarScroll = (e: React.UIEvent) => updateScrollTop(e.currentTarget.scrollTop); - - // useEffect(() => { - // const sidebarContainer = sidebarRef.current; - // if (!sidebarContainer) return; - // sidebarContainer.scrollTop = scrollTop; - // }, [scrollTop]); - - 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
-
- -
- {sidebarToRender && sidebarToRender({ title, blockUpdateHandler, blocks, enableReorder })} -
-
-
- {/* {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 && ( - - )} -
-
-
- ); -}; diff --git a/web/components/gantt-chart/chart/main-content.tsx b/web/components/gantt-chart/chart/main-content.tsx new file mode 100644 index 000000000..8d5f9d5fe --- /dev/null +++ b/web/components/gantt-chart/chart/main-content.tsx @@ -0,0 +1,139 @@ +import { useRef } from "react"; +// components +import { + BiWeekChartView, + DayChartView, + GanttChartBlocksList, + HourChartView, + IBlockUpdateData, + IGanttBlock, + MonthChartView, + QuarterChartView, + TGanttViews, + WeekChartView, + YearChartView, + useChart, +} from "components/gantt-chart"; +// helpers +import { cn } from "helpers/common.helper"; + +type Props = { + blocks: IGanttBlock[] | null; + blockToRender: (data: any, textDisplacement: number) => React.ReactNode; + blockUpdateHandler: (block: any, payload: IBlockUpdateData) => void; + bottomSpacing: boolean; + chartBlocks: IGanttBlock[] | null; + enableBlockLeftResize: boolean; + enableBlockMove: boolean; + enableBlockRightResize: boolean; + enableReorder: boolean; + itemsContainerWidth: number; + showAllBlocks: boolean; + sidebarToRender: (props: any) => React.ReactNode; + title: string; + updateCurrentViewRenderPayload: (direction: "left" | "right", currentView: TGanttViews) => void; +}; + +export const GanttChartMainContent: React.FC = (props) => { + const { + blocks, + blockToRender, + blockUpdateHandler, + bottomSpacing, + chartBlocks, + enableBlockLeftResize, + enableBlockMove, + enableBlockRightResize, + enableReorder, + itemsContainerWidth, + showAllBlocks, + sidebarToRender, + title, + updateCurrentViewRenderPayload, + } = props; + // refs + const sidebarRef = useRef(null); + // chart hook + const { currentView, currentViewData, updateScrollLeft, updateScrollTop } = useChart(); + + // handling scroll functionality + const onScroll = (e: React.UIEvent) => { + const { clientWidth: clientVisibleWidth, scrollLeft: currentLeftScrollPosition, scrollWidth } = e.currentTarget; + + updateScrollLeft(currentLeftScrollPosition); + + const approxRangeLeft = scrollWidth >= clientVisibleWidth + 1000 ? 1000 : scrollWidth - clientVisibleWidth; + const approxRangeRight = scrollWidth - (approxRangeLeft + clientVisibleWidth); + + if (currentLeftScrollPosition >= approxRangeRight) updateCurrentViewRenderPayload("right", currentView); + if (currentLeftScrollPosition <= approxRangeLeft) updateCurrentViewRenderPayload("left", currentView); + }; + + const onSidebarScroll = (e: React.UIEvent) => updateScrollTop(e.currentTarget.scrollTop); + + const CHART_VIEW_COMPONENTS: { + [key in TGanttViews]: React.FC; + } = { + hours: HourChartView, + day: DayChartView, + week: WeekChartView, + bi_week: BiWeekChartView, + month: MonthChartView, + quarter: QuarterChartView, + year: YearChartView, + }; + const ActiveChartView = CHART_VIEW_COMPONENTS[currentView]; + + return ( +
+
+
+
{title}
+
Duration
+
+ +
+ {sidebarToRender && sidebarToRender({ title, blockUpdateHandler, blocks, enableReorder })} +
+
+ {currentView && ( +
+ + {/* blocks */} + {currentViewData && ( + + )} +
+ )} +
+ ); +}; diff --git a/web/components/gantt-chart/chart/month.tsx b/web/components/gantt-chart/chart/month.tsx deleted file mode 100644 index 0b7a4c452..000000000 --- a/web/components/gantt-chart/chart/month.tsx +++ /dev/null @@ -1,72 +0,0 @@ -import { FC } from "react"; -// hooks -import { useChart } from "../hooks"; -// types -import { IMonthBlock } from "../views"; - -export const MonthChartView: FC = () => { - const { currentViewData, renderView } = useChart(); - - const monthBlocks: IMonthBlock[] = renderView; - - return ( - <> -
- {monthBlocks && - monthBlocks.length > 0 && - monthBlocks.map((block, _idxRoot) => ( -
-
-
-
- {block?.title} -
-
- -
- {block?.children && - block?.children.length > 0 && - block?.children.map((monthDay, _idx) => ( -
-
- {monthDay.dayData.shortTitle[0]}{" "} - - {monthDay.day} - -
-
- ))} -
-
- -
- {block?.children && - block?.children.length > 0 && - block?.children.map((monthDay, _idx) => ( -
-
- {/* {monthDay?.today && ( -
- )} */} -
-
- ))} -
-
- ))} -
- - ); -}; diff --git a/web/components/gantt-chart/chart/root.tsx b/web/components/gantt-chart/chart/root.tsx new file mode 100644 index 000000000..82cca4911 --- /dev/null +++ b/web/components/gantt-chart/chart/root.tsx @@ -0,0 +1,216 @@ +import { FC, useEffect, useState } from "react"; +// components +import { GanttChartHeader, useChart, GanttChartMainContent } from "components/gantt-chart"; +// views +import { + // generateHourChart, + // generateDayChart, + // generateWeekChart, + // generateBiWeekChart, + generateMonthChart, + // generateQuarterChart, + // generateYearChart, + getNumberOfDaysBetweenTwoDatesInMonth, + // getNumberOfDaysBetweenTwoDatesInQuarter, + // getNumberOfDaysBetweenTwoDatesInYear, + getMonthChartItemPositionWidthInMonth, +} from "../views"; +// helpers +import { cn } from "helpers/common.helper"; +// types +import { ChartDataType, IBlockUpdateData, IGanttBlock, TGanttViews } from "../types"; +// data +import { currentViewDataWithView } from "../data"; + +type ChartViewRootProps = { + border: boolean; + title: string; + loaderTitle: string; + blocks: IGanttBlock[] | null; + blockUpdateHandler: (block: any, payload: IBlockUpdateData) => void; + blockToRender: (data: any, textDisplacement: number) => React.ReactNode; + sidebarToRender: (props: any) => React.ReactNode; + enableBlockLeftResize: boolean; + enableBlockRightResize: boolean; + enableBlockMove: boolean; + enableReorder: boolean; + bottomSpacing: boolean; + showAllBlocks: boolean; +}; + +export const ChartViewRoot: FC = (props) => { + const { + border, + title, + blocks = null, + loaderTitle, + blockUpdateHandler, + sidebarToRender, + blockToRender, + enableBlockLeftResize, + enableBlockRightResize, + enableBlockMove, + enableReorder, + bottomSpacing, + showAllBlocks, + } = props; + // states + const [itemsContainerWidth, setItemsContainerWidth] = useState(0); + const [fullScreenMode, setFullScreenMode] = useState(false); + const [chartBlocks, setChartBlocks] = useState(null); + // hooks + const { currentView, currentViewData, renderView, dispatch } = useChart(); + + // rendering the block structure + const renderBlockStructure = (view: any, blocks: IGanttBlock[] | null) => + blocks && blocks.length > 0 + ? blocks.map((block: any) => ({ + ...block, + position: getMonthChartItemPositionWidthInMonth(view, block), + })) + : []; + + useEffect(() => { + if (!currentViewData || !blocks) return; + setChartBlocks(() => renderBlockStructure(currentViewData, blocks)); + }, [currentViewData, blocks]); + + 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 scrollContainer = document.getElementById("scroll-container") as HTMLDivElement; + + const updatingCurrentLeftScrollPosition = (width: number) => { + if (!scrollContainer) return; + + scrollContainer.scrollLeft = width + scrollContainer?.scrollLeft; + setItemsContainerWidth(width + scrollContainer?.scrollLeft); + }; + + const handleScrollToCurrentSelectedDate = (currentState: ChartDataType, date: Date) => { + if (!scrollContainer) return; + + 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; + }; + + return ( +
+ setFullScreenMode((prevData) => !prevData)} + handleChartView={(key) => updateCurrentViewRenderPayload(null, key)} + handleToday={handleToday} + loaderTitle={loaderTitle} + title={title} + /> + +
+ ); +}; diff --git a/web/components/gantt-chart/chart/bi-week.tsx b/web/components/gantt-chart/chart/views/bi-week.tsx similarity index 97% rename from web/components/gantt-chart/chart/bi-week.tsx rename to web/components/gantt-chart/chart/views/bi-week.tsx index f4a6080cd..6e53d5390 100644 --- a/web/components/gantt-chart/chart/bi-week.tsx +++ b/web/components/gantt-chart/chart/views/bi-week.tsx @@ -1,6 +1,6 @@ import { FC } from "react"; // context -import { useChart } from "../hooks"; +import { useChart } from "components/gantt-chart"; export const BiWeekChartView: FC = () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/web/components/gantt-chart/chart/day.tsx b/web/components/gantt-chart/chart/views/day.tsx similarity index 98% rename from web/components/gantt-chart/chart/day.tsx rename to web/components/gantt-chart/chart/views/day.tsx index 32b3caca0..a50b7748a 100644 --- a/web/components/gantt-chart/chart/day.tsx +++ b/web/components/gantt-chart/chart/views/day.tsx @@ -1,6 +1,6 @@ import { FC } from "react"; // context -import { useChart } from "../hooks"; +import { useChart } from "../../hooks"; export const DayChartView: FC = () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/web/components/gantt-chart/chart/hours.tsx b/web/components/gantt-chart/chart/views/hours.tsx similarity index 97% rename from web/components/gantt-chart/chart/hours.tsx rename to web/components/gantt-chart/chart/views/hours.tsx index 5693b38b8..e1fd02e3f 100644 --- a/web/components/gantt-chart/chart/hours.tsx +++ b/web/components/gantt-chart/chart/views/hours.tsx @@ -1,6 +1,6 @@ import { FC } from "react"; // context -import { useChart } from "../hooks"; +import { useChart } from "components/gantt-chart"; export const HourChartView: FC = () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/web/components/gantt-chart/chart/views/index.ts b/web/components/gantt-chart/chart/views/index.ts new file mode 100644 index 000000000..8936623c2 --- /dev/null +++ b/web/components/gantt-chart/chart/views/index.ts @@ -0,0 +1,7 @@ +export * from "./bi-week"; +export * from "./day"; +export * from "./hours"; +export * from "./month"; +export * from "./quarter"; +export * from "./week"; +export * from "./year"; diff --git a/web/components/gantt-chart/chart/views/month.tsx b/web/components/gantt-chart/chart/views/month.tsx new file mode 100644 index 000000000..0b605bfe2 --- /dev/null +++ b/web/components/gantt-chart/chart/views/month.tsx @@ -0,0 +1,70 @@ +import { FC } from "react"; +// hooks +import { useChart } from "components/gantt-chart"; +// helpers +import { cn } from "helpers/common.helper"; +// types +import { IMonthBlock } from "../../views"; + +export const MonthChartView: FC = () => { + // chart hook + const { currentViewData, renderView } = useChart(); + + const monthBlocks: IMonthBlock[] = renderView; + + return ( + <> +
+ {monthBlocks?.map((block, rootIndex) => ( +
+
+
+
+ {block?.title} +
+
+ +
+ {block?.children?.map((monthDay, _idx) => ( +
+
+ {monthDay.dayData.shortTitle[0]}{" "} + + {monthDay.day} + +
+
+ ))} +
+
+ +
+ {block?.children?.map((monthDay, index) => ( +
+
+ {/* highlight today */} + {/* {monthDay?.today && ( +
+ )} */} +
+
+ ))} +
+
+ ))} +
+ + ); +}; diff --git a/web/components/gantt-chart/chart/quarter.tsx b/web/components/gantt-chart/chart/views/quarter.tsx similarity index 98% rename from web/components/gantt-chart/chart/quarter.tsx rename to web/components/gantt-chart/chart/views/quarter.tsx index a15f6f34d..ffbc1cbfe 100644 --- a/web/components/gantt-chart/chart/quarter.tsx +++ b/web/components/gantt-chart/chart/views/quarter.tsx @@ -1,6 +1,6 @@ import { FC } from "react"; // context -import { useChart } from "../hooks"; +import { useChart } from "../../hooks"; export const QuarterChartView: FC = () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/web/components/gantt-chart/chart/week.tsx b/web/components/gantt-chart/chart/views/week.tsx similarity index 98% rename from web/components/gantt-chart/chart/week.tsx rename to web/components/gantt-chart/chart/views/week.tsx index b90caf8b7..8170affa4 100644 --- a/web/components/gantt-chart/chart/week.tsx +++ b/web/components/gantt-chart/chart/views/week.tsx @@ -1,6 +1,6 @@ import { FC } from "react"; // context -import { useChart } from "../hooks"; +import { useChart } from "../../hooks"; export const WeekChartView: FC = () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/web/components/gantt-chart/chart/year.tsx b/web/components/gantt-chart/chart/views/year.tsx similarity index 98% rename from web/components/gantt-chart/chart/year.tsx rename to web/components/gantt-chart/chart/views/year.tsx index 7c3a34b53..9dbeedece 100644 --- a/web/components/gantt-chart/chart/year.tsx +++ b/web/components/gantt-chart/chart/views/year.tsx @@ -1,6 +1,6 @@ import { FC } from "react"; // context -import { useChart } from "../hooks"; +import { useChart } from "../../hooks"; export const YearChartView: FC = () => { // eslint-disable-next-line @typescript-eslint/no-unused-vars diff --git a/web/components/gantt-chart/helpers/block-structure.tsx b/web/components/gantt-chart/helpers/block-structure.ts similarity index 100% rename from web/components/gantt-chart/helpers/block-structure.tsx rename to web/components/gantt-chart/helpers/block-structure.ts diff --git a/web/components/gantt-chart/helpers/draggable.tsx b/web/components/gantt-chart/helpers/draggable.tsx index 9df420934..79d672572 100644 --- a/web/components/gantt-chart/helpers/draggable.tsx +++ b/web/components/gantt-chart/helpers/draggable.tsx @@ -212,7 +212,9 @@ export const ChartDraggable: React.FC = (props) => { if (!block) return; - setPosFromLeft(block.getBoundingClientRect().left); + requestAnimationFrame(() => { + setPosFromLeft(block.getBoundingClientRect().left); + }); }, [scrollLeft]); // check if block is hidden on either side const isBlockHiddenOnLeft = @@ -238,17 +240,17 @@ export const ChartDraggable: React.FC = (props) => {
)} {/* move to right side hidden block button */} - {isBlockHiddenOnRight && ( -
- -
- )} + {/* {isBlockHiddenOnRight && ( */} +
+ +
+ {/* )} */}