"use client"; /** * V2 공정 작업기준 설정 패널 * 토스식 단계별 UX: 데이터 소스 -> 작업 단계 관리 -> 상세 유형 관리 -> 레이아웃(접힘) */ import React, { useState } from "react"; import { Input } from "@/components/ui/input"; import { Switch } from "@/components/ui/switch"; import { Button } from "@/components/ui/button"; import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible"; import { Settings, ChevronDown, Plus, Trash2, GripVertical, Database, Layers } from "lucide-react"; import { cn } from "@/lib/utils"; import type { ProcessWorkStandardConfig, WorkPhaseDefinition, DetailTypeDefinition, } from "@/lib/registry/components/v2-process-work-standard/types"; import { defaultConfig } from "@/lib/registry/components/v2-process-work-standard/config"; interface V2ProcessWorkStandardConfigPanelProps { config: Partial; onChange: (config: Partial) => void; } export const V2ProcessWorkStandardConfigPanel: React.FC = ({ config: configProp, onChange, }) => { const [dataSourceOpen, setDataSourceOpen] = useState(false); const [layoutOpen, setLayoutOpen] = useState(false); const config: ProcessWorkStandardConfig = { ...defaultConfig, ...configProp, dataSource: { ...defaultConfig.dataSource, ...configProp?.dataSource }, phases: configProp?.phases?.length ? configProp.phases : defaultConfig.phases, detailTypes: configProp?.detailTypes?.length ? configProp.detailTypes : defaultConfig.detailTypes, }; const update = (partial: Partial) => { onChange({ ...configProp, ...partial }); }; const updateDataSource = (field: string, value: string) => { update({ dataSource: { ...config.dataSource, [field]: value } }); }; // ─── 작업 단계 관리 ─── const addPhase = () => { const nextOrder = config.phases.length + 1; update({ phases: [ ...config.phases, { key: `PHASE_${nextOrder}`, label: `단계 ${nextOrder}`, sortOrder: nextOrder }, ], }); }; const removePhase = (idx: number) => { update({ phases: config.phases.filter((_, i) => i !== idx) }); }; const updatePhase = (idx: number, field: keyof WorkPhaseDefinition, value: string | number) => { const next = [...config.phases]; next[idx] = { ...next[idx], [field]: value }; update({ phases: next }); }; // ─── 상세 유형 관리 ─── const addDetailType = () => { update({ detailTypes: [ ...config.detailTypes, { value: `TYPE_${config.detailTypes.length + 1}`, label: "신규 유형" }, ], }); }; const removeDetailType = (idx: number) => { update({ detailTypes: config.detailTypes.filter((_, i) => i !== idx) }); }; const updateDetailType = (idx: number, field: keyof DetailTypeDefinition, value: string) => { const next = [...config.detailTypes]; next[idx] = { ...next[idx], [field]: value }; update({ detailTypes: next }); }; return (
{/* ─── 1단계: 작업 단계 설정 ─── */}

작업 단계 설정

공정별 작업 단계(Phase)를 정의해요

{config.phases.map((phase, idx) => (
updatePhase(idx, "key", e.target.value)} className="h-7 w-20 text-[10px]" placeholder="키" /> updatePhase(idx, "label", e.target.value)} className="h-7 flex-1 text-[10px]" placeholder="표시명" /> updatePhase(idx, "sortOrder", parseInt(e.target.value) || 1)} className="h-7 w-12 text-[10px] text-center" placeholder="순서" title="정렬 순서" />
))}
{/* ─── 2단계: 상세 유형 옵션 ─── */}

상세 유형 옵션

작업 항목의 상세 유형 드롭다운 옵션을 설정해요

{config.detailTypes.map((dt, idx) => (
updateDetailType(idx, "value", e.target.value)} className="h-7 w-24 text-[10px]" placeholder="값" /> updateDetailType(idx, "label", e.target.value)} className="h-7 flex-1 text-[10px]" placeholder="표시명" />
))}
{/* ─── 3단계: 데이터 소스 (Collapsible) ─── */}
품목 테이블 updateDataSource("itemTable", e.target.value)} className="h-7 w-[160px] text-xs" />
품목명 컬럼 updateDataSource("itemNameColumn", e.target.value)} className="h-7 w-[160px] text-xs" />
품목코드 컬럼 updateDataSource("itemCodeColumn", e.target.value)} className="h-7 w-[160px] text-xs" />
라우팅 버전 테이블 updateDataSource("routingVersionTable", e.target.value)} className="h-7 w-[160px] text-xs" />
품목 연결 FK updateDataSource("routingFkColumn", e.target.value)} className="h-7 w-[160px] text-xs" />
버전명 컬럼 updateDataSource("routingVersionNameColumn", e.target.value)} className="h-7 w-[160px] text-xs" />
라우팅 상세 테이블 updateDataSource("routingDetailTable", e.target.value)} className="h-7 w-[160px] text-xs" />
공정 마스터 테이블 updateDataSource("processTable", e.target.value)} className="h-7 w-[160px] text-xs" />
공정명 컬럼 updateDataSource("processNameColumn", e.target.value)} className="h-7 w-[160px] text-xs" />
공정코드 컬럼 updateDataSource("processCodeColumn", e.target.value)} className="h-7 w-[160px] text-xs" />
{/* ─── 4단계: 레이아웃 & 기타 (Collapsible) ─── */}
좌측 패널 비율 (%)

품목/공정 선택 패널의 너비

update({ splitRatio: parseInt(e.target.value) || 30 })} className="h-7 w-[80px] text-xs" />
좌측 패널 제목 update({ leftPanelTitle: e.target.value })} placeholder="품목 및 공정 선택" className="h-7 w-[160px] text-xs" />

읽기 전용

수정/삭제 버튼을 숨겨요

update({ readonly: checked })} />
); }; V2ProcessWorkStandardConfigPanel.displayName = "V2ProcessWorkStandardConfigPanel"; export default V2ProcessWorkStandardConfigPanel;