釐清 inventoryLotLineId=實際批,對齊 actualPickLotLineId(無行為變更) tab 數量 0 不顯示 (0);Badge→文字 (n);欄位「工單編號/貨品編號」;中文 i18n(工單流程、預計生產日期、含未按規劃完成…)production
| @@ -167,6 +167,7 @@ interface JobOrderOpsTableProps { | |||||
| printerCombo?: PrinterCombo[]; | printerCombo?: PrinterCombo[]; | ||||
| } | } | ||||
| /** FP-MTMS Version Checklist | Functions Ref. No. 47 | v1.0.1 | 2026-08-05 */ | |||||
| const JobOrderOpsTable: React.FC<JobOrderOpsTableProps> = ({ | const JobOrderOpsTable: React.FC<JobOrderOpsTableProps> = ({ | ||||
| onSelectProcess, | onSelectProcess, | ||||
| printerCombo = [], | printerCombo = [], | ||||
| @@ -517,17 +518,49 @@ const JobOrderOpsTable: React.FC<JobOrderOpsTableProps> = ({ | |||||
| scrollButtons="auto" | scrollButtons="auto" | ||||
| sx={{ mb: 1, borderBottom: 1, borderColor: "divider" }} | sx={{ mb: 1, borderBottom: 1, borderColor: "divider" }} | ||||
| > | > | ||||
| <Tab value="all" label={`${t("All")} (${counts.all})`} /> | |||||
| <Tab value="pending" label={`${t("pending")} (${counts.pending})`} /> | |||||
| <Tab value="processing" label={`${t("Processing")} (${counts.processing})`} /> | |||||
| <Tab | |||||
| value="all" | |||||
| label={counts.all > 0 ? `${t("All")} (${counts.all})` : t("All")} | |||||
| /> | |||||
| <Tab | |||||
| value="pending" | |||||
| label={ | |||||
| counts.pending > 0 | |||||
| ? `${t("pending")} (${counts.pending})` | |||||
| : t("pending") | |||||
| } | |||||
| /> | |||||
| <Tab | |||||
| value="processing" | |||||
| label={ | |||||
| counts.processing > 0 | |||||
| ? `${t("Processing")} (${counts.processing})` | |||||
| : t("Processing") | |||||
| } | |||||
| /> | |||||
| <Tab | <Tab | ||||
| value="pending_qc" | value="pending_qc" | ||||
| label={`${t("Waiting QC Put Away")} (${counts.pendingQc})`} | |||||
| label={ | |||||
| counts.pendingQc > 0 | |||||
| ? `${t("Waiting QC Put Away")} (${counts.pendingQc})` | |||||
| : t("Waiting QC Put Away") | |||||
| } | |||||
| /> | |||||
| <Tab | |||||
| value="putawayed" | |||||
| label={ | |||||
| counts.putawayed > 0 | |||||
| ? `${t("Put Awayed")} (${counts.putawayed})` | |||||
| : t("Put Awayed") | |||||
| } | |||||
| /> | /> | ||||
| <Tab value="putawayed" label={`${t("Put Awayed")} (${counts.putawayed})`} /> | |||||
| <Tab | <Tab | ||||
| value="issue" | value="issue" | ||||
| label={`${t("Issue")} (${counts.stop + counts.cancel})`} | |||||
| label={ | |||||
| counts.stop + counts.cancel > 0 | |||||
| ? `${t("Issue")} (${counts.stop + counts.cancel})` | |||||
| : t("Issue") | |||||
| } | |||||
| /> | /> | ||||
| </Tabs> | </Tabs> | ||||
| @@ -561,8 +594,22 @@ const JobOrderOpsTable: React.FC<JobOrderOpsTableProps> = ({ | |||||
| onChange={(_, v: IssueSubTab) => setIssueSub(v)} | onChange={(_, v: IssueSubTab) => setIssueSub(v)} | ||||
| sx={{ mb: 2 }} | sx={{ mb: 2 }} | ||||
| > | > | ||||
| <Tab value="stop" label={`${t("Stop (paused)")} (${counts.stop})`} /> | |||||
| <Tab value="cancel" label={`${t("Cancelled")} (${counts.cancel})`} /> | |||||
| <Tab | |||||
| value="stop" | |||||
| label={ | |||||
| counts.stop > 0 | |||||
| ? `${t("Stop (paused)")} (${counts.stop})` | |||||
| : t("Stop (paused)") | |||||
| } | |||||
| /> | |||||
| <Tab | |||||
| value="cancel" | |||||
| label={ | |||||
| counts.cancel > 0 | |||||
| ? `${t("Cancelled")} (${counts.cancel})` | |||||
| : t("Cancelled") | |||||
| } | |||||
| /> | |||||
| </Tabs> | </Tabs> | ||||
| )} | )} | ||||
| @@ -576,8 +623,8 @@ const JobOrderOpsTable: React.FC<JobOrderOpsTableProps> = ({ | |||||
| <Table size="small" stickyHeader sx={{ minWidth: 800 }}> | <Table size="small" stickyHeader sx={{ minWidth: 800 }}> | ||||
| <TableHead> | <TableHead> | ||||
| <TableRow> | <TableRow> | ||||
| <TableCell>{t("Job Order")}</TableCell> | |||||
| <TableCell>{t("Item")}</TableCell> | |||||
| <TableCell>{t("Job Order Code")}</TableCell> | |||||
| <TableCell>{t("Item Code")}</TableCell> | |||||
| <TableCell align="right">{t("Required Qty")}</TableCell> | <TableCell align="right">{t("Required Qty")}</TableCell> | ||||
| <TableCell>{t("Production Date")}</TableCell> | <TableCell>{t("Production Date")}</TableCell> | ||||
| <TableCell>{t("Status")}</TableCell> | <TableCell>{t("Status")}</TableCell> | ||||
| @@ -22,7 +22,6 @@ import { | |||||
| DialogActions, | DialogActions, | ||||
| Tabs, | Tabs, | ||||
| Tab, | Tab, | ||||
| Badge, | |||||
| Tooltip, | Tooltip, | ||||
| IconButton, | IconButton, | ||||
| Avatar, | Avatar, | ||||
| @@ -145,7 +144,7 @@ function normalizeListTab(raw: string | undefined | null): ProductionProcessList | |||||
| return "needs_action"; | return "needs_action"; | ||||
| } | } | ||||
| /** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.0 | 2026-08-03 */ | |||||
| /** FP-MTMS Version Checklist | Functions Ref. No. 40 | v1.0.2 | 2026-08-05 */ | |||||
| const ProductProcessList: React.FC<ProductProcessListProps> = ({ | const ProductProcessList: React.FC<ProductProcessListProps> = ({ | ||||
| onSelectProcess, | onSelectProcess, | ||||
| printerCombo, | printerCombo, | ||||
| @@ -578,38 +577,8 @@ const ProductProcessList: React.FC<ProductProcessListProps> = ({ | |||||
| }, [loading, filteredProcesses, totalPages]); // eslint-disable-line react-hooks/exhaustive-deps | }, [loading, filteredProcesses, totalPages]); // eslint-disable-line react-hooks/exhaustive-deps | ||||
| const renderBucketTabLabel = useCallback( | const renderBucketTabLabel = useCallback( | ||||
| (labelKey: string, count: number) => ( | |||||
| <Tooltip title={count > 0 ? t(labelKey) + `: ${count}` : t(labelKey)}> | |||||
| <Box component="span" sx={{ display: "inline-flex", alignItems: "center" }}> | |||||
| <Badge | |||||
| color="error" | |||||
| variant="standard" | |||||
| badgeContent={count > 99 ? "99+" : count} | |||||
| invisible={count === 0} | |||||
| sx={{ | |||||
| "& .MuiBadge-badge": { | |||||
| fontWeight: 800, | |||||
| fontSize: "0.7rem", | |||||
| minWidth: 18, | |||||
| height: 18, | |||||
| lineHeight: "18px", | |||||
| px: 0.5, | |||||
| right: -8, | |||||
| top: 2, | |||||
| }, | |||||
| }} | |||||
| > | |||||
| <Typography | |||||
| component="span" | |||||
| variant="inherit" | |||||
| sx={{ pr: count > 0 ? 1 : 0 }} | |||||
| > | |||||
| {t(labelKey)} | |||||
| </Typography> | |||||
| </Badge> | |||||
| </Box> | |||||
| </Tooltip> | |||||
| ), | |||||
| (labelKey: string, count: number) => | |||||
| count > 0 ? `${t(labelKey)} (${count})` : t(labelKey), | |||||
| [t], | [t], | ||||
| ); | ); | ||||
| const handleUpdateJo = useCallback(async (process: AllJoborderProductProcessInfoResponse) => { | const handleUpdateJo = useCallback(async (process: AllJoborderProductProcessInfoResponse) => { | ||||
| @@ -822,17 +791,14 @@ const ProductProcessList: React.FC<ProductProcessListProps> = ({ | |||||
| <Tab | <Tab | ||||
| value="needs_action" | value="needs_action" | ||||
| label={renderBucketTabLabel("Needs action", needsActionCount)} | label={renderBucketTabLabel("Needs action", needsActionCount)} | ||||
| sx={{ pr: needsActionCount > 0 ? 4 : 2 }} | |||||
| /> | /> | ||||
| <Tab | <Tab | ||||
| value="pending" | value="pending" | ||||
| label={renderBucketTabLabel("pending", pendingCount)} | label={renderBucketTabLabel("pending", pendingCount)} | ||||
| sx={{ pr: pendingCount > 0 ? 4 : 2 }} | |||||
| /> | /> | ||||
| <Tab | <Tab | ||||
| value="processing" | value="processing" | ||||
| label={renderBucketTabLabel("Processing", processingCount)} | label={renderBucketTabLabel("Processing", processingCount)} | ||||
| sx={{ pr: processingCount > 0 ? 4 : 2 }} | |||||
| /> | /> | ||||
| <Tab | <Tab | ||||
| value="pending_qc" | value="pending_qc" | ||||
| @@ -840,12 +806,10 @@ const ProductProcessList: React.FC<ProductProcessListProps> = ({ | |||||
| "Waiting QC Put Away", | "Waiting QC Put Away", | ||||
| pendingQcCount, | pendingQcCount, | ||||
| )} | )} | ||||
| sx={{ pr: pendingQcCount > 0 ? 4 : 2 }} | |||||
| /> | /> | ||||
| <Tab | <Tab | ||||
| value="putawayed" | value="putawayed" | ||||
| label={renderBucketTabLabel("Put Awayed", putawayedCount)} | label={renderBucketTabLabel("Put Awayed", putawayedCount)} | ||||
| sx={{ pr: putawayedCount > 0 ? 4 : 2 }} | |||||
| /> | /> | ||||
| </Tabs> | </Tabs> | ||||
| @@ -77,7 +77,7 @@ | |||||
| "Job Order No.": "工單編號", | "Job Order No.": "工單編號", | ||||
| "Job Order and Product": "工單及貨品", | "Job Order and Product": "工單及貨品", | ||||
| "Issue": "異常", | "Issue": "異常", | ||||
| "Job Order Ops Table": "查看工單流程情況", | |||||
| "Job Order Ops Table": "工單流程", | |||||
| "Pending (picked)": "已提料", | "Pending (picked)": "已提料", | ||||
| "Pending (not picked)": "未提料", | "Pending (not picked)": "未提料", | ||||
| "Processing (picked)": "已提料", | "Processing (picked)": "已提料", | ||||
| @@ -148,7 +148,7 @@ | |||||
| "Processing Time": "生產時間", | "Processing Time": "生產時間", | ||||
| "Processing Time (mins)": "步驟時間(分鐘)", | "Processing Time (mins)": "步驟時間(分鐘)", | ||||
| "Product process status": "生產流程狀態", | "Product process status": "生產流程狀態", | ||||
| "Production Date": "生產日期", | |||||
| "Production Date": "預計生產日期", | |||||
| "Production Equipment Status Dashboard": "儀表板 - 生產設備最新狀態", | "Production Equipment Status Dashboard": "儀表板 - 生產設備最新狀態", | ||||
| "Production Output Data": "生產輸出數據", | "Production Output Data": "生產輸出數據", | ||||
| "Production Output Data Entry": "生產輸出數據輸入", | "Production Output Data Entry": "生產輸出數據輸入", | ||||
| @@ -158,7 +158,7 @@ | |||||
| "Production Process Line Remark": "工藝明細", | "Production Process Line Remark": "工藝明細", | ||||
| "Production Process Steps": "生產流程步驟", | "Production Process Steps": "生產流程步驟", | ||||
| "Production Time Remaining": "生產剩餘時間", | "Production Time Remaining": "生產剩餘時間", | ||||
| "Production date": "生產日期", | |||||
| "Production date": "預計生產日期", | |||||
| "Put Awayed Job Orders": "已上架工單", | "Put Awayed Job Orders": "已上架工單", | ||||
| "Qty": "數量", | "Qty": "數量", | ||||
| "Quality Check": "品質檢查", | "Quality Check": "品質檢查", | ||||
| @@ -212,8 +212,8 @@ | |||||
| "Total Time": "總時間", | "Total Time": "總時間", | ||||
| "Total finished QC job orders": "總完成QC工單數量", | "Total finished QC job orders": "總完成QC工單數量", | ||||
| "Total job orders": "總工單數量", | "Total job orders": "總工單數量", | ||||
| "Including carried over": "含過去轉來", | |||||
| "Carried over from past day": "過去轉來的工單", | |||||
| "Including carried over": "含未按規劃完成工單", | |||||
| "Carried over from past day": "未按規劃完成工單的工單", | |||||
| "All unfinished": "需處理", | "All unfinished": "需處理", | ||||
| "Needs action": "需處理", | "Needs action": "需處理", | ||||
| "Not picked · Not started": "未提料 · 未開工", | "Not picked · Not started": "未提料 · 未開工", | ||||