diff --git a/src/components/production/ProductionDashboard/index.tsx b/src/components/production/ProductionDashboard/index.tsx index 6733b04d..9f865cc3 100644 --- a/src/components/production/ProductionDashboard/index.tsx +++ b/src/components/production/ProductionDashboard/index.tsx @@ -57,13 +57,34 @@ export default function ProductionDashboard() { const result = await getProcessOptions(); if (result.success) { setProcessOptions(result.data); - // 동적 탭 옵션 생성: 전체 + 공정 목록 + // 동적 탭 옵션 생성: 전체 + 공정 목록 (절곡 계열은 하위 탭으로 그룹화) + const bendingParent: TabOption[] = []; + const bendingChildren: TabOption[] = []; + const otherTabs: TabOption[] = []; + + for (const p of result.data) { + if (p.name.startsWith('절곡')) { + if (p.name === '절곡') { + bendingParent.push({ value: p.code, label: p.name }); + } else { + // "절곡 (재공품-가이드레일)" → "가이드레일" + const shortLabel = p.name.replace(/^절곡\s*\(재공품-?/, '').replace(/\)$/, '') || p.name; + bendingChildren.push({ value: p.code, label: shortLabel }); + } + } else { + otherTabs.push({ value: p.code, label: p.name }); + } + } + + // 절곡 부모에 하위 탭 연결 + const bendingTab: TabOption | null = bendingParent.length > 0 + ? { ...bendingParent[0], children: bendingChildren.length > 0 ? bendingChildren : undefined } + : null; + const dynamicTabs: TabOption[] = [ { value: 'all', label: '전체' }, - ...result.data.map((p) => ({ - value: p.code, - label: p.name, - })), + ...otherTabs, + ...(bendingTab ? [bendingTab] : []), ]; setTabOptions(dynamicTabs); } else { @@ -170,21 +191,53 @@ export default function ProductionDashboard() { - {/* 공정별 탭 (동적 생성) */} -
- - - {isLoadingProcesses ? ( - 전체 - ) : ( - tabOptions.map((tab) => ( - - {tab.label} - - )) - )} - - + {/* 공정별 탭 (동적 생성, 절곡은 depth 구조) */} +
+
+ t.children?.some(c => c.value === selectedTab))?.value || selectedTab + } onValueChange={(v) => { + // 하위 탭이 있는 부모 선택 시 부모 값으로 설정 + setSelectedTab(v); + }}> + + {isLoadingProcesses ? ( + 전체 + ) : ( + tabOptions.map((tab) => ( + + {tab.label} + + )) + )} + + +
+ + {/* 하위 탭 (절곡 재공품 세분화) */} + {(() => { + const parentTab = tabOptions.find(t => t.children && t.children.length > 0 && + (t.value === selectedTab || t.children.some(c => c.value === selectedTab)) + ); + if (!parentTab?.children) return null; + return ( +
+ + + + 전체 + + {parentTab.children.map((sub) => ( + + {sub.label} + + ))} + + +
+ ); + })()}
{/* 로딩 상태 */} diff --git a/src/components/production/ProductionDashboard/types.ts b/src/components/production/ProductionDashboard/types.ts index dccfdbc1..267b232c 100644 --- a/src/components/production/ProductionDashboard/types.ts +++ b/src/components/production/ProductionDashboard/types.ts @@ -97,6 +97,7 @@ export interface DashboardStats { export interface TabOption { value: string; // 'all' 또는 process_code label: string; // '전체' 또는 process_name + children?: TabOption[]; // 하위 탭 (절곡 → 재공품 세분화) } // 상태 라벨