Skip to content

Commit

Permalink
Merge pull request #124 from melfore/develop
Browse files Browse the repository at this point in the history
[Timeline] Fix timezone
  • Loading branch information
luciob committed Oct 18, 2023
2 parents f39cec8 + f1ac520 commit f0befa7
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 28 deletions.
3 changes: 1 addition & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
## [1.14.1](https://github.com/melfore/konva-timeline/compare/v1.14.0...v1.14.1) (2023-10-17)


### Bug Fixes

* 🐛 [Task] Receive changes from outside and update state ([e2d0528](https://github.com/melfore/konva-timeline/commit/e2d052872169a79458d64b9fd529ceb3d6784153))
- 🐛 [Task] Receive changes from outside and update state ([e2d0528](https://github.com/melfore/konva-timeline/commit/e2d052872169a79458d64b9fd529ceb3d6784153))

# [1.14.0](https://github.com/melfore/konva-timeline/compare/v1.13.1...v1.14.0) (2023-10-17)

Expand Down
23 changes: 23 additions & 0 deletions src/KonvaTimeline/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,26 @@ export const MixedDateTimeFormats: Story = {
},
},
};

export const NonPreciseRange: Story = {
args: {
...Primary.args,
range: {
start: 1697632200000,
end: 1698244200000,
},
tasks: [
{
id: "1",
label: "Task 1",
resourceId: "1",
time: {
start: 1697632200000,
end: 1697639400000,
},
},
],
resolution: "1day",
timezone: "Europe/Rome",
},
};
11 changes: 8 additions & 3 deletions src/tasks/utils/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,12 @@ export const getTaskYCoordinate = (rowIndex: number, rowHeight: number) =>
* @param tasks list of tasks as passed to the component
* @param intervals intervals as passed to the component
*/
export const validateTasks = (tasks: TaskData[], range: InternalTimeRange | null, timezone: string): FilteredTasks => {
export const validateTasks = (
tasks: TaskData[],
range: InternalTimeRange | null,
timezone: string | undefined
): FilteredTasks => {
const tz = timezone || "system";
if (!range || !range.start || !range.end) {
return { items: [], errors: [{ entity: "task", level: "warn", message: "Invalid range" }] };
}
Expand All @@ -54,8 +59,8 @@ export const validateTasks = (tasks: TaskData[], range: InternalTimeRange | null
(task): TaskData<InternalTimeRange> => ({
...task,
time: {
start: getValidTime(task.time.start, timezone),
end: getValidTime(task.time.end, timezone),
start: getValidTime(task.time.start, tz),
end: getValidTime(task.time.end, tz),
},
})
)
Expand Down
45 changes: 30 additions & 15 deletions src/timeline/TimelineContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,24 @@ export const TimelineProvider = ({
resolution: externalResolution,
resources: externalResources,
rowHeight: externalRowHeight,
timezone = "utc",
timezone: externalTimezone,
theme: externalTheme = "light",
}: TimelineProviderProps) => {
console.log("=> TimelineContext");

const timezone = useMemo(() => {
if (!externalTimezone) {
return "system";
}

const dateCheck = DateTime.fromMillis(0, { zone: externalTimezone });
if (!dateCheck.isValid) {
return "system";
}

return externalTimezone;
}, [externalTimezone]);

const [drawRange, setDrawRange] = useState(DEFAULT_DRAW_RANGE);

useEffect(() => {
Expand All @@ -136,6 +151,19 @@ export const TimelineProvider = ({
return { start, end };
}, [externalRange, timezone]);

const resolution = useMemo(
() => executeWithPerfomanceCheck("TimelineProvider", "resolution", () => getResolutionData(externalResolution)),
[externalResolution]
);

const interval = useMemo(
() =>
executeWithPerfomanceCheck("TimelineProvider", "interval", () =>
getIntervalFromInternalTimeRange(range, resolution, timezone)
),
[range, resolution, timezone]
);

const initialDateTime = useMemo(() => {
let initial = !externalInitialDateTime
? DateTime.now().toMillis()
Expand All @@ -155,19 +183,6 @@ export const TimelineProvider = ({
[externalTasks, range, timezone]
);

const interval = useMemo(
() =>
executeWithPerfomanceCheck("TimelineProvider", "interval", () =>
getIntervalFromInternalTimeRange(range, timezone)
),
[range, timezone]
);

const resolution = useMemo(
() => executeWithPerfomanceCheck("TimelineProvider", "resolution", () => getResolutionData(externalResolution)),
[externalResolution]
);

const timeBlocks = useMemo(
() =>
executeWithPerfomanceCheck("TimelineProvider", "timeBlocks", () =>
Expand Down Expand Up @@ -285,7 +300,7 @@ export const TimelineProvider = ({
tasks,
theme,
timeBlocks,
timezone,
timezone: timezone || "system",
visibleTimeBlocks,
blocksOffset: timeblocksOffset,
}}
Expand Down
7 changes: 4 additions & 3 deletions src/timeline/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ const Timeline: FC<TimelineProps> = () => {
const {
hideResources,
initialDateTime,
interval: { start: intervalStart },
interval,
columnWidth,
resourcesContentHeight,
resolution,
Expand Down Expand Up @@ -100,9 +100,10 @@ const Timeline: FC<TimelineProps> = () => {
}

const timeStart = DateTime.fromMillis(initialDateTime);
const startOffsetInUnit = timeStart.diff(intervalStart!).as(resolution.unit);
console.log("=> Timeline", interval, timeStart.toMillis());
const startOffsetInUnit = timeStart.diff(interval.start!).as(resolution.unit);
wrapper.current.scrollTo({ left: (startOffsetInUnit * columnWidth) / resolution.sizeInUnits });
}, [columnWidth, initialDateTime, intervalStart, resolution.sizeInUnits, resolution.unit]);
}, [columnWidth, initialDateTime, interval, resolution.sizeInUnits, resolution.unit]);

const fullTimelineWidth = useMemo(() => columnWidth * timeBlocks.length, [columnWidth, timeBlocks]);

Expand Down
15 changes: 10 additions & 5 deletions src/utils/time.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { DateTime, Interval } from "luxon";

import { ResolutionData } from "./time-resolution";

export interface TimeRange {
/**
* Start of time range interval
Expand All @@ -21,7 +23,8 @@ export interface InternalTimeRange {
* @param date the input date (number or string formats)
*/
export const getValidTime = (date: number | string, timezone: string | undefined): number => {
const dateInMillis = typeof date === "number" ? date : DateTime.fromISO(date, { zone: timezone }).toMillis();
const tz = timezone || "system";
const dateInMillis = typeof date === "number" ? date : DateTime.fromISO(date, { zone: tz }).toMillis();
if (Number.isNaN(dateInMillis)) {
return new Date().getTime();
}
Expand All @@ -35,10 +38,12 @@ export const getValidTime = (date: number | string, timezone: string | undefined
*/
export const getIntervalFromInternalTimeRange = (
{ start, end }: InternalTimeRange,
resolution: ResolutionData,
timezone: string | undefined
): Interval => {
return Interval.fromDateTimes(
DateTime.fromMillis(start, { zone: timezone }),
DateTime.fromMillis(end, { zone: timezone })
);
const tz = timezone || "system";
const startDateTime = DateTime.fromMillis(start, { zone: tz }).startOf(resolution.unit);
const endDateTime = DateTime.fromMillis(end, { zone: tz }).endOf(resolution.unit);
console.log("=> getIntervalFromInternalTimeRange", start, startDateTime, end, endDateTime);
return Interval.fromDateTimes(startDateTime, endDateTime);
};

0 comments on commit f0befa7

Please sign in to comment.