|
|
|
@@ -27,6 +27,10 @@ import { |
|
|
|
editBomClient, |
|
|
|
fetchBomComboClient, |
|
|
|
fetchBomDetailClient, |
|
|
|
fetchAllEquipmentsMasterClient, |
|
|
|
fetchAllProcessesMasterClient, |
|
|
|
type EquipmentMasterRow, |
|
|
|
type ProcessMasterRow, |
|
|
|
} from "@/app/api/bom/client"; |
|
|
|
import type { SelectChangeEvent } from "@mui/material/Select"; |
|
|
|
import { useTranslation } from "react-i18next"; |
|
|
|
@@ -37,6 +41,26 @@ import SaveIcon from "@mui/icons-material/Save"; |
|
|
|
import CancelIcon from "@mui/icons-material/Cancel"; |
|
|
|
import DeleteIcon from "@mui/icons-material/Delete"; |
|
|
|
import EditIcon from "@mui/icons-material/Edit"; |
|
|
|
|
|
|
|
/** 以 description + "-" + name 對應 code,或同一筆設備的 description+name。 */ |
|
|
|
function resolveEquipmentCode( |
|
|
|
list: EquipmentMasterRow[], |
|
|
|
description: string, |
|
|
|
name: string, |
|
|
|
): string | null { |
|
|
|
const d = description.trim(); |
|
|
|
const n = name.trim(); |
|
|
|
if (!d && !n) return null; |
|
|
|
if (!d || !n) return null; |
|
|
|
const composite = `${d}-${n}`; |
|
|
|
const byCode = list.find((e) => e.code === composite); |
|
|
|
if (byCode) return byCode.code; |
|
|
|
const byPair = list.find( |
|
|
|
(e) => e.description === d && e.name === n, |
|
|
|
); |
|
|
|
return byPair?.code ?? null; |
|
|
|
} |
|
|
|
|
|
|
|
const ImportBomDetailTab: React.FC = () => { |
|
|
|
const { t } = useTranslation( "common" ); |
|
|
|
const [bomList, setBomList] = useState<BomCombo[]>([]); |
|
|
|
@@ -69,7 +93,9 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
processCode?: string; |
|
|
|
processName?: string; |
|
|
|
description: string; |
|
|
|
equipmentCode?: string; |
|
|
|
/** 設備主檔 description(下拉),與 equipmentName 一併解析為 equipment.code */ |
|
|
|
equipmentDescription: string; |
|
|
|
equipmentName: string; |
|
|
|
durationInMinute: number; |
|
|
|
prepTimeInMinute: number; |
|
|
|
postProdTimeInMinute: number; |
|
|
|
@@ -96,17 +122,27 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
const [editMaterials, setEditMaterials] = useState<EditMaterialRow[]>([]); |
|
|
|
const [editProcesses, setEditProcesses] = useState<EditProcessRow[]>([]); |
|
|
|
|
|
|
|
// Process add form (uses dropdown selections). |
|
|
|
const [equipmentMasterList, setEquipmentMasterList] = useState< |
|
|
|
EquipmentMasterRow[] |
|
|
|
>([]); |
|
|
|
const [processMasterList, setProcessMasterList] = useState< |
|
|
|
ProcessMasterRow[] |
|
|
|
>([]); |
|
|
|
const [editMasterLoading, setEditMasterLoading] = useState(false); |
|
|
|
|
|
|
|
// Process add form (uses dropdown selections from master tables). |
|
|
|
const [processAddForm, setProcessAddForm] = useState<{ |
|
|
|
processCode: string; |
|
|
|
equipmentCode: string; |
|
|
|
equipmentDescription: string; |
|
|
|
equipmentName: string; |
|
|
|
description: string; |
|
|
|
durationInMinute: number; |
|
|
|
prepTimeInMinute: number; |
|
|
|
postProdTimeInMinute: number; |
|
|
|
}>({ |
|
|
|
processCode: "", |
|
|
|
equipmentCode: "", |
|
|
|
equipmentDescription: "", |
|
|
|
equipmentName: "", |
|
|
|
description: "", |
|
|
|
durationInMinute: 0, |
|
|
|
prepTimeInMinute: 0, |
|
|
|
@@ -115,19 +151,27 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
|
|
|
|
const processCodeOptions = useMemo(() => { |
|
|
|
const codes = new Set<string>(); |
|
|
|
(detail?.processes ?? []).forEach((p) => { |
|
|
|
if (p.processCode) codes.add(p.processCode); |
|
|
|
processMasterList.forEach((p) => { |
|
|
|
if (p.code) codes.add(p.code); |
|
|
|
}); |
|
|
|
return Array.from(codes); |
|
|
|
}, [detail]); |
|
|
|
return Array.from(codes).sort(); |
|
|
|
}, [processMasterList]); |
|
|
|
|
|
|
|
const equipmentCodeOptions = useMemo(() => { |
|
|
|
const codes = new Set<string>(); |
|
|
|
(detail?.processes ?? []).forEach((p) => { |
|
|
|
if (p.equipmentCode) codes.add(p.equipmentCode); |
|
|
|
const equipmentDescriptionOptions = useMemo(() => { |
|
|
|
const s = new Set<string>(); |
|
|
|
equipmentMasterList.forEach((e) => { |
|
|
|
if (e.description) s.add(e.description); |
|
|
|
}); |
|
|
|
return Array.from(codes); |
|
|
|
}, [detail]); |
|
|
|
return Array.from(s).sort(); |
|
|
|
}, [equipmentMasterList]); |
|
|
|
|
|
|
|
const equipmentNameOptions = useMemo(() => { |
|
|
|
const s = new Set<string>(); |
|
|
|
equipmentMasterList.forEach((e) => { |
|
|
|
if (e.name) s.add(e.name); |
|
|
|
}); |
|
|
|
return Array.from(s).sort(); |
|
|
|
}, [equipmentMasterList]); |
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
const loadList = async () => { |
|
|
|
@@ -242,57 +286,82 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
|
|
|
|
const genKey = () => Math.random().toString(36).slice(2); |
|
|
|
|
|
|
|
const startEdit = useCallback(() => { |
|
|
|
const startEdit = useCallback(async () => { |
|
|
|
if (!detail) return; |
|
|
|
|
|
|
|
setEditError(null); |
|
|
|
setEditBasic({ |
|
|
|
description: detail.description ?? "", |
|
|
|
outputQty: detail.outputQty ?? 0, |
|
|
|
outputQtyUom: detail.outputQtyUom ?? "", |
|
|
|
setEditMasterLoading(true); |
|
|
|
try { |
|
|
|
const [equipments, processes] = await Promise.all([ |
|
|
|
fetchAllEquipmentsMasterClient(), |
|
|
|
fetchAllProcessesMasterClient(), |
|
|
|
]); |
|
|
|
setEquipmentMasterList(equipments); |
|
|
|
setProcessMasterList(processes); |
|
|
|
|
|
|
|
isDark: detail.isDark ?? 0, |
|
|
|
isFloat: detail.isFloat ?? 0, |
|
|
|
isDense: detail.isDense ?? 0, |
|
|
|
scrapRate: detail.scrapRate ?? 0, |
|
|
|
allergicSubstances: detail.allergicSubstances ?? 0, |
|
|
|
timeSequence: detail.timeSequence ?? 0, |
|
|
|
complexity: detail.complexity ?? 0, |
|
|
|
isDrink: detail.isDrink ?? false, |
|
|
|
}); |
|
|
|
setEditBasic({ |
|
|
|
description: detail.description ?? "", |
|
|
|
outputQty: detail.outputQty ?? 0, |
|
|
|
outputQtyUom: detail.outputQtyUom ?? "", |
|
|
|
|
|
|
|
setEditMaterials( |
|
|
|
(detail.materials ?? []).map((m) => ({ |
|
|
|
key: genKey(), |
|
|
|
id: undefined, |
|
|
|
itemCode: m.itemCode ?? "", |
|
|
|
itemName: m.itemName ?? "", |
|
|
|
qty: m.baseQty ?? 0, |
|
|
|
isConsumable: m.isConsumable ?? false, |
|
|
|
baseUom: m.baseUom, |
|
|
|
stockQty: m.stockQty, |
|
|
|
stockUom: m.stockUom, |
|
|
|
salesQty: m.salesQty, |
|
|
|
salesUom: m.salesUom, |
|
|
|
})), |
|
|
|
); |
|
|
|
isDark: detail.isDark ?? 0, |
|
|
|
isFloat: detail.isFloat ?? 0, |
|
|
|
isDense: detail.isDense ?? 0, |
|
|
|
scrapRate: detail.scrapRate ?? 0, |
|
|
|
allergicSubstances: detail.allergicSubstances ?? 0, |
|
|
|
timeSequence: detail.timeSequence ?? 0, |
|
|
|
complexity: detail.complexity ?? 0, |
|
|
|
isDrink: detail.isDrink ?? false, |
|
|
|
}); |
|
|
|
|
|
|
|
setEditProcesses( |
|
|
|
(detail.processes ?? []).map((p) => ({ |
|
|
|
key: genKey(), |
|
|
|
id: undefined, |
|
|
|
seqNo: p.seqNo, |
|
|
|
processCode: p.processCode ?? "", |
|
|
|
processName: p.processName, |
|
|
|
description: p.processDescription ?? "", |
|
|
|
equipmentCode: p.equipmentCode ?? p.equipmentName ?? "", |
|
|
|
durationInMinute: p.durationInMinute ?? 0, |
|
|
|
prepTimeInMinute: p.prepTimeInMinute ?? 0, |
|
|
|
postProdTimeInMinute: p.postProdTimeInMinute ?? 0, |
|
|
|
})), |
|
|
|
); |
|
|
|
setEditMaterials( |
|
|
|
(detail.materials ?? []).map((m) => ({ |
|
|
|
key: genKey(), |
|
|
|
id: undefined, |
|
|
|
itemCode: m.itemCode ?? "", |
|
|
|
itemName: m.itemName ?? "", |
|
|
|
qty: m.baseQty ?? 0, |
|
|
|
isConsumable: m.isConsumable ?? false, |
|
|
|
baseUom: m.baseUom, |
|
|
|
stockQty: m.stockQty, |
|
|
|
stockUom: m.stockUom, |
|
|
|
salesQty: m.salesQty, |
|
|
|
salesUom: m.salesUom, |
|
|
|
})), |
|
|
|
); |
|
|
|
|
|
|
|
setEditProcesses( |
|
|
|
(detail.processes ?? []).map((p) => { |
|
|
|
const code = (p.equipmentCode ?? "").trim(); |
|
|
|
const eq = code |
|
|
|
? equipments.find((e) => e.code === code) |
|
|
|
: undefined; |
|
|
|
return { |
|
|
|
key: genKey(), |
|
|
|
id: undefined, |
|
|
|
seqNo: p.seqNo, |
|
|
|
processCode: p.processCode ?? "", |
|
|
|
processName: p.processName, |
|
|
|
description: p.processDescription ?? "", |
|
|
|
equipmentDescription: eq?.description ?? "", |
|
|
|
equipmentName: eq?.name ?? "", |
|
|
|
durationInMinute: p.durationInMinute ?? 0, |
|
|
|
prepTimeInMinute: p.prepTimeInMinute ?? 0, |
|
|
|
postProdTimeInMinute: p.postProdTimeInMinute ?? 0, |
|
|
|
}; |
|
|
|
}), |
|
|
|
); |
|
|
|
|
|
|
|
setIsEditing(true); |
|
|
|
setIsEditing(true); |
|
|
|
} catch (e: unknown) { |
|
|
|
const msg = |
|
|
|
e && typeof e === "object" && "message" in e |
|
|
|
? String((e as { message?: string }).message) |
|
|
|
: "載入製程/設備主檔失敗"; |
|
|
|
setEditError(msg); |
|
|
|
} finally { |
|
|
|
setEditMasterLoading(false); |
|
|
|
} |
|
|
|
}, [detail]); |
|
|
|
|
|
|
|
const cancelEdit = useCallback(() => { |
|
|
|
@@ -304,12 +373,15 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
setEditProcesses([]); |
|
|
|
setProcessAddForm({ |
|
|
|
processCode: "", |
|
|
|
equipmentCode: "", |
|
|
|
equipmentDescription: "", |
|
|
|
equipmentName: "", |
|
|
|
description: "", |
|
|
|
durationInMinute: 0, |
|
|
|
prepTimeInMinute: 0, |
|
|
|
postProdTimeInMinute: 0, |
|
|
|
}); |
|
|
|
setEquipmentMasterList([]); |
|
|
|
setProcessMasterList([]); |
|
|
|
}, []); |
|
|
|
|
|
|
|
const addMaterialRow = useCallback(() => { |
|
|
|
@@ -339,7 +411,8 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
processCode: "", |
|
|
|
processName: "", |
|
|
|
description: "", |
|
|
|
equipmentCode: "", |
|
|
|
equipmentDescription: "", |
|
|
|
equipmentName: "", |
|
|
|
durationInMinute: 0, |
|
|
|
prepTimeInMinute: 0, |
|
|
|
postProdTimeInMinute: 0, |
|
|
|
@@ -354,6 +427,22 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
const ed = processAddForm.equipmentDescription.trim(); |
|
|
|
const en = processAddForm.equipmentName.trim(); |
|
|
|
if ((ed && !en) || (!ed && en)) { |
|
|
|
setEditError("設備描述與名稱需同時選取,或同時留空(不適用)"); |
|
|
|
return; |
|
|
|
} |
|
|
|
if (ed && en) { |
|
|
|
const resolved = resolveEquipmentCode(equipmentMasterList, ed, en); |
|
|
|
if (!resolved) { |
|
|
|
setEditError( |
|
|
|
`設備組合「${ed}-${en}」在主檔中找不到對應設備代碼,請確認後再試`, |
|
|
|
); |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
setEditProcesses((prev) => [ |
|
|
|
...prev, |
|
|
|
{ |
|
|
|
@@ -362,7 +451,8 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
processCode: pCode, |
|
|
|
processName: "", |
|
|
|
description: processAddForm.description ?? "", |
|
|
|
equipmentCode: processAddForm.equipmentCode.trim(), |
|
|
|
equipmentDescription: ed, |
|
|
|
equipmentName: en, |
|
|
|
durationInMinute: processAddForm.durationInMinute ?? 0, |
|
|
|
prepTimeInMinute: processAddForm.prepTimeInMinute ?? 0, |
|
|
|
postProdTimeInMinute: processAddForm.postProdTimeInMinute ?? 0, |
|
|
|
@@ -371,14 +461,15 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
|
|
|
|
setProcessAddForm({ |
|
|
|
processCode: "", |
|
|
|
equipmentCode: "", |
|
|
|
equipmentDescription: "", |
|
|
|
equipmentName: "", |
|
|
|
description: "", |
|
|
|
durationInMinute: 0, |
|
|
|
prepTimeInMinute: 0, |
|
|
|
postProdTimeInMinute: 0, |
|
|
|
}); |
|
|
|
setEditError(null); |
|
|
|
}, [processAddForm]); |
|
|
|
}, [processAddForm, equipmentMasterList]); |
|
|
|
|
|
|
|
const deleteMaterialRow = useCallback((key: string) => { |
|
|
|
setEditMaterials((prev) => prev.filter((r) => r.key !== key)); |
|
|
|
@@ -398,6 +489,19 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
if (!p.processCode?.trim()) { |
|
|
|
throw new Error("工序行 Process Code 不能为空"); |
|
|
|
} |
|
|
|
const ed = p.equipmentDescription.trim(); |
|
|
|
const en = p.equipmentName.trim(); |
|
|
|
if ((ed && !en) || (!ed && en)) { |
|
|
|
throw new Error("各製程行的設備描述與名稱需同時填寫或同時留空"); |
|
|
|
} |
|
|
|
if (ed && en) { |
|
|
|
const resolved = resolveEquipmentCode(equipmentMasterList, ed, en); |
|
|
|
if (!resolved) { |
|
|
|
throw new Error( |
|
|
|
`設備「${ed}-${en}」在主檔中無對應設備代碼,請修正後再儲存`, |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
const payload: any = { |
|
|
|
@@ -413,16 +517,24 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
timeSequence: editBasic.timeSequence, |
|
|
|
complexity: editBasic.complexity, |
|
|
|
isDrink: editBasic.isDrink, |
|
|
|
processes: editProcesses.map((p) => ({ |
|
|
|
id: p.id, |
|
|
|
seqNo: p.seqNo, |
|
|
|
processCode: p.processCode?.trim() || undefined, |
|
|
|
equipmentCode: p.equipmentCode?.trim() || undefined, |
|
|
|
description: p.description || undefined, |
|
|
|
durationInMinute: p.durationInMinute, |
|
|
|
prepTimeInMinute: p.prepTimeInMinute, |
|
|
|
postProdTimeInMinute: p.postProdTimeInMinute, |
|
|
|
})), |
|
|
|
processes: editProcesses.map((p) => { |
|
|
|
const ed = p.equipmentDescription.trim(); |
|
|
|
const en = p.equipmentName.trim(); |
|
|
|
const equipmentCode = |
|
|
|
ed && en |
|
|
|
? resolveEquipmentCode(equipmentMasterList, ed, en) ?? undefined |
|
|
|
: undefined; |
|
|
|
return { |
|
|
|
id: p.id, |
|
|
|
seqNo: p.seqNo, |
|
|
|
processCode: p.processCode?.trim() || undefined, |
|
|
|
equipmentCode, |
|
|
|
description: p.description || undefined, |
|
|
|
durationInMinute: p.durationInMinute, |
|
|
|
prepTimeInMinute: p.prepTimeInMinute, |
|
|
|
postProdTimeInMinute: p.postProdTimeInMinute, |
|
|
|
}; |
|
|
|
}), |
|
|
|
}; |
|
|
|
|
|
|
|
const updated = await editBomClient(detail.id, payload); |
|
|
|
@@ -433,7 +545,7 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
} finally { |
|
|
|
setEditLoading(false); |
|
|
|
} |
|
|
|
}, [detail, editBasic, editProcesses]); |
|
|
|
}, [detail, editBasic, editProcesses, equipmentMasterList]); |
|
|
|
|
|
|
|
return ( |
|
|
|
<Stack spacing={2}> |
|
|
|
@@ -480,11 +592,18 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
{!isEditing ? ( |
|
|
|
<Button |
|
|
|
size="small" |
|
|
|
startIcon={<EditIcon />} |
|
|
|
startIcon={ |
|
|
|
editMasterLoading ? ( |
|
|
|
<CircularProgress size={16} /> |
|
|
|
) : ( |
|
|
|
<EditIcon /> |
|
|
|
) |
|
|
|
} |
|
|
|
variant="outlined" |
|
|
|
onClick={startEdit} |
|
|
|
onClick={() => void startEdit()} |
|
|
|
disabled={editMasterLoading} |
|
|
|
> |
|
|
|
{t("Edit")} |
|
|
|
{editMasterLoading ? t("Loading...") : t("Edit")} |
|
|
|
</Button> |
|
|
|
) : ( |
|
|
|
<Stack direction="row" spacing={1}> |
|
|
|
@@ -770,6 +889,9 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
})) |
|
|
|
} |
|
|
|
> |
|
|
|
<MenuItem value=""> |
|
|
|
<em>請選擇</em> |
|
|
|
</MenuItem> |
|
|
|
{processCodeOptions.map((c) => ( |
|
|
|
<MenuItem key={c} value={c}> |
|
|
|
{c} |
|
|
|
@@ -779,19 +901,40 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
</FormControl> |
|
|
|
|
|
|
|
<FormControl size="small" sx={{ minWidth: 200 }}> |
|
|
|
<InputLabel>{t("Equipment Code")}</InputLabel> |
|
|
|
<InputLabel>設備說明</InputLabel> |
|
|
|
<Select |
|
|
|
label="設備說明" |
|
|
|
value={processAddForm.equipmentDescription} |
|
|
|
onChange={(e) => |
|
|
|
setProcessAddForm((p) => ({ |
|
|
|
...p, |
|
|
|
equipmentDescription: String(e.target.value), |
|
|
|
})) |
|
|
|
} |
|
|
|
> |
|
|
|
<MenuItem value="">不適用</MenuItem> |
|
|
|
{equipmentDescriptionOptions.map((c) => ( |
|
|
|
<MenuItem key={c} value={c}> |
|
|
|
{c} |
|
|
|
</MenuItem> |
|
|
|
))} |
|
|
|
</Select> |
|
|
|
</FormControl> |
|
|
|
|
|
|
|
<FormControl size="small" sx={{ minWidth: 200 }}> |
|
|
|
<InputLabel>設備名稱</InputLabel> |
|
|
|
<Select |
|
|
|
label={t("Equipment Code")} |
|
|
|
value={processAddForm.equipmentCode} |
|
|
|
label="設備名稱" |
|
|
|
value={processAddForm.equipmentName} |
|
|
|
onChange={(e) => |
|
|
|
setProcessAddForm((p) => ({ |
|
|
|
...p, |
|
|
|
equipmentCode: String(e.target.value), |
|
|
|
equipmentName: String(e.target.value), |
|
|
|
})) |
|
|
|
} |
|
|
|
> |
|
|
|
<MenuItem value="">不適用</MenuItem> |
|
|
|
{equipmentCodeOptions.map((c) => ( |
|
|
|
{equipmentNameOptions.map((c) => ( |
|
|
|
<MenuItem key={c} value={c}> |
|
|
|
{c} |
|
|
|
</MenuItem> |
|
|
|
@@ -866,7 +1009,7 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
<TableCell> {t("Process Name")}</TableCell> |
|
|
|
<TableCell> {t("Process Description")}</TableCell> |
|
|
|
<TableCell> {t("Process Code")}</TableCell> |
|
|
|
<TableCell> {t("Equipment Code")}</TableCell> |
|
|
|
<TableCell>設備(說明/名稱)</TableCell> |
|
|
|
<TableCell align="right"> {t("Duration (Minutes)")}</TableCell> |
|
|
|
<TableCell align="right"> {t("Prep Time (Minutes)")}</TableCell> |
|
|
|
<TableCell align="right"> {t("Post Prod Time (Minutes)")}</TableCell> |
|
|
|
@@ -923,30 +1066,60 @@ const ImportBomDetailTab: React.FC = () => { |
|
|
|
</FormControl> |
|
|
|
</TableCell> |
|
|
|
<TableCell> |
|
|
|
<FormControl size="small" fullWidth> |
|
|
|
<Select |
|
|
|
value={p.equipmentCode ?? ""} |
|
|
|
onChange={(e) => |
|
|
|
setEditProcesses((prev) => |
|
|
|
prev.map((x) => |
|
|
|
x.key === p.key |
|
|
|
? { |
|
|
|
...x, |
|
|
|
equipmentCode: String(e.target.value), |
|
|
|
} |
|
|
|
: x, |
|
|
|
), |
|
|
|
) |
|
|
|
} |
|
|
|
> |
|
|
|
<MenuItem value="">不適用</MenuItem> |
|
|
|
{equipmentCodeOptions.map((c) => ( |
|
|
|
<MenuItem key={c} value={c}> |
|
|
|
{c} |
|
|
|
</MenuItem> |
|
|
|
))} |
|
|
|
</Select> |
|
|
|
</FormControl> |
|
|
|
<Stack direction="row" spacing={0.5} flexWrap="wrap"> |
|
|
|
<FormControl size="small" sx={{ minWidth: 140 }}> |
|
|
|
<Select |
|
|
|
displayEmpty |
|
|
|
value={p.equipmentDescription} |
|
|
|
onChange={(e) => |
|
|
|
setEditProcesses((prev) => |
|
|
|
prev.map((x) => |
|
|
|
x.key === p.key |
|
|
|
? { |
|
|
|
...x, |
|
|
|
equipmentDescription: String( |
|
|
|
e.target.value, |
|
|
|
), |
|
|
|
} |
|
|
|
: x, |
|
|
|
), |
|
|
|
) |
|
|
|
} |
|
|
|
> |
|
|
|
<MenuItem value="">不適用</MenuItem> |
|
|
|
{equipmentDescriptionOptions.map((c) => ( |
|
|
|
<MenuItem key={c} value={c}> |
|
|
|
{c} |
|
|
|
</MenuItem> |
|
|
|
))} |
|
|
|
</Select> |
|
|
|
</FormControl> |
|
|
|
<FormControl size="small" sx={{ minWidth: 140 }}> |
|
|
|
<Select |
|
|
|
displayEmpty |
|
|
|
value={p.equipmentName} |
|
|
|
onChange={(e) => |
|
|
|
setEditProcesses((prev) => |
|
|
|
prev.map((x) => |
|
|
|
x.key === p.key |
|
|
|
? { |
|
|
|
...x, |
|
|
|
equipmentName: String(e.target.value), |
|
|
|
} |
|
|
|
: x, |
|
|
|
), |
|
|
|
) |
|
|
|
} |
|
|
|
> |
|
|
|
<MenuItem value="">不適用</MenuItem> |
|
|
|
{equipmentNameOptions.map((c) => ( |
|
|
|
<MenuItem key={c} value={c}> |
|
|
|
{c} |
|
|
|
</MenuItem> |
|
|
|
))} |
|
|
|
</Select> |
|
|
|
</FormControl> |
|
|
|
</Stack> |
|
|
|
</TableCell> |
|
|
|
<TableCell align="right"> |
|
|
|
<TextField |
|
|
|
|