diff --git a/src/KonvaTimeline/yearly-scenario.stories.tsx b/src/KonvaTimeline/yearly-scenario.stories.tsx index f680f0c..50daee9 100644 --- a/src/KonvaTimeline/yearly-scenario.stories.tsx +++ b/src/KonvaTimeline/yearly-scenario.stories.tsx @@ -31,7 +31,7 @@ export const YearlyReport: Story = { columnWidth: 120, range: { start: 1698357600000, - end: 1698966000000, + end: 1712095200000, }, tasks: [ { @@ -43,6 +43,15 @@ export const YearlyReport: Story = { end: 1700434800000, }, }, + { + id: "2", + label: "26Marzo", + resourceId: "1", + time: { + start: 1711839600000, + end: 1711922399000, + }, + }, ], }, }; diff --git a/src/grid/Cell/index.tsx b/src/grid/Cell/index.tsx index edd2053..d6986ba 100644 --- a/src/grid/Cell/index.tsx +++ b/src/grid/Cell/index.tsx @@ -9,9 +9,13 @@ interface GridCellProps { column: Interval; height: number; index: number; + visibleDayInfo: { + backHour?: boolean; + nextHour?: boolean; + }; } -const GridCell = ({ column, height, index }: GridCellProps) => { +const GridCell = ({ column, height, index, visibleDayInfo }: GridCellProps) => { const { blocksOffset, columnWidth, @@ -22,7 +26,25 @@ const GridCell = ({ column, height, index }: GridCellProps) => { const cellLabel = useMemo(() => displayInterval(column, resolutionUnit), [column, resolutionUnit]); - const xPos = useMemo(() => columnWidth * (index + blocksOffset), [blocksOffset, columnWidth, index]); + const xPos = useMemo(() => { + if (resolutionUnit === "day") { + if (visibleDayInfo.backHour) { + return columnWidth * (index + blocksOffset) + columnWidth / 24; + } + if (visibleDayInfo.nextHour) { + return columnWidth * (index + blocksOffset) - columnWidth / 24; + } + } + if (resolutionUnit === "week") { + if (visibleDayInfo.backHour) { + return columnWidth * (index + blocksOffset) + columnWidth / 168; + } + if (visibleDayInfo.nextHour) { + return columnWidth * (index + blocksOffset) - columnWidth / 168; + } + } + return columnWidth * (index + blocksOffset); + }, [blocksOffset, columnWidth, index, visibleDayInfo, resolutionUnit]); const yPos = useMemo(() => rowHeight * 0.8, [rowHeight]); diff --git a/src/grid/CellGroup/index.tsx b/src/grid/CellGroup/index.tsx index 655da1a..5403195 100644 --- a/src/grid/CellGroup/index.tsx +++ b/src/grid/CellGroup/index.tsx @@ -8,7 +8,12 @@ import { displayAboveInterval } from "../../utils/time-resolution"; interface GridCellGroupProps { column: Interval; index: number; - dayInfo?: { thisMonth?: number; untilNow?: number; backHour: boolean; forNowHour: boolean }[]; + dayInfo?: { + thisMonth?: number; + untilNow?: number; + backHour: boolean; + nextHour: boolean; + }[]; } const GridCellGroup = ({ column, index, dayInfo }: GridCellGroupProps) => { @@ -38,11 +43,31 @@ const GridCellGroup = ({ column, index, dayInfo }: GridCellGroupProps) => { if (unitAbove === "month") { const pxUntil = index !== 0 ? Duration.fromObject({ ["day"]: dayInfo![index - 1].untilNow }).as("week") / sizeInUnits : 0; - const a = pxUntil * columnWidth; - return a + unitAboveSpanInPx; + if (dayInfo![index].backHour) { + const hourInMonthPx = columnWidth / 168; + return pxUntil * columnWidth + unitAboveSpanInPx + hourInMonthPx; + } + if (dayInfo![index].nextHour) { + const hourInMonthPx = columnWidth / 168; + return pxUntil * columnWidth + unitAboveSpanInPx - hourInMonthPx; + } + return pxUntil * columnWidth + unitAboveSpanInPx; } - if (unitAbove === "day" && dayInfo![index].forNowHour) { - return index * unitAboveSpanInPx + columnWidth / sizeInUnits; + if (unitAbove === "day") { + if (dayInfo![index].backHour) { + return index * unitAboveSpanInPx + columnWidth / sizeInUnits; + } + if (dayInfo![index].nextHour) { + return index * unitAboveSpanInPx - columnWidth / sizeInUnits; + } + } + if (unitAbove === "week") { + if (dayInfo![index].backHour) { + return index * unitAboveSpanInPx + columnWidth / 24; + } + if (dayInfo![index].nextHour) { + return index * unitAboveSpanInPx - columnWidth / 24; + } } return index * unitAboveSpanInPx; diff --git a/src/grid/Cells/index.tsx b/src/grid/Cells/index.tsx index e94656a..e585adc 100644 --- a/src/grid/Cells/index.tsx +++ b/src/grid/Cells/index.tsx @@ -17,25 +17,83 @@ const GridCells = ({ height }: GridCellsProps) => { visibleTimeBlocks, resolution: { unitAbove }, } = useTimelineContext(); - const dayInfo: { thisMonth?: number; untilNow?: number; backHour: boolean; forNowHour: boolean }[] = []; - if (unitAbove === "month" || unitAbove === "day") { + const dayInfo: { + thisMonth?: number; + untilNow?: number; + backHour: boolean; + nextHour: boolean; + }[] = []; + const visibleDayInfo: { + backHour?: boolean; + nextHour?: boolean; + }[] = []; + const tz = interval.start!.toISO()?.slice(-6); + if (unitAbove === "month" || unitAbove === "day" || unitAbove === "week") { aboveTimeBlocks.forEach((column, index) => { - const hrs = column.end!.diff(column.start!, "hour").hours; const month = getMonth(column); const year = getYear(column); const currentMonthDays = daysInMonth(Number(month), Number(year)); - const bchour = hrs > 24 ? true : false; if (index === 0) { const startDay = getStartMonthsDay(interval.start!); const daysToMonthEnd = currentMonthDays - Number(startDay) + 1; - dayInfo.push({ thisMonth: daysToMonthEnd, untilNow: daysToMonthEnd, backHour: bchour, forNowHour: false }); + dayInfo.push({ + thisMonth: daysToMonthEnd, + untilNow: daysToMonthEnd, + backHour: false, + nextHour: false, + }); return; } - const forNowHour = dayInfo[index - 1].forNowHour ? true : dayInfo[index - 1].backHour ? true : false; const n = dayInfo[index - 1].untilNow! + currentMonthDays; - dayInfo.push({ thisMonth: currentMonthDays, untilNow: n, backHour: bchour, forNowHour: forNowHour }); + const tzStart = column.start!.toISO()?.slice(-6); + if (tz !== tzStart) { + if (Number(tz?.slice(1, 3)) - Number(tzStart!.slice(1, 3)) > 0) { + dayInfo.push({ + thisMonth: currentMonthDays, + untilNow: n, + backHour: true, + nextHour: false, + }); + return; + } + dayInfo.push({ + thisMonth: currentMonthDays, + untilNow: n, + backHour: false, + nextHour: true, + }); + } + + dayInfo.push({ + thisMonth: currentMonthDays, + untilNow: n, + backHour: false, + nextHour: false, + }); }); } + visibleTimeBlocks.forEach((column) => { + const tzStart = column.start!.toISO()?.slice(-6); + + if (tz !== tzStart) { + if (Number(tz?.slice(1, 3)) - Number(tzStart!.slice(1, 3)) > 0) { + visibleDayInfo.push({ + backHour: true, + nextHour: false, + }); + return; + } + visibleDayInfo.push({ + backHour: false, + nextHour: true, + }); + } + visibleDayInfo.push({ + backHour: false, + nextHour: false, + }); + return; + }); return ( @@ -43,7 +101,13 @@ const GridCells = ({ height }: GridCellsProps) => { ))} {visibleTimeBlocks.map((column, index) => ( - + ))} );