Skip to content

Commit

Permalink
[Timeline]: Earliest date defaulted to current date when found date w…
Browse files Browse the repository at this point in the history
…as later than current day (#3458)

* 🐛 Timeline startDate defaulted to current Date when later than current day

* 🧪 Added tests

* Update @navikt/core/react/src/timeline/hooks/useTimelineRows.ts

Co-authored-by: Halvor Haugan <[email protected]>

* 🔥 Removed old exceptions

* 📝 Changeset

---------

Co-authored-by: Halvor Haugan <[email protected]>
  • Loading branch information
KenAJoh and HalvorHaugan authored Dec 16, 2024
1 parent 3b43ad5 commit 6d6900c
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 9 deletions.
5 changes: 5 additions & 0 deletions .changeset/wise-worms-destroy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@navikt/ds-react": patch
---

Timeline: In cases where earliest found date were after current date, timeline-start ended up defaulting to current date.
34 changes: 25 additions & 9 deletions @navikt/core/react/src/timeline/hooks/useTimelineRows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,17 +134,33 @@ export const useTimelineRows = (
[rows, startDate, endDate, direction],
);

const earliestDate = (earliest: Date, period: Period) =>
period.start < earliest ? period.start : earliest;
export const useEarliestDate = ({
startDate,
rows,
}: {
startDate?: Date;
rows: Pick<Period, "start">[][];
}) =>
useMemo(() => {
if (startDate) {
return startDate;
}

const earliestFomDate = (rader: Period[][]) =>
rader.flat().reduce(earliestDate, new Date());
const startDates = rows
.flat()
.filter((period) => period.start)
.map((period) => period.start);

export const useEarliestDate = ({ startDate, rows }: any) =>
useMemo(
() => (startDate ? startDate : earliestFomDate(rows)),
[startDate, rows],
);
if (startDates.length === 0) {
return new Date();
}

const earliestDate = startDates.reduce((earliest, current) =>
current < earliest ? current : earliest,
);

return earliestDate;
}, [startDate, rows]);

const latestDate = (latest: Date, period: Period) =>
period.end > latest ? period.end : latest;
Expand Down
131 changes: 131 additions & 0 deletions @navikt/core/react/src/timeline/tests/useTimelineRows.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
import { renderHook } from "@testing-library/react";
import { addDays, isSameDay } from "date-fns";
import { describe, expect, test } from "vitest";
import {
useEarliestDate,
useLatestDate,
useTimelineRows,
} from "../hooks/useTimelineRows";

describe("useEarliestDate", () => {
test("returns the provided startDate if it exists", () => {
const startDate = new Date(2023, 0, 1);
const { result } = renderHook(() =>
useEarliestDate({ startDate, rows: [] }),
);
expect(result.current).toEqual(startDate);
});

test("returns the earliest date from the rows if startDate is not provided", () => {
const rows = [
[{ start: new Date(2023, 0, 1) }],
[{ start: new Date(2022, 0, 1) }],
];

const { result } = renderHook(() => useEarliestDate({ rows }));
expect(result.current).toEqual(new Date(2022, 0, 1));
});

test("returns the earliest date from the rows if startDate is not provided and date is later than todays date", () => {
const earliestDate = addDays(new Date(), 400);
const rows = [
[{ start: earliestDate }],
[{ start: addDays(earliestDate, 40) }],
];

const { result } = renderHook(() => useEarliestDate({ rows }));
expect(result.current).toEqual(earliestDate);
});

test("returns the current date if no startDate and rows are empty", () => {
const { result } = renderHook(() => useEarliestDate({ rows: [] }));
expect(isSameDay(result.current, new Date())).toBeTruthy();
});
});

describe("useLatestDate", () => {
test("returns the provided endDate if it exists", () => {
const endDate = new Date(2023, 0, 1);
const { result } = renderHook(() => useLatestDate({ endDate, rows: [] }));
expect(result.current).toEqual(endDate);
});

test("returns the latest date from the rows plus one day if endDate is not provided", () => {
const rows = [
[{ start: new Date(2023, 0, 1), end: new Date(2023, 0, 10) }],
[{ start: new Date(2022, 0, 1), end: new Date(2022, 0, 5) }],
];
const { result } = renderHook(() => useLatestDate({ rows }));
expect(result.current).toEqual(addDays(new Date(2023, 0, 10), 1));
});

test("returns the current date plus one day if no endDate and rows are empty", () => {
const { result } = renderHook(() => useLatestDate({ rows: [] }));
expect(result.current).toEqual(addDays(new Date(0), 1));
});
});

describe("useTimelineRows", () => {
const rows = [
{
label: "Row 1",
periods: [
{
start: new Date(2023, 0, 1),
end: new Date(2023, 0, 10),
status: "active",
},
{
start: new Date(2023, 0, 15),
end: new Date(2023, 0, 20),
status: "inactive",
},
],
},
{
label: "Row 2",
periods: [
{
start: new Date(2022, 0, 1),
end: new Date(2022, 0, 5),
status: "active",
},
],
},
];

test("returns the correct timeline rows", () => {
const startDate = new Date(2022, 0, 1);
const endDate = new Date(2023, 0, 31);
const direction = "left";
const { result } = renderHook(() =>
useTimelineRows(rows, startDate, endDate, direction),
);

expect(result.current).toHaveLength(2);
expect(result.current[0].periods).toHaveLength(2);
expect(result.current[1].periods).toHaveLength(1);
});

test("handles empty rows", () => {
const startDate = new Date(2022, 0, 1);
const endDate = new Date(2023, 0, 31);
const direction = "left";
const { result } = renderHook(() =>
useTimelineRows([], startDate, endDate, direction),
);

expect(result.current).toHaveLength(0);
});

test("handles different directions", () => {
const startDate = new Date(2022, 0, 1);
const endDate = new Date(2023, 0, 31);
const direction = "right";
const { result } = renderHook(() =>
useTimelineRows(rows, startDate, endDate, direction),
);

expect(result.current[0].periods[0].start).toEqual(new Date(2023, 0, 15));
});
});

0 comments on commit 6d6900c

Please sign in to comment.