mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-02 16:43:13 +00:00
fix(workorders): let dispatchers clear the completed date from the board cell (SH-390)
The completed-date cell editor had no Clear control. It now offers Clear when a date is set and the row is editable, patching completedDate to an empty value, which the board PATCH persists as null. Completed and Canceled rows stay locked, matching set/change.
This commit is contained in:
parent
6367dc2a7a
commit
460397dacb
3 changed files with 136 additions and 0 deletions
|
|
@ -114,6 +114,9 @@ export function WoTableRowServiceCells({
|
|||
value={row.completedDate}
|
||||
q={search}
|
||||
onSave={(date) => onPatchRow({ completedDate: date })}
|
||||
onClear={
|
||||
row.completedDate && !viewOnly ? () => onPatchRow({ completedDate: "" }) : undefined
|
||||
}
|
||||
/>
|
||||
</td>
|
||||
<td style={{ padding: "0 14px" }} onClick={(e) => e.stopPropagation()}>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,128 @@
|
|||
import { fireEvent, screen } from "@testing-library/react";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { WoTableRowServiceCells } from "@/app/(protected)/workorders/_components/list/table/wo-table-row-service-cells";
|
||||
import type { WoTableRowHandlers } from "@/app/(protected)/workorders/_components/list/table/wo-table-row";
|
||||
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
|
||||
import { renderWithProviders } from "@/test/test-utils";
|
||||
|
||||
function makeRow(overrides: Partial<WorkOrderTableRow> = {}): WorkOrderTableRow {
|
||||
return {
|
||||
id: 9,
|
||||
woNumber: "24818000001",
|
||||
site: "BK5",
|
||||
type: "PM",
|
||||
severity: null,
|
||||
dispatcherId: "u1",
|
||||
dispatcherName: "Alex",
|
||||
scheduledOn: "2026-07-15",
|
||||
completedDate: "2026-07-20",
|
||||
targetWeek: "2026-07-15",
|
||||
dayGroup: "07/15",
|
||||
dayLabel: "Tue",
|
||||
location: "Lobby",
|
||||
locationId: "loc-1",
|
||||
pm: "HVAC",
|
||||
serviceNotes: "",
|
||||
extraServices: [],
|
||||
vendorId: "7",
|
||||
company: "Acme",
|
||||
tech: "Sam",
|
||||
techPhone: "",
|
||||
apptStart: "",
|
||||
apptEnd: "",
|
||||
apptTime: "09:00 – 10:00",
|
||||
status: "Incomplete",
|
||||
docStatus: "Yes",
|
||||
pocName: "",
|
||||
pocPhone: "",
|
||||
pocNotes: "",
|
||||
dueDate: "2026-07-22",
|
||||
rescheduleCount: 0,
|
||||
carriedOver: 0,
|
||||
originalWeek: "",
|
||||
originalDate: "",
|
||||
isPastDue: false,
|
||||
scheduleWeekOnly: false,
|
||||
isAddOn: false,
|
||||
mediaCount: 1,
|
||||
title: "",
|
||||
priority: "",
|
||||
primaryDispatchId: null,
|
||||
rowVersion: "",
|
||||
dispatchRowVersion: "",
|
||||
flagColor: null,
|
||||
additionalContacts: [],
|
||||
upliftSummary: { hasUplift: false, pendingCount: 0 },
|
||||
...overrides,
|
||||
};
|
||||
}
|
||||
|
||||
const handlers: WoTableRowHandlers = {
|
||||
onRowClick: vi.fn(),
|
||||
onView: vi.fn(),
|
||||
onEdit: vi.fn(),
|
||||
onOpenMedia: vi.fn(),
|
||||
onPatch: vi.fn(),
|
||||
onScheduleDate: vi.fn(),
|
||||
onScheduleWeek: vi.fn(),
|
||||
onScheduleRange: vi.fn(),
|
||||
onOpenSlideOver: vi.fn(),
|
||||
onOpenCompDoc: vi.fn(),
|
||||
onOpenUplifts: vi.fn(),
|
||||
onReorder: vi.fn(),
|
||||
onDragStart: vi.fn(),
|
||||
onDragOver: vi.fn(),
|
||||
onDrop: vi.fn(),
|
||||
onDragEnd: vi.fn(),
|
||||
};
|
||||
|
||||
function renderCells(row: WorkOrderTableRow, viewOnly = false) {
|
||||
const onPatchRow = vi.fn();
|
||||
renderWithProviders(
|
||||
<table>
|
||||
<tbody>
|
||||
<tr>
|
||||
<WoTableRowServiceCells
|
||||
row={row}
|
||||
vendors={[]}
|
||||
pmTypes={[]}
|
||||
viewOnly={viewOnly}
|
||||
handlers={handlers}
|
||||
onPatchRow={onPatchRow}
|
||||
/>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>,
|
||||
);
|
||||
return onPatchRow;
|
||||
}
|
||||
|
||||
describe("WoTableRowServiceCells completed date Clear (SH-390)", () => {
|
||||
it("shows Clear in the completed-date editor and patches completedDate to empty", async () => {
|
||||
const onPatchRow = renderCells(makeRow());
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: /07-20/ }));
|
||||
|
||||
fireEvent.click(await screen.findByRole("button", { name: /clear/i }));
|
||||
|
||||
expect(onPatchRow).toHaveBeenCalledWith({ completedDate: "" });
|
||||
});
|
||||
|
||||
it("offers no Clear when the completed date is already empty", async () => {
|
||||
renderCells(makeRow({ completedDate: "" }));
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: "—" }));
|
||||
|
||||
expect(await screen.findByRole("button", { name: "20" })).toBeInTheDocument();
|
||||
expect(screen.queryByRole("button", { name: /clear/i })).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("offers no Clear on a Completed (view-only) row", async () => {
|
||||
renderCells(makeRow({ status: "Completed" }), true);
|
||||
|
||||
fireEvent.click(screen.getByRole("button", { name: /07-20/ }));
|
||||
|
||||
expect(await screen.findByRole("button", { name: "20" })).toBeInTheDocument();
|
||||
expect(screen.queryByRole("button", { name: /clear/i })).not.toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
|
@ -16,6 +16,11 @@ describe("COMPLETED DATE board column wiring", () => {
|
|||
expect(ops).toEqual([{ field: "completedDate", value: "2026-07-30" }]);
|
||||
});
|
||||
|
||||
it("expands a clearing completedDate patch to an empty-string board field op (SH-390)", () => {
|
||||
const ops = expandScalarBoardOps({ completedDate: "" });
|
||||
expect(ops).toEqual([{ field: "completedDate", value: "" }]);
|
||||
});
|
||||
|
||||
it("maps completedDate returned by a board GET row", () => {
|
||||
const row = mapWorkOrderTableRow({
|
||||
id: 42,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue