mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-10-04 02:03:14 +00:00
fix(work-orders): prefer stored media over a zero detail media count
The detail endpoint's info inherits MediaCount from the board row DTO but the service never sets it, so it serializes as 0. The previous guard trusted any numeric value and returned that 0, leaving the slide-over completion gate reporting "At least 1 photo" even after an upload. Take the larger of the reported count and the stored (non-legacy) attachments so a positive API count still wins while a spurious or omitted 0 no longer masks present media. Dropping the unused mapped-row argument also removes a flat-payload path that would have counted legacy items.
This commit is contained in:
parent
74765427bc
commit
a9d8416f0f
2 changed files with 23 additions and 18 deletions
|
|
@ -6,10 +6,7 @@ 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,
|
||||
WorkOrderTableRow,
|
||||
} from "@/domain/work-orders/types/work-order-table-row";
|
||||
import type { CompletionDocStatus } from "@/domain/work-orders/types/work-order-table-row";
|
||||
import type {
|
||||
WorkOrderAuditEntry,
|
||||
WorkOrderComment,
|
||||
|
|
@ -273,21 +270,17 @@ 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. Keep an explicit count when present; otherwise count the same
|
||||
* set the board counts — stored (non-legacy) attachments.
|
||||
* `GET workorders/{id}/detail` info serializes the board row's `MediaCount` as 0 — the detail
|
||||
* DTO inherits the field but the service never sets it — so trusting it verbatim would leave the
|
||||
* slide-over closability gate reporting "At least 1 photo" even after an upload. Take the larger
|
||||
* of the reported count and the stored (non-legacy) attachments: a positive API count still wins,
|
||||
* but a spurious (or omitted) 0 can no longer mask media that are actually present.
|
||||
*/
|
||||
function resolveDetailMediaCount(
|
||||
infoRaw: unknown,
|
||||
info: WorkOrderTableRow,
|
||||
media: WorkOrderBoardMediaItem[],
|
||||
): number {
|
||||
function resolveDetailMediaCount(infoRaw: unknown, media: WorkOrderBoardMediaItem[]): number {
|
||||
const record = asRecord(infoRaw);
|
||||
if (typeof (record.mediaCount ?? record.MediaCount) === "number") {
|
||||
return info.mediaCount;
|
||||
}
|
||||
return media.filter((item) => !item.isLegacy).length;
|
||||
const explicit = record.mediaCount ?? record.MediaCount;
|
||||
const nonLegacyCount = media.filter((item) => !item.isLegacy).length;
|
||||
return Math.max(typeof explicit === "number" ? explicit : 0, nonLegacyCount);
|
||||
}
|
||||
|
||||
export function mapWorkOrderBoardDetail(raw: unknown): WorkOrderBoardDetail {
|
||||
|
|
@ -307,7 +300,7 @@ export function mapWorkOrderBoardDetail(raw: unknown): WorkOrderBoardDetail {
|
|||
const info = mapWorkOrderTableRow(infoRaw);
|
||||
|
||||
return {
|
||||
info: { ...info, mediaCount: resolveDetailMediaCount(infoRaw, info, media) },
|
||||
info: { ...info, mediaCount: resolveDetailMediaCount(infoRaw, media) },
|
||||
completion: mapCompletion(completionRaw ?? {}),
|
||||
comments,
|
||||
audit,
|
||||
|
|
|
|||
|
|
@ -297,6 +297,18 @@ describe("mapWorkOrderBoardDetail media count (SH-339)", () => {
|
|||
);
|
||||
});
|
||||
|
||||
it("prefers stored media when detail info reports an explicit zero", () => {
|
||||
const detail = mapWorkOrderBoardDetail({
|
||||
...SAMPLE_DETAIL,
|
||||
info: { ...reactiveInfo, mediaCount: 0 },
|
||||
});
|
||||
|
||||
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,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue