1027 lines
37 KiB
Markdown
1027 lines
37 KiB
Markdown
|
|
# 화면 디자이너 V2 - 재설계 계획서
|
|||
|
|
|
|||
|
|
> 작성일: 2026-02-27
|
|||
|
|
> 방향: 기존 기능 형태는 인정하되, 새로운 방식으로 재설립
|
|||
|
|
> 핵심 철학: "컴포넌트를 계속 추가하는 시스템"에서 "소수의 강력한 컴포넌트로 유연하게 조합하는 시스템"으로
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 1. 현재 시스템의 근본적 문제
|
|||
|
|
|
|||
|
|
### 1.1 "컴포넌트 폭증" 문제
|
|||
|
|
|
|||
|
|
현재 등록된 컴포넌트 수: **70개 이상**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
기본 입력 13종 + V2 입력 4종 + V2 데이터 5종
|
|||
|
|
기존 레이아웃 8종 + V2 레이아웃 16종 + 특수 10종+
|
|||
|
|
ConfigPanel 26개 + Renderer 21개 + 위젯 10종+
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**문제**: 새 기능이 필요할 때마다 아래 작업을 반복해야 함
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
새 기능 요청 → ComponentDefinition 작성
|
|||
|
|
→ Renderer 작성
|
|||
|
|
→ ConfigPanel 작성
|
|||
|
|
→ index.ts에 import 추가
|
|||
|
|
→ 테스트
|
|||
|
|
→ 약 5~8개 파일, 500~1500줄 추가
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
거래처별 품목정보? → `customer-item-mapping` 컴포넌트 추가
|
|||
|
|
BOM 트리? → `v2-bom-tree` + `v2-bom-item-editor` 추가
|
|||
|
|
세금계산서? → `tax-invoice-list` 추가
|
|||
|
|
타임라인? → `v2-timeline-scheduler` 추가
|
|||
|
|
|
|||
|
|
**매번 개발자가 코드를 작성해야만 새 기능이 가능**하다.
|
|||
|
|
|
|||
|
|
### 1.2 설정 패널의 사용성 문제
|
|||
|
|
|
|||
|
|
ConfigPanel이 26개이고, 각각 UI 구조/용어/설정 방식이 다름:
|
|||
|
|
|
|||
|
|
| 패널 | 설정 항목 | 사용자 관점 |
|
|||
|
|
|------|-----------|------------|
|
|||
|
|
| TextConfigPanel | inputType, placeholder, maxLength... | "이게 뭐지?" |
|
|||
|
|
| EntityConfigPanel | joinTable, joinColumn, displayColumn... | "조인? 컬럼?" |
|
|||
|
|
| SelectConfigPanel | optionSource, staticOptions, dynamicApi... | "동적 API?" |
|
|||
|
|
| FlowWidgetConfigPanel | flowDefinitionId, stepMapping... | "스텝 매핑?" |
|
|||
|
|
| ButtonConfigPanel | actionType, dataFlow, targetScreen... | "데이터 플로우?" |
|
|||
|
|
|
|||
|
|
**사용자(현업 관리자)가 이 설정들을 이해하고 사용하기가 극히 어려움.**
|
|||
|
|
|
|||
|
|
### 1.3 컴포넌트 간 연결의 제한성
|
|||
|
|
|
|||
|
|
현재 컴포넌트들은 대부분 **독립적**으로 동작:
|
|||
|
|
|
|||
|
|
- 거래처를 선택하면 → 납품처가 자동으로 바뀌어야 하는데 → 별도 코드 필요
|
|||
|
|
- 마스터 테이블에서 행을 선택하면 → 디테일 테이블이 자동 필터링 → SplitPanel로 하드코딩
|
|||
|
|
- 버튼 클릭하면 → 특정 필드 값에 따라 다른 동작 → FlowWidget으로만 가능
|
|||
|
|
|
|||
|
|
**컴포넌트 간 동적 상호작용을 사용자가 설정할 방법이 없음.**
|
|||
|
|
|
|||
|
|
### 1.4 V1/V2/기존/신규 혼재
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// 같은 테이블 컴포넌트가 3종류
|
|||
|
|
import "./table-list/TableListRenderer"; // 기존
|
|||
|
|
import "./v2-table-list/TableListRenderer"; // V2
|
|||
|
|
import "./v2-table-grouped/TableGroupedRenderer"; // V2 그룹화
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
동일 기능의 컴포넌트가 "기존 호환"이라는 이유로 중복 존재.
|
|||
|
|
어떤 걸 써야 하는지 사용자도 개발자도 혼란.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. 새로운 비전
|
|||
|
|
|
|||
|
|
### 2.1 핵심 원칙
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
❌ 기존: "기능 = 컴포넌트" → 기능이 늘어나면 컴포넌트가 늘어남
|
|||
|
|
✅ 새롭게: "기능 = 설정" → 소수의 메타 컴포넌트 + 풍부한 설정으로 무한 확장
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
❌ 기존: "개발자가 만들어주는 화면" → 요청 → 개발 → 배포 → 1~3일
|
|||
|
|
✅ 새롭게: "사용자가 조립하는 화면" → 드래그 → 설정 → 바로 사용 → 5분
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2.2 메타 컴포넌트 체계
|
|||
|
|
|
|||
|
|
70개 이상의 컴포넌트를 **7개의 메타 컴포넌트**로 통합:
|
|||
|
|
|
|||
|
|
| 메타 컴포넌트 | 대체 범위 | 핵심 능력 |
|
|||
|
|
|---------------|-----------|-----------|
|
|||
|
|
| **Field** | text, number, date, select, entity, checkbox, radio, file, textarea, code, numbering | 테이블 컬럼의 webType에 따라 자동 변환 |
|
|||
|
|
| **DataView** | table-list, repeater, card-display, pivot-grid, bom-tree, aggregation, timeline | 같은 데이터를 테이블/카드/트리/피벗/타임라인 등 뷰 모드 전환 |
|
|||
|
|
| **Action** | button-primary, flow-widget, related-data-buttons | 클릭 시 저장/삭제/조회/이동/모달/API 호출 등 설정 |
|
|||
|
|
| **Layout** | split-panel, tabs, section-card, section-paper, conditional-container, accordion | 영역 분할, 탭, 섹션, 조건부 표시 |
|
|||
|
|
| **Display** | text-display, divider, badge, alert, stats-card, chart, image, progress | 읽기 전용 정보 표시 |
|
|||
|
|
| **Search** | table-search, advanced-filters, autocomplete | 데이터 필터링/검색 |
|
|||
|
|
| **Modal** | universal-form-modal, repeat-screen-modal | 데이터 입력/편집 팝업 |
|
|||
|
|
|
|||
|
|
### 2.3 "테이블 드롭 → 화면 완성" 흐름
|
|||
|
|
|
|||
|
|
**현재** (약 15분):
|
|||
|
|
```
|
|||
|
|
1. 테이블 컬럼을 하나씩 드래그
|
|||
|
|
2. 각 컬럼마다 컴포넌트 타입 확인
|
|||
|
|
3. entity 컬럼이면 → EntityConfigPanel에서 조인 테이블, 조인 컬럼 수동 설정
|
|||
|
|
4. select 컬럼이면 → SelectConfigPanel에서 옵션 소스 수동 설정
|
|||
|
|
5. 버튼 컴포넌트 별도 추가
|
|||
|
|
6. 데이터 테이블 별도 추가
|
|||
|
|
7. 각각 설정...
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**새로운 방식** (약 2분):
|
|||
|
|
```
|
|||
|
|
1. 테이블을 통째로 드롭
|
|||
|
|
2. 시스템이 자동으로:
|
|||
|
|
- 컬럼 타입(webType) 분석 → Field 컴포넌트 자동 생성
|
|||
|
|
- entity 컬럼 → 조인 정보 자동 감지 (FK 관계)
|
|||
|
|
- select 컬럼 → 코드 테이블 자동 연결
|
|||
|
|
- CRUD 버튼 자동 생성 (Action 컴포넌트)
|
|||
|
|
- DataView(테이블 뷰) 자동 생성
|
|||
|
|
3. 사용자는 세부 설정만 조정
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. 메타 컴포넌트 상세 설계
|
|||
|
|
|
|||
|
|
### 3.1 Field (통합 입력 컴포넌트)
|
|||
|
|
|
|||
|
|
**대체 대상**: text-input, number-input, date-input, select-basic, checkbox-basic, radio-basic, entity-search-input, file-upload, textarea, code-input, numbering-rule, v2-input, v2-select, v2-date, v2-file-upload, autocomplete-search-input, toggle-switch, slider
|
|||
|
|
|
|||
|
|
**핵심 개념**: 하나의 Field 컴포넌트가 `webType`에 따라 모양과 동작이 바뀜
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface FieldConfig {
|
|||
|
|
// 자동 결정 (테이블 컬럼 기반)
|
|||
|
|
webType: "text" | "number" | "date" | "datetime" | "select" | "entity"
|
|||
|
|
| "checkbox" | "radio" | "file" | "textarea" | "code" | "numbering"
|
|||
|
|
| "email" | "tel" | "url" | "password" | "color" | "toggle" | "slider";
|
|||
|
|
|
|||
|
|
// 데이터 바인딩 (자동)
|
|||
|
|
tableName: string;
|
|||
|
|
columnName: string;
|
|||
|
|
|
|||
|
|
// 조인 정보 (entity 타입일 때 자동 감지)
|
|||
|
|
join?: {
|
|||
|
|
targetTable: string; // FK가 참조하는 테이블
|
|||
|
|
targetColumn: string; // PK 컬럼
|
|||
|
|
displayColumn: string; // 표시할 컬럼 (자동: name 또는 첫 번째 text 컬럼)
|
|||
|
|
additionalColumns?: string[]; // 추가 표시 컬럼
|
|||
|
|
searchable?: boolean; // 검색 가능 여부
|
|||
|
|
filterBy?: Record<string, string>; // 다른 Field 값으로 필터링
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// select 옵션 (자동 감지)
|
|||
|
|
options?: {
|
|||
|
|
source: "code_table" | "static" | "api";
|
|||
|
|
codeCategory?: string; // code_table일 때
|
|||
|
|
staticList?: { value: string; label: string }[];
|
|||
|
|
apiEndpoint?: string;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 공통 설정
|
|||
|
|
label?: string;
|
|||
|
|
placeholder?: string;
|
|||
|
|
required?: boolean;
|
|||
|
|
readonly?: boolean;
|
|||
|
|
disabled?: boolean;
|
|||
|
|
defaultValue?: any;
|
|||
|
|
|
|||
|
|
// 검증
|
|||
|
|
validation?: {
|
|||
|
|
min?: number;
|
|||
|
|
max?: number;
|
|||
|
|
minLength?: number;
|
|||
|
|
maxLength?: number;
|
|||
|
|
pattern?: string;
|
|||
|
|
customMessage?: string;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 연동 (다른 Field와의 관계)
|
|||
|
|
linkedTo?: {
|
|||
|
|
fieldId: string; // 연결된 Field의 ID
|
|||
|
|
relationship: "filter" | "copy" | "calculate" | "show_hide";
|
|||
|
|
expression?: string; // 계산식 또는 조건식
|
|||
|
|
}[];
|
|||
|
|
|
|||
|
|
// 레이아웃
|
|||
|
|
display?: {
|
|||
|
|
width?: string; // "full" | "half" | "third" | "quarter" | 커스텀
|
|||
|
|
labelPosition?: "top" | "left" | "hidden";
|
|||
|
|
helpText?: string;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**사용자 설정 UI (새로운 방식)**:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────┐
|
|||
|
|
│ Field 설정 │
|
|||
|
|
├─────────────────────────────────────┤
|
|||
|
|
│ 표시 형태: [텍스트 ▼] │ ← 드롭다운 하나로 webType 전환
|
|||
|
|
│ │
|
|||
|
|
│ 라벨: [수주번호 ] │
|
|||
|
|
│ 필수: [✓] 읽기전용: [ ] │
|
|||
|
|
│ │
|
|||
|
|
│ ─── 데이터 연결 ──── │
|
|||
|
|
│ 테이블: sales_order_mng (자동) │
|
|||
|
|
│ 컬럼: order_no (자동) │
|
|||
|
|
│ │
|
|||
|
|
│ ─── 연동 설정 ──── │
|
|||
|
|
│ + 다른 필드와 연결 추가 │
|
|||
|
|
│ [거래처] 변경 시 → [납품처] 필터링 │
|
|||
|
|
│ [수량] × [단가] → [금액] 자동계산 │
|
|||
|
|
│ │
|
|||
|
|
│ ─── 표시 ──── │
|
|||
|
|
│ 너비: [절반 ▼] │
|
|||
|
|
│ 도움말: [주문 번호를 입력하세요] │
|
|||
|
|
└─────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**핵심 차이점**:
|
|||
|
|
- 기존: 컴포넌트 타입 선택 → 타입별 ConfigPanel → 복잡한 설정
|
|||
|
|
- 새로운: Field 하나 놓으면 → webType 자동 감지 → 간단한 통합 설정
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3.2 DataView (통합 데이터 뷰)
|
|||
|
|
|
|||
|
|
**대체 대상**: table-list, v2-table-list, v2-repeater, card-display, v2-card-display, pivot-grid, v2-pivot-grid, bom-tree, aggregation-widget, v2-aggregation-widget, v2-table-grouped, v2-timeline-scheduler, simple-repeater-table, modal-repeater-table
|
|||
|
|
|
|||
|
|
**핵심 개념**: 하나의 데이터 소스를 여러 뷰 모드로 전환
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface DataViewConfig {
|
|||
|
|
// 데이터 소스
|
|||
|
|
dataSource: {
|
|||
|
|
tableName: string;
|
|||
|
|
columns: ColumnConfig[]; // 표시할 컬럼 목록
|
|||
|
|
defaultSort?: { column: string; direction: "asc" | "desc" };
|
|||
|
|
defaultFilter?: FilterConfig[];
|
|||
|
|
pageSize?: number;
|
|||
|
|
|
|||
|
|
// 마스터-디테일 자동 연결
|
|||
|
|
masterField?: string; // 상위 DataView의 어떤 컬럼과 연결
|
|||
|
|
detailForeignKey?: string; // 하위 테이블의 FK 컬럼
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 뷰 모드 (사용자가 런타임에 전환 가능)
|
|||
|
|
viewMode: "table" | "card" | "list" | "tree" | "pivot" | "timeline" | "kanban" | "calendar";
|
|||
|
|
allowedViewModes?: string[]; // 허용된 뷰 모드 목록
|
|||
|
|
|
|||
|
|
// 테이블 뷰 설정
|
|||
|
|
tableConfig?: {
|
|||
|
|
showRowNumber?: boolean;
|
|||
|
|
showCheckbox?: boolean;
|
|||
|
|
stickyHeader?: boolean;
|
|||
|
|
groupBy?: string[]; // 그룹화 컬럼
|
|||
|
|
summaryColumns?: string[]; // 합계 표시 컬럼
|
|||
|
|
editableColumns?: string[]; // 인라인 편집 가능 컬럼
|
|||
|
|
frozenColumns?: number; // 고정 컬럼 수
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 카드 뷰 설정
|
|||
|
|
cardConfig?: {
|
|||
|
|
titleColumn: string;
|
|||
|
|
descriptionColumn?: string;
|
|||
|
|
imageColumn?: string;
|
|||
|
|
columnsPerRow?: 2 | 3 | 4;
|
|||
|
|
cardStyle?: "compact" | "standard" | "detailed";
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 트리 뷰 설정
|
|||
|
|
treeConfig?: {
|
|||
|
|
parentColumn: string;
|
|||
|
|
childColumn: string;
|
|||
|
|
labelColumn: string;
|
|||
|
|
expandLevel?: number;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 피벗 설정
|
|||
|
|
pivotConfig?: {
|
|||
|
|
rowFields: string[];
|
|||
|
|
columnFields: string[];
|
|||
|
|
valueFields: { column: string; aggregation: "sum" | "count" | "avg" | "min" | "max" }[];
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// CRUD 동작 (Action 컴포넌트와 자동 연결)
|
|||
|
|
actions?: {
|
|||
|
|
create?: boolean;
|
|||
|
|
read?: boolean;
|
|||
|
|
update?: boolean;
|
|||
|
|
delete?: boolean;
|
|||
|
|
export?: boolean;
|
|||
|
|
import?: boolean;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 검색/필터 (Search 컴포넌트와 자동 연결)
|
|||
|
|
searchable?: boolean;
|
|||
|
|
filterColumns?: string[];
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**사용자 설정 UI**:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────┐
|
|||
|
|
│ DataView 설정 │
|
|||
|
|
├─────────────────────────────────────┤
|
|||
|
|
│ 테이블: [sales_order_mng ▼] │
|
|||
|
|
│ │
|
|||
|
|
│ 뷰 모드: [테이블] [카드] [트리] │ ← 클릭 한 번으로 전환
|
|||
|
|
│ ☑테이블 ☑카드 ☐트리 │ ← 허용 모드 체크
|
|||
|
|
│ │
|
|||
|
|
│ ─── 컬럼 선택 ──── │
|
|||
|
|
│ ☑ 수주번호 표시명: 수주번호 │
|
|||
|
|
│ ☑ 거래처 표시명: 거래처 │
|
|||
|
|
│ ☑ 수주수량 표시명: 수량 합계☑│
|
|||
|
|
│ ☐ 생성일 (숨김) │
|
|||
|
|
│ [↕ 드래그로 순서 변경] │
|
|||
|
|
│ │
|
|||
|
|
│ ─── 기능 ──── │
|
|||
|
|
│ ☑ 행 번호 ☑ 체크박스 ☑ 검색 │
|
|||
|
|
│ ☑ 등록 ☑ 수정 ☑ 삭제 │
|
|||
|
|
│ ☐ 엑셀 내보내기 ☐ 가져오기 │
|
|||
|
|
│ │
|
|||
|
|
│ ─── 연결 ──── │
|
|||
|
|
│ 마스터: [없음 ▼] │ ← 다른 DataView 선택 시
|
|||
|
|
│ 연결 키: [customer_code ▼] │ 자동 마스터-디테일
|
|||
|
|
└─────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3.3 Action (통합 액션 컴포넌트)
|
|||
|
|
|
|||
|
|
**대체 대상**: button-primary, v2-button-primary, flow-widget, related-data-buttons
|
|||
|
|
|
|||
|
|
**핵심 개념**: 하나의 Action 컴포넌트에 여러 동작을 설정으로 정의
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface ActionConfig {
|
|||
|
|
// 표시
|
|||
|
|
label: string;
|
|||
|
|
variant: "default" | "outline" | "destructive" | "ghost";
|
|||
|
|
icon?: string;
|
|||
|
|
position?: "toolbar" | "inline" | "floating" | "context-menu";
|
|||
|
|
|
|||
|
|
// 동작 정의 (파이프라인 방식 - 순차 실행)
|
|||
|
|
steps: ActionStep[];
|
|||
|
|
|
|||
|
|
// 실행 조건
|
|||
|
|
enableCondition?: {
|
|||
|
|
type: "always" | "selected" | "field_value" | "expression";
|
|||
|
|
fieldId?: string;
|
|||
|
|
operator?: "eq" | "ne" | "gt" | "lt" | "empty" | "not_empty";
|
|||
|
|
value?: any;
|
|||
|
|
expression?: string;
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 확인 대화상자
|
|||
|
|
confirmDialog?: {
|
|||
|
|
title: string;
|
|||
|
|
message: string;
|
|||
|
|
confirmText?: string;
|
|||
|
|
cancelText?: string;
|
|||
|
|
variant?: "default" | "destructive";
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
type ActionStep =
|
|||
|
|
| { type: "save"; target: string } // 데이터 저장
|
|||
|
|
| { type: "delete"; target: string } // 데이터 삭제
|
|||
|
|
| { type: "refresh"; target: string } // 데이터 새로고침
|
|||
|
|
| { type: "navigate"; screenId: number } // 화면 이동
|
|||
|
|
| { type: "openModal"; modalId: string } // 모달 열기
|
|||
|
|
| { type: "setField"; fieldId: string; value: any } // 필드 값 설정
|
|||
|
|
| { type: "api"; method: string; endpoint: string; body?: any } // API 호출
|
|||
|
|
| { type: "flowMove"; flowId: number; stepId: number } // 플로우 이동
|
|||
|
|
| { type: "export"; format: "excel" | "csv" | "pdf" } // 내보내기
|
|||
|
|
| { type: "validate"; target: string } // 유효성 검사
|
|||
|
|
| { type: "toast"; message: string; variant: "success" | "error" | "warning" }; // 알림
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**사용자 설정 UI**:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────┐
|
|||
|
|
│ Action 설정 │
|
|||
|
|
├─────────────────────────────────────┤
|
|||
|
|
│ 버튼명: [저장 ] │
|
|||
|
|
│ 스타일: [기본●] [외곽] [위험] [고스트]│
|
|||
|
|
│ 아이콘: [Save ▼] │
|
|||
|
|
│ │
|
|||
|
|
│ ─── 동작 순서 ──── │
|
|||
|
|
│ 1. [유효성 검사 ▼] → 주문 폼 │
|
|||
|
|
│ 2. [데이터 저장 ▼] → sales_order │
|
|||
|
|
│ 3. [알림 ▼] → "저장 완료" │
|
|||
|
|
│ 4. [새로고침 ▼] → 주문 목록 │
|
|||
|
|
│ [+ 동작 추가] │
|
|||
|
|
│ │
|
|||
|
|
│ ─── 실행 조건 ──── │
|
|||
|
|
│ [행 선택 시만 ▼] │
|
|||
|
|
│ │
|
|||
|
|
│ ─── 확인 ──── │
|
|||
|
|
│ ☑ 실행 전 확인 대화상자 │
|
|||
|
|
│ 제목: [저장 확인] │
|
|||
|
|
│ 메시지: [변경사항을 저장합니다] │
|
|||
|
|
└─────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3.4 Layout (통합 레이아웃)
|
|||
|
|
|
|||
|
|
**대체 대상**: split-panel-layout, v2-split-panel-layout, tabs, v2-tabs, section-card, v2-section-card, section-paper, v2-section-paper, conditional-container, accordion, screen-split-panel, repeat-container
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface LayoutConfig {
|
|||
|
|
mode: "columns" | "rows" | "tabs" | "accordion" | "card" | "conditional";
|
|||
|
|
|
|||
|
|
// columns/rows 모드
|
|||
|
|
areas?: {
|
|||
|
|
id: string;
|
|||
|
|
label?: string;
|
|||
|
|
size?: string; // "1fr", "300px", "auto"
|
|||
|
|
minSize?: string;
|
|||
|
|
maxSize?: string;
|
|||
|
|
collapsible?: boolean;
|
|||
|
|
resizable?: boolean; // 드래그로 크기 조절
|
|||
|
|
}[];
|
|||
|
|
|
|||
|
|
// tabs 모드
|
|||
|
|
tabs?: {
|
|||
|
|
id: string;
|
|||
|
|
label: string;
|
|||
|
|
icon?: string;
|
|||
|
|
closable?: boolean;
|
|||
|
|
lazy?: boolean; // 탭 전환 시 지연 로드
|
|||
|
|
}[];
|
|||
|
|
|
|||
|
|
// conditional 모드 (조건에 따라 영역 표시/숨김)
|
|||
|
|
conditions?: {
|
|||
|
|
areaId: string;
|
|||
|
|
showWhen: {
|
|||
|
|
fieldId: string;
|
|||
|
|
operator: "eq" | "ne" | "in" | "not_in";
|
|||
|
|
value: any;
|
|||
|
|
};
|
|||
|
|
}[];
|
|||
|
|
|
|||
|
|
// 공통
|
|||
|
|
gap?: number;
|
|||
|
|
padding?: number;
|
|||
|
|
bordered?: boolean;
|
|||
|
|
title?: string;
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3.5 Display (통합 표시 컴포넌트)
|
|||
|
|
|
|||
|
|
**대체 대상**: text-display, v2-text-display, divider-line, v2-divider-line, badge, alert, stats-card, chart, image, progress-bar, v2-media, v2-split-line
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface DisplayConfig {
|
|||
|
|
displayType: "text" | "heading" | "divider" | "badge" | "alert" | "stat"
|
|||
|
|
| "chart" | "image" | "progress" | "spacer" | "html";
|
|||
|
|
|
|||
|
|
// 데이터 바인딩 (선택)
|
|||
|
|
dataBinding?: {
|
|||
|
|
tableName?: string;
|
|||
|
|
columnName?: string;
|
|||
|
|
expression?: string; // 계산식: "{total_amount} / {quantity}"
|
|||
|
|
format?: string; // 숫자/날짜 포맷
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 텍스트 설정
|
|||
|
|
text?: {
|
|||
|
|
content: string;
|
|||
|
|
size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl";
|
|||
|
|
weight?: "normal" | "medium" | "semibold" | "bold";
|
|||
|
|
color?: string;
|
|||
|
|
align?: "left" | "center" | "right";
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 차트 설정
|
|||
|
|
chart?: {
|
|||
|
|
chartType: "bar" | "line" | "pie" | "donut" | "area";
|
|||
|
|
dataSource: string;
|
|||
|
|
xAxis: string;
|
|||
|
|
yAxis: string[];
|
|||
|
|
colors?: string[];
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 통계 카드
|
|||
|
|
stat?: {
|
|||
|
|
value: string;
|
|||
|
|
label: string;
|
|||
|
|
change?: string;
|
|||
|
|
changeType?: "increase" | "decrease" | "neutral";
|
|||
|
|
icon?: string;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3.6 Search (통합 검색)
|
|||
|
|
|
|||
|
|
**대체 대상**: table-search-widget, v2-table-search-widget, AdvancedSearchFilters
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface SearchConfig {
|
|||
|
|
// 연결된 DataView
|
|||
|
|
targetDataView: string;
|
|||
|
|
|
|||
|
|
// 검색 모드
|
|||
|
|
mode: "simple" | "advanced" | "combined";
|
|||
|
|
|
|||
|
|
// 검색 필드
|
|||
|
|
fields?: {
|
|||
|
|
columnName: string;
|
|||
|
|
label: string;
|
|||
|
|
searchType: "text" | "exact" | "range" | "select" | "date_range" | "entity";
|
|||
|
|
defaultExpanded?: boolean;
|
|||
|
|
}[];
|
|||
|
|
|
|||
|
|
// 퀵 필터 (버튼 형태)
|
|||
|
|
quickFilters?: {
|
|||
|
|
label: string;
|
|||
|
|
filter: { column: string; operator: string; value: any };
|
|||
|
|
}[];
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 3.7 Modal (통합 모달)
|
|||
|
|
|
|||
|
|
**대체 대상**: universal-form-modal, repeat-screen-modal, selected-items-detail-input
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface ModalConfig {
|
|||
|
|
// 트리거
|
|||
|
|
trigger: "button" | "row_click" | "row_double_click" | "action";
|
|||
|
|
|
|||
|
|
// 모달 내부
|
|||
|
|
content: {
|
|||
|
|
type: "form" | "screen" | "custom";
|
|||
|
|
|
|||
|
|
// form: 필드 자동 구성
|
|||
|
|
formConfig?: {
|
|||
|
|
tableName: string;
|
|||
|
|
mode: "create" | "edit" | "view";
|
|||
|
|
columns: string[]; // 표시할 컬럼
|
|||
|
|
layout?: "single" | "two_column";
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// screen: 다른 화면 임베딩
|
|||
|
|
screenId?: number;
|
|||
|
|
|
|||
|
|
// 데이터 전달
|
|||
|
|
passData?: {
|
|||
|
|
from: string; // 현재 화면의 필드/컬럼
|
|||
|
|
to: string; // 모달 내부의 필드/컬럼
|
|||
|
|
}[];
|
|||
|
|
};
|
|||
|
|
|
|||
|
|
// 크기
|
|||
|
|
size?: "sm" | "md" | "lg" | "xl" | "full";
|
|||
|
|
|
|||
|
|
// 닫힐 때 동작
|
|||
|
|
onClose?: ActionStep[];
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. 컴포넌트 간 동적 연동 시스템
|
|||
|
|
|
|||
|
|
### 4.1 현재의 한계
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
[거래처 Field] → 독립 동작 ← [납품처 Field]
|
|||
|
|
연결 없음
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.2 새로운 연동 시스템: Reactive Bindings
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
interface ReactiveBinding {
|
|||
|
|
id: string;
|
|||
|
|
source: {
|
|||
|
|
componentId: string;
|
|||
|
|
event: "change" | "select" | "click" | "load";
|
|||
|
|
field?: string;
|
|||
|
|
};
|
|||
|
|
target: {
|
|||
|
|
componentId: string;
|
|||
|
|
action: "filter" | "setValue" | "show" | "hide" | "enable" | "disable" | "refresh";
|
|||
|
|
field?: string;
|
|||
|
|
};
|
|||
|
|
transform?: {
|
|||
|
|
type: "direct" | "lookup" | "calculate" | "condition";
|
|||
|
|
expression?: string;
|
|||
|
|
};
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**사용자가 설정하는 방식**:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────┐
|
|||
|
|
│ 연동 설정 │
|
|||
|
|
├─────────────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ [거래처 ●]─── 변경 시 ───→[납품처 ●] │
|
|||
|
|
│ └ 필터링: customer_code 일치 │
|
|||
|
|
│ │
|
|||
|
|
│ [수량 ●]──┐ │
|
|||
|
|
│ ├─ 계산 ──→[금액 ●] │
|
|||
|
|
│ [단가 ●]──┘ 수량 × 단가 │
|
|||
|
|
│ │
|
|||
|
|
│ [상태 ●]─── "출고완료" 일 때 ──→[삭제 ●] │
|
|||
|
|
│ └ 비활성화 │
|
|||
|
|
│ │
|
|||
|
|
│ [+ 새 연동 추가] │
|
|||
|
|
└─────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4.3 마스터-디테일 자동 연결
|
|||
|
|
|
|||
|
|
현재는 SplitPanel + 하드코딩된 이벤트 처리가 필요하지만,
|
|||
|
|
새로운 시스템에서는:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
DataView(마스터: 수주목록)
|
|||
|
|
↕ 자동 연결 (FK: order_id)
|
|||
|
|
DataView(디테일: 수주상세품목)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**설정 방법**: DataView의 `dataSource.masterField` 하나만 선택하면 자동 연결
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. 통합 설정 패널 재설계
|
|||
|
|
|
|||
|
|
### 5.1 현재 → 새로운 방식
|
|||
|
|
|
|||
|
|
**현재**: 26개의 각기 다른 ConfigPanel
|
|||
|
|
|
|||
|
|
**새로운**: 1개의 통합 설정 패널 (UnifiedConfigPanel)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────┐
|
|||
|
|
│ 📋 설정 [×] │
|
|||
|
|
├─────────────────────────────────────┤
|
|||
|
|
│ [기본] [데이터] [표시] [연동] [조건]│ ← 5개 탭으로 통일
|
|||
|
|
├─────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ ◆ 기본 탭 │
|
|||
|
|
│ 컴포넌트 유형: Field │
|
|||
|
|
│ 표시 형태: [텍스트 ▼] │
|
|||
|
|
│ 라벨: [수주번호] │
|
|||
|
|
│ 필수: ☑ 읽기전용: ☐ │
|
|||
|
|
│ │
|
|||
|
|
│ ◆ 데이터 탭 │
|
|||
|
|
│ 테이블: sales_order_mng │
|
|||
|
|
│ 컬럼: order_no │
|
|||
|
|
│ 기본값: [자동생성] │
|
|||
|
|
│ │
|
|||
|
|
│ ◆ 표시 탭 │
|
|||
|
|
│ 너비: [━━━━━━○━━] 50% │
|
|||
|
|
│ 라벨 위치: [좌측 ▼] │
|
|||
|
|
│ 도움말: [...] │
|
|||
|
|
│ │
|
|||
|
|
│ ◆ 연동 탭 │
|
|||
|
|
│ 거래처 변경 시 → 납품처 필터링 │
|
|||
|
|
│ [+ 연동 추가] │
|
|||
|
|
│ │
|
|||
|
|
│ ◆ 조건 탭 │
|
|||
|
|
│ 표시 조건: [항상 ▼] │
|
|||
|
|
│ 활성 조건: [항상 ▼] │
|
|||
|
|
└─────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 5.2 설정 난이도별 UI 분리
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
[간편 모드] ← 기본 (현업 관리자용)
|
|||
|
|
라벨, 필수, 읽기전용, 너비 정도만
|
|||
|
|
|
|||
|
|
[상세 모드] ← 토글로 전환 (파워유저용)
|
|||
|
|
검증 규칙, 계산식, 조건부 표시, API 연결 등
|
|||
|
|
|
|||
|
|
[개발자 모드] ← 숨겨진 모드 (개발자 전용)
|
|||
|
|
커스텀 렌더러, 이벤트 훅, CSS 오버라이드
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. 캔버스/디자이너 UI 재설계
|
|||
|
|
|
|||
|
|
### 6.1 새로운 디자이너 레이아웃
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────┐
|
|||
|
|
│ [← 목록] │ 수주관리 화면 │ 💾 자동저장 ON │ [미리보기]│
|
|||
|
|
├──────────┼──────────────────────────────┼────────────┤
|
|||
|
|
│ │ │ │
|
|||
|
|
│ 컴포넌트 │ ┌──────────────────┐ │ 설정 │
|
|||
|
|
│ --------│ │ │ │ -------- │
|
|||
|
|
│ 📊 Data │ │ [캔버스 영역] │ │ [기본] │
|
|||
|
|
│ 📝 Field│ │ │ │ [데이터] │
|
|||
|
|
│ ▶ Action│ │ 드래그하여 │ │ [표시] │
|
|||
|
|
│ 📐 Layout │ 컴포넌트 추가 │ │ [연동] │
|
|||
|
|
│ 📄 Display │ │ │ [조건] │
|
|||
|
|
│ 🔍 Search│ │ │ │ │
|
|||
|
|
│ 📋 Modal │ └──────────────────┘ │ │
|
|||
|
|
│ │ │ │
|
|||
|
|
│ 테이블 │ ────────────────────────── │ │
|
|||
|
|
│ --------│ [줌: 100%] [맞춤] [그리드] │ │
|
|||
|
|
│ 수주관리 │ │ │
|
|||
|
|
│ └ 컬럼들│ │ │
|
|||
|
|
├──────────┼──────────────────────────────┼────────────┤
|
|||
|
|
│ [연동 설정] 컴포넌트 간 연결 시각화 │
|
|||
|
|
│ [거래처] ─── 변경 시 ──→ [납품처] 필터링 │
|
|||
|
|
└─────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 6.2 핵심 UX 개선 사항
|
|||
|
|
|
|||
|
|
| 항목 | 현재 | 새로운 |
|
|||
|
|
|------|------|--------|
|
|||
|
|
| 컴포넌트 패널 | 70개 위젯 나열 | 7개 메타 컴포넌트 + 테이블 컬럼 |
|
|||
|
|
| 드롭 피드백 | 없음 | 스냅 가이드라인 + 드롭 영역 하이라이트 |
|
|||
|
|
| 설정 패널 | 컴포넌트별 26개 | 통합 5탭 패널 (간편/상세/개발자 모드) |
|
|||
|
|
| 빈 캔버스 | 빈 화면 | "테이블을 드래그하여 시작하세요" 가이드 |
|
|||
|
|
| 줌 | 마우스 휠만 | 우하단 줌 컨트롤 (+/-/맞춤/100%) |
|
|||
|
|
| 저장 | 수동만 | 자동 저장 + 수동 저장 |
|
|||
|
|
| 연동 | 코드 필요 | 하단 연동 패널에서 시각적 설정 |
|
|||
|
|
| 미리보기 | 새 창 | 인라인 미리보기 모드 (디자인↔미리보기 전환) |
|
|||
|
|
|
|||
|
|
### 6.3 "테이블 드롭" 자동 화면 생성
|
|||
|
|
|
|||
|
|
테이블을 캔버스에 드롭하면 자동으로 화면 구성:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
[sales_order_mng 테이블 드롭]
|
|||
|
|
↓
|
|||
|
|
┌─────────────────────────────────────┐
|
|||
|
|
│ 🪄 화면 자동 생성 │
|
|||
|
|
├─────────────────────────────────────┤
|
|||
|
|
│ 어떤 형태로 만들까요? │
|
|||
|
|
│ │
|
|||
|
|
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │
|
|||
|
|
│ │목록형│ │폼형 │ │마디 │ │카드 │ │
|
|||
|
|
│ │ │ │ │ │ │ │ │ │
|
|||
|
|
│ │ ≡≡≡ │ │ □□ │ │≡≡│□│ │ ▦▦▦ │ │
|
|||
|
|
│ │ ≡≡≡ │ │ □□ │ │≡≡│□│ │ ▦▦▦ │ │
|
|||
|
|
│ └─────┘ └─────┘ └─────┘ └─────┘ │
|
|||
|
|
│ 테이블 입력폼 마스터 카드 그리드│
|
|||
|
|
│ + CRUD + 저장 디테일 + 필터 │
|
|||
|
|
│ │
|
|||
|
|
│ 포함할 컬럼: │
|
|||
|
|
│ ☑ order_no (수주번호) │
|
|||
|
|
│ ☑ customer_code (거래처) → entity │
|
|||
|
|
│ ☑ order_date (수주일) → date │
|
|||
|
|
│ ☑ quantity (수량) → number │
|
|||
|
|
│ ☐ created_by (생성자) [숨김 추천] │
|
|||
|
|
│ ☐ updated_at (수정일) [숨김 추천] │
|
|||
|
|
│ │
|
|||
|
|
│ [생성하기] │
|
|||
|
|
└─────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**생성 결과** (목록형 선택 시):
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
자동 생성되는 컴포넌트:
|
|||
|
|
1. Search 컴포넌트 (검색바)
|
|||
|
|
2. Action 컴포넌트 그룹 (등록/수정/삭제 버튼)
|
|||
|
|
3. DataView 컴포넌트 (테이블 뷰, 선택한 컬럼 포함)
|
|||
|
|
4. Modal 컴포넌트 (등록/수정용 폼 모달, Field 자동 구성)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7. 마이그레이션 전략
|
|||
|
|
|
|||
|
|
### 7.1 기존 레이아웃 호환
|
|||
|
|
|
|||
|
|
기존 1,407개 레이아웃(version: "2.0")은 유지하면서 새 시스템 도입:
|
|||
|
|
|
|||
|
|
```typescript
|
|||
|
|
// 레이아웃 로드 시 자동 변환
|
|||
|
|
function loadLayout(data: LayoutData): LayoutData {
|
|||
|
|
if (data.version === "2.0") {
|
|||
|
|
// 기존 컴포넌트 → 메타 컴포넌트 매핑
|
|||
|
|
return migrateTo3_0(data);
|
|||
|
|
}
|
|||
|
|
return data;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function migrateTo3_0(data: LayoutData): LayoutData {
|
|||
|
|
const newComponents = data.components.map(comp => {
|
|||
|
|
// text-input, number-input, date-input 등 → Field
|
|||
|
|
if (isInputComponent(comp.componentType)) {
|
|||
|
|
return convertToField(comp);
|
|||
|
|
}
|
|||
|
|
// table-list, v2-table-list 등 → DataView
|
|||
|
|
if (isDataComponent(comp.componentType)) {
|
|||
|
|
return convertToDataView(comp);
|
|||
|
|
}
|
|||
|
|
// button-primary → Action
|
|||
|
|
if (isButtonComponent(comp.componentType)) {
|
|||
|
|
return convertToAction(comp);
|
|||
|
|
}
|
|||
|
|
return comp; // 변환 불가 시 기존 유지
|
|||
|
|
});
|
|||
|
|
|
|||
|
|
return { ...data, version: "3.0", components: newComponents };
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 7.2 단계적 전환 계획
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Phase A: 메타 컴포넌트 코어 개발 (3~4주)
|
|||
|
|
- Field, DataView, Action 핵심 3개 먼저
|
|||
|
|
- 통합 설정 패널 (UnifiedConfigPanel)
|
|||
|
|
- Reactive Bindings 엔진
|
|||
|
|
|
|||
|
|
Phase B: 자동 생성 시스템 (2~3주)
|
|||
|
|
- 테이블 드롭 → 화면 자동 생성
|
|||
|
|
- 컬럼 webType → Field 자동 변환
|
|||
|
|
- FK 관계 → 연동 자동 설정
|
|||
|
|
|
|||
|
|
Phase C: 나머지 메타 컴포넌트 (2~3주)
|
|||
|
|
- Layout, Display, Search, Modal
|
|||
|
|
- 뷰 모드 전환 (테이블↔카드↔트리)
|
|||
|
|
|
|||
|
|
Phase D: 마이그레이션 & 정리 (2주)
|
|||
|
|
- 기존 레이아웃 자동 변환
|
|||
|
|
- 레거시 컴포넌트 정리
|
|||
|
|
- 사용자 가이드 작성
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 7.3 공존 기간
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
[현재] → [Phase A~C] → [Phase D] → [완료]
|
|||
|
|
70개 위젯 70개 위젯 70개 위젯 7개 메타
|
|||
|
|
+ 7개 메타 + 7개 메타 (기본) (기존 호환 유지)
|
|||
|
|
(선택적 사용) (기존은 마이그레이션)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8. 기존 컴포넌트 → 메타 컴포넌트 매핑표
|
|||
|
|
|
|||
|
|
### 8.1 Field로 통합 (18개 → 1개)
|
|||
|
|
|
|||
|
|
| 기존 컴포넌트 | webType 매핑 | 비고 |
|
|||
|
|
|---------------|-------------|------|
|
|||
|
|
| text-input | text | |
|
|||
|
|
| number-input | number | |
|
|||
|
|
| date-input | date | |
|
|||
|
|
| select-basic | select | options 자동 감지 |
|
|||
|
|
| checkbox-basic | checkbox | |
|
|||
|
|
| radio-basic | radio | |
|
|||
|
|
| textarea-basic | textarea | |
|
|||
|
|
| file-upload | file | |
|
|||
|
|
| entity-search-input | entity | join 자동 감지 |
|
|||
|
|
| autocomplete-search-input | entity | searchable: true |
|
|||
|
|
| slider-basic | slider | |
|
|||
|
|
| toggle-switch | toggle | |
|
|||
|
|
| numbering-rule | numbering | autoGeneration 설정 |
|
|||
|
|
| image-widget | file | accept: "image/*" |
|
|||
|
|
| v2-input | text/number/email/tel/url | inputType에 따라 |
|
|||
|
|
| v2-select | select | |
|
|||
|
|
| v2-date | date/datetime | |
|
|||
|
|
| v2-file-upload | file | |
|
|||
|
|
|
|||
|
|
### 8.2 DataView로 통합 (14개 → 1개)
|
|||
|
|
|
|||
|
|
| 기존 컴포넌트 | viewMode 매핑 | 비고 |
|
|||
|
|
|---------------|-------------|------|
|
|||
|
|
| table-list | table | |
|
|||
|
|
| v2-table-list | table | |
|
|||
|
|
| v2-table-grouped | table | groupBy 설정 |
|
|||
|
|
| v2-repeater | table | editableColumns 설정 |
|
|||
|
|
| simple-repeater-table | table | inline edit |
|
|||
|
|
| modal-repeater-table | table + modal | |
|
|||
|
|
| card-display | card | |
|
|||
|
|
| v2-card-display | card | |
|
|||
|
|
| pivot-grid | pivot | |
|
|||
|
|
| v2-pivot-grid | pivot | |
|
|||
|
|
| v2-bom-tree | tree | |
|
|||
|
|
| aggregation-widget | table | summaryColumns 설정 |
|
|||
|
|
| v2-aggregation-widget | table | summaryColumns 설정 |
|
|||
|
|
| v2-timeline-scheduler | timeline | |
|
|||
|
|
|
|||
|
|
### 8.3 Action으로 통합 (4개 → 1개)
|
|||
|
|
|
|||
|
|
| 기존 컴포넌트 | 비고 |
|
|||
|
|
|---------------|------|
|
|||
|
|
| button-primary | steps 설정 |
|
|||
|
|
| v2-button-primary | steps 설정 |
|
|||
|
|
| flow-widget | flowMove step |
|
|||
|
|
| related-data-buttons | navigate step |
|
|||
|
|
|
|||
|
|
### 8.4 Layout으로 통합 (12개 → 1개)
|
|||
|
|
|
|||
|
|
| 기존 컴포넌트 | mode 매핑 |
|
|||
|
|
|---------------|-----------|
|
|||
|
|
| split-panel-layout | columns |
|
|||
|
|
| v2-split-panel-layout | columns |
|
|||
|
|
| screen-split-panel | columns (화면 임베딩) |
|
|||
|
|
| tabs | tabs |
|
|||
|
|
| v2-tabs-widget | tabs |
|
|||
|
|
| section-card | card |
|
|||
|
|
| v2-section-card | card |
|
|||
|
|
| section-paper | card (variant) |
|
|||
|
|
| v2-section-paper | card (variant) |
|
|||
|
|
| conditional-container | conditional |
|
|||
|
|
| accordion-basic | accordion |
|
|||
|
|
| repeat-container | rows (반복) |
|
|||
|
|
| v2-repeat-container | rows (반복) |
|
|||
|
|
|
|||
|
|
### 8.5 Display로 통합 (12개 → 1개)
|
|||
|
|
|
|||
|
|
| 기존 컴포넌트 | displayType 매핑 |
|
|||
|
|
|---------------|-----------------|
|
|||
|
|
| text-display | text |
|
|||
|
|
| v2-text-display | text |
|
|||
|
|
| divider-line | divider |
|
|||
|
|
| v2-divider-line | divider |
|
|||
|
|
| v2-split-line | divider |
|
|||
|
|
| badge | badge |
|
|||
|
|
| alert | alert |
|
|||
|
|
| stats-card | stat |
|
|||
|
|
| chart | chart |
|
|||
|
|
| image-display | image |
|
|||
|
|
| progress-bar | progress |
|
|||
|
|
| v2-media | image |
|
|||
|
|
|
|||
|
|
### 8.6 특수 컴포넌트 (별도 유지 또는 DataView 확장)
|
|||
|
|
|
|||
|
|
| 기존 컴포넌트 | 처리 방안 |
|
|||
|
|
|---------------|-----------|
|
|||
|
|
| v2-bom-item-editor | DataView(tree) + inline edit |
|
|||
|
|
| rack-structure | 별도 유지 (특수 시각화) |
|
|||
|
|
| v2-rack-structure | 별도 유지 |
|
|||
|
|
| v2-location-swap-selector | 별도 유지 (특수 UI) |
|
|||
|
|
| location-swap-selector | 별도 유지 |
|
|||
|
|
| map | 별도 유지 (지도) |
|
|||
|
|
| category-manager | DataView(tree) + Action 조합 |
|
|||
|
|
| v2-category-manager | DataView(tree) + Action 조합 |
|
|||
|
|
| customer-item-mapping | DataView + Search 조합 |
|
|||
|
|
| tax-invoice-list | DataView + Action + Modal 조합 |
|
|||
|
|
| mail-recipient-selector | 별도 유지 (특수 UI) |
|
|||
|
|
| v2-process-work-standard | DataView + Modal 조합 |
|
|||
|
|
| v2-item-routing | DataView(tree) + Action 조합 |
|
|||
|
|
| repeater-field-group | Layout(rows) + Field 조합 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 9. 기술 스택 결정 사항
|
|||
|
|
|
|||
|
|
| 영역 | 선택 | 이유 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| 상태 관리 | Zustand | 경량, 보일러플레이트 적음, React에 최적화 |
|
|||
|
|
| DnD | @dnd-kit | 터치 지원, 커스텀 오버레이, 접근성 |
|
|||
|
|
| 연동 엔진 | 자체 구현 (EventBus 확장) | 기존 EventBus 활용, 프로젝트 특화 |
|
|||
|
|
| 설정 UI | Schema-driven form | configSchema 기반 자동 폼 생성 |
|
|||
|
|
| 캔버스 | CSS Grid + 절대 좌표 하이브리드 | 기존 호환 + 반응형 전환 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 10. 성공 지표
|
|||
|
|
|
|||
|
|
| 지표 | 현재 | 목표 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| 새 화면 만드는 시간 (현업) | 불가능 (개발자 필요) | 5~10분 |
|
|||
|
|
| 새 화면 만드는 시간 (개발자) | 15~30분 | 2~5분 |
|
|||
|
|
| 새 위젯 타입 추가 시 개발 공수 | 1~3일 (5~8파일) | 대부분 설정으로 해결, 특수한 경우만 개발 |
|
|||
|
|
| 컴포넌트 패널 항목 수 | 70개+ (혼란) | 7개 메타 + 테이블 컬럼 |
|
|||
|
|
| ConfigPanel 파일 수 | 26개 | 1개 (UnifiedConfigPanel) |
|
|||
|
|
| 컴포넌트 간 연동 설정 | 코드 필요 | UI로 클릭 설정 |
|
|||
|
|
| ScreenDesigner.tsx 줄 수 | 7,593줄 | 1,500줄 이하 (훅 분리) |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 11. 위험 요소
|
|||
|
|
|
|||
|
|
| 위험 | 영향 | 완화 방안 |
|
|||
|
|
|------|------|-----------|
|
|||
|
|
| 기존 1,407개 레이아웃 마이그레이션 실패 | 운영 중단 | 자동 변환 + 수동 검증 + 롤백 가능 |
|
|||
|
|
| 메타 컴포넌트가 모든 케이스를 커버 못 함 | 특수 기능 불가 | 특수 컴포넌트 별도 유지 (8.6 참고) |
|
|||
|
|
| 통합 설정 패널이 오히려 복잡해질 수 있음 | UX 저하 | 간편/상세/개발자 3단계 모드 분리 |
|
|||
|
|
| Reactive Bindings 디버깅 어려움 | 유지보수 | 연동 시각화 패널 + 로그 제공 |
|
|||
|
|
| 개발 기간 장기화 | 일정 지연 | Phase별 독립 배포 가능하게 설계 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 12. 결론
|
|||
|
|
|
|||
|
|
**현재 시스템의 본질적 한계**: 기능 = 컴포넌트. 기능이 늘면 컴포넌트가 늘고, 코드가 늘고, 복잡도가 늘어남.
|
|||
|
|
|
|||
|
|
**새로운 방향**: 7개의 메타 컴포넌트(Field, DataView, Action, Layout, Display, Search, Modal)로 통합하고, 컴포넌트 간 Reactive Bindings로 동적 연동을 지원.
|
|||
|
|
|
|||
|
|
**사용자가 얻는 것**: 테이블 드롭 한 번으로 기본 화면 완성, 설정 몇 번으로 업무에 맞게 커스터마이징, 개발자 없이 화면 변경 가능.
|
|||
|
|
|
|||
|
|
**개발팀이 얻는 것**: 새 기능 요청 시 코드 작성 대신 설정 가이드 제공, ConfigPanel 26개 → 1개로 유지보수 대폭 감소, 7,593줄 거대 파일 분리.
|
|||
|
|
|
|||
|
|
전체 예상 기간: **9~12주** (Phase A~D)
|