530 lines
15 KiB
Markdown
530 lines
15 KiB
Markdown
|
|
# POP 화면 시스템 아키텍처
|
||
|
|
|
||
|
|
**최종 업데이트: 2026-02-04**
|
||
|
|
|
||
|
|
POP(Point of Production) 화면은 모바일/태블릿 환경에 최적화된 터치 기반 화면 시스템입니다.
|
||
|
|
이 문서는 POP 화면 구현에 관련된 모든 파일과 그 역할을 정리합니다.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 목차
|
||
|
|
|
||
|
|
1. [폴더 구조 개요](#1-폴더-구조-개요)
|
||
|
|
2. [App 라우팅 (app/(pop))](#2-app-라우팅-apppop)
|
||
|
|
3. [컴포넌트 (components/pop)](#3-컴포넌트-componentspop)
|
||
|
|
4. [라이브러리 (lib)](#4-라이브러리-lib)
|
||
|
|
5. [버전별 레이아웃 시스템](#5-버전별-레이아웃-시스템)
|
||
|
|
6. [데이터 흐름](#6-데이터-흐름)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 1. 폴더 구조 개요
|
||
|
|
|
||
|
|
```
|
||
|
|
frontend/
|
||
|
|
├── app/(pop)/ # Next.js App Router - POP 라우팅
|
||
|
|
│ ├── layout.tsx # POP 전용 레이아웃
|
||
|
|
│ └── pop/
|
||
|
|
│ ├── page.tsx # POP 대시보드 (메인)
|
||
|
|
│ ├── screens/[screenId]/ # 개별 POP 화면 뷰어
|
||
|
|
│ ├── test-v4/ # v4 렌더러 테스트 페이지
|
||
|
|
│ └── work/ # 작업 화면
|
||
|
|
│
|
||
|
|
├── components/pop/ # POP 컴포넌트 라이브러리
|
||
|
|
│ ├── designer/ # 디자이너 모듈
|
||
|
|
│ │ ├── panels/ # 편집 패널 (좌측/우측)
|
||
|
|
│ │ ├── renderers/ # 레이아웃 렌더러
|
||
|
|
│ │ └── types/ # 타입 정의
|
||
|
|
│ ├── management/ # 화면 관리 모듈
|
||
|
|
│ └── dashboard/ # 대시보드 모듈
|
||
|
|
│
|
||
|
|
└── lib/
|
||
|
|
├── api/popScreenGroup.ts # POP 화면 그룹 API
|
||
|
|
├── registry/PopComponentRegistry.ts # 컴포넌트 레지스트리
|
||
|
|
└── schemas/popComponentConfig.ts # 컴포넌트 설정 스키마
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 2. App 라우팅 (app/(pop))
|
||
|
|
|
||
|
|
### `app/(pop)/layout.tsx`
|
||
|
|
|
||
|
|
POP 전용 레이아웃. 데스크톱 레이아웃과 분리되어 터치 최적화 환경 제공.
|
||
|
|
|
||
|
|
### `app/(pop)/pop/page.tsx`
|
||
|
|
|
||
|
|
**경로**: `/pop`
|
||
|
|
|
||
|
|
POP 메인 대시보드. 메뉴 그리드, KPI, 공지사항 등을 표시.
|
||
|
|
|
||
|
|
### `app/(pop)/pop/screens/[screenId]/page.tsx`
|
||
|
|
|
||
|
|
**경로**: `/pop/screens/:screenId`
|
||
|
|
|
||
|
|
**역할**: 개별 POP 화면 뷰어 (디자인 모드 X, 실행 모드)
|
||
|
|
|
||
|
|
**핵심 기능**:
|
||
|
|
- v3/v4 레이아웃 자동 감지 및 렌더링
|
||
|
|
- 반응형 모드 감지 (태블릿/모바일, 가로/세로)
|
||
|
|
- 프리뷰 모드 지원 (`?preview=true`)
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// 레이아웃 버전 감지 및 렌더링
|
||
|
|
if (popLayoutV4) {
|
||
|
|
// v4: PopFlexRenderer 사용
|
||
|
|
<PopFlexRenderer layout={popLayoutV4} viewportWidth={...} />
|
||
|
|
} else if (popLayoutV3) {
|
||
|
|
// v3: PopLayoutRenderer 사용
|
||
|
|
<PopLayoutV3Renderer layout={popLayoutV3} modeKey={currentModeKey} />
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### `app/(pop)/pop/test-v4/page.tsx`
|
||
|
|
|
||
|
|
**경로**: `/pop/test-v4`
|
||
|
|
|
||
|
|
**역할**: v4 레이아웃 시스템 테스트 페이지
|
||
|
|
|
||
|
|
**구성**:
|
||
|
|
- 왼쪽: 컴포넌트 팔레트 (PopPanel)
|
||
|
|
- 중앙: v4 캔버스 (PopCanvasV4)
|
||
|
|
- 오른쪽: 속성 패널 (ComponentEditorPanelV4)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 3. 컴포넌트 (components/pop)
|
||
|
|
|
||
|
|
### 3.1 디자이너 모듈 (`designer/`)
|
||
|
|
|
||
|
|
#### `PopDesigner.tsx`
|
||
|
|
|
||
|
|
**역할**: POP 화면 디자이너 메인 컴포넌트
|
||
|
|
|
||
|
|
**핵심 기능**:
|
||
|
|
- v3/v4 모드 전환 (상단 탭)
|
||
|
|
- 레이아웃 로드/저장
|
||
|
|
- 컴포넌트 추가/삭제/수정
|
||
|
|
- 드래그 앤 드롭 (react-dnd)
|
||
|
|
|
||
|
|
**상태 관리**:
|
||
|
|
```typescript
|
||
|
|
const [layoutMode, setLayoutMode] = useState<"v3" | "v4">("v3");
|
||
|
|
const [layoutV3, setLayoutV3] = useState<PopLayoutDataV3>(...);
|
||
|
|
const [layoutV4, setLayoutV4] = useState<PopLayoutDataV4>(...);
|
||
|
|
const [selectedComponentId, setSelectedComponentId] = useState<string | null>(null);
|
||
|
|
```
|
||
|
|
|
||
|
|
**레이아웃**:
|
||
|
|
```
|
||
|
|
┌─────────────────────────────────────────────────┐
|
||
|
|
│ 툴바 (뒤로가기, 화면명, 모드전환, 저장) │
|
||
|
|
├──────────┬──────────────────────────┬──────────┤
|
||
|
|
│ 왼쪽 │ 중앙 캔버스 │ 오른쪽 │
|
||
|
|
│ 패널 │ │ 패널 │
|
||
|
|
│ (20%) │ (60%) │ (20%) │
|
||
|
|
│ │ │ (v4만) │
|
||
|
|
└──────────┴──────────────────────────┴──────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
#### `PopCanvas.tsx` (v3용)
|
||
|
|
|
||
|
|
**역할**: v3 레이아웃용 CSS Grid 기반 캔버스
|
||
|
|
|
||
|
|
**핵심 기능**:
|
||
|
|
- 4개 모드 전환 (태블릿 가로/세로, 모바일 가로/세로)
|
||
|
|
- 그리드 기반 컴포넌트 배치
|
||
|
|
- 드래그로 위치/크기 조정
|
||
|
|
|
||
|
|
#### `PopCanvasV4.tsx` (v4용)
|
||
|
|
|
||
|
|
**역할**: v4 레이아웃용 Flexbox 기반 캔버스
|
||
|
|
|
||
|
|
**핵심 기능**:
|
||
|
|
- 단일 캔버스 + 뷰포트 프리뷰
|
||
|
|
- 3가지 프리셋 (모바일 375px, 태블릿 768px, 데스크톱 1024px)
|
||
|
|
- 너비 슬라이더로 반응형 테스트
|
||
|
|
- 줌 컨트롤 (30%~150%)
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
const VIEWPORT_PRESETS = [
|
||
|
|
{ id: "mobile", label: "모바일", width: 375, height: 667 },
|
||
|
|
{ id: "tablet", label: "태블릿", width: 768, height: 1024 },
|
||
|
|
{ id: "desktop", label: "데스크톱", width: 1024, height: 768 },
|
||
|
|
];
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3.2 패널 모듈 (`designer/panels/`)
|
||
|
|
|
||
|
|
#### `PopPanel.tsx`
|
||
|
|
|
||
|
|
**역할**: 왼쪽 패널 - 컴포넌트 팔레트 & 편집 탭
|
||
|
|
|
||
|
|
**탭 구성**:
|
||
|
|
1. **컴포넌트 탭**: 드래그 가능한 6개 컴포넌트
|
||
|
|
2. **편집 탭**: 선택된 컴포넌트 설정
|
||
|
|
|
||
|
|
**컴포넌트 팔레트**:
|
||
|
|
```typescript
|
||
|
|
const COMPONENT_PALETTE = [
|
||
|
|
{ type: "pop-field", label: "필드", description: "텍스트, 숫자 등 데이터 입력" },
|
||
|
|
{ type: "pop-button", label: "버튼", description: "저장, 삭제 등 액션 실행" },
|
||
|
|
{ type: "pop-list", label: "리스트", description: "데이터 목록" },
|
||
|
|
{ type: "pop-indicator", label: "인디케이터", description: "KPI, 상태 표시" },
|
||
|
|
{ type: "pop-scanner", label: "스캐너", description: "바코드/QR 스캔" },
|
||
|
|
{ type: "pop-numpad", label: "숫자패드", description: "숫자 입력 전용" },
|
||
|
|
];
|
||
|
|
```
|
||
|
|
|
||
|
|
**드래그 아이템 타입**:
|
||
|
|
```typescript
|
||
|
|
export const DND_ITEM_TYPES = { COMPONENT: "component" };
|
||
|
|
export interface DragItemComponent {
|
||
|
|
type: typeof DND_ITEM_TYPES.COMPONENT;
|
||
|
|
componentType: PopComponentType;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### `ComponentEditorPanelV4.tsx`
|
||
|
|
|
||
|
|
**역할**: v4 오른쪽 패널 - 컴포넌트/컨테이너 속성 편집
|
||
|
|
|
||
|
|
**3개 탭**:
|
||
|
|
1. **크기 탭**: 너비/높이 제약 (fixed/fill/hug)
|
||
|
|
2. **설정 탭**: 라벨, 타입별 설정
|
||
|
|
3. **데이터 탭**: 데이터 바인딩 (미구현)
|
||
|
|
|
||
|
|
**크기 제약 편집**:
|
||
|
|
```typescript
|
||
|
|
// 너비/높이 모드
|
||
|
|
type SizeMode = "fixed" | "fill" | "hug";
|
||
|
|
|
||
|
|
// fixed: 고정 px 값
|
||
|
|
// fill: 남은 공간 채움 (flex: 1)
|
||
|
|
// hug: 내용에 맞춤 (width: auto)
|
||
|
|
```
|
||
|
|
|
||
|
|
**컨테이너 설정**:
|
||
|
|
- 방향 (horizontal/vertical)
|
||
|
|
- 줄바꿈 (wrap)
|
||
|
|
- 간격 (gap)
|
||
|
|
- 패딩 (padding)
|
||
|
|
- 정렬 (alignItems, justifyContent)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3.3 렌더러 모듈 (`designer/renderers/`)
|
||
|
|
|
||
|
|
#### `PopLayoutRenderer.tsx` (v3용)
|
||
|
|
|
||
|
|
**역할**: v3 레이아웃을 CSS Grid로 렌더링
|
||
|
|
|
||
|
|
**입력**:
|
||
|
|
- `layout`: PopLayoutDataV3
|
||
|
|
- `modeKey`: 현재 모드 (tablet_landscape 등)
|
||
|
|
- `isDesignMode`: 디자인 모드 여부
|
||
|
|
|
||
|
|
#### `PopFlexRenderer.tsx` (v4용)
|
||
|
|
|
||
|
|
**역할**: v4 레이아웃을 Flexbox로 렌더링
|
||
|
|
|
||
|
|
**핵심 기능**:
|
||
|
|
- 컨테이너 재귀 렌더링
|
||
|
|
- 반응형 규칙 적용 (breakpoint)
|
||
|
|
- 크기 제약 → CSS 스타일 변환
|
||
|
|
- 컴포넌트 숨김 처리 (hideBelow)
|
||
|
|
|
||
|
|
**크기 제약 변환 로직**:
|
||
|
|
```typescript
|
||
|
|
function calculateSizeStyle(size: PopSizeConstraintV4): React.CSSProperties {
|
||
|
|
const style: React.CSSProperties = {};
|
||
|
|
|
||
|
|
// 너비
|
||
|
|
switch (size.width) {
|
||
|
|
case "fixed": style.width = `${size.fixedWidth}px`; style.flexShrink = 0; break;
|
||
|
|
case "fill": style.flex = 1; style.minWidth = size.minWidth || 0; break;
|
||
|
|
case "hug": style.width = "auto"; style.flexShrink = 0; break;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 높이
|
||
|
|
switch (size.height) {
|
||
|
|
case "fixed": style.height = `${size.fixedHeight}px`; break;
|
||
|
|
case "fill": style.flexGrow = 1; break;
|
||
|
|
case "hug": style.height = "auto"; break;
|
||
|
|
}
|
||
|
|
|
||
|
|
return style;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### `ComponentRenderer.tsx`
|
||
|
|
|
||
|
|
**역할**: 개별 컴포넌트 렌더링 (디자인 모드용 플레이스홀더)
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3.4 타입 정의 (`designer/types/`)
|
||
|
|
|
||
|
|
#### `pop-layout.ts`
|
||
|
|
|
||
|
|
**역할**: POP 레이아웃 전체 타입 시스템 정의
|
||
|
|
|
||
|
|
**파일 크기**: 1442줄 (v1~v4 모든 버전 포함)
|
||
|
|
|
||
|
|
상세 내용은 [버전별 레이아웃 시스템](#5-버전별-레이아웃-시스템) 참조.
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3.5 관리 모듈 (`management/`)
|
||
|
|
|
||
|
|
#### `PopCategoryTree.tsx`
|
||
|
|
|
||
|
|
POP 화면 카테고리 트리 컴포넌트
|
||
|
|
|
||
|
|
#### `PopScreenSettingModal.tsx`
|
||
|
|
|
||
|
|
POP 화면 설정 모달
|
||
|
|
|
||
|
|
#### `PopScreenPreview.tsx`
|
||
|
|
|
||
|
|
POP 화면 미리보기
|
||
|
|
|
||
|
|
#### `PopScreenFlowView.tsx`
|
||
|
|
|
||
|
|
화면 간 플로우 시각화
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
### 3.6 대시보드 모듈 (`dashboard/`)
|
||
|
|
|
||
|
|
| 파일 | 역할 |
|
||
|
|
|------|------|
|
||
|
|
| `PopDashboard.tsx` | 대시보드 메인 컴포넌트 |
|
||
|
|
| `DashboardHeader.tsx` | 상단 헤더 (로고, 시간, 사용자) |
|
||
|
|
| `DashboardFooter.tsx` | 하단 푸터 |
|
||
|
|
| `MenuGrid.tsx` | 메뉴 그리드 (앱 아이콘 형태) |
|
||
|
|
| `KpiBar.tsx` | KPI 요약 바 |
|
||
|
|
| `NoticeBanner.tsx` | 공지 배너 |
|
||
|
|
| `NoticeList.tsx` | 공지 목록 |
|
||
|
|
| `ActivityList.tsx` | 최근 활동 목록 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 4. 라이브러리 (lib)
|
||
|
|
|
||
|
|
### `lib/api/popScreenGroup.ts`
|
||
|
|
|
||
|
|
**역할**: POP 화면 그룹 API 클라이언트
|
||
|
|
|
||
|
|
**API 함수**:
|
||
|
|
```typescript
|
||
|
|
// 조회
|
||
|
|
getPopScreenGroups(searchTerm?: string): Promise<PopScreenGroup[]>
|
||
|
|
|
||
|
|
// 생성
|
||
|
|
createPopScreenGroup(data: CreatePopScreenGroupRequest): Promise<...>
|
||
|
|
|
||
|
|
// 수정
|
||
|
|
updatePopScreenGroup(id: number, data: UpdatePopScreenGroupRequest): Promise<...>
|
||
|
|
|
||
|
|
// 삭제
|
||
|
|
deletePopScreenGroup(id: number): Promise<...>
|
||
|
|
|
||
|
|
// 루트 그룹 확보
|
||
|
|
ensurePopRootGroup(): Promise<...>
|
||
|
|
```
|
||
|
|
|
||
|
|
**트리 변환 유틸리티**:
|
||
|
|
```typescript
|
||
|
|
// 플랫 리스트 → 트리 구조
|
||
|
|
buildPopGroupTree(groups: PopScreenGroup[]): PopScreenGroup[]
|
||
|
|
```
|
||
|
|
|
||
|
|
### `lib/registry/PopComponentRegistry.ts`
|
||
|
|
|
||
|
|
**역할**: POP 컴포넌트 중앙 레지스트리
|
||
|
|
|
||
|
|
**주요 메서드**:
|
||
|
|
```typescript
|
||
|
|
class PopComponentRegistry {
|
||
|
|
static registerComponent(definition: PopComponentDefinition): void
|
||
|
|
static unregisterComponent(id: string): void
|
||
|
|
static getComponent(id: string): PopComponentDefinition | undefined
|
||
|
|
static getComponentByUrl(url: string): PopComponentDefinition | undefined
|
||
|
|
static getAllComponents(): PopComponentDefinition[]
|
||
|
|
static getComponentsByCategory(category: PopComponentCategory): PopComponentDefinition[]
|
||
|
|
static getComponentsByDevice(device: "mobile" | "tablet"): PopComponentDefinition[]
|
||
|
|
static searchComponents(query: string): PopComponentDefinition[]
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**카테고리**:
|
||
|
|
```typescript
|
||
|
|
type PopComponentCategory =
|
||
|
|
| "display" // 데이터 표시 (카드, 리스트, 배지)
|
||
|
|
| "input" // 입력 (스캐너, 터치 입력)
|
||
|
|
| "action" // 액션 (버튼, 스와이프)
|
||
|
|
| "layout" // 레이아웃 (컨테이너, 그리드)
|
||
|
|
| "feedback"; // 피드백 (토스트, 로딩)
|
||
|
|
```
|
||
|
|
|
||
|
|
### `lib/schemas/popComponentConfig.ts`
|
||
|
|
|
||
|
|
**역할**: POP 컴포넌트 설정 스키마 (Zod 기반)
|
||
|
|
|
||
|
|
**제공 내용**:
|
||
|
|
- 컴포넌트별 기본값 (`popCardListDefaults`, `popTouchButtonDefaults` 등)
|
||
|
|
- 컴포넌트별 Zod 스키마 (`popCardListOverridesSchema` 등)
|
||
|
|
- URL → 기본값/스키마 조회 함수
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 5. 버전별 레이아웃 시스템
|
||
|
|
|
||
|
|
### v1.0 (deprecated)
|
||
|
|
|
||
|
|
- 단일 모드
|
||
|
|
- 섹션 중첩 구조
|
||
|
|
- CSS Grid
|
||
|
|
|
||
|
|
### v2.0 (deprecated)
|
||
|
|
|
||
|
|
- 4개 모드 (태블릿/모바일 x 가로/세로)
|
||
|
|
- 섹션 + 컴포넌트 분리
|
||
|
|
- CSS Grid
|
||
|
|
|
||
|
|
### v3.0 (현재 기본)
|
||
|
|
|
||
|
|
- 4개 모드
|
||
|
|
- **섹션 제거**, 컴포넌트 직접 배치
|
||
|
|
- CSS Grid
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface PopLayoutDataV3 {
|
||
|
|
version: "pop-3.0";
|
||
|
|
layouts: {
|
||
|
|
tablet_landscape: { componentPositions: Record<string, GridPosition> };
|
||
|
|
tablet_portrait: { componentPositions: Record<string, GridPosition> };
|
||
|
|
mobile_landscape: { componentPositions: Record<string, GridPosition> };
|
||
|
|
mobile_portrait: { componentPositions: Record<string, GridPosition> };
|
||
|
|
};
|
||
|
|
components: Record<string, PopComponentDefinition>;
|
||
|
|
dataFlow: PopDataFlow;
|
||
|
|
settings: PopGlobalSettings;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### v4.0 (신규, 권장)
|
||
|
|
|
||
|
|
- **단일 소스** (1번 설계 → 모든 화면 자동 적응)
|
||
|
|
- **제약 기반** (fixed/fill/hug)
|
||
|
|
- **Flexbox** 렌더링
|
||
|
|
- **반응형 규칙** (breakpoint)
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface PopLayoutDataV4 {
|
||
|
|
version: "pop-4.0";
|
||
|
|
root: PopContainerV4; // 루트 컨테이너 (스택)
|
||
|
|
components: Record<string, PopComponentDefinitionV4>;
|
||
|
|
dataFlow: PopDataFlow;
|
||
|
|
settings: PopGlobalSettingsV4;
|
||
|
|
}
|
||
|
|
|
||
|
|
interface PopContainerV4 {
|
||
|
|
id: string;
|
||
|
|
type: "stack";
|
||
|
|
direction: "horizontal" | "vertical";
|
||
|
|
wrap: boolean;
|
||
|
|
gap: number;
|
||
|
|
alignItems: "start" | "center" | "end" | "stretch";
|
||
|
|
justifyContent: "start" | "center" | "end" | "space-between";
|
||
|
|
padding?: number;
|
||
|
|
responsive?: PopResponsiveRuleV4[]; // 반응형 규칙
|
||
|
|
children: (string | PopContainerV4)[]; // 컴포넌트 ID 또는 중첩 컨테이너
|
||
|
|
}
|
||
|
|
|
||
|
|
interface PopSizeConstraintV4 {
|
||
|
|
width: "fixed" | "fill" | "hug";
|
||
|
|
height: "fixed" | "fill" | "hug";
|
||
|
|
fixedWidth?: number;
|
||
|
|
fixedHeight?: number;
|
||
|
|
minWidth?: number;
|
||
|
|
maxWidth?: number;
|
||
|
|
minHeight?: number;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 버전 비교표
|
||
|
|
|
||
|
|
| 항목 | v3 | v4 |
|
||
|
|
|------|----|----|
|
||
|
|
| 설계 횟수 | 4번 (모드별) | 1번 |
|
||
|
|
| 위치 지정 | col, row, colSpan, rowSpan | 제약 (fill/fixed/hug) |
|
||
|
|
| 렌더링 | CSS Grid | Flexbox |
|
||
|
|
| 반응형 | 수동 (모드 전환) | 자동 (breakpoint 규칙) |
|
||
|
|
| 복잡도 | 높음 | 낮음 |
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 6. 데이터 흐름
|
||
|
|
|
||
|
|
### 화면 로드 흐름
|
||
|
|
|
||
|
|
```
|
||
|
|
[사용자 접속]
|
||
|
|
↓
|
||
|
|
[/pop/screens/:screenId]
|
||
|
|
↓
|
||
|
|
[screenApi.getLayoutPop(screenId)]
|
||
|
|
↓
|
||
|
|
[레이아웃 버전 감지]
|
||
|
|
├── v4 → PopFlexRenderer
|
||
|
|
├── v3 → PopLayoutRenderer
|
||
|
|
└── v1/v2 → ensureV3Layout() → v3로 변환
|
||
|
|
```
|
||
|
|
|
||
|
|
### 디자이너 저장 흐름
|
||
|
|
|
||
|
|
```
|
||
|
|
[사용자 편집]
|
||
|
|
↓
|
||
|
|
[hasChanges = true]
|
||
|
|
↓
|
||
|
|
[저장 버튼 클릭]
|
||
|
|
↓
|
||
|
|
[screenApi.saveLayoutPop(screenId, layoutV3 | layoutV4)]
|
||
|
|
↓
|
||
|
|
[hasChanges = false]
|
||
|
|
```
|
||
|
|
|
||
|
|
### 컴포넌트 드래그 앤 드롭 흐름
|
||
|
|
|
||
|
|
```
|
||
|
|
[PopPanel의 컴포넌트 드래그]
|
||
|
|
↓
|
||
|
|
[DragItemComponent { type: "component", componentType: "pop-button" }]
|
||
|
|
↓
|
||
|
|
[캔버스 Drop 감지]
|
||
|
|
↓
|
||
|
|
[v3: handleDropComponentV3(type, gridPosition)]
|
||
|
|
[v4: handleDropComponentV4(type, containerId)]
|
||
|
|
↓
|
||
|
|
[레이아웃 상태 업데이트]
|
||
|
|
↓
|
||
|
|
[hasChanges = true]
|
||
|
|
```
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
## 관련 문서
|
||
|
|
|
||
|
|
- [PLAN.md](./PLAN.md) - 개발 계획 및 로드맵
|
||
|
|
- [components-spec.md](./components-spec.md) - 컴포넌트 상세 스펙
|
||
|
|
- [CHANGELOG.md](./CHANGELOG.md) - 변경 이력
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
*이 문서는 POP 화면 시스템의 구조를 이해하고 유지보수하기 위한 참조용으로 작성되었습니다.*
|