mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-01 14:23:11 +00:00
fix(work-orders): separate Unscheduled header collapse and Add WO controls
[recover] remove malicious eslint payload (was ccec7322)
This commit is contained in:
parent
78ed8571a0
commit
2ed770bc79
6 changed files with 445 additions and 34 deletions
|
|
@ -118,6 +118,15 @@ Pending (`No`)=2, Uploaded (`Yes`)=1, N/N (`NN`)=3.
|
|||
}
|
||||
```
|
||||
|
||||
#### Buckets
|
||||
|
||||
| Array | Inclusion rule |
|
||||
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `scheduled` | WOs with `scheduledDate` inside `weekStart`–`weekEnd` |
|
||||
| `unscheduled` | **All** WOs without `scheduledDate` (cross-week). Visible for every week request; `targetWeek` is not a week filter — Schedule-cell marker only |
|
||||
|
||||
The FE concatenates `unscheduled + scheduled` into `items` and renders `unscheduled` in the pinned Unscheduled section above day groups. Dated WOs without a dispatcher stay in `scheduled` / day groups (Assigned To highlight), not in `unscheduled`.
|
||||
|
||||
### `/board/search`
|
||||
|
||||
```json
|
||||
|
|
|
|||
|
|
@ -23,52 +23,79 @@ export function WoTableSectionHeader({
|
|||
const isUnscheduled = variant === "unscheduled";
|
||||
|
||||
if (isUnscheduled) {
|
||||
const toggleCollapse = () => {
|
||||
onToggleCollapse?.();
|
||||
};
|
||||
|
||||
return (
|
||||
<tr style={{ background: "rgba(217, 119, 6, 0.08)" }}>
|
||||
<td
|
||||
colSpan={WO_TABLE_COLS.length}
|
||||
onClick={onToggleCollapse}
|
||||
style={{
|
||||
height: 40,
|
||||
padding: "0 14px",
|
||||
cursor: "pointer",
|
||||
boxShadow: "inset 3px 0 0 var(--warning)",
|
||||
borderTop: "1px solid #FDE68A",
|
||||
borderBottom: "1px solid #FDE68A",
|
||||
}}
|
||||
>
|
||||
<div className="flex items-center gap-2.5">
|
||||
<AlertTriangle size={14} className="shrink-0" style={{ color: "var(--warning)" }} />
|
||||
<span
|
||||
className="uppercase"
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-2.5"
|
||||
aria-expanded={!collapsed}
|
||||
aria-label={label}
|
||||
onClick={toggleCollapse}
|
||||
style={{
|
||||
fontFamily: "var(--font-mono)",
|
||||
fontSize: 12,
|
||||
fontWeight: 700,
|
||||
letterSpacing: "0.08em",
|
||||
color: "var(--warning)",
|
||||
background: "transparent",
|
||||
border: "none",
|
||||
padding: 0,
|
||||
cursor: "pointer",
|
||||
color: "inherit",
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
<span style={{ fontSize: 12, color: "var(--color-text-muted)" }}>
|
||||
{count} work order{count !== 1 ? "s" : ""}
|
||||
</span>
|
||||
<AlertTriangle size={14} className="shrink-0" style={{ color: "var(--warning)" }} />
|
||||
<span
|
||||
className="uppercase"
|
||||
style={{
|
||||
fontFamily: "var(--font-mono)",
|
||||
fontSize: 12,
|
||||
fontWeight: 700,
|
||||
letterSpacing: "0.08em",
|
||||
color: "var(--warning)",
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
</span>
|
||||
<span style={{ fontSize: 12, color: "var(--color-text-muted)" }}>
|
||||
{count} work order{count !== 1 ? "s" : ""}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
className="flex items-center gap-1 transition-opacity hover:opacity-70"
|
||||
style={{ fontSize: 12.5, fontWeight: 600, color: "var(--primary)" }}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onAddWo();
|
||||
}}
|
||||
onClick={onAddWo}
|
||||
>
|
||||
<Plus size={13} />
|
||||
Add WO
|
||||
</button>
|
||||
<span className="ml-auto flex items-center" style={{ color: "var(--warning)" }}>
|
||||
<button
|
||||
type="button"
|
||||
className="ml-auto flex items-center"
|
||||
aria-expanded={!collapsed}
|
||||
aria-label={collapsed ? `Expand ${label}` : `Collapse ${label}`}
|
||||
onClick={toggleCollapse}
|
||||
style={{
|
||||
background: "transparent",
|
||||
border: "none",
|
||||
padding: 0,
|
||||
cursor: "pointer",
|
||||
color: "var(--warning)",
|
||||
}}
|
||||
>
|
||||
{collapsed ? <ChevronRight size={14} /> : <ChevronDown size={14} />}
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
@ -129,10 +156,7 @@ export function WoTableSectionHeader({
|
|||
type="button"
|
||||
className="flex items-center gap-1 transition-opacity hover:opacity-70"
|
||||
style={{ fontSize: 12.5, fontWeight: 600, color: "var(--primary)" }}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
onAddWo();
|
||||
}}
|
||||
onClick={onAddWo}
|
||||
>
|
||||
<Plus size={13} />
|
||||
Add WO
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import type {
|
|||
WorkOrderTableRow,
|
||||
} from "@/domain/work-orders/types/work-order-table-row";
|
||||
import { ADVANCED_FILTER_PREDICATES } from "@/domain/work-orders/utils/advanced-filter-predicates";
|
||||
import { isDateInWeek } from "@/domain/work-orders/utils/table-day-utils";
|
||||
import { weekRange } from "@/domain/work-orders/utils/list-week-utils";
|
||||
|
||||
const TERMINAL_STATUSES = new Set(["Completed", "Canceled", "Done", "Cancelled"]);
|
||||
|
|
@ -91,14 +90,10 @@ export function filterByBarAndSearch(
|
|||
}
|
||||
}
|
||||
|
||||
if (row.scheduledOn) {
|
||||
if (row.scheduledOn < weekFrom || row.scheduledOn > weekTo) {
|
||||
return false;
|
||||
}
|
||||
} else if (row.targetWeek) {
|
||||
if (!isDateInWeek(row.targetWeek, bar.weekMonday)) {
|
||||
return false;
|
||||
}
|
||||
// Design weekScoped: undated (!scheduledOn) stay visible every week; targetWeek
|
||||
// is a Schedule-cell marker only, never a week-inclusion predicate.
|
||||
if (row.scheduledOn && (row.scheduledOn < weekFrom || row.scheduledOn > weekTo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,153 @@
|
|||
import { render, screen } from "@testing-library/react";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { WoTableBody } from "@/app/(protected)/workorders/_components/list/table/wo-table-body";
|
||||
import type { ReturnTypeOfUseWorkOrdersTableData } from "@/app/(protected)/workorders/_components/list/table/wo-table-types";
|
||||
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
|
||||
|
||||
function makeRow(overrides: Partial<WorkOrderTableRow> = {}): WorkOrderTableRow {
|
||||
return {
|
||||
id: "1",
|
||||
woNumber: "24991",
|
||||
site: "CLV2",
|
||||
type: "PM",
|
||||
dispatcherId: "",
|
||||
dispatcherName: "",
|
||||
scheduledOn: "2026-06-02",
|
||||
targetWeek: "",
|
||||
dayGroup: "06/02",
|
||||
dayLabel: "TUE · 06/02",
|
||||
location: "Cleveland, OH",
|
||||
locationId: "",
|
||||
pm: "Backflow",
|
||||
serviceNotes: "",
|
||||
extraServices: [],
|
||||
company: "",
|
||||
tech: "",
|
||||
techPhone: "",
|
||||
apptStart: "",
|
||||
apptEnd: "",
|
||||
apptTime: "—",
|
||||
status: "Incomplete",
|
||||
docStatus: "No",
|
||||
pocName: "",
|
||||
pocPhone: "",
|
||||
pocNotes: "",
|
||||
dueDate: "",
|
||||
rescheduleCount: 0,
|
||||
carriedOver: 0,
|
||||
originalWeek: "",
|
||||
originalDate: "",
|
||||
isPastDue: false,
|
||||
scheduleWeekOnly: false,
|
||||
mediaCount: 0,
|
||||
title: "",
|
||||
priority: "",
|
||||
vendorId: "",
|
||||
primaryDispatchId: null,
|
||||
rowVersion: "",
|
||||
dispatchRowVersion: "",
|
||||
flagColor: null,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function baseTableData(
|
||||
overrides: Partial<ReturnTypeOfUseWorkOrdersTableData> = {},
|
||||
): ReturnTypeOfUseWorkOrdersTableData {
|
||||
return {
|
||||
rows: [],
|
||||
isLoading: false,
|
||||
isFetching: false,
|
||||
error: null,
|
||||
refetch: vi.fn(),
|
||||
advActive: false,
|
||||
advResults: [],
|
||||
unscheduled: [],
|
||||
displayGroups: [],
|
||||
searchActive: false,
|
||||
noSearchResults: false,
|
||||
isEmptyWeek: false,
|
||||
todayKey: null,
|
||||
draftDayKey: null,
|
||||
draft: null,
|
||||
setDraft: vi.fn(),
|
||||
unschedOpen: true,
|
||||
setUnschedOpen: vi.fn(),
|
||||
selectedId: null,
|
||||
setSelectedId: vi.fn(),
|
||||
selectedRow: null,
|
||||
flashId: null,
|
||||
triggerFlash: vi.fn(),
|
||||
dragViz: null,
|
||||
setDragViz: vi.fn(),
|
||||
dragState: null,
|
||||
patchRow: vi.fn(),
|
||||
clearRowPatch: vi.fn(),
|
||||
reorderRows: vi.fn(),
|
||||
endDrag: vi.fn(),
|
||||
startDayDraft: vi.fn(),
|
||||
cancelDraft: vi.fn(),
|
||||
addRow: vi.fn(),
|
||||
scopeTotalCount: 0,
|
||||
totalCount: 0,
|
||||
search: "",
|
||||
...overrides,
|
||||
} as ReturnTypeOfUseWorkOrdersTableData;
|
||||
}
|
||||
|
||||
describe("WoTableBody Unscheduled vs day groups", () => {
|
||||
it("renders Unscheduled above day groups and keeps dated unassigned under the day header", () => {
|
||||
const datedUnassigned = makeRow({ id: "u-dated", woNumber: "24991" });
|
||||
const undated = makeRow({
|
||||
id: "us1",
|
||||
woNumber: "25021",
|
||||
scheduledOn: "",
|
||||
dayGroup: "",
|
||||
dayLabel: "",
|
||||
});
|
||||
|
||||
const tableData = baseTableData({
|
||||
unscheduled: [undated],
|
||||
displayGroups: [
|
||||
{
|
||||
key: "06/02",
|
||||
label: "TUE · 06/02",
|
||||
date: "2026-06-02",
|
||||
items: [datedUnassigned],
|
||||
},
|
||||
],
|
||||
unschedOpen: true,
|
||||
});
|
||||
|
||||
render(
|
||||
<table>
|
||||
<WoTableBody
|
||||
tableData={tableData}
|
||||
renderRow={(row) => (
|
||||
<tr key={String(row.id)} data-testid={`row-${row.id}`}>
|
||||
<td>{row.woNumber}</td>
|
||||
</tr>
|
||||
)}
|
||||
renderInlineRow={() => null}
|
||||
/>
|
||||
</table>,
|
||||
);
|
||||
|
||||
expect(screen.getByRole("button", { name: "Unscheduled" })).toBeInTheDocument();
|
||||
expect(screen.getByText("TUE · 06/02")).toBeInTheDocument();
|
||||
|
||||
const unscheduledHeader = screen.getByRole("button", { name: "Unscheduled" });
|
||||
const dayLabel = screen.getByText("TUE · 06/02");
|
||||
const undatedRow = screen.getByTestId("row-us1");
|
||||
const datedRow = screen.getByTestId("row-u-dated");
|
||||
|
||||
expect(
|
||||
unscheduledHeader.compareDocumentPosition(undatedRow) & Node.DOCUMENT_POSITION_FOLLOWING,
|
||||
).toBeTruthy();
|
||||
expect(
|
||||
dayLabel.compareDocumentPosition(datedRow) & Node.DOCUMENT_POSITION_FOLLOWING,
|
||||
).toBeTruthy();
|
||||
expect(screen.queryByTestId("row-u-dated")).toBeInTheDocument();
|
||||
expect(screen.getAllByTestId(/row-/)).toHaveLength(2);
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,165 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import type { WorkOrderBarFilters } from "@/domain/work-orders/types/work-order-list-filters";
|
||||
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
|
||||
import { deriveDayFields } from "@/domain/work-orders/utils/table-day-utils";
|
||||
import {
|
||||
filterByBarAndSearch,
|
||||
splitScheduledUnscheduled,
|
||||
} from "@/domain/work-orders/utils/table-filter-utils";
|
||||
import { weekRange } from "@/domain/work-orders/utils/list-week-utils";
|
||||
|
||||
/**
|
||||
* Design oracle — mirrors shoc-desing/src/pages/WorkOrders.tsx:
|
||||
* - weekScoped (~L9734): !scheduledOn || (scheduledOn >= wStart && scheduledOn <= wEnd)
|
||||
* - split (~L9762): unscheduled = !scheduledOn; dated-but-unassigned stay in day groups
|
||||
*/
|
||||
|
||||
type DesignRow = Pick<WorkOrderTableRow, "id" | "scheduledOn" | "dispatcherId" | "targetWeek">;
|
||||
|
||||
function designWeekScoped(rows: DesignRow[], weekStart: string, weekEnd: string): DesignRow[] {
|
||||
return rows.filter(
|
||||
(row) => !row.scheduledOn || (row.scheduledOn >= weekStart && row.scheduledOn <= weekEnd),
|
||||
);
|
||||
}
|
||||
|
||||
function designSplit(rows: DesignRow[]): {
|
||||
scheduled: DesignRow[];
|
||||
unscheduled: DesignRow[];
|
||||
} {
|
||||
const scheduled: DesignRow[] = [];
|
||||
const unscheduled: DesignRow[] = [];
|
||||
for (const row of rows) {
|
||||
if (!row.scheduledOn) {
|
||||
unscheduled.push(row);
|
||||
} else {
|
||||
scheduled.push(row);
|
||||
}
|
||||
}
|
||||
return { scheduled, unscheduled };
|
||||
}
|
||||
|
||||
function makeRow(overrides: Partial<WorkOrderTableRow> = {}): WorkOrderTableRow {
|
||||
return {
|
||||
id: "1",
|
||||
woNumber: "24991",
|
||||
site: "CLV2",
|
||||
type: "PM",
|
||||
dispatcherId: "u1",
|
||||
dispatcherName: "Alice",
|
||||
scheduledOn: "2026-06-02",
|
||||
targetWeek: "",
|
||||
dayGroup: "06/02",
|
||||
dayLabel: "TUE · 06/02",
|
||||
location: "Cleveland, OH",
|
||||
locationId: "",
|
||||
pm: "Backflow",
|
||||
serviceNotes: "",
|
||||
extraServices: [],
|
||||
company: "",
|
||||
tech: "",
|
||||
techPhone: "",
|
||||
apptStart: "",
|
||||
apptEnd: "",
|
||||
apptTime: "—",
|
||||
status: "Incomplete",
|
||||
docStatus: "No",
|
||||
pocName: "",
|
||||
pocPhone: "",
|
||||
pocNotes: "",
|
||||
dueDate: "",
|
||||
rescheduleCount: 0,
|
||||
carriedOver: 0,
|
||||
originalWeek: "",
|
||||
originalDate: "",
|
||||
isPastDue: false,
|
||||
scheduleWeekOnly: false,
|
||||
mediaCount: 0,
|
||||
title: "",
|
||||
priority: "",
|
||||
vendorId: "",
|
||||
primaryDispatchId: null,
|
||||
rowVersion: "",
|
||||
dispatchRowVersion: "",
|
||||
flagColor: null,
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
function idsOf(rows: { id: string | number }[]): string[] {
|
||||
return rows.map((row) => String(row.id)).sort();
|
||||
}
|
||||
|
||||
describe("board Unscheduled design parity", () => {
|
||||
const weekMonday = "2026-06-01";
|
||||
const [weekStart, weekEnd] = weekRange(weekMonday);
|
||||
|
||||
const fixtures: WorkOrderTableRow[] = [
|
||||
makeRow({
|
||||
id: "u-dated",
|
||||
dispatcherId: "",
|
||||
dispatcherName: "",
|
||||
scheduledOn: "2026-06-02",
|
||||
...deriveDayFields("2026-06-02"),
|
||||
}),
|
||||
makeRow({
|
||||
id: "us-undated",
|
||||
dispatcherId: "",
|
||||
dispatcherName: "",
|
||||
scheduledOn: "",
|
||||
dayGroup: "",
|
||||
dayLabel: "",
|
||||
}),
|
||||
makeRow({
|
||||
id: "ua-assigned-undated",
|
||||
dispatcherId: "sarah",
|
||||
dispatcherName: "Sarah",
|
||||
scheduledOn: "",
|
||||
dayGroup: "",
|
||||
dayLabel: "",
|
||||
}),
|
||||
makeRow({
|
||||
id: "tw-other-week",
|
||||
dispatcherId: "sarah",
|
||||
dispatcherName: "Sarah",
|
||||
scheduledOn: "",
|
||||
targetWeek: "2026-07-06",
|
||||
dayGroup: "",
|
||||
dayLabel: "",
|
||||
}),
|
||||
makeRow({
|
||||
id: "dated-other-week",
|
||||
scheduledOn: "2026-06-15",
|
||||
...deriveDayFields("2026-06-15"),
|
||||
}),
|
||||
];
|
||||
|
||||
const bar: WorkOrderBarFilters = {
|
||||
weekMonday,
|
||||
dispatcherIds: new Set(),
|
||||
type: "All",
|
||||
};
|
||||
|
||||
it("matches design weekScoped ID set via filterByBarAndSearch", () => {
|
||||
const designIds = idsOf(designWeekScoped(fixtures, weekStart, weekEnd));
|
||||
const feIds = idsOf(filterByBarAndSearch(fixtures, bar, ""));
|
||||
expect(feIds).toEqual(designIds);
|
||||
expect(feIds).toContain("tw-other-week");
|
||||
expect(feIds).not.toContain("dated-other-week");
|
||||
});
|
||||
|
||||
it("matches design split: dated unassigned in scheduled, undated in Unscheduled", () => {
|
||||
const scoped = filterByBarAndSearch(fixtures, bar, "");
|
||||
const feSplit = splitScheduledUnscheduled(scoped);
|
||||
const designSplitResult = designSplit(designWeekScoped(fixtures, weekStart, weekEnd));
|
||||
|
||||
expect(idsOf(feSplit.unscheduled)).toEqual(idsOf(designSplitResult.unscheduled));
|
||||
expect(idsOf(feSplit.scheduled)).toEqual(idsOf(designSplitResult.scheduled));
|
||||
|
||||
expect(idsOf(feSplit.scheduled)).toContain("u-dated");
|
||||
expect(idsOf(feSplit.unscheduled)).not.toContain("u-dated");
|
||||
expect(idsOf(feSplit.unscheduled)).toContain("tw-other-week");
|
||||
expect(idsOf(feSplit.unscheduled)).toEqual(
|
||||
expect.arrayContaining(["us-undated", "ua-assigned-undated", "tw-other-week"]),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -1,8 +1,10 @@
|
|||
import { describe, expect, it } from "vitest";
|
||||
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
|
||||
import { EMPTY_ADVANCED_FILTERS } from "@/domain/work-orders/types/work-order-advanced-filters";
|
||||
import type { WorkOrderBarFilters } from "@/domain/work-orders/types/work-order-list-filters";
|
||||
import {
|
||||
buildDayGroups,
|
||||
filterByBarAndSearch,
|
||||
matchesAdvancedFilters,
|
||||
splitScheduledUnscheduled,
|
||||
} from "@/domain/work-orders/utils/table-filter-utils";
|
||||
|
|
@ -57,6 +59,18 @@ function makeRow(overrides: Partial<WorkOrderTableRow> = {}): WorkOrderTableRow
|
|||
};
|
||||
}
|
||||
|
||||
function bar(
|
||||
weekMonday: string,
|
||||
overrides: Partial<WorkOrderBarFilters> = {},
|
||||
): WorkOrderBarFilters {
|
||||
return {
|
||||
weekMonday,
|
||||
dispatcherIds: new Set(),
|
||||
type: "All",
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
describe("deriveDayFields", () => {
|
||||
it("derives MM/DD group and weekday label", () => {
|
||||
expect(deriveDayFields("2026-06-23")).toEqual({
|
||||
|
|
@ -66,6 +80,40 @@ describe("deriveDayFields", () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe("filterByBarAndSearch", () => {
|
||||
const weekMonday = "2026-06-01";
|
||||
|
||||
it("keeps undated rows for any week, including targetWeek outside the active week", () => {
|
||||
const undated = makeRow({ id: "us1", scheduledOn: "", targetWeek: "" });
|
||||
const undatedOtherTarget = makeRow({
|
||||
id: "tw1",
|
||||
scheduledOn: "",
|
||||
targetWeek: "2026-07-06",
|
||||
});
|
||||
|
||||
const ids = filterByBarAndSearch([undated, undatedOtherTarget], bar(weekMonday), "").map(
|
||||
(row) => row.id,
|
||||
);
|
||||
expect(ids).toEqual(["us1", "tw1"]);
|
||||
});
|
||||
|
||||
it("excludes dated rows outside the active week", () => {
|
||||
const inWeek = makeRow({
|
||||
id: "in",
|
||||
scheduledOn: "2026-06-03",
|
||||
...deriveDayFields("2026-06-03"),
|
||||
});
|
||||
const outWeek = makeRow({
|
||||
id: "out",
|
||||
scheduledOn: "2026-06-15",
|
||||
...deriveDayFields("2026-06-15"),
|
||||
});
|
||||
|
||||
const ids = filterByBarAndSearch([inWeek, outWeek], bar(weekMonday), "").map((row) => row.id);
|
||||
expect(ids).toEqual(["in"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("splitScheduledUnscheduled", () => {
|
||||
it("splits rows without scheduledOn into unscheduled", () => {
|
||||
const scheduled = makeRow({ id: "a", scheduledOn: "2026-06-23" });
|
||||
|
|
@ -75,6 +123,23 @@ describe("splitScheduledUnscheduled", () => {
|
|||
expect(result.unscheduled).toHaveLength(1);
|
||||
expect(result.unscheduled[0].id).toBe("b");
|
||||
});
|
||||
|
||||
it("keeps dated unassigned in scheduled and undated in unscheduled without duplicate ids", () => {
|
||||
const datedUnassigned = makeRow({
|
||||
id: "u-dated",
|
||||
dispatcherId: "",
|
||||
dispatcherName: "",
|
||||
scheduledOn: "2026-06-02",
|
||||
...deriveDayFields("2026-06-02"),
|
||||
});
|
||||
const undated = makeRow({ id: "us-undated", scheduledOn: "", dispatcherId: "" });
|
||||
const result = splitScheduledUnscheduled([datedUnassigned, undated]);
|
||||
|
||||
expect(result.scheduled.map((row) => row.id)).toEqual(["u-dated"]);
|
||||
expect(result.unscheduled.map((row) => row.id)).toEqual(["us-undated"]);
|
||||
const allIds = [...result.scheduled, ...result.unscheduled].map((row) => row.id);
|
||||
expect(new Set(allIds).size).toBe(allIds.length);
|
||||
});
|
||||
});
|
||||
|
||||
describe("buildDayGroups", () => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue