mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-04 16:02:08 +00:00
Merge pull request #208 from Sea-Haven-Industries/fix/ab/sh-369-completion-doc-service-gate
Some checks are pending
Some checks are pending
SH-369: keep completion document disabled until a service is selected
This commit is contained in:
commit
9fb2cc9702
3 changed files with 74 additions and 2 deletions
|
|
@ -8,13 +8,29 @@ type SlideOverCompletionActionsProps = {
|
||||||
docStatus: CompletionDocStatus;
|
docStatus: CompletionDocStatus;
|
||||||
rowVersion?: string | number | null;
|
rowVersion?: string | number | null;
|
||||||
completionPending: boolean;
|
completionPending: boolean;
|
||||||
|
/** Completion documents require a selected primary service. */
|
||||||
|
hasService: boolean;
|
||||||
hasUploadHandler: boolean;
|
hasUploadHandler: boolean;
|
||||||
pdfInputRef: RefObject<HTMLInputElement | null>;
|
pdfInputRef: RefObject<HTMLInputElement | null>;
|
||||||
onPdfSelected: (files: FileList | null) => void;
|
onPdfSelected: (files: FileList | null) => void;
|
||||||
onOpenCompletionDoc: () => void;
|
onOpenCompletionDoc: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
function DocStatusButtonContent({ docStatus }: { docStatus: CompletionDocStatus }) {
|
function DocStatusButtonContent({
|
||||||
|
docStatus,
|
||||||
|
hasService,
|
||||||
|
}: {
|
||||||
|
docStatus: CompletionDocStatus;
|
||||||
|
hasService: boolean;
|
||||||
|
}) {
|
||||||
|
if (!hasService) {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<FileText size={13} />
|
||||||
|
Select service
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
if (docStatus === "Yes") {
|
if (docStatus === "Yes") {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
@ -43,6 +59,7 @@ export function SlideOverCompletionActions({
|
||||||
docStatus,
|
docStatus,
|
||||||
rowVersion,
|
rowVersion,
|
||||||
completionPending,
|
completionPending,
|
||||||
|
hasService,
|
||||||
hasUploadHandler,
|
hasUploadHandler,
|
||||||
pdfInputRef,
|
pdfInputRef,
|
||||||
onPdfSelected,
|
onPdfSelected,
|
||||||
|
|
@ -83,10 +100,17 @@ export function SlideOverCompletionActions({
|
||||||
<Button
|
<Button
|
||||||
variant="outline"
|
variant="outline"
|
||||||
className="w-full gap-1.5 text-[12px]"
|
className="w-full gap-1.5 text-[12px]"
|
||||||
|
disabled={!hasService}
|
||||||
|
title={hasService ? undefined : "Select a service before opening the completion document"}
|
||||||
onClick={onOpenCompletionDoc}
|
onClick={onOpenCompletionDoc}
|
||||||
>
|
>
|
||||||
<DocStatusButtonContent docStatus={docStatus} />
|
<DocStatusButtonContent docStatus={docStatus} hasService={hasService} />
|
||||||
</Button>
|
</Button>
|
||||||
|
{!hasService && (
|
||||||
|
<Text as="p" style={{ fontSize: 11, color: "var(--color-text-muted)" }}>
|
||||||
|
Select a service before opening the completion document.
|
||||||
|
</Text>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import type { UploadableMediaCategory } from "@/domain/work-orders/mappers/work-
|
||||||
import type { WorkOrderBoardCompletion } from "@/domain/work-orders/types/work-order-board-detail";
|
import type { WorkOrderBoardCompletion } from "@/domain/work-orders/types/work-order-board-detail";
|
||||||
import type { MediaFile } from "@/domain/work-orders/types/work-order-media";
|
import type { MediaFile } from "@/domain/work-orders/types/work-order-media";
|
||||||
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 { hasCompletionDocService } from "@/domain/work-orders/utils/completion-doc-service-gate";
|
||||||
import { hasCompletionMediaGallery } from "@/domain/work-orders/utils/partition-slide-over-media";
|
import { hasCompletionMediaGallery } from "@/domain/work-orders/utils/partition-slide-over-media";
|
||||||
import {
|
import {
|
||||||
formatMediaSizeLimit,
|
formatMediaSizeLimit,
|
||||||
|
|
@ -126,6 +127,7 @@ export function SlideOverCompletionTab({
|
||||||
docStatus={docStatus}
|
docStatus={docStatus}
|
||||||
rowVersion={row.rowVersion}
|
rowVersion={row.rowVersion}
|
||||||
completionPending={completionPending}
|
completionPending={completionPending}
|
||||||
|
hasService={hasCompletionDocService(row.pm)}
|
||||||
hasUploadHandler={Boolean(onUploadCompletionPdf)}
|
hasUploadHandler={Boolean(onUploadCompletionPdf)}
|
||||||
pdfInputRef={pdfInputRef}
|
pdfInputRef={pdfInputRef}
|
||||||
onPdfSelected={handlePdfSelected}
|
onPdfSelected={handlePdfSelected}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
import { fireEvent, render, screen } from "@testing-library/react";
|
||||||
|
import { describe, expect, it, vi } from "vitest";
|
||||||
|
import { SlideOverCompletionTab } from "@/app/(protected)/workorders/_components/detail/tabs/slide-over-completion-tab";
|
||||||
|
import type { WorkOrderTableRow } from "@/domain/work-orders/types/work-order-table-row";
|
||||||
|
|
||||||
|
function renderTab(pm: string, onOpenCompletionDoc = vi.fn()) {
|
||||||
|
const row = { id: "1", type: "PM", pm, docStatus: "No", rowVersion: "1" } as WorkOrderTableRow;
|
||||||
|
render(
|
||||||
|
<SlideOverCompletionTab
|
||||||
|
row={row}
|
||||||
|
isReadOnly={false}
|
||||||
|
media={[]}
|
||||||
|
onOpenCompletionDoc={onOpenCompletionDoc}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
return onOpenCompletionDoc;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("SlideOverCompletionTab service gate", () => {
|
||||||
|
it("disables the completion document button until a service is selected", () => {
|
||||||
|
const onOpen = renderTab(" ");
|
||||||
|
|
||||||
|
const button = screen.getByRole("button", { name: /select service/i });
|
||||||
|
expect(button).toBeDisabled();
|
||||||
|
expect(
|
||||||
|
screen.getByText("Select a service before opening the completion document."),
|
||||||
|
).toBeInTheDocument();
|
||||||
|
expect(
|
||||||
|
screen.queryByRole("button", { name: /open completion document/i }),
|
||||||
|
).not.toBeInTheDocument();
|
||||||
|
|
||||||
|
fireEvent.click(button);
|
||||||
|
expect(onOpen).not.toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("opens the completion document when a service is selected", () => {
|
||||||
|
const onOpen = renderTab("HVAC Inspection");
|
||||||
|
|
||||||
|
const button = screen.getByRole("button", { name: /open completion document/i });
|
||||||
|
expect(button).toBeEnabled();
|
||||||
|
expect(screen.queryByText(/select service/i)).not.toBeInTheDocument();
|
||||||
|
|
||||||
|
fireEvent.click(button);
|
||||||
|
expect(onOpen).toHaveBeenCalledTimes(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
Loading…
Add table
Reference in a new issue