From 9af7fe5b980ef65259d79e92ab4f8b5ce4eb1335 Mon Sep 17 00:00:00 2001 From: kjs Date: Tue, 23 Dec 2025 14:20:18 +0900 Subject: [PATCH] =?UTF-8?q?=EC=9E=85=EB=A0=A5=ED=83=80=EC=9E=85=20?= =?UTF-8?q?=EC=BB=B4=ED=8F=AC=EB=84=8C=ED=8A=B8=20=ED=86=B5=ED=95=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/routes/cascadingAutoFillRoutes.ts | 1 + .../src/routes/cascadingConditionRoutes.ts | 1 + .../src/routes/cascadingHierarchyRoutes.ts | 1 + .../routes/cascadingMutualExclusionRoutes.ts | 1 + docs/노드플로우_개선사항.md | 1 + docs/메일발송_기능_사용_가이드.md | 1 + docs/즉시저장_버튼_액션_구현_계획서.md | 1 + docs/컴포넌트_분석_및_통합_계획.md | 339 ++++++++++++++++++ .../screen/panels/ComponentsPanel.tsx | 45 ++- frontend/contexts/ActiveTabContext.tsx | 1 + frontend/hooks/useAutoFill.ts | 1 + ..._임베딩_및_데이터_전달_시스템_구현_계획서.md | 1 + 화면_임베딩_시스템_Phase1-4_구현_완료.md | 1 + 화면_임베딩_시스템_충돌_분석_보고서.md | 1 + 14 files changed, 387 insertions(+), 9 deletions(-) create mode 100644 docs/컴포넌트_분석_및_통합_계획.md diff --git a/backend-node/src/routes/cascadingAutoFillRoutes.ts b/backend-node/src/routes/cascadingAutoFillRoutes.ts index c1d69e9f..acb0cbc7 100644 --- a/backend-node/src/routes/cascadingAutoFillRoutes.ts +++ b/backend-node/src/routes/cascadingAutoFillRoutes.ts @@ -56,3 +56,4 @@ export default router; + diff --git a/backend-node/src/routes/cascadingConditionRoutes.ts b/backend-node/src/routes/cascadingConditionRoutes.ts index bbc9384d..96ab25be 100644 --- a/backend-node/src/routes/cascadingConditionRoutes.ts +++ b/backend-node/src/routes/cascadingConditionRoutes.ts @@ -52,3 +52,4 @@ export default router; + diff --git a/backend-node/src/routes/cascadingHierarchyRoutes.ts b/backend-node/src/routes/cascadingHierarchyRoutes.ts index 35ced071..f77019be 100644 --- a/backend-node/src/routes/cascadingHierarchyRoutes.ts +++ b/backend-node/src/routes/cascadingHierarchyRoutes.ts @@ -68,3 +68,4 @@ export default router; + diff --git a/backend-node/src/routes/cascadingMutualExclusionRoutes.ts b/backend-node/src/routes/cascadingMutualExclusionRoutes.ts index 29ac8ee4..6e4094f1 100644 --- a/backend-node/src/routes/cascadingMutualExclusionRoutes.ts +++ b/backend-node/src/routes/cascadingMutualExclusionRoutes.ts @@ -56,3 +56,4 @@ export default router; + diff --git a/docs/노드플로우_개선사항.md b/docs/노드플로우_개선사항.md index 32757807..a59f4499 100644 --- a/docs/노드플로우_개선사항.md +++ b/docs/노드플로우_개선사항.md @@ -588,3 +588,4 @@ const result = await executeNodeFlow(flowId, { + diff --git a/docs/메일발송_기능_사용_가이드.md b/docs/메일발송_기능_사용_가이드.md index 8bfe484e..ef62a60a 100644 --- a/docs/메일발송_기능_사용_가이드.md +++ b/docs/메일발송_기능_사용_가이드.md @@ -361,3 +361,4 @@ + diff --git a/docs/즉시저장_버튼_액션_구현_계획서.md b/docs/즉시저장_버튼_액션_구현_계획서.md index 8d8fb497..806e480d 100644 --- a/docs/즉시저장_버튼_액션_구현_계획서.md +++ b/docs/즉시저장_버튼_액션_구현_계획서.md @@ -347,3 +347,4 @@ const getComponentValue = (componentId: string) => { + diff --git a/docs/컴포넌트_분석_및_통합_계획.md b/docs/컴포넌트_분석_및_통합_계획.md new file mode 100644 index 00000000..88be78c8 --- /dev/null +++ b/docs/컴포넌트_분석_및_통합_계획.md @@ -0,0 +1,339 @@ +# 입력 컴포넌트 분석 및 통합 계획 + +> 작성일: 2024-12-23 +> 상태: 1차 정리 완료 + +## 분석 대상 컴포넌트 목록 + +| 번호 | 컴포넌트 ID | 한글명 | 패널 표시 | 통합 대상 | +|------|-------------|--------|----------|----------| +| 1 | rack-structure | 렉 구조 설정 | 숨김 | UnifiedBiz (rack) | +| 2 | mail-recipient-selector | 메일 수신자 선택 | 숨김 | DataFlow 전용 | +| 3 | repeater-field-group | 반복 필드 그룹 | 숨김 | 현재 사용 안함 | +| 4 | universal-form-modal | 범용 폼 모달 | **유지** | 독립 유지 | +| 5 | selected-items-detail-input | 선택 항목 상세입력 | **유지** | 독립 유지 | +| 6 | entity-search-input | 엔티티 검색 입력 | 숨김 | UnifiedSelect (entity 모드) | +| 7 | image-widget | 이미지 위젯 | 숨김 | UnifiedMedia (image) | +| 8 | autocomplete-search-input | 자동완성 검색 입력 | 숨김 | UnifiedSelect (autocomplete 모드) | +| 9 | location-swap-selector | 출발지/도착지 선택 | **유지** | 독립 유지 | +| 10 | file-upload | 파일 업로드 | 숨김 | UnifiedMedia (file) | + +--- + +## 1. 렉 구조 설정 (rack-structure) + +### 현재 구현 +- **위치**: `frontend/lib/registry/components/rack-structure/` +- **주요 기능**: + - 창고 렉 위치를 열 범위와 단 수로 일괄 생성 + - 조건별 설정 (렉 라인, 열 범위, 단 수) + - 미리보기 및 통계 표시 + - 템플릿 저장/불러오기 +- **카테고리**: INPUT +- **크기**: 1200 x 800 + +### 분석 +- WMS(창고관리) 전용 특수 컴포넌트 +- 복잡한 비즈니스 로직 포함 (위치 코드 자동 생성) +- formData 컨텍스트 의존 (창고ID, 층, 구역 등) + +### 통합 방안 +- **결정**: `UnifiedBiz` 컴포넌트의 `rack` 비즈니스 타입으로 통합 +- **이유**: 비즈니스 특화 컴포넌트이므로 UnifiedBiz가 적합 +- **작업**: + - UnifiedBiz에서 bizType="rack" 선택 시 RackStructureComponent 렌더링 + - 설정 패널 통합 + +--- + +## 2. 메일 수신자 선택 (mail-recipient-selector) + +### 현재 구현 +- **위치**: `frontend/lib/registry/components/mail-recipient-selector/` +- **주요 기능**: + - 내부 인원 선택 (user_info 테이블) + - 외부 이메일 직접 입력 + - 수신자(To) / 참조(CC) 구분 +- **카테고리**: INPUT +- **크기**: 400 x 200 + +### 분석 +- 메일 발송 워크플로우 전용 컴포넌트 +- 내부 사용자 검색 + 외부 이메일 입력 복합 기능 +- DataFlow 노드에서 참조됨 (EmailActionProperties) + +### 통합 방안 +- **결정**: **독립 유지** +- **이유**: + - 메일 시스템 전용 복합 기능 + - 다른 컴포넌트와 기능이 겹치지 않음 + - DataFlow와의 긴밀한 연동 + +--- + +## 3. 반복 필드 그룹 (repeater-field-group) + +### 현재 구현 +- **위치**: `frontend/components/webtypes/RepeaterInput.tsx`, `frontend/components/webtypes/config/RepeaterConfigPanel.tsx` +- **주요 기능**: + - 동적 항목 추가/제거 + - 다양한 필드 타입 지원 (text, number, select, category, calculated 등) + - 계산식 필드 (합계, 평균 등) + - 레이아웃 옵션 (grid, table, card) + - 드래그앤드롭 순서 변경 +- **카테고리**: INPUT +- **크기**: 화면 설정에 따라 동적 + +### 분석 +- 매우 복잡한 컴포넌트 (943줄) +- 견적서, 주문서 등 반복 입력이 필요한 화면에서 핵심 역할 +- 카테고리 매핑, 계산식, 반응형 지원 + +### 통합 방안 +- **결정**: **독립 유지** +- **이유**: + - 너무 복잡하고 기능이 방대함 + - 이미 잘 동작하고 있음 + - 통합 시 오히려 유지보수 어려워짐 + +--- + +## 4. 범용 폼 모달 (universal-form-modal) + +### 현재 구현 +- **위치**: `frontend/lib/registry/components/universal-form-modal/` +- **주요 기능**: + - 섹션 기반 폼 레이아웃 + - 반복 섹션 (겸직 등록 등) + - 채번규칙 연동 + - 다중 행 저장 + - 외부 데이터 수신 +- **카테고리**: INPUT +- **크기**: 800 x 600 + +### 분석 +- ScreenModal, SaveModal과 기능 중복 가능성 +- 섹션 기반 레이아웃이 핵심 차별점 +- 복잡한 입력 시나리오 지원 + +### 통합 방안 +- **결정**: `UnifiedGroup`의 `formModal` 타입으로 통합 검토 +- **현실적 접근**: + - 당장 통합보다는 ScreenModal 시스템과의 차별화 유지 + - 향후 섹션 기반 레이아웃 기능을 ScreenModal에 반영 + +--- + +## 5. 선택 항목 상세입력 (selected-items-detail-input) + +### 현재 구현 +- **위치**: `frontend/lib/registry/components/selected-items-detail-input/` +- **주요 기능**: + - 선택된 데이터 목록 표시 + - 각 항목별 추가 필드 입력 + - 레이아웃 옵션 (grid, table) +- **카테고리**: INPUT +- **크기**: 800 x 400 + +### 분석 +- RepeatScreenModal과 연계되는 컴포넌트 +- 선택된 항목에 대한 상세 정보 일괄 입력 용도 +- 특수한 사용 사례 (품목 선택 후 수량 입력 등) + +### 통합 방안 +- **결정**: **독립 유지** +- **이유**: + - 특수한 워크플로우 지원 + - 다른 컴포넌트와 기능 중복 없음 + +--- + +## 6. 엔티티 검색 입력 (entity-search-input) + +### 현재 구현 +- **위치**: `frontend/lib/registry/components/entity-search-input/` +- **주요 기능**: + - 콤보박스 모드 (inline) + - 모달 검색 모드 + - 추가 필드 표시 옵션 +- **카테고리**: INPUT +- **크기**: 300 x 40 +- **webType**: entity + +### 분석 +- UnifiedSelect의 entity 모드와 기능 중복 +- 모달 검색 기능이 차별점 +- EntityWidget과도 유사 + +### 통합 방안 +- **결정**: `UnifiedSelect` entity 모드로 통합 +- **작업**: + - UnifiedSelect에 `searchMode: "modal" | "inline" | "autocomplete"` 옵션 추가 + - 모달 검색 UI 통합 + - 기존 entity-search-input은 deprecated 처리 + +--- + +## 7. 이미지 위젯 (image-widget) + +### 현재 구현 +- **위치**: `frontend/lib/registry/components/image-widget/` +- **주요 기능**: + - 이미지 업로드 + - 미리보기 + - 드래그앤드롭 지원 +- **카테고리**: INPUT +- **크기**: 200 x 200 +- **webType**: image + +### 분석 +- UnifiedMedia의 ImageUploader와 기능 동일 +- 이미 ImageWidget 컴포넌트 재사용 중 + +### 통합 방안 +- **결정**: `UnifiedMedia` image 타입으로 통합 완료 +- **상태**: 이미 UnifiedMedia.ImageUploader로 구현됨 +- **작업**: + - 컴포넌트 패널에서 image-widget 제거 + - UnifiedMedia 사용 권장 + +--- + +## 8. 자동완성 검색 입력 (autocomplete-search-input) + +### 현재 구현 +- **위치**: `frontend/lib/registry/components/autocomplete-search-input/` +- **주요 기능**: + - 타이핑 시 드롭다운 검색 + - 엔티티 테이블 연동 + - 추가 필드 표시 +- **카테고리**: INPUT +- **크기**: 300 x 40 +- **webType**: entity + +### 분석 +- entity-search-input과 유사하지만 UI 방식이 다름 +- Command/Popover 기반 자동완성 + +### 통합 방안 +- **결정**: `UnifiedSelect` entity 모드의 autocomplete 옵션으로 통합 +- **작업**: + - UnifiedSelect에서 `searchMode: "autocomplete"` 옵션 추가 + - 자동완성 검색 로직 통합 + +--- + +## 9. 출발지/도착지 선택 (location-swap-selector) + +### 현재 구현 +- **위치**: `frontend/lib/registry/components/location-swap-selector/` +- **주요 기능**: + - 출발지/도착지 두 개 필드 동시 관리 + - 스왑 버튼으로 교환 + - 모바일 최적화 UI + - 다양한 데이터 소스 (table, code, static) +- **카테고리**: INPUT +- **크기**: 400 x 100 + +### 분석 +- 물류/운송 시스템 전용 컴포넌트 +- 두 개의 Select를 묶은 복합 컴포넌트 +- 스왑 기능이 핵심 + +### 통합 방안 +- **결정**: **독립 유지** +- **이유**: + - 특수 용도 (물류 시스템) + - 다른 컴포넌트와 기능 중복 없음 + - 복합 필드 관리 (출발지 + 도착지) + +--- + +## 10. 파일 업로드 (file-upload) + +### 현재 구현 +- **위치**: `frontend/lib/registry/components/file-upload/` +- **주요 기능**: + - 파일 선택/업로드 + - 드래그앤드롭 + - 업로드 진행률 표시 + - 파일 목록 관리 +- **카테고리**: INPUT +- **크기**: 350 x 240 +- **webType**: file + +### 분석 +- UnifiedMedia의 FileUploader와 기능 동일 +- attach_file_info 테이블 연동 + +### 통합 방안 +- **결정**: `UnifiedMedia` file 타입으로 통합 +- **상태**: 이미 UnifiedMedia.FileUploader로 구현됨 +- **작업**: + - 컴포넌트 패널에서 file-upload 제거 + - UnifiedMedia 사용 권장 + +--- + +## 통합 우선순위 및 작업 계획 + +### Phase 1: 즉시 통합 가능 (작업 최소) + +| 컴포넌트 | 통합 대상 | 예상 작업량 | 비고 | +|----------|----------|------------|------| +| image-widget | UnifiedMedia (image) | 1일 | 이미 구현됨, 패널에서 숨기기만 | +| file-upload | UnifiedMedia (file) | 1일 | 이미 구현됨, 패널에서 숨기기만 | + +### Phase 2: 기능 통합 필요 (중간 작업) + +| 컴포넌트 | 통합 대상 | 예상 작업량 | 비고 | +|----------|----------|------------|------| +| entity-search-input | UnifiedSelect (entity) | 3일 | 모달 검색 모드 추가 | +| autocomplete-search-input | UnifiedSelect (entity) | 2일 | autocomplete 모드 추가 | +| rack-structure | UnifiedBiz (rack) | 2일 | 비즈니스 타입 연결 | + +### Phase 3: 독립 유지 (작업 없음) + +| 컴포넌트 | 이유 | +|----------|------| +| mail-recipient-selector | 메일 시스템 전용 | +| repeater-field-group | 너무 복잡, 잘 동작 중 | +| universal-form-modal | ScreenModal과 차별화 필요 | +| selected-items-detail-input | 특수 워크플로우 | +| location-swap-selector | 물류 시스템 전용 | + +--- + +## 결론 + +### 즉시 실행 가능한 작업 +1. **ComponentsPanel 정리**: + - `image-widget`, `file-upload` 숨김 처리 (UnifiedMedia 사용) + - 중복 컴포넌트 정리 + +2. **UnifiedBiz 연결**: + - `bizType: "rack"` 선택 시 `RackStructureComponent` 렌더링 연결 + +### 향후 계획 +1. UnifiedSelect에 entity 검색 모드 통합 +2. UnifiedMedia 설정 패널 강화 +3. 독립 유지 컴포넌트들의 문서화 + +--- + +## 컴포넌트 패널 정리 제안 + +### 숨길 컴포넌트 (Unified로 대체됨) +- `image-widget` → UnifiedMedia 사용 +- `file-upload` → UnifiedMedia 사용 +- `entity-search-input` → UnifiedSelect (entity 모드) 사용 예정 +- `autocomplete-search-input` → UnifiedSelect (autocomplete 모드) 사용 예정 + +### 유지할 컴포넌트 (독립 기능) +- `rack-structure` - WMS 전용 (UnifiedBiz 연결 예정) +- `mail-recipient-selector` - 메일 시스템 전용 +- `repeater-field-group` - 반복 입력 전용 +- `universal-form-modal` - 복잡한 폼 전용 +- `selected-items-detail-input` - 상세 입력 전용 +- `location-swap-selector` - 물류 시스템 전용 + diff --git a/frontend/components/screen/panels/ComponentsPanel.tsx b/frontend/components/screen/panels/ComponentsPanel.tsx index 104c2721..9121a376 100644 --- a/frontend/components/screen/panels/ComponentsPanel.tsx +++ b/frontend/components/screen/panels/ComponentsPanel.tsx @@ -96,19 +96,46 @@ export function ComponentsPanel({ // 카테고리별 컴포넌트 그룹화 const componentsByCategory = useMemo(() => { - // 숨길 컴포넌트 ID 목록 (기본 입력 컴포넌트들) - const hiddenInputComponents = ["text-input", "number-input", "date-input", "textarea-basic"]; + // 숨길 컴포넌트 ID 목록 + const hiddenComponents = [ + // 기본 입력 컴포넌트 (테이블 컬럼 드래그 시 자동 생성) + "text-input", + "number-input", + "date-input", + "textarea-basic", + // Unified 컴포넌트로 대체됨 + "image-widget", // → UnifiedMedia (image) + "file-upload", // → UnifiedMedia (file) + "entity-search-input", // → UnifiedSelect (entity 모드) + "autocomplete-search-input", // → UnifiedSelect (autocomplete 모드) + // UnifiedBiz로 통합 예정 + "rack-structure", // → UnifiedBiz (rack) + // DataFlow 전용 (일반 화면에서 불필요) + "mail-recipient-selector", + // 현재 사용 안함 + "repeater-field-group", + ]; return { input: allComponents.filter( - (c) => c.category === ComponentCategory.INPUT && !hiddenInputComponents.includes(c.id), + (c) => c.category === ComponentCategory.INPUT && !hiddenComponents.includes(c.id), ), - action: allComponents.filter((c) => c.category === ComponentCategory.ACTION), - display: allComponents.filter((c) => c.category === ComponentCategory.DISPLAY), - data: allComponents.filter((c) => c.category === ComponentCategory.DATA), // 🆕 데이터 카테고리 추가 - layout: allComponents.filter((c) => c.category === ComponentCategory.LAYOUT), - utility: allComponents.filter((c) => c.category === ComponentCategory.UTILITY), - unified: unifiedComponents, // 🆕 Unified 컴포넌트 카테고리 추가 + action: allComponents.filter( + (c) => c.category === ComponentCategory.ACTION && !hiddenComponents.includes(c.id), + ), + display: allComponents.filter( + (c) => c.category === ComponentCategory.DISPLAY && !hiddenComponents.includes(c.id), + ), + data: allComponents.filter( + (c) => c.category === ComponentCategory.DATA && !hiddenComponents.includes(c.id), + ), + layout: allComponents.filter( + (c) => c.category === ComponentCategory.LAYOUT && !hiddenComponents.includes(c.id), + ), + utility: allComponents.filter( + (c) => c.category === ComponentCategory.UTILITY && !hiddenComponents.includes(c.id), + ), + unified: unifiedComponents, }; }, [allComponents, unifiedComponents]); diff --git a/frontend/contexts/ActiveTabContext.tsx b/frontend/contexts/ActiveTabContext.tsx index 35081225..72e06525 100644 --- a/frontend/contexts/ActiveTabContext.tsx +++ b/frontend/contexts/ActiveTabContext.tsx @@ -141,3 +141,4 @@ export const useActiveTabOptional = () => { + diff --git a/frontend/hooks/useAutoFill.ts b/frontend/hooks/useAutoFill.ts index 7d78322b..381f1840 100644 --- a/frontend/hooks/useAutoFill.ts +++ b/frontend/hooks/useAutoFill.ts @@ -198,3 +198,4 @@ export function applyAutoFillToFormData( + diff --git a/화면_임베딩_및_데이터_전달_시스템_구현_계획서.md b/화면_임베딩_및_데이터_전달_시스템_구현_계획서.md index 1108475c..b2b81c07 100644 --- a/화면_임베딩_및_데이터_전달_시스템_구현_계획서.md +++ b/화면_임베딩_및_데이터_전달_시스템_구현_계획서.md @@ -1690,3 +1690,4 @@ const 출고등록_설정: ScreenSplitPanel = { + diff --git a/화면_임베딩_시스템_Phase1-4_구현_완료.md b/화면_임베딩_시스템_Phase1-4_구현_완료.md index c20a94bc..23212951 100644 --- a/화면_임베딩_시스템_Phase1-4_구현_완료.md +++ b/화면_임베딩_시스템_Phase1-4_구현_완료.md @@ -537,3 +537,4 @@ const { data: config } = await getScreenSplitPanel(screenId); + diff --git a/화면_임베딩_시스템_충돌_분석_보고서.md b/화면_임베딩_시스템_충돌_분석_보고서.md index 77ad05b2..92e95ded 100644 --- a/화면_임베딩_시스템_충돌_분석_보고서.md +++ b/화면_임베딩_시스템_충돌_분석_보고서.md @@ -524,3 +524,4 @@ function ScreenViewPage() { +