mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-02 09:43:12 +00:00
fix(work-orders): count detail media for slide-over completion gate
Detail info omits MediaCount, so the slide-over closability gate always reported a missing photo on Reactive/Emergency work orders. Refs SH-339.
This commit is contained in:
parent
fc3e7591dc
commit
e7f8772802
2 changed files with 70 additions and 2 deletions
|
|
@ -6,7 +6,10 @@ import type {
|
|||
WorkOrderBoardMediaItem,
|
||||
} from "@/domain/work-orders/types/work-order-board-detail";
|
||||
import { BOARD_MEDIA_CATEGORY_API } from "@/domain/work-orders/types/work-order-board-detail";
|
||||
import type { CompletionDocStatus } from "@/domain/work-orders/types/work-order-table-row";
|
||||
import type {
|
||||
CompletionDocStatus,
|
||||
WorkOrderTableRow,
|
||||
} from "@/domain/work-orders/types/work-order-table-row";
|
||||
import type {
|
||||
WorkOrderAuditEntry,
|
||||
WorkOrderComment,
|
||||
|
|
@ -269,6 +272,24 @@ export function boardMediaItemsToMediaFiles(items: WorkOrderBoardMediaItem[]): M
|
|||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* `GET workorders/{id}/detail` info omits the board row's `MediaCount`, so the table-row mapper
|
||||
* defaults it to 0 and the slide-over closability gate would report "At least 1 photo" even
|
||||
* after an upload (SH-339). Keep an explicit count when present; otherwise count the same
|
||||
* set the board counts — stored (non-legacy) attachments.
|
||||
*/
|
||||
function resolveDetailMediaCount(
|
||||
infoRaw: unknown,
|
||||
info: WorkOrderTableRow,
|
||||
media: WorkOrderBoardMediaItem[],
|
||||
): number {
|
||||
const record = asRecord(infoRaw);
|
||||
if (typeof (record.mediaCount ?? record.MediaCount) === "number") {
|
||||
return info.mediaCount;
|
||||
}
|
||||
return media.filter((item) => !item.isLegacy).length;
|
||||
}
|
||||
|
||||
export function mapWorkOrderBoardDetail(raw: unknown): WorkOrderBoardDetail {
|
||||
const root = asRecord(raw);
|
||||
const infoRaw = root.info ?? root.Info ?? root;
|
||||
|
|
@ -283,8 +304,10 @@ export function mapWorkOrderBoardDetail(raw: unknown): WorkOrderBoardDetail {
|
|||
: [];
|
||||
const media = Array.isArray(mediaRaw) ? mediaRaw.map(mapBoardDetailMediaItem) : [];
|
||||
|
||||
const info = mapWorkOrderTableRow(infoRaw);
|
||||
|
||||
return {
|
||||
info: mapWorkOrderTableRow(infoRaw),
|
||||
info: { ...info, mediaCount: resolveDetailMediaCount(infoRaw, info, media) },
|
||||
completion: mapCompletion(completionRaw ?? {}),
|
||||
comments,
|
||||
audit,
|
||||
|
|
|
|||
|
|
@ -6,6 +6,10 @@ import {
|
|||
mapBoardDetailMediaItem,
|
||||
mapWorkOrderBoardDetail,
|
||||
} from "@/domain/work-orders/mappers/work-order-board-detail-mapper";
|
||||
import {
|
||||
getClosabilityGaps,
|
||||
tableRowToClosabilityInput,
|
||||
} from "@/domain/work-orders/utils/wo-closability";
|
||||
|
||||
const SAMPLE_DETAIL = {
|
||||
info: {
|
||||
|
|
@ -279,3 +283,44 @@ describe("mapWorkOrderBoardDetail", () => {
|
|||
expect(completionForm.get("file")).toBeInstanceOf(File);
|
||||
});
|
||||
});
|
||||
|
||||
describe("mapWorkOrderBoardDetail media count (SH-339)", () => {
|
||||
const reactiveInfo = { ...SAMPLE_DETAIL.info, workOrderType: 6 };
|
||||
|
||||
it("derives mediaCount from stored media when detail info omits it", () => {
|
||||
const detail = mapWorkOrderBoardDetail({ ...SAMPLE_DETAIL, info: reactiveInfo });
|
||||
|
||||
expect(detail.info.type).toBe("Reactive");
|
||||
expect(detail.info.mediaCount).toBe(2);
|
||||
expect(getClosabilityGaps(tableRowToClosabilityInput(detail.info))).not.toContain(
|
||||
"At least 1 photo",
|
||||
);
|
||||
});
|
||||
|
||||
it("does not count legacy URL-column media, matching the board row count", () => {
|
||||
const detail = mapWorkOrderBoardDetail({
|
||||
...SAMPLE_DETAIL,
|
||||
info: reactiveInfo,
|
||||
media: [
|
||||
{
|
||||
id: -1,
|
||||
category: 1,
|
||||
url: "https://cdn.example.com/legacy.jpg",
|
||||
fileName: "legacy.jpg",
|
||||
isLegacy: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
expect(detail.info.mediaCount).toBe(0);
|
||||
});
|
||||
|
||||
it("keeps an explicit info mediaCount", () => {
|
||||
const detail = mapWorkOrderBoardDetail({
|
||||
...SAMPLE_DETAIL,
|
||||
info: { ...reactiveInfo, mediaCount: 5 },
|
||||
});
|
||||
|
||||
expect(detail.info.mediaCount).toBe(5);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue