From 59b45dc706f43fffdf2927ca526a2fa82d0a887b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=EB=B3=B4=EA=B3=A4?= Date: Sat, 21 Mar 2026 15:25:36 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20[=EA=B3=B5=EC=A0=95=EA=B4=80=EB=A6=AC]?= =?UTF-8?q?=20parent=5Fid=20=EA=B8=B0=EB=B0=98=20=ED=8A=B8=EB=A6=AC=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=E2=80=94=20processGroup=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0,=20parentId/children=20=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/process-management/actions.ts | 8 +++++++- .../production/WorkerScreen/index.tsx | 19 ++++++++++++++----- src/types/process.ts | 8 ++++++-- 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/components/process-management/actions.ts b/src/components/process-management/actions.ts index 5dbf2971..2f780b83 100644 --- a/src/components/process-management/actions.ts +++ b/src/components/process-management/actions.ts @@ -13,6 +13,9 @@ import type { Process, ProcessFormData, ClassificationRule, IndividualItem, Proc interface ApiProcess { id: number; tenant_id: number; + parent_id: number | null; + parent?: { id: number; process_code: string; process_name: string } | null; + children?: ApiProcess[]; process_code: string; process_name: string; description: string | null; @@ -103,7 +106,10 @@ function transformApiToFrontend(apiData: ApiProcess): Process { workLogTemplateName: apiData.work_log_template_relation?.name ?? undefined, needsInspection: apiData.options?.needs_inspection ?? false, needsWorkLog: apiData.options?.needs_work_log ?? false, - processGroup: apiData.options?.process_group ?? undefined, + parentId: apiData.parent_id ? String(apiData.parent_id) : undefined, + parentProcessCode: apiData.parent?.process_code ?? undefined, + parentProcessName: apiData.parent?.process_name ?? undefined, + children: (apiData.children ?? []).map(transformProcessApiToFrontend), classificationRules: [...patternRules, ...individualRules], requiredWorkers: apiData.required_workers, equipmentInfo: apiData.equipment_info ?? undefined, diff --git a/src/components/production/WorkerScreen/index.tsx b/src/components/production/WorkerScreen/index.tsx index f1e311e5..89d69681 100644 --- a/src/components/production/WorkerScreen/index.tsx +++ b/src/components/production/WorkerScreen/index.tsx @@ -289,18 +289,26 @@ export default function WorkerScreen() { return processListCache.filter((p) => p.status === '사용중'); }, [processListCache]); - // 그룹별 탭 구성 (process_group 기준, 없으면 공정명 사용) + // 그룹별 탭 구성 (parent_id 기반 트리 구조) const groupedTabs = useMemo(() => { const groupMap = new Map(); + + // 루트 공정 기준 그룹 구성 activeProcesses.forEach((p) => { - const group = p.processGroup || p.processName; + if (p.parentId) return; // 자식은 건너뜀 + + const group = p.processName; if (!groupMap.has(group)) groupMap.set(group, []); groupMap.get(group)!.push(p); + + // 자식 공정 추가 + const children = activeProcesses.filter((c) => c.parentId === p.id); + children.forEach((c) => groupMap.get(group)!.push(c)); }); + return Array.from(groupMap.entries()).map(([group, processes]) => ({ group, processes, - // 그룹 내 첫 번째 공정 ID를 탭 value로 사용 defaultProcessId: processes[0].id, })); }, [activeProcesses]); @@ -315,8 +323,9 @@ export default function WorkerScreen() { const activeGroup = useMemo(() => { const process = processListCache.find((p) => p.id === activeTab); if (!process) return null; - const group = process.processGroup || process.processName; - return groupedTabs.find((g) => g.group === group) || null; + // 자식이면 부모 공정명, 루트면 자기 공정명 + const groupName = process.parentProcessName || process.processName; + return groupedTabs.find((g) => g.group === groupName) || null; }, [activeTab, processListCache, groupedTabs]); // 공정 목록 로드 후 첫 번째 그룹을 기본 선택 diff --git a/src/types/process.ts b/src/types/process.ts index 1cd825e8..16b90b0b 100644 --- a/src/types/process.ts +++ b/src/types/process.ts @@ -92,8 +92,11 @@ export interface Process { // 단계 목록 steps?: ProcessStep[]; - // 공정 그룹 (같은 그룹은 하나의 탭으로 표시) - processGroup?: string; + // 부모-자식 트리 구조 + parentId?: string; + parentProcessCode?: string; + parentProcessName?: string; + children?: Process[]; // 상태 status: ProcessStatus; @@ -105,6 +108,7 @@ export interface Process { // 공정 등록/수정 폼 데이터 export interface ProcessFormData { + parentId?: number; processName: string; processType: ProcessType; department: string;