diff --git a/src/app/(protected)/workorders/_components/list/table/cells/uplift-cell.tsx b/src/app/(protected)/workorders/_components/list/table/cells/uplift-cell.tsx index 6f4c4558..9e357667 100644 --- a/src/app/(protected)/workorders/_components/list/table/cells/uplift-cell.tsx +++ b/src/app/(protected)/workorders/_components/list/table/cells/uplift-cell.tsx @@ -7,9 +7,11 @@ import { type UpliftCellProps = { summary: UpliftSummary; onOpen?: () => void; + /** Closed work orders show a dash (not "Manage") that still opens the read-only history. */ + readOnly?: boolean; }; -export function UpliftCell({ summary, onOpen }: UpliftCellProps) { +export function UpliftCell({ summary, onOpen, readOnly = false }: UpliftCellProps) { const label = getUpliftCellLabel(summary); if (!onOpen) { @@ -30,7 +32,7 @@ export function UpliftCell({ summary, onOpen }: UpliftCellProps) { e.stopPropagation(); onOpen(); }} - title={label ? "View uplifts" : "Manage uplifts"} + title={label || readOnly ? "View uplifts" : "Manage uplifts"} className="flex w-full items-center justify-start transition-opacity hover:opacity-80" > {label && pillStyle ? ( @@ -40,6 +42,8 @@ export function UpliftCell({ summary, onOpen }: UpliftCellProps) { > {label} + ) : readOnly ? ( + — ) : ( Manage )} diff --git a/src/app/(protected)/workorders/_components/list/table/wo-table-row-service-cells.tsx b/src/app/(protected)/workorders/_components/list/table/wo-table-row-service-cells.tsx index 21731f67..a9b51892 100644 --- a/src/app/(protected)/workorders/_components/list/table/wo-table-row-service-cells.tsx +++ b/src/app/(protected)/workorders/_components/list/table/wo-table-row-service-cells.tsx @@ -9,7 +9,7 @@ import { StatusCell } from "./cells/status-cell"; import { UpliftCell } from "./cells/uplift-cell"; import { VendorCell } from "./cells/vendor-cell"; import { EMPTY_UPLIFT_SUMMARY } from "@/domain/work-orders/types/work-order-uplift"; -import { canOpenUpliftsDialog } from "@/domain/work-orders/utils/uplift-display-utils"; +import { isWorkOrderUpliftsReadOnly } from "@/domain/work-orders/utils/uplift-display-utils"; import { applyVendorTableSave } from "@/domain/work-orders/utils/work-order-feedback-toasts"; import { effectiveCompany } from "@/domain/work-orders/utils/effective-completion-snapshot"; import type { WoTableRowHandlers } from "./wo-table-row"; @@ -132,12 +132,8 @@ export function WoTableRowServiceCells({ e.stopPropagation()}> handlers.onOpenUplifts!(row) - : undefined - } + onOpen={handlers.onOpenUplifts ? () => handlers.onOpenUplifts!(row) : undefined} + readOnly={isWorkOrderUpliftsReadOnly(row.status)} /> diff --git a/src/domain/work-orders/utils/uplift-display-utils.ts b/src/domain/work-orders/utils/uplift-display-utils.ts index a72d8837..7b271420 100644 --- a/src/domain/work-orders/utils/uplift-display-utils.ts +++ b/src/domain/work-orders/utils/uplift-display-utils.ts @@ -74,16 +74,6 @@ export function isWorkOrderUpliftsReadOnly(status: WorkOrderTableRow["status"]): return status === "Completed" || status === "Canceled"; } -export function canOpenUpliftsDialog( - summary: UpliftSummary, - status: WorkOrderTableRow["status"], -): boolean { - if (summary.hasUplift || summary.pendingCount > 0) { - return true; - } - return !isWorkOrderUpliftsReadOnly(status); -} - export function canRevokeWorkOrderUplift( uplift: Pick, currentUserId: string | number | null | undefined, diff --git a/src/test/app/(protected)/workorders/wo-table-row-service-cells-uplift-open.test.tsx b/src/test/app/(protected)/workorders/wo-table-row-service-cells-uplift-open.test.tsx new file mode 100644 index 00000000..87f2bda4 --- /dev/null +++ b/src/test/app/(protected)/workorders/wo-table-row-service-cells-uplift-open.test.tsx @@ -0,0 +1,81 @@ +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"; + +vi.mock("@/app/(protected)/workorders/_components/list/table/cells/pm-type-cell", () => ({ + PMTypeCell: () => null, +})); +vi.mock("@/app/(protected)/workorders/_components/list/table/cells/appt-time-cell", () => ({ + ApptTimeCell: () => null, +})); +vi.mock("@/app/(protected)/workorders/_components/list/table/cells/status-cell", () => ({ + StatusCell: () => null, +})); +vi.mock("@/app/(protected)/workorders/_components/list/table/cells/comp-doc-cell", () => ({ + CompDocCell: () => null, +})); +vi.mock("@/app/(protected)/workorders/_components/list/table/cells/date-cell", () => ({ + DateCell: () => null, +})); +vi.mock("@/app/(protected)/workorders/_components/list/table/cells/vendor-cell", () => ({ + VendorCell: () => null, +})); + +function renderCells(row: WorkOrderTableRow, onOpenUplifts = vi.fn()) { + const handlers = { onOpenUplifts } as unknown as WoTableRowHandlers; + renderWithProviders( + + + + + + +
, + { withAuth: false }, + ); + return onOpenUplifts; +} + +describe("WoTableRowServiceCells uplift column", () => { + // A closed work order whose uplifts were all cancelled or revoked has no live uplift, + // but its read-only uplift history must stay one click away. + it.each(["Completed", "Canceled"] as const)( + "opens the read-only uplift history from a dash on a %s work order with no live uplift", + (status) => { + const row = { + id: 7, + status, + upliftSummary: { hasUplift: false, pendingCount: 0 }, + } as WorkOrderTableRow; + + const onOpenUplifts = renderCells(row); + + const trigger = screen.getByRole("button", { name: "—" }); + expect(screen.queryByText("Manage")).not.toBeInTheDocument(); + fireEvent.click(trigger); + expect(onOpenUplifts).toHaveBeenCalledWith(row); + }, + ); + + it("offers Manage on an open work order with no live uplift", () => { + const row = { + id: 8, + status: "Scheduled", + upliftSummary: { hasUplift: false, pendingCount: 0 }, + } as WorkOrderTableRow; + + const onOpenUplifts = renderCells(row); + + fireEvent.click(screen.getByRole("button", { name: "Manage" })); + expect(onOpenUplifts).toHaveBeenCalledWith(row); + }); +});