From 0288c2b1c2a2017379d163dab772f7eb5f0ad0d5 Mon Sep 17 00:00:00 2001 From: natib21 Date: Sat, 4 Jul 2026 03:02:17 +0000 Subject: [PATCH] fix --- .../src/pages/operations/FirstMilePage.tsx | 31 +++++++++++++++++- .../src/pages/operations/LastMilePage.tsx | 32 ++++++++++++++++++- .../backoffice/src/types/booking.ts | 2 ++ 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/apps/edr-freight-web/backoffice/src/pages/operations/FirstMilePage.tsx b/apps/edr-freight-web/backoffice/src/pages/operations/FirstMilePage.tsx index 9f5efd993..2b130848c 100644 --- a/apps/edr-freight-web/backoffice/src/pages/operations/FirstMilePage.tsx +++ b/apps/edr-freight-web/backoffice/src/pages/operations/FirstMilePage.tsx @@ -664,6 +664,35 @@ const FirstMilePage = () => { return opts; }, [vehicleOptions, activeRecord]); + // Full booking (with container units) for the assign modal's container dropdown. + // Fetched on open so container numbers show regardless of what the list embeds. + const { data: assignBooking } = useQuery({ + queryKey: activeRecord?.bookingId + ? QUERY_KEYS.BOOKINGS.byId(activeRecord.bookingId) + : ["bookings", "detail", "none"], + queryFn: () => bookingsService.getById(activeRecord!.bookingId), + enabled: assignOpen && !bulkMode && Boolean(activeRecord?.bookingId), + }); + + // Container-number options for the dropdown = the booking's real per-container + // numbers (units), falling back to whatever the list record carried. + const containerOptions = useMemo(() => { + const real = (n?: string | null): n is string => + Boolean(n) && !/^TBD/i.test(n!.trim()); + const out: string[] = []; + for (const c of assignBooking?.bookingContainers ?? []) { + const units = [...(c.units ?? [])].sort( + (a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0), + ); + if (units.length) { + for (const u of units) if (real(u.containerNumber)) out.push(u.containerNumber); + } else if (real(c.containerNumber)) { + out.push(c.containerNumber); + } + } + return out.length ? out : activeRecord ? bookingContainerNumbers(activeRecord) : []; + }, [assignBooking, activeRecord]); + const selectedIds = useMemo( () => Object.keys(rowSelection).filter((id) => rowSelection[id]), [rowSelection], @@ -1312,7 +1341,7 @@ const FirstMilePage = () => { style={{ flex: 1 }} label={i === 0 ? "Container no." : undefined} placeholder="Container number" - data={(activeRecord ? bookingContainerNumbers(activeRecord) : []).filter( + data={containerOptions.filter( (n) => n === row.containerNumber || !vehicleRows.some((r, idx) => idx !== i && r.containerNumber === n), diff --git a/apps/edr-freight-web/backoffice/src/pages/operations/LastMilePage.tsx b/apps/edr-freight-web/backoffice/src/pages/operations/LastMilePage.tsx index 5ee5f05b4..4b5cec080 100644 --- a/apps/edr-freight-web/backoffice/src/pages/operations/LastMilePage.tsx +++ b/apps/edr-freight-web/backoffice/src/pages/operations/LastMilePage.tsx @@ -42,6 +42,7 @@ import { } from "@mantine/core"; import type { ArrivalQueueItem, ImportUnloadedItem, WarehouseInventoryItem } from "@/types/warehouse"; import { warehouseService } from "@/services/warehouse.service"; +import { bookingsService } from "@/services/bookings.service"; import { ruleEngineTable } from "@/components/ruleEngine/ruleEngineStyles"; import { QUERY_KEYS } from "@/constants/QUERY_KEYS"; @@ -853,6 +854,35 @@ const LastMilePage = () => { return opts; }, [vehicleOptions, activeRecord]); + // Full booking (with container units) for the assign modal's container dropdown. + // Fetched on open so container numbers show regardless of what the list embeds. + const { data: assignBooking } = useQuery({ + queryKey: activeRecord?.bookingId + ? QUERY_KEYS.BOOKINGS.byId(activeRecord.bookingId) + : ["bookings", "detail", "none"], + queryFn: () => bookingsService.getById(activeRecord!.bookingId), + enabled: assignOpen && !bulkMode && Boolean(activeRecord?.bookingId), + }); + + // Container-number options for the dropdown = the booking's real per-container + // numbers (units), falling back to whatever the list record carried. + const containerOptions = useMemo(() => { + const real = (n?: string | null): n is string => + Boolean(n) && !/^TBD/i.test(n!.trim()); + const out: string[] = []; + for (const c of assignBooking?.bookingContainers ?? []) { + const units = [...(c.units ?? [])].sort( + (a, b) => (a.sortOrder ?? 0) - (b.sortOrder ?? 0), + ); + if (units.length) { + for (const u of units) if (real(u.containerNumber)) out.push(u.containerNumber); + } else if (real(c.containerNumber)) { + out.push(c.containerNumber); + } + } + return out.length ? out : activeRecord ? bookingContainerNumbers(activeRecord) : []; + }, [assignBooking, activeRecord]); + const pickupReadyByBooking = useMemo(() => { const map = new Map(); for (const row of pickupReadyRows) { @@ -1671,7 +1701,7 @@ const LastMilePage = () => { style={{ flex: 1 }} label={i === 0 ? "Container no." : undefined} placeholder="Container number" - data={(activeRecord ? bookingContainerNumbers(activeRecord) : []).filter( + data={containerOptions.filter( (n) => n === row.containerNumber || !vehicleRows.some((r, idx) => idx !== i && r.containerNumber === n), diff --git a/apps/edr-freight-web/backoffice/src/types/booking.ts b/apps/edr-freight-web/backoffice/src/types/booking.ts index 71d9fd793..2c0be4726 100644 --- a/apps/edr-freight-web/backoffice/src/types/booking.ts +++ b/apps/edr-freight-web/backoffice/src/types/booking.ts @@ -83,6 +83,8 @@ export interface BookingContainerUnit { export interface BookingContainerLine { id: string; containerTypeId: string; + /** Line-level number — often a "TBD-…" placeholder; real numbers live in units. */ + containerNumber?: string | null; quantity: number; vgmPerUnitTons: number; containerType?: {