- InteractiveScreenViewer는 screenId가 아닌 component, allComponents를 받음 - screenApi.getLayout()과 getScreen()으로 화면 데이터 로드 - 로드된 컴포넌트들을 InteractiveScreenViewer로 렌더링 - 화면 로딩 상태 추가 - screenInfo 전달하여 테이블 컨텍스트 제공 |
||
|---|---|---|
| .. | ||
| ConditionalContainerComponent.tsx | ||
| ConditionalContainerConfigPanel.tsx | ||
| ConditionalContainerRenderer.tsx | ||
| ConditionalSectionViewer.tsx | ||
| README.md | ||
| index.ts | ||
| types.ts | ||
README.md
조건부 컨테이너 (ConditionalContainer) - 화면 선택 방식
제어 셀렉트박스 값에 따라 다른 화면을 표시하는 조건부 컨테이너 컴포넌트입니다.
📋 개요
화면 편집기에서 조건별로 표시할 화면을 선택하여 조건부 UI를 구성할 수 있는 컨테이너입니다. 상단의 셀렉트박스 값에 따라 하단에 미리 만들어진 화면을 표시합니다.
✨ 주요 기능
- ✅ 조건별 화면 전환: 셀렉트박스 값에 따라 다른 화면 표시
- ✅ 화면 재사용: 기존에 만든 화면을 조건별로 할당
- ✅ 간편한 구성: 복잡한 입력 폼도 화면 선택으로 간단히 구성
- ✅ 자동 동기화: 화면 수정 시 자동 반영
- ✅ 폼 데이터 연동: formData와 자동 동기화
- ✅ 커스터마이징: 테두리, 간격, 기본값 등 설정 가능
🎯 사용 사례
1. 입력 방식 선택
[셀렉트: 입력 방식]
├─ 거래처 우선: "거래처_우선_입력_화면" (화면 ID: 101)
├─ 견적서 기반: "견적서_업로드_화면" (화면 ID: 102)
└─ 단가 직접입력: "단가_직접입력_화면" (화면 ID: 103)
2. 판매 유형 선택
[셀렉트: 판매 유형]
├─ 국내 판매: "국내판매_기본폼" (화면 ID: 201)
└─ 해외 판매: "해외판매_무역정보폼" (화면 ID: 202)
3. 문서 유형 선택
[셀렉트: 문서 유형]
├─ 신규 작성: "신규문서_입력폼" (화면 ID: 301)
├─ 복사 생성: "문서복사_화면" (화면 ID: 302)
└─ 불러오기: "파일업로드_화면" (화면 ID: 303)
📐 구조
┌─────────────────────────────────┐
│ ConditionalContainer │
├─────────────────────────────────┤
│ [제어 셀렉트박스] │ ← controlField, controlLabel
├─────────────────────────────────┤
│ 📄 조건 1: "옵션 A" 선택 시 │ ← sections[0]
│ ┌─────────────────────────────┐│
│ │ [선택된 화면이 표시됨] ││ ← screenId로 지정된 화면
│ │ (화면 ID: 101) ││
│ │ ││
│ └─────────────────────────────┘│
├─────────────────────────────────┤
│ 📄 조건 2: "옵션 B" 선택 시 │ ← sections[1]
│ ┌─────────────────────────────┐│
│ │ [다른 화면이 표시됨] ││ ← screenId로 지정된 다른 화면
│ │ (화면 ID: 102) ││
│ └─────────────────────────────┘│
└─────────────────────────────────┘
🔧 설정 방법
1. 컴포넌트 추가
화면 편집기의 컴포넌트 패널에서 **"조건부 컨테이너"**를 드래그하여 캔버스에 배치합니다.
2. 설정 패널에서 구성
제어 필드 설정
- 제어 필드명: formData에 저장될 필드명 (예:
inputMode) - 셀렉트박스 라벨: 화면에 표시될 라벨 (예: "입력 방식")
조건별 섹션 추가
- "섹션 추가" 버튼 클릭
- 각 섹션 설정:
- 조건 값: 고유한 값 (예:
customer_first) - 표시 라벨: 사용자에게 보이는 텍스트 (예: "거래처 우선")
- 조건 값: 고유한 값 (예:
기본값 설정
- 처음 화면 로드 시 선택될 기본 조건 선택
스타일 설정
- 섹션 테두리 표시: ON/OFF
- 섹션 간격: 좁게 / 보통 / 넓게
3. 조건별 화면 선택
- 디자인 모드에서 모든 조건 섹션이 표시됩니다
- 각 섹션의 "표시할 화면" 드롭다운에서 화면을 선택합니다
- 선택된 화면 ID와 이름이 자동으로 저장됩니다
장점:
- ✅ 이미 만든 화면을 재사용
- ✅ 복잡한 입력 폼도 간단히 구성
- ✅ 화면 수정 시 자동 반영
4. 실행 모드 동작
- 셀렉트박스에서 조건 선택
- 선택된 조건의 화면이 표시됨
- 다른 조건의 화면은 자동으로 숨김
💻 기술 사양
Props
interface ConditionalContainerProps {
// 제어 필드
controlField: string; // 예: "inputMode"
controlLabel: string; // 예: "입력 방식"
// 조건별 섹션
sections: ConditionalSection[];
// 기본값
defaultValue?: string;
// 스타일
showBorder?: boolean; // 기본: true
spacing?: "tight" | "normal" | "loose"; // 기본: "normal"
// 폼 연동
formData?: Record<string, any>;
onFormDataChange?: (fieldName: string, value: any) => void;
}
interface ConditionalSection {
id: string; // 고유 ID
condition: string; // 조건 값
label: string; // 표시 라벨
screenId: number | null; // 표시할 화면 ID
screenName?: string; // 화면 이름 (표시용)
}
기본 설정
defaultSize: {
width: 800,
height: 600,
}
defaultConfig: {
controlField: "condition",
controlLabel: "조건 선택",
sections: [
{
id: "section_1",
condition: "option1",
label: "옵션 1",
screenId: null, // 화면 미선택 상태
},
{
id: "section_2",
condition: "option2",
label: "옵션 2",
screenId: null, // 화면 미선택 상태
},
],
defaultValue: "option1",
showBorder: true,
spacing: "normal",
}
🎨 디자인 모드 vs 실행 모드
디자인 모드 (편집기)
- ✅ 모든 조건 섹션 표시
- ✅ 각 섹션에 "조건: XXX" 라벨 표시
- ✅ 화면 선택 안내 메시지 (미선택 시)
- ✅ 선택된 화면 ID 표시
- ✅ 활성 조건 "(활성)" 표시
실행 모드 (할당된 화면)
- ✅ 선택된 조건의 화면만 표시
- ✅ 다른 조건의 화면 자동 숨김
- ✅ 깔끔한 UI (라벨, 점선 테두리 제거)
- ✅ 선택된 화면이 완전히 통합되어 표시
📊 폼 데이터 연동
자동 동기화
// formData 읽기
formData[controlField] // 현재 선택된 값
// formData 쓰기
onFormDataChange(controlField, newValue)
예시
// controlField = "salesType"
formData = {
salesType: "export", // ← 자동으로 여기에 저장됨
// ... 다른 필드들
}
// 셀렉트박스 값 변경 시 자동으로 formData 업데이트
🔍 주의사항
- 조건 값은 고유해야 함: 각 섹션의
condition값은 중복되면 안 됩니다 - 최소 1개 섹션 필요: 섹션이 없으면 안내 메시지 표시
- 컴포넌트 ID 충돌 방지: 각 섹션의 컴포넌트 ID는 전역적으로 고유해야 함
📝 예시: 수주 입력 방식 선택
{
controlField: "inputMode",
controlLabel: "입력 방식",
sections: [
{
id: "customer_first",
condition: "customer_first",
label: "거래처 우선",
components: [
// 거래처 검색 컴포넌트
// 품목 선택 테이블
// 저장 버튼
]
},
{
id: "quotation",
condition: "quotation",
label: "견적서 기반",
components: [
// 견적서 검색 컴포넌트
// 견적서 내용 표시
// 수주 전환 버튼
]
},
{
id: "unit_price",
condition: "unit_price",
label: "단가 직접입력",
components: [
// 품목 입력 테이블
// 단가 입력 필드들
// 계산 위젯
]
}
],
defaultValue: "customer_first",
showBorder: true,
spacing: "normal"
}
🚀 로드맵
- 다중 제어 필드 지원 (AND/OR 조건)
- 섹션 전환 애니메이션
- 조건별 검증 규칙
- 템플릿 저장/불러오기
🐛 트러블슈팅
Q: 섹션이 전환되지 않아요
A: controlField 값이 formData에 제대로 저장되고 있는지 확인하세요.
Q: 컴포넌트가 드롭되지 않아요
A: 디자인 모드인지 확인하고, 드롭존 영역에 정확히 드롭하세요.
Q: 다른 조건의 UI가 계속 보여요
A: 실행 모드로 전환했는지 확인하세요. 디자인 모드에서는 모든 조건이 표시됩니다.
📦 파일 구조
conditional-container/
├── types.ts # 타입 정의
├── ConditionalContainerComponent.tsx # 메인 컴포넌트
├── ConditionalSectionDropZone.tsx # 드롭존 컴포넌트
├── ConditionalContainerConfigPanel.tsx # 설정 패널
├── ConditionalContainerRenderer.tsx # 렌더러 및 등록
├── index.ts # 컴포넌트 정의
└── README.md # 이 파일
🎉 완료!
이제 화면 편집기에서 조건부 컨테이너를 사용하여 동적인 UI를 만들 수 있습니다! 🚀