From 83ed3067a58e7be72486ce301c205df415d61e45 Mon Sep 17 00:00:00 2001 From: Nathan Date: Sun, 6 Oct 2024 19:31:44 -0400 Subject: [PATCH 1/4] feat: allow custom tooltip function with project data --- src/App.tsx | 11 +++++- src/components/Calendar/Calendar.tsx | 15 +++++--- src/components/Scheduler/Scheduler.tsx | 1 + src/components/Tooltip/Tooltip.tsx | 50 ++++++++++++++------------ src/components/Tooltip/types.ts | 4 ++- src/types/global.ts | 7 ++++ src/utils/getTooltipData.ts | 18 +++++++++- 7 files changed, 76 insertions(+), 30 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index bc6fc4de..a2e74beb 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -66,7 +66,16 @@ function App() { isLoading={false} onTileClick={handleTileClick} onFilterData={handleFilterData} - config={{ zoom: 0, maxRecordsPerPage: maxRecordsPerPage, showThemeToggle: true }} + config={{ + zoom: 0, + maxRecordsPerPage: maxRecordsPerPage, + showThemeToggle: true, + customTooltip: (_, project) => ( +
+ {project?.title} | {project?.subtitle} +
+ ) + }} onItemClick={(data) => console.log("clicked: ", data)} /> ) : ( diff --git a/src/components/Calendar/Calendar.tsx b/src/components/Calendar/Calendar.tsx index 04199ecf..9deda1c4 100644 --- a/src/components/Calendar/Calendar.tsx +++ b/src/components/Calendar/Calendar.tsx @@ -12,6 +12,7 @@ import { StyledOuterWrapper, StyledInnerWrapper, StyledEmptyBoxWrapper } from ". const initialTooltipData: TooltipData = { coords: { x: 0, y: 0 }, resourceIndex: 0, + project: undefined, disposition: { taken: { hours: 0, minutes: 0 }, free: { hours: 0, minutes: 0 }, @@ -33,7 +34,7 @@ export const Calendar: FC = ({ const { zoom, startDate, - config: { includeTakenHoursOnWeekendsInDayView, showTooltip, showThemeToggle } + config: { includeTakenHoursOnWeekendsInDayView, showTooltip, showThemeToggle, customTooltip } } = useCalendar(); const gridRef = useRef(null); const { @@ -62,7 +63,8 @@ export const Calendar: FC = ({ const { coords: { x, y }, resourceIndex, - disposition + disposition, + project } = getTooltipData( startDate, tooltipCoords, @@ -71,7 +73,7 @@ export const Calendar: FC = ({ zoom, includeTakenHoursOnWeekendsInDayView ); - setTooltipData({ coords: { x, y }, resourceIndex, disposition }); + setTooltipData({ coords: { x, y }, resourceIndex, disposition, project }); setIsVisible(true); }, 300 @@ -157,7 +159,12 @@ export const Calendar: FC = ({ )} {showTooltip && isVisible && tooltipData?.resourceIndex > -1 && ( - + )} diff --git a/src/components/Scheduler/Scheduler.tsx b/src/components/Scheduler/Scheduler.tsx index 1f4fc9c9..3d0913a8 100644 --- a/src/components/Scheduler/Scheduler.tsx +++ b/src/components/Scheduler/Scheduler.tsx @@ -28,6 +28,7 @@ const Scheduler = ({ includeTakenHoursOnWeekendsInDayView: false, showTooltip: true, translations: undefined, + customTooltip: undefined, ...config }), [config] diff --git a/src/components/Tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx index af9089f6..90953693 100644 --- a/src/components/Tooltip/Tooltip.tsx +++ b/src/components/Tooltip/Tooltip.tsx @@ -1,6 +1,7 @@ import { FC, useLayoutEffect, useRef } from "react"; import { dayWidth, weekWidth, zoom2ColumnWidth } from "@/constants"; import { useLanguage } from "@/context/LocaleProvider"; +import { CustomTooltipFunction } from "@/types/global"; import Icon from "../Icon"; import { StyledContentWrapper, @@ -14,9 +15,8 @@ import { } from "./styles"; import { TooltipProps } from "./types"; -const Tooltip: FC = ({ tooltipData, zoom }) => { +const Tooltip: FC = ({ tooltipData, project, zoom, customTooltip }) => { const { taken, free, over } = useLanguage(); - const { coords, disposition } = tooltipData; const tooltipRef = useRef(null); let width = weekWidth; @@ -51,31 +51,35 @@ const Tooltip: FC = ({ tooltipData, zoom }) => { tooltipRef.current.style.top = `${coords.y + 8}px`; // disposition.overtime affects tooltip's width, thus it's needed to recalculate it's coords whenever overtime changes - }, [coords.x, width, disposition.overtime, coords.y, zoom]); + }, [coords.x, width, disposition.overtime, coords.y, zoom, project]); return ( - - - - - {`${taken}: ${disposition.taken.hours}h ${disposition.taken.minutes}m`} - {(disposition.overtime.hours > 0 || disposition.overtime.minutes > 0) && ( - <> -  {"-"}  - {`${disposition.overtime.hours}h ${disposition.overtime.minutes}m ${over}`} - - )} - - - - - - {`${free}: ${disposition.free.hours}h ${disposition.free.minutes}m`} - - - + {customTooltip ? ( + customTooltip(tooltipData, project) + ) : ( + + + + + {`${taken}: ${disposition.taken.hours}h ${disposition.taken.minutes}m`} + {(disposition.overtime.hours > 0 || disposition.overtime.minutes > 0) && ( + <> +  {"-"}  + {`${disposition.overtime.hours}h ${disposition.overtime.minutes}m ${over}`} + + )} + + + + + + {`${free}: ${disposition.free.hours}h ${disposition.free.minutes}m`} + + + + )} diff --git a/src/components/Tooltip/types.ts b/src/components/Tooltip/types.ts index 2d5caf34..ee23a172 100644 --- a/src/components/Tooltip/types.ts +++ b/src/components/Tooltip/types.ts @@ -1,6 +1,8 @@ -import { TooltipData } from "@/types/global"; +import { CustomTooltipFunction, SchedulerProjectData, TooltipData } from "@/types/global"; export type TooltipProps = { tooltipData: TooltipData; zoom: number; + project?: SchedulerProjectData; + customTooltip?: CustomTooltipFunction; }; diff --git a/src/types/global.ts b/src/types/global.ts index fd94bf5f..7623c1e8 100644 --- a/src/types/global.ts +++ b/src/types/global.ts @@ -51,8 +51,14 @@ export type Config = { */ defaultTheme?: "light" | "dark"; theme?: Theme; + customTooltip?: CustomTooltipFunction; }; +export type CustomTooltipFunction = ( + tooltipData: TooltipData, + project?: SchedulerProjectData +) => JSX.Element; + export type Theme = { light?: Partial>; dark?: Partial>; @@ -192,4 +198,5 @@ export type TooltipData = { coords: Coords; resourceIndex: number; disposition: OccupancyData; + project?: SchedulerProjectData; }; diff --git a/src/utils/getTooltipData.ts b/src/utils/getTooltipData.ts index af912919..35e29a66 100644 --- a/src/utils/getTooltipData.ts +++ b/src/utils/getTooltipData.ts @@ -50,5 +50,21 @@ export const getTooltipData = ( zoom, includeTakenHoursOnWeekendsInDayView ); - return { coords: { x: xPos, y: yPos }, resourceIndex, disposition }; + const project = resourcesData[resourceIndex].flat(2).find((item) => { + if (zoom === 1) { + return dayjs(focusedDate).isBetween(item.startDate, item.endDate, "day", "[]"); + } else if (zoom === 2) { + return dayjs(focusedDate).isBetween(item.startDate, item.endDate, "hour", "[]"); + } else { + return ( + dayjs(item.startDate).isBetween( + dayjs(focusedDate), + dayjs(focusedDate).add(6, "days"), + "day", + "[]" + ) || dayjs(focusedDate).isBetween(dayjs(item.startDate), dayjs(item.endDate), "day", "[]") + ); + } + }); + return { coords: { x: xPos, y: yPos }, resourceIndex, disposition, project }; }; From 709d242bc450856a6519ae68315eea59ad086022 Mon Sep 17 00:00:00 2001 From: Nathan Date: Sun, 6 Oct 2024 19:43:42 -0400 Subject: [PATCH 2/4] fix: remove custom tooltip from app sample --- src/App.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index a2e74beb..4db826ec 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -69,12 +69,7 @@ function App() { config={{ zoom: 0, maxRecordsPerPage: maxRecordsPerPage, - showThemeToggle: true, - customTooltip: (_, project) => ( -
- {project?.title} | {project?.subtitle} -
- ) + showThemeToggle: true }} onItemClick={(data) => console.log("clicked: ", data)} /> From ec5547e01537e846bba01fdc456e3900b0b53ba2 Mon Sep 17 00:00:00 2001 From: Nathan Date: Sun, 6 Oct 2024 20:30:52 -0400 Subject: [PATCH 3/4] fix: resolve issue with wrong project being selected for tooltip --- src/components/Tooltip/Tooltip.tsx | 1 - src/utils/getTooltipData.ts | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/components/Tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx index 90953693..b3b06414 100644 --- a/src/components/Tooltip/Tooltip.tsx +++ b/src/components/Tooltip/Tooltip.tsx @@ -1,7 +1,6 @@ import { FC, useLayoutEffect, useRef } from "react"; import { dayWidth, weekWidth, zoom2ColumnWidth } from "@/constants"; import { useLanguage } from "@/context/LocaleProvider"; -import { CustomTooltipFunction } from "@/types/global"; import Icon from "../Icon"; import { StyledContentWrapper, diff --git a/src/utils/getTooltipData.ts b/src/utils/getTooltipData.ts index 35e29a66..85338ea7 100644 --- a/src/utils/getTooltipData.ts +++ b/src/utils/getTooltipData.ts @@ -40,6 +40,8 @@ export const getTooltipData = ( const sumOfRows = array.slice(0, index + 1).reduce((acc, cur) => acc + cur, 0); return sumOfRows >= rowPosition; }); + const rowPositionForPerson = + rowPosition - rowsPerPerson.slice(0, resourceIndex).reduce((acc, cur) => acc + cur, 0) - 1; const xPos = zoom === 2 ? (column + 1) * currBoxWidth : column * currBoxWidth; const yPos = (rowPosition - 1) * boxHeight + boxHeight; @@ -50,7 +52,7 @@ export const getTooltipData = ( zoom, includeTakenHoursOnWeekendsInDayView ); - const project = resourcesData[resourceIndex].flat(2).find((item) => { + const project = resourcesData[resourceIndex][rowPositionForPerson].find((item) => { if (zoom === 1) { return dayjs(focusedDate).isBetween(item.startDate, item.endDate, "day", "[]"); } else if (zoom === 2) { From d71a0bf4faa3aa7ae437929d42b7f6e67108675e Mon Sep 17 00:00:00 2001 From: Nathan Date: Sun, 6 Oct 2024 21:08:17 -0400 Subject: [PATCH 4/4] fix: remove additional project parameter since it is part of tooltipData --- src/components/Calendar/Calendar.tsx | 7 +------ src/components/Tooltip/Tooltip.tsx | 6 +++--- src/components/Tooltip/types.ts | 3 +-- src/types/global.ts | 5 +---- 4 files changed, 6 insertions(+), 15 deletions(-) diff --git a/src/components/Calendar/Calendar.tsx b/src/components/Calendar/Calendar.tsx index 9deda1c4..3b3db9c1 100644 --- a/src/components/Calendar/Calendar.tsx +++ b/src/components/Calendar/Calendar.tsx @@ -159,12 +159,7 @@ export const Calendar: FC = ({ )} {showTooltip && isVisible && tooltipData?.resourceIndex > -1 && ( - + )} diff --git a/src/components/Tooltip/Tooltip.tsx b/src/components/Tooltip/Tooltip.tsx index b3b06414..54eaa6ca 100644 --- a/src/components/Tooltip/Tooltip.tsx +++ b/src/components/Tooltip/Tooltip.tsx @@ -14,9 +14,9 @@ import { } from "./styles"; import { TooltipProps } from "./types"; -const Tooltip: FC = ({ tooltipData, project, zoom, customTooltip }) => { +const Tooltip: FC = ({ tooltipData, zoom, customTooltip }) => { const { taken, free, over } = useLanguage(); - const { coords, disposition } = tooltipData; + const { coords, disposition, project } = tooltipData; const tooltipRef = useRef(null); let width = weekWidth; switch (zoom) { @@ -56,7 +56,7 @@ const Tooltip: FC = ({ tooltipData, project, zoom, customTooltip } {customTooltip ? ( - customTooltip(tooltipData, project) + customTooltip(tooltipData) ) : ( diff --git a/src/components/Tooltip/types.ts b/src/components/Tooltip/types.ts index ee23a172..5b7d4a63 100644 --- a/src/components/Tooltip/types.ts +++ b/src/components/Tooltip/types.ts @@ -1,8 +1,7 @@ -import { CustomTooltipFunction, SchedulerProjectData, TooltipData } from "@/types/global"; +import { CustomTooltipFunction, TooltipData } from "@/types/global"; export type TooltipProps = { tooltipData: TooltipData; zoom: number; - project?: SchedulerProjectData; customTooltip?: CustomTooltipFunction; }; diff --git a/src/types/global.ts b/src/types/global.ts index 7623c1e8..552d01e8 100644 --- a/src/types/global.ts +++ b/src/types/global.ts @@ -54,10 +54,7 @@ export type Config = { customTooltip?: CustomTooltipFunction; }; -export type CustomTooltipFunction = ( - tooltipData: TooltipData, - project?: SchedulerProjectData -) => JSX.Element; +export type CustomTooltipFunction = (tooltipData: TooltipData) => JSX.Element | string; export type Theme = { light?: Partial>;