From 408086acc71d85b793dfa23f6118574afe0d7579 Mon Sep 17 00:00:00 2001 From: Harry Groves Date: Mon, 12 Oct 2026 16:14:00 +0800 Subject: [PATCH] Use new anonymous floor and bin labels Workbench, delivery search, reports, and lot suggestion now match new db --- src/app/(main)/chart/delivery/page.tsx | 5 +- src/app/api/chart/client.ts | 7 +-- src/app/api/do/actions.tsx | 3 +- src/app/api/doworkbench/actions.ts | 5 +- src/app/api/jo/actions.ts | 3 +- src/app/api/pickOrder/actions.ts | 3 +- .../settings/deliveryOrderFloor/constants.ts | 5 +- src/app/utils/formatUtil.ts | 5 +- .../truckSchedule/TruckScheduleDashboard.tsx | 7 +-- .../DeliveryOrderFloorSettings.tsx | 33 ++++++------ src/components/DoDetail/DoDetail.tsx | 17 +++--- src/components/DoSearch/DoSearch.tsx | 19 +++---- .../DoSearchWorkbench/DoSearchWorkbench.tsx | 5 +- .../TruckRoutingSummaryTabWorkbench.tsx | 3 +- .../DoWorkbench/WorkbenchEtraMergeDialog.tsx | 7 +-- .../DoWorkbench/WorkbenchFloorLanePanel.tsx | 47 ++++++++-------- .../WorkbenchGoodPickExecutionDetail.tsx | 7 +-- .../WorkbenchLotLabelPrintModal.tsx | 4 +- .../WorkbenchTicketReleaseTable.tsx | 5 +- .../DoWorkbench/workbenchLanePanelPrefs.ts | 7 +-- .../FinishedGoodSearch/FGPickOrderCard.tsx | 13 ++--- .../FGPickOrderTicketReleaseTable.tsx | 5 +- .../FinishedGoodCartonDashboardTab.tsx | 39 +++++++------- .../FinishedGoodFloorLanePanel.tsx | 53 ++++++++++--------- .../FinishedGoodSearch/FinishedGoodSearch.tsx | 7 +-- .../GoodPickExecutiondetail.tsx | 11 ++-- .../ReleasedDoPickOrderSelectModal.tsx | 7 +-- .../TruckRoutingSummaryTab.tsx | 3 +- .../InventorySearch/LotLabelPrintModal.tsx | 10 ++-- .../JoWorkbench/JoPickOrderList.tsx | 11 ++-- .../JoWorkbench/newJobPickExecution.tsx | 32 ++++++----- src/components/Jodetail/JoPickOrderList.tsx | 19 +++---- src/components/Jodetail/JodetailSearch.tsx | 3 +- .../Jodetail/PlasticBoxCartonDashboardTab.tsx | 43 +++++++-------- .../Jodetail/completeJobOrderRecord.tsx | 7 +-- .../Jodetail/newJobPickExecution.tsx | 24 ++++++--- src/components/Jodetail/pickRecordHelpers.ts | 9 ++-- .../LotSuggestionRules/LotSuggestionRules.tsx | 17 +++--- src/components/Shop/RouteBoard.tsx | 43 +++++++-------- src/components/Shop/Shop.tsx | 7 +-- src/components/Shop/ShopDetail.tsx | 5 +- src/components/Shop/TruckLane.tsx | 11 ++-- src/components/Shop/TruckLaneDetail.tsx | 17 +++--- .../Shop/computeTruckLaneWarnings.ts | 11 ++-- .../Shop/routeBoardImportPreview.ts | 3 +- .../ApproverStockTakeAll.tsx | 7 +-- .../StockTakeManagement/PickerCardList.tsx | 7 +-- src/config/demoFloors.ts | 19 +++++++ src/config/reportConfig.ts | 13 ++--- 49 files changed, 367 insertions(+), 286 deletions(-) create mode 100644 src/config/demoFloors.ts diff --git a/src/app/(main)/chart/delivery/page.tsx b/src/app/(main)/chart/delivery/page.tsx index bbbf3bb8..9aa9bbe1 100644 --- a/src/app/(main)/chart/delivery/page.tsx +++ b/src/app/(main)/chart/delivery/page.tsx @@ -1,5 +1,6 @@ "use client"; +import { FLOOR_A, FLOOR_B } from "@/config/demoFloors"; import React, { useCallback, useMemo, useState } from "react"; import { Box, @@ -37,8 +38,8 @@ const STAFF_PERF_STORE_FILTER_OPTIONS: { label: string; }[] = [ { value: "all", label: "全部" }, - { value: "2/F", label: "2/F" }, - { value: "4/F", label: "4/F" }, + { value: FLOOR_A, label: FLOOR_A }, + { value: FLOOR_B, label: FLOOR_B }, { value: "null_only", label: "車線-X" }, ]; diff --git a/src/app/api/chart/client.ts b/src/app/api/chart/client.ts index 96823649..29deacd6 100644 --- a/src/app/api/chart/client.ts +++ b/src/app/api/chart/client.ts @@ -1,3 +1,4 @@ +import { FLOOR_A, FLOOR_B } from "@/config/demoFloors"; import { clientAuthFetch } from "@/app/utils/clientAuthFetch"; import { NEXT_PUBLIC_API_URL } from "@/config/api"; @@ -577,7 +578,7 @@ export async function fetchPlannedOutputByDateAndItem( } /** Warehouse / lane filter for staff delivery performance chart (delivery_order_pick_order.store_id). */ -export type StaffDeliveryPerformanceStoreFilter = "all" | "2/F" | "4/F" | "null_only"; +export type StaffDeliveryPerformanceStoreFilter = "all" | typeof FLOOR_A | typeof FLOOR_B | "null_only"; /** FP-MTMS Version Checklist | Functions Ref. No. 61 | v1.0.0 | 2026-08-10 */ export async function fetchStaffDeliveryPerformance( @@ -591,8 +592,8 @@ export async function fetchStaffDeliveryPerformance( if (endDate) p.set("endDate", endDate); (staffNos ?? []).forEach((no) => p.append("staffNo", no)); if (storeFilter === "null_only") p.set("storeIdNull", "true"); - else if (storeFilter === "2/F") p.set("storeId", "2/F"); - else if (storeFilter === "4/F") p.set("storeId", "4/F"); + else if (storeFilter === FLOOR_A) p.set("storeId", FLOOR_A); + else if (storeFilter === FLOOR_B) p.set("storeId", FLOOR_B); const q = p.toString(); const res = await clientAuthFetch( q ? `${BASE}/staff-delivery-performance?${q}` : `${BASE}/staff-delivery-performance` diff --git a/src/app/api/do/actions.tsx b/src/app/api/do/actions.tsx index 0a60d3cf..fb4cb7f3 100644 --- a/src/app/api/do/actions.tsx +++ b/src/app/api/do/actions.tsx @@ -1,4 +1,5 @@ "use server"; +import { FLOOR_A, FLOOR_B } from "@/config/demoFloors"; import { BASE_API_URL } from "@/config/api"; // import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; import { revalidateTag } from "next/cache"; @@ -85,7 +86,7 @@ export interface ReleaseDoResponse { export interface AssignByStoreRequest { - storeId: string; // "2/F" or "4/F" + storeId: string; // FLOOR_A or FLOOR_B assignTo: number; } diff --git a/src/app/api/doworkbench/actions.ts b/src/app/api/doworkbench/actions.ts index 60a0040d..1e3f177a 100644 --- a/src/app/api/doworkbench/actions.ts +++ b/src/app/api/doworkbench/actions.ts @@ -1,5 +1,6 @@ "use server"; +import { FLOOR_A_KEY, FLOOR_B_KEY } from "@/config/demoFloors"; import { revalidateTag } from "next/cache"; import { BASE_API_URL } from "@/config/api"; import { serverFetchJson } from "@/app/utils/fetchUtil"; @@ -244,7 +245,7 @@ export async function fetchWorkbenchReleasedDoPickOrdersForSelection( storeId?: string, truck?: string, releaseType?: string, - /** Optional `2F`/`4F`: Truck X split by DO supplier preferred floor (storeId stays null). */ + /** Optional `${FLOOR_A_KEY}`/`${FLOOR_B_KEY}`: Truck X split by DO supplier preferred floor (storeId stays null). */ floor?: string ): Promise { const params = new URLSearchParams(); @@ -266,7 +267,7 @@ export async function fetchWorkbenchReleasedDoPickOrdersForSelectionToday( truck?: string, requiredDeliveryDate?: string, releaseType?: string, - /** Optional `2F`/`4F`: Truck X split by DO supplier preferred floor (storeId stays null). */ + /** Optional `${FLOOR_A_KEY}`/`${FLOOR_B_KEY}`: Truck X split by DO supplier preferred floor (storeId stays null). */ floor?: string ): Promise { const params = new URLSearchParams(); diff --git a/src/app/api/jo/actions.ts b/src/app/api/jo/actions.ts index 87d6fcfb..5178a4ec 100644 --- a/src/app/api/jo/actions.ts +++ b/src/app/api/jo/actions.ts @@ -1,5 +1,6 @@ "use server"; +import { FLOOR_A_KEY, FLOOR_B_KEY, FLOOR_D_KEY } from "@/config/demoFloors"; import { cache } from 'react'; import { Pageable, ServerFetchError, serverFetchBlob, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; import { JobOrder, JoStatus, Machine, Operator } from "."; @@ -133,7 +134,7 @@ export interface PrintPickRecordRequest{ pickOrderId: number; printerId: number; printQty: number; - floor?: "2F" | "3F" | "4F" | "ALL"; + floor?: typeof FLOOR_A_KEY | typeof FLOOR_D_KEY | typeof FLOOR_B_KEY | "ALL"; plasticBoxCartonQty?: number; plasticBoxCartonQty2f?: number; plasticBoxCartonQty3f?: number; diff --git a/src/app/api/pickOrder/actions.ts b/src/app/api/pickOrder/actions.ts index 25409697..86e1170e 100644 --- a/src/app/api/pickOrder/actions.ts +++ b/src/app/api/pickOrder/actions.ts @@ -1,4 +1,5 @@ "use server"; +import { FLOOR_A, FLOOR_B } from "@/config/demoFloors"; import { BASE_API_URL } from "@/config/api"; // import { ServerFetchError, serverFetchJson, serverFetchWithNoContent } from "@/app/utils/fetchUtil"; import { revalidateTag } from "next/cache"; @@ -333,7 +334,7 @@ export interface DoPickOrderDetail { } export interface AutoAssignReleaseByStoreRequest { userId: number; - storeId: string; // "2/F" | "4/F" + storeId: string; // FLOOR_A | FLOOR_B } export interface UpdateDoPickOrderHideStatusRequest { id: number; diff --git a/src/app/api/settings/deliveryOrderFloor/constants.ts b/src/app/api/settings/deliveryOrderFloor/constants.ts index 25ce37e4..8da730c7 100644 --- a/src/app/api/settings/deliveryOrderFloor/constants.ts +++ b/src/app/api/settings/deliveryOrderFloor/constants.ts @@ -1,5 +1,6 @@ +import { SETTING_SUPPLIERS_A, SETTING_SUPPLIERS_B } from "@/config/demoFloors"; /** `settings.name`:逗號分隔 supplier **code**(須與後端讀取邏輯一致)。 */ -export const SETTING_DO_FLOOR_SUPPLIERS_2F = "DO.floor.suppliers.2F"; -export const SETTING_DO_FLOOR_SUPPLIERS_4F = "DO.floor.suppliers.4F"; +export const SETTING_DO_FLOOR_SUPPLIERS_2F = SETTING_SUPPLIERS_A; +export const SETTING_DO_FLOOR_SUPPLIERS_4F = SETTING_SUPPLIERS_B; export const SETTING_DO_FLOOR_CATEGORY = "DO_FLOOR"; \ No newline at end of file diff --git a/src/app/utils/formatUtil.ts b/src/app/utils/formatUtil.ts index 9d1d1494..a7eaa146 100644 --- a/src/app/utils/formatUtil.ts +++ b/src/app/utils/formatUtil.ts @@ -1,3 +1,4 @@ +import { FLOOR_A_KEY, FLOOR_B_KEY } from "@/config/demoFloors"; import dayjs, { ConfigType, Dayjs } from "dayjs"; import { Uom } from "../api/settings/uom"; import { @@ -249,7 +250,7 @@ export const normalizeStoreId = (storeId: string | number | String | Number | nu const storeIdStr = typeof storeId === 'string' || storeId instanceof String ? String(storeId) : String(storeId); - if (storeIdStr === "2" || storeIdStr === "2F") return "2F"; - if (storeIdStr === "4" || storeIdStr === "4F") return "4F"; + if (storeIdStr === "2" || storeIdStr === FLOOR_A_KEY) return FLOOR_A_KEY; + if (storeIdStr === "4" || storeIdStr === FLOOR_B_KEY) return FLOOR_B_KEY; return storeIdStr; }; \ No newline at end of file diff --git a/src/components/DashboardPage/truckSchedule/TruckScheduleDashboard.tsx b/src/components/DashboardPage/truckSchedule/TruckScheduleDashboard.tsx index 5c12aad5..6f8a6623 100644 --- a/src/components/DashboardPage/truckSchedule/TruckScheduleDashboard.tsx +++ b/src/components/DashboardPage/truckSchedule/TruckScheduleDashboard.tsx @@ -1,5 +1,6 @@ "use client"; +import { FLOOR_A, FLOOR_B } from "@/config/demoFloors"; import React, { useState, useEffect, useCallback, useMemo, useRef } from 'react'; import { Box, @@ -449,8 +450,8 @@ const TruckScheduleDashboard: React.FC = () => { displayEmpty > {t("All Stores")} - 2/F - 4/F + {FLOOR_A} + {FLOOR_B} @@ -535,7 +536,7 @@ const TruckScheduleDashboard: React.FC = () => { diff --git a/src/components/DeliveryOrderFloorSettings/DeliveryOrderFloorSettings.tsx b/src/components/DeliveryOrderFloorSettings/DeliveryOrderFloorSettings.tsx index 1729aa4d..953191cc 100644 --- a/src/components/DeliveryOrderFloorSettings/DeliveryOrderFloorSettings.tsx +++ b/src/components/DeliveryOrderFloorSettings/DeliveryOrderFloorSettings.tsx @@ -1,5 +1,6 @@ "use client"; +import { FLOOR_A_KEY, FLOOR_B_KEY, FLOOR_A, FLOOR_B } from "@/config/demoFloors"; import React, { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; import EditOutlined from "@mui/icons-material/EditOutlined"; @@ -57,7 +58,7 @@ function formatBracketList(codesCsv: string): string { return `[${n.split(",").join(", ")}]`; } -type EditFloor = "2F" | "4F"; +type EditFloor = typeof FLOOR_A_KEY | typeof FLOOR_B_KEY; type FloorRow = { code: string; name: string }; @@ -97,7 +98,7 @@ const DeliveryOrderFloorSettings: React.FC = () => { const [codes4F, setCodes4F] = useState(""); const [editOpen, setEditOpen] = useState(false); - const [editFloor, setEditFloor] = useState("2F"); + const [editFloor, setEditFloor] = useState(FLOOR_A_KEY); const [dialogSaving, setDialogSaving] = useState(false); const [comboLoading, setComboLoading] = useState(false); const [supplierCombo, setSupplierCombo] = useState(null); @@ -130,8 +131,8 @@ const DeliveryOrderFloorSettings: React.FC = () => { const display2F = useMemo(() => formatBracketList(codes2F), [codes2F]); const display4F = useMemo(() => formatBracketList(codes4F), [codes4F]); - const currentDraftRows = editFloor === "2F" ? draftRows2F : draftRows4F; - const setCurrentDraftRows = editFloor === "2F" ? setDraftRows2F : setDraftRows4F; + const currentDraftRows = editFloor === FLOOR_A_KEY ? draftRows2F : draftRows4F; + const setCurrentDraftRows = editFloor === FLOOR_A_KEY ? setDraftRows2F : setDraftRows4F; const openEdit = async (floor: EditFloor) => { setEditFloor(floor); @@ -172,12 +173,12 @@ const DeliveryOrderFloorSettings: React.FC = () => { setError(null); setSuccess(null); try { - const rows = editFloor === "2F" ? draftRows2F : draftRows4F; + const rows = editFloor === FLOOR_A_KEY ? draftRows2F : draftRows4F; const normalized = normalizeCodesCsv(floorRowsToCsv(rows)); const key = - editFloor === "2F" ? SETTING_DO_FLOOR_SUPPLIERS_2F : SETTING_DO_FLOOR_SUPPLIERS_4F; + editFloor === FLOOR_A_KEY ? SETTING_DO_FLOOR_SUPPLIERS_2F : SETTING_DO_FLOOR_SUPPLIERS_4F; await postSettingClient(key, normalized); - if (editFloor === "2F") setCodes2F(normalized); + if (editFloor === FLOOR_A_KEY) setCodes2F(normalized); else setCodes4F(normalized); setSuccess(t("Saved")); setEditOpen(false); @@ -237,7 +238,7 @@ const DeliveryOrderFloorSettings: React.FC = () => { return; } const canonical = hit.code.trim(); - const otherRows = editFloor === "2F" ? draftRows4F : draftRows2F; + const otherRows = editFloor === FLOOR_A_KEY ? draftRows4F : draftRows2F; if (currentDraftRows.some((r) => r.code.toLowerCase() === canonical.toLowerCase())) { setAddError(t("Duplicate in floor")); return; @@ -286,7 +287,7 @@ const DeliveryOrderFloorSettings: React.FC = () => { }} > - {t("2F supplier")} + {t(FLOOR_A_KEY + " supplier")} { {display2F} void openEdit("2F")} + onClick={() => void openEdit(FLOOR_A_KEY)} size="small" > @@ -319,7 +320,7 @@ const DeliveryOrderFloorSettings: React.FC = () => { }} > - {t("4F supplier")} + {t(FLOOR_B_KEY + " supplier")} { {display4F} void openEdit("4F")} + onClick={() => void openEdit(FLOOR_B_KEY)} size="small" > @@ -361,8 +362,8 @@ const DeliveryOrderFloorSettings: React.FC = () => { onChange={onFloorSelectChange} disabled={dialogSaving || comboLoading} > - 2/F - 4/F + {FLOOR_A} + {FLOOR_B} @@ -224,20 +225,20 @@ const DoDetail: React.FC = ({ diff --git a/src/components/DoSearch/DoSearch.tsx b/src/components/DoSearch/DoSearch.tsx index e4da4268..da8114da 100644 --- a/src/components/DoSearch/DoSearch.tsx +++ b/src/components/DoSearch/DoSearch.tsx @@ -1,5 +1,6 @@ "use client"; +import { FLOOR_A, FLOOR_A_KEY, FLOOR_B, FLOOR_B_KEY } from "@/config/demoFloors"; import { DoResult } from "@/app/api/do"; import { DoSearchAll, @@ -64,8 +65,8 @@ type Props = { }; type SearchBoxInputs = Record<"code" | "status" | "estimatedArrivalDate" | "orderDate" | "supplierName" | "shopName" | "deliveryOrderLines" | "truckLanceCode" | "codeTo" | "statusTo" | "estimatedArrivalDateTo" | "orderDateTo" | "supplierNameTo" | "shopNameTo" | "deliveryOrderLinesTo" | "truckLanceCodeTo", string>; type SearchParamNames = keyof SearchBoxInputs; -type DoSearchTab = "2F" | "4F" | "TRUCK_X" | "ETRA" | "REPLENISH"; -type TabFilter = { floor: "2F" | "4F" | null; isExtra: boolean; forceTruckKeyword?: string }; +type DoSearchTab = typeof FLOOR_A_KEY | typeof FLOOR_B_KEY | "TRUCK_X" | "ETRA" | "REPLENISH"; +type TabFilter = { floor: typeof FLOOR_A_KEY | typeof FLOOR_B_KEY | null; isExtra: boolean; forceTruckKeyword?: string }; // put all this into a new component // ConsoDoForm @@ -103,7 +104,7 @@ const DoSearch: React.FC = ({ filterArgs, searchQuery, onDeliveryOrderSea const [searchAllDos, setSearchAllDos] = useState([]); const [totalCount, setTotalCount] = useState(0); const [isWorkbench, setIsWorkbench] = useState(false); - const [activeTab, setActiveTab] = useState("2F"); + const [activeTab, setActiveTab] = useState(FLOOR_A_KEY); const [searchBoxResetKey, setSearchBoxResetKey] = useState(0); const [pagingController, setPagingController] = useState({ pageNum: 1, @@ -326,10 +327,10 @@ const DoSearch: React.FC = ({ filterArgs, searchQuery, onDeliveryOrderSea const resolveTabFilter = useCallback((tab: DoSearchTab): TabFilter => { switch (tab) { - case "2F": - return { floor: "2F", isExtra: false }; - case "4F": - return { floor: "4F", isExtra: false }; + case FLOOR_A_KEY: + return { floor: FLOOR_A_KEY, isExtra: false }; + case FLOOR_B_KEY: + return { floor: FLOOR_B_KEY, isExtra: false }; case "TRUCK_X": return { floor: null, isExtra: false, forceTruckKeyword: "x" }; case "ETRA": @@ -802,8 +803,8 @@ const DoSearch: React.FC = ({ filterArgs, searchQuery, onDeliveryOrderSea onChange={handleTabChange} variant="scrollable" > - - + + diff --git a/src/components/DoSearchWorkbench/DoSearchWorkbench.tsx b/src/components/DoSearchWorkbench/DoSearchWorkbench.tsx index 39aafb1d..25941ae0 100644 --- a/src/components/DoSearchWorkbench/DoSearchWorkbench.tsx +++ b/src/components/DoSearchWorkbench/DoSearchWorkbench.tsx @@ -1,5 +1,6 @@ "use client"; +import { FLOOR_A_KEY, FLOOR_B_KEY } from "@/config/demoFloors"; import { DoResult } from "@/app/api/do"; import { DoSearchAll, DoSearchLiteResponse, fetchDoSearch, fetchAllDoSearch, fetchDoSearchList, releaseDo } from "@/app/api/do/actions"; import { @@ -150,8 +151,8 @@ const DoSearchWorkbench: React.FC = ({ paramName: "floor", type: "select-labelled", options: [ - { label: "2F", value: "2F" }, - { label: "4F", value: "4F" }, + { label: FLOOR_A_KEY, value: FLOOR_A_KEY }, + { label: FLOOR_B_KEY, value: FLOOR_B_KEY }, ], }, { diff --git a/src/components/DoWorkbench/TruckRoutingSummaryTabWorkbench.tsx b/src/components/DoWorkbench/TruckRoutingSummaryTabWorkbench.tsx index c47689f1..686bd72f 100644 --- a/src/components/DoWorkbench/TruckRoutingSummaryTabWorkbench.tsx +++ b/src/components/DoWorkbench/TruckRoutingSummaryTabWorkbench.tsx @@ -1,5 +1,6 @@ "use client"; +import { FLOOR_A, FLOOR_B } from "@/config/demoFloors"; import { useEffect, useState } from "react"; import { Box, Button, MenuItem, Stack, TextField, Typography } from "@mui/material"; import DownloadIcon from "@mui/icons-material/Download"; @@ -114,7 +115,7 @@ const TruckRoutingSummaryTabWorkbench: React.FC = () => { onStoreChange(e.target.value)} > diff --git a/src/components/DoWorkbench/WorkbenchEtraMergeDialog.tsx b/src/components/DoWorkbench/WorkbenchEtraMergeDialog.tsx index 6f199782..5f03a2aa 100644 --- a/src/components/DoWorkbench/WorkbenchEtraMergeDialog.tsx +++ b/src/components/DoWorkbench/WorkbenchEtraMergeDialog.tsx @@ -1,5 +1,6 @@ "use client"; +import { FLOOR_A, FLOOR_A_KEY, FLOOR_B, FLOOR_B_KEY } from "@/config/demoFloors"; import { Box, Button, @@ -41,8 +42,8 @@ type Props = { function floorLabel(storeId: string | null | undefined, t: (k: string) => string): string { const s = (storeId ?? "").trim().replace(/\//g, "").toUpperCase(); - if (s === "2F") return "2/F"; - if (s === "4F") return "4/F"; + if (s === FLOOR_A_KEY) return FLOOR_A; + if (s === FLOOR_B_KEY) return FLOOR_B; if (!s) return t("Truck X"); return storeId ?? ""; } @@ -58,7 +59,7 @@ function laneSecondary(c: WorkbenchMergeTicketCandidate, t: (k: string) => strin const dep = (c.truckDepartureTime ?? "").trim(); const lane = (c.truckLanceCode ?? "").trim(); const floor = floorLabel(c.storeId, t); - const is4F = (c.storeId ?? "").trim().replace(/\//g, "").toUpperCase() === "4F"; + const is4F = (c.storeId ?? "").trim().replace(/\//g, "").toUpperCase() === FLOOR_B_KEY; const seq = is4F && c.loadingSequence != null ? `${t("Loading sequence")} ${c.loadingSequence} · ` diff --git a/src/components/DoWorkbench/WorkbenchFloorLanePanel.tsx b/src/components/DoWorkbench/WorkbenchFloorLanePanel.tsx index 76b722bf..2334b7fc 100644 --- a/src/components/DoWorkbench/WorkbenchFloorLanePanel.tsx +++ b/src/components/DoWorkbench/WorkbenchFloorLanePanel.tsx @@ -1,5 +1,6 @@ "use client"; +import { FLOOR_A, FLOOR_A_KEY, FLOOR_B, FLOOR_B_KEY } from "@/config/demoFloors"; import { Box, Button, Grid, Stack, Typography, Select, MenuItem, FormControl, InputLabel } from "@mui/material"; import { useCallback, useEffect, useMemo, useRef, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -53,7 +54,7 @@ const WorkbenchFloorLanePanel: React.FC = ({ const { t } = useTranslation("pickOrder"); const { data: session } = useSession() as { data: SessionWithTokens | null }; const currentUserId = session?.id ? parseInt(session.id) : undefined; - const [selectedStore, setSelectedStore] = useState("2/F"); + const [selectedStore, setSelectedStore] = useState(FLOOR_A); const [selectedTruck, setSelectedTruck] = useState(""); const [modalOpen, setModalOpen] = useState(false); const [truckCounts2F, setTruckCounts2F] = useState<{ truck: string; count: number }[]>([]); @@ -92,7 +93,7 @@ const WorkbenchFloorLanePanel: React.FC = ({ [ticketFloor], ); const defaultTruckCount = - (ticketFloor === "2/F" ? summary2F?.defaultTruckCount : summary4F?.defaultTruckCount) ?? 0; + (ticketFloor === FLOOR_A ? summary2F?.defaultTruckCount : summary4F?.defaultTruckCount) ?? 0; const etraEnterInFlightRef = useRef(false); const [etraMergeDialogOpen, setEtraMergeDialogOpen] = useState(false); @@ -167,8 +168,8 @@ const WorkbenchFloorLanePanel: React.FC = ({ else if (selectedDate === "tomorrow") dateParam = dayjs().add(1, "day").format("YYYY-MM-DD"); else if (selectedDate === "dayAfterTomorrow") dateParam = dayjs().add(2, "day").format("YYYY-MM-DD"); const [s2, s4] = await Promise.all([ - fetchWorkbenchStoreLaneSummary("2/F", dateParam, releaseType), - fetchWorkbenchStoreLaneSummary("4/F", dateParam, releaseType), + fetchWorkbenchStoreLaneSummary(FLOOR_A, dateParam, releaseType), + fetchWorkbenchStoreLaneSummary(FLOOR_B, dateParam, releaseType), ]); setSummary2F(s2); setSummary4F(s4); @@ -217,8 +218,8 @@ const WorkbenchFloorLanePanel: React.FC = ({ startFullTimer(); try { const [list2F, list4F] = await Promise.all([ - fetchWorkbenchReleasedDoPickOrdersForSelection(undefined, "2/F"), - fetchWorkbenchReleasedDoPickOrdersForSelection(undefined, "4/F"), + fetchWorkbenchReleasedDoPickOrdersForSelection(undefined, FLOOR_A), + fetchWorkbenchReleasedDoPickOrdersForSelection(undefined, FLOOR_B), ]); const groupByTruck = (list: { truckLanceCode?: string | null }[]) => { const map: Record = {}; @@ -441,8 +442,8 @@ const WorkbenchFloorLanePanel: React.FC = ({ {t("Floor ticket")} @@ -481,10 +482,10 @@ const WorkbenchFloorLanePanel: React.FC = ({ {!inEtraUi ? ( - {ticketFloor === "2/F" && ( + {ticketFloor === FLOOR_A && ( - 2/F + {FLOOR_A} {isLoadingSummary ? {t("Loading...")} : !summary2F?.rows?.length ? renderNoEntry() : ( @@ -494,7 +495,7 @@ const WorkbenchFloorLanePanel: React.FC = ({ {row.truckDepartureTime} {row.lanes.map((lane) => ( - ))} @@ -509,10 +510,10 @@ const WorkbenchFloorLanePanel: React.FC = ({ )} - {ticketFloor === "4/F" && ( + {ticketFloor === FLOOR_B && ( - 4/F + {FLOOR_B} {isLoadingSummary ? {t("Loading...")} : !truckGroups4F.length ? renderNoEntry() : ( @@ -524,7 +525,7 @@ const WorkbenchFloorLanePanel: React.FC = ({ {slots.map((slot) => { const handlerName = (slot.lane.handlerName ?? "").trim(); return ( - ); @@ -585,21 +586,21 @@ const WorkbenchFloorLanePanel: React.FC = ({ - {ticketFloor === "2/F" && ( + {ticketFloor === FLOOR_A && ( - 2/F + {FLOOR_A} {truckCounts2F.length === 0 ? renderNoEntry() : ( {truckCounts2F.map(({ truck, count }) => ( - + @@ -3913,7 +3919,7 @@ const JobPickExecution: React.FC = ({ filterArgs, onBackToList, printerCo variant="contained" color="primary" size="small" - onClick={() => handlePickRecord("3F")} + onClick={() => handlePickRecord(FLOOR_D_KEY)} > {t("Print Pick Record")} 3F @@ -3921,7 +3927,7 @@ const JobPickExecution: React.FC = ({ filterArgs, onBackToList, printerCo variant="contained" color="primary" size="small" - onClick={() => handlePickRecord("4F")} + onClick={() => handlePickRecord(FLOOR_B_KEY)} > {t("Print Pick Record")} 4F diff --git a/src/components/Jodetail/JoPickOrderList.tsx b/src/components/Jodetail/JoPickOrderList.tsx index 40d73411..a26ae458 100644 --- a/src/components/Jodetail/JoPickOrderList.tsx +++ b/src/components/Jodetail/JoPickOrderList.tsx @@ -1,5 +1,6 @@ /* "use client"; +import { FLOOR_A_KEY, FLOOR_B_KEY, FLOOR_D_KEY } from "@/config/demoFloors"; import React, { useCallback, useEffect, useState } from "react"; import { Box, @@ -28,7 +29,7 @@ const JoPickOrderList: React.FC = ({ onSwitchToRecordTab }) =>{ const [selectedJobOrderId, setSelectedJobOrderId] = useState(undefined); type PickOrderFilter = "all" | "drink" | "Powder_Mixture" | "other"; const [filter, setFilter] = useState("all"); - type FloorFilter = "ALL" | "2F" | "3F" | "4F" | "NO_LOT"; + type FloorFilter = "ALL" | typeof FLOOR_A_KEY | typeof FLOOR_D_KEY | typeof FLOOR_B_KEY | "NO_LOT"; const [floorFilter, setFloorFilter] = useState("ALL"); const fetchPickOrders = useCallback(async () => { setLoading(true); @@ -124,25 +125,25 @@ const JoPickOrderList: React.FC = ({ onSwitchToRecordTab }) =>{ {t("Select All")}