mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-04 16:02:08 +00:00
fix(work-orders): keep carry-over rows in day reorder and one-char search
This commit is contained in:
parent
08e00c213d
commit
bc1e7a1fa2
5 changed files with 76 additions and 3 deletions
|
|
@ -1,5 +1,6 @@
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
|
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
|
||||||
|
import { applyCarryOverDisplayDayFields } from "@/domain/work-orders/utils/carry-over-display";
|
||||||
import { deriveDayFields } from "@/domain/work-orders/utils/table-day-utils";
|
import { deriveDayFields } from "@/domain/work-orders/utils/table-day-utils";
|
||||||
import { enrichTableRow } from "@/domain/work-orders/utils/table-filter-utils";
|
import { enrichTableRow } from "@/domain/work-orders/utils/table-filter-utils";
|
||||||
import {
|
import {
|
||||||
|
|
@ -62,8 +63,11 @@ export function useWorkOrdersTableLocalState({
|
||||||
const displayRows = useMemo(() => {
|
const displayRows = useMemo(() => {
|
||||||
const apiIds = new Set(apiRows.map((r) => String(r.id)));
|
const apiIds = new Set(apiRows.map((r) => String(r.id)));
|
||||||
const extra = localRows.filter((r) => !apiIds.has(String(r.id)));
|
const extra = localRows.filter((r) => !apiIds.has(String(r.id)));
|
||||||
return applyRowOrderByDay([...apiRows, ...extra.map(enrichTableRow)], rowOrderByDay);
|
const merged = [...apiRows, ...extra.map(enrichTableRow)].map((row) =>
|
||||||
}, [apiRows, localRows, rowOrderByDay]);
|
applyCarryOverDisplayDayFields(row, weekMonday),
|
||||||
|
);
|
||||||
|
return applyRowOrderByDay(merged, rowOrderByDay);
|
||||||
|
}, [apiRows, localRows, rowOrderByDay, weekMonday]);
|
||||||
|
|
||||||
const clearRowPatch = useCallback((id: string | number) => {
|
const clearRowPatch = useCallback((id: string | number) => {
|
||||||
const key = String(id);
|
const key = String(id);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { compactWeekLabel } from "@/domain/work-orders/utils/list-week-utils";
|
import { compactWeekLabel } from "@/domain/work-orders/utils/list-week-utils";
|
||||||
import { formatRescheduleCountLabel } from "@/domain/work-orders/utils/reschedule-indicator";
|
import { formatRescheduleCountLabel } from "@/domain/work-orders/utils/reschedule-indicator";
|
||||||
|
import { deriveDayFields } from "@/domain/work-orders/utils/table-day-utils";
|
||||||
import { addDaysIso, mondayOf } from "@/domain/work-orders/utils/wizard-date-utils";
|
import { addDaysIso, mondayOf } from "@/domain/work-orders/utils/wizard-date-utils";
|
||||||
|
|
||||||
const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
const ISO_DATE = /^\d{4}-\d{2}-\d{2}$/;
|
||||||
|
|
@ -92,3 +93,17 @@ export function rowMatchesCarryOverDay(
|
||||||
}
|
}
|
||||||
return mapCarryOverDisplayDay(row.scheduledOn, weekMonday) === selectedDayIso;
|
return mapCarryOverDisplayDay(row.scheduledOn, weekMonday) === selectedDayIso;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Aligns UI day keys with the mapped weekday so reorder stays on the displayed tab. */
|
||||||
|
export function applyCarryOverDisplayDayFields<
|
||||||
|
T extends CarryOverRow & { dayGroup: string; dayLabel: string },
|
||||||
|
>(row: T, weekMonday: string): T {
|
||||||
|
if (!isCarryOverDisplayRow(row, weekMonday)) {
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
const displayDay = mapCarryOverDisplayDay(row.scheduledOn, weekMonday);
|
||||||
|
if (!displayDay) {
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
return { ...row, ...deriveDayFields(displayDay) };
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import type {
|
||||||
WorkOrderTableRow,
|
WorkOrderTableRow,
|
||||||
} from "@/domain/work-orders/types/work-order-table-row";
|
} from "@/domain/work-orders/types/work-order-table-row";
|
||||||
import { ADVANCED_FILTER_PREDICATES } from "@/domain/work-orders/utils/advanced-filter-predicates";
|
import { ADVANCED_FILTER_PREDICATES } from "@/domain/work-orders/utils/advanced-filter-predicates";
|
||||||
|
import { isCarryOverDisplayRow } from "@/domain/work-orders/utils/carry-over-display";
|
||||||
import { isDateInWeek } from "@/domain/work-orders/utils/table-day-utils";
|
import { isDateInWeek } from "@/domain/work-orders/utils/table-day-utils";
|
||||||
import { weekRange } from "@/domain/work-orders/utils/list-week-utils";
|
import { weekRange } from "@/domain/work-orders/utils/list-week-utils";
|
||||||
|
|
||||||
|
|
@ -96,7 +97,7 @@ export function filterByBarAndSearch(
|
||||||
|
|
||||||
if (row.scheduledOn) {
|
if (row.scheduledOn) {
|
||||||
if (row.scheduledOn < weekFrom || row.scheduledOn > weekTo) {
|
if (row.scheduledOn < weekFrom || row.scheduledOn > weekTo) {
|
||||||
return false;
|
return isCarryOverDisplayRow(row, bar.weekMonday);
|
||||||
}
|
}
|
||||||
} else if (row.targetWeek) {
|
} else if (row.targetWeek) {
|
||||||
if (!isDateInWeek(row.targetWeek, bar.weekMonday)) {
|
if (!isDateInWeek(row.targetWeek, bar.weekMonday)) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { describe, expect, it } from "vitest";
|
import { describe, expect, it } from "vitest";
|
||||||
import {
|
import {
|
||||||
|
applyCarryOverDisplayDayFields,
|
||||||
formatCarriedOverHover,
|
formatCarriedOverHover,
|
||||||
isCarryOverDisplayRow,
|
isCarryOverDisplayRow,
|
||||||
mapCarryOverDisplayDay,
|
mapCarryOverDisplayDay,
|
||||||
|
|
@ -60,4 +61,34 @@ describe("carry-over-display", () => {
|
||||||
expect(mapCarryOverDisplayDay("2026-05-16", "2026-05-18")).toBe("2026-05-18");
|
expect(mapCarryOverDisplayDay("2026-05-16", "2026-05-18")).toBe("2026-05-18");
|
||||||
expect(mapCarryOverDisplayDay("2026-05-17", "2026-05-18")).toBe("2026-05-18");
|
expect(mapCarryOverDisplayDay("2026-05-17", "2026-05-18")).toBe("2026-05-18");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("remaps dayGroup to the viewed weekday without changing scheduledOn", () => {
|
||||||
|
const row = {
|
||||||
|
scheduledOn: "2026-05-13",
|
||||||
|
status: "Scheduled",
|
||||||
|
dayGroup: "05/13",
|
||||||
|
dayLabel: "WED · 05/13",
|
||||||
|
};
|
||||||
|
const next = applyCarryOverDisplayDayFields(row, "2026-05-18");
|
||||||
|
expect(next.scheduledOn).toBe("2026-05-13");
|
||||||
|
expect(next.dayGroup).toBe("05/20");
|
||||||
|
expect(next.dayLabel).toBe("WED · 05/20");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("leaves in-week and terminal rows' dayGroup unchanged", () => {
|
||||||
|
const inWeek = {
|
||||||
|
scheduledOn: "2026-05-20",
|
||||||
|
status: "Scheduled",
|
||||||
|
dayGroup: "05/20",
|
||||||
|
dayLabel: "WED · 05/20",
|
||||||
|
};
|
||||||
|
const completed = {
|
||||||
|
scheduledOn: "2026-05-13",
|
||||||
|
status: "Completed",
|
||||||
|
dayGroup: "05/13",
|
||||||
|
dayLabel: "WED · 05/13",
|
||||||
|
};
|
||||||
|
expect(applyCarryOverDisplayDayFields(inWeek, "2026-05-18")).toEqual(inWeek);
|
||||||
|
expect(applyCarryOverDisplayDayFields(completed, "2026-05-18")).toEqual(completed);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,28 @@ describe("filterByBarAndSearch", () => {
|
||||||
expect(ids).toEqual(["in"]);
|
expect(ids).toEqual(["in"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("keeps prior-week unresolved carry-over rows that match a one-character search", () => {
|
||||||
|
const carried = makeRow({
|
||||||
|
id: "co",
|
||||||
|
woNumber: "WO-CARRY",
|
||||||
|
scheduledOn: "2026-05-13",
|
||||||
|
status: "Scheduled",
|
||||||
|
...deriveDayFields("2026-05-13"),
|
||||||
|
});
|
||||||
|
const completed = makeRow({
|
||||||
|
id: "done",
|
||||||
|
woNumber: "WO-DONE",
|
||||||
|
scheduledOn: "2026-05-13",
|
||||||
|
status: "Completed",
|
||||||
|
...deriveDayFields("2026-05-13"),
|
||||||
|
});
|
||||||
|
|
||||||
|
const ids = filterByBarAndSearch([carried, completed], bar("2026-05-18"), "W").map(
|
||||||
|
(row) => row.id,
|
||||||
|
);
|
||||||
|
expect(ids).toEqual(["co"]);
|
||||||
|
});
|
||||||
|
|
||||||
it("keeps the union of selected types (OR)", () => {
|
it("keeps the union of selected types (OR)", () => {
|
||||||
const pm = makeRow({ id: "pm", type: "PM", scheduledOn: "2026-06-03" });
|
const pm = makeRow({ id: "pm", type: "PM", scheduledOn: "2026-06-03" });
|
||||||
const emergency = makeRow({ id: "em", type: "Emergency", scheduledOn: "2026-06-03" });
|
const emergency = makeRow({ id: "em", type: "Emergency", scheduledOn: "2026-06-03" });
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue