fix(work-orders): follow Aveta draft on Extra Docs while editing

Extras treated a persisted false as authoritative, so unsaved Aveta
toggles never reached the overlay. Refresh the filters visual baseline
for the Aveta Compliance section.
This commit is contained in:
Arthur Bassi 2026-08-25 13:36:38 -03:00
parent b47167bb2b
commit 838d79c2dd
5 changed files with 148 additions and 1 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 149 KiB

After

Width:  |  Height:  |  Size: 151 KiB

View file

@ -10,6 +10,7 @@ import type {
WorkOrderUser,
} from "@/domain/work-orders/types/work-order";
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
import { resolveSlideOverAvetaRequired } from "@/domain/work-orders/utils/resolve-slide-over-aveta-required";
import type { useWorkOrderSlideOver, SlideOverTab } from "./use-work-order-slide-over";
import { WorkOrderSlideOverTabPanel } from "./work-order-slide-over-tab-panel";
@ -146,7 +147,11 @@ export function WorkOrderSlideOverTabs({
>
<SlideOverExtrasTab
uploads={state.extrasUploads}
avetaRequired={Boolean(infoSource?.avetaRequired ?? activeDraft?.avetaRequired)}
avetaRequired={resolveSlideOverAvetaRequired(
state.editing,
infoSource?.avetaRequired,
activeDraft?.avetaRequired,
)}
isReadOnly={state.isExtrasReadOnly}
pending={state.mediaPending}
onUpload={(files) => {

View file

@ -0,0 +1,8 @@
/** Extras overlay follows the unsaved Info draft while editing. */
export function resolveSlideOverAvetaRequired(
editing: boolean,
persisted: boolean | undefined,
draft: boolean | undefined,
): boolean {
return Boolean(editing ? draft : persisted);
}

View file

@ -0,0 +1,117 @@
import { screen } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { WorkOrderSlideOverTabs } from "@/app/(protected)/workorders/_components/detail/work-order-slide-over-tabs";
import type { useWorkOrderSlideOver } from "@/app/(protected)/workorders/_components/detail/use-work-order-slide-over";
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
import { renderWithProviders } from "@/test/test-utils";
type SlideOverState = ReturnType<typeof useWorkOrderSlideOver>;
function baseRow(overrides: Partial<WorkOrderTableRow> = {}): WorkOrderTableRow {
return {
id: 42,
woNumber: "WO-42",
site: "SEA1",
type: "PM",
severity: null,
dispatcherId: "u1",
dispatcherName: "Dispatcher",
scheduledOn: "2026-07-20",
completedDate: "",
targetWeek: "",
dayGroup: "07/20",
dayLabel: "Mon",
location: "Seattle",
locationId: "loc-1",
pm: "HVAC",
serviceNotes: "",
extraServices: [],
company: "Vendor Co",
tech: "Tech",
techPhone: "",
vendorId: "v1",
apptStart: "",
apptEnd: "",
apptTime: "",
status: "Scheduled",
docStatus: "No",
pocName: "",
pocPhone: "",
pocNotes: "",
additionalContacts: [],
dueDate: "",
rescheduleCount: 0,
carriedOver: 0,
originalWeek: "",
originalDate: "",
isPastDue: false,
scheduleWeekOnly: false,
mediaCount: 0,
title: "PM — SEA1",
priority: "Sev 3",
primaryDispatchId: null,
rowVersion: "v1",
dispatchRowVersion: "",
flagColor: null,
isAddOn: false,
avetaRequired: false,
upliftSummary: { hasUplift: false, pendingCount: 0 },
...overrides,
};
}
function extrasState(editing: boolean, persisted: boolean, draft: boolean): SlideOverState {
return {
error: null,
detailForRow: undefined,
isLoading: false,
infoSource: baseRow({ avetaRequired: persisted }),
activeDraft: baseRow({ avetaRequired: draft }),
showDetailSkeleton: false,
errorMessage: "",
refetch: vi.fn(),
extrasUploads: [],
isExtrasReadOnly: true,
mediaPending: false,
uploadExtraFiles: vi.fn(),
removeMedia: vi.fn(),
editing,
} as unknown as SlideOverState;
}
function renderExtras(state: SlideOverState) {
return renderWithProviders(
<WorkOrderSlideOverTabs
tab="extras"
state={state}
users={[]}
sites={[]}
vendors={[]}
pmTypes={[]}
allOrders={[]}
onOpenCompletionDoc={vi.fn()}
/>,
);
}
describe("WorkOrderSlideOverTabs Extras Aveta draft", () => {
it("shows the Extras Aveta indicator from an unsaved false-to-true draft", () => {
renderExtras(extrasState(true, false, true));
expect(screen.getByText("Extra Documents")).toBeInTheDocument();
expect(screen.getByText("Aveta")).toBeInTheDocument();
});
it("hides the Extras Aveta indicator from an unsaved true-to-false draft", () => {
renderExtras(extrasState(true, true, false));
expect(screen.getByText("Extra Documents")).toBeInTheDocument();
expect(screen.queryByText("Aveta")).not.toBeInTheDocument();
});
it("keeps the persisted Aveta indicator when not editing", () => {
renderExtras(extrasState(false, true, false));
expect(screen.getByText("Aveta")).toBeInTheDocument();
});
});

View file

@ -0,0 +1,17 @@
import { describe, expect, it } from "vitest";
import { resolveSlideOverAvetaRequired } from "@/domain/work-orders/utils/resolve-slide-over-aveta-required";
describe("resolveSlideOverAvetaRequired", () => {
it("uses the draft when editing false-to-true", () => {
expect(resolveSlideOverAvetaRequired(true, false, true)).toBe(true);
});
it("uses the draft when editing true-to-false", () => {
expect(resolveSlideOverAvetaRequired(true, true, false)).toBe(false);
});
it("uses the persisted row when not editing", () => {
expect(resolveSlideOverAvetaRequired(false, false, true)).toBe(false);
expect(resolveSlideOverAvetaRequired(false, true, false)).toBe(true);
});
});