67 KiB
POP 변경 이력
형식: Keep a Changelog
[미출시]
- Phase 0:
공통 인프라 구현 (useDataSource, usePopEvent)완료 - Phase 2: pop-button, pop-icon 구현
- Phase 3: pop-table 구현
- Phase 4: pop-search, pop-field, pop-lookup 구현
- Phase 5: pop-table 카드 템플릿, 차트, 게이지
- Phase 6: pop-system 구현
- 워크플로우 연동
[2026-02-11] Phase 0 공통 인프라: usePopEvent + useDataSource 훅 구현
배경
모든 데이터 연동 POP 컴포넌트(pop-button, pop-table, pop-search 등)가 공유하는 2개 핵심 훅을 구현.
기존 대시보드 dataFetcher.ts의 조회 로직과 dataApi CRUD를 공통 훅으로 래핑하는 작업.
Added
-
usePopEvent훅 (frontend/hooks/pop/usePopEvent.ts)- screenId 기반 이벤트 버스 (publish/subscribe/sharedData)
- 전역 Map 2개 (screenBuses, sharedDataStore) - 모듈 스코프, SSR 가드
cleanupScreen(screenId)유틸 (화면 언마운트 시 메모리 정리)
-
popSqlBuilder유틸 (frontend/hooks/pop/popSqlBuilder.ts)dataFetcher.ts에서 SQL 빌더 로직 5개 함수 추출 (로직 변경 없이 복사)escapeSQL,sanitizeIdentifier,validateDataSourceConfig,buildWhereClause,buildAggregationSQL
-
useDataSource훅 (frontend/hooks/pop/useDataSource.ts)- DataSourceConfig 기반 DB 테이블 CRUD 통합
- 조회 분기: 집계/조인 → SQL 빌더 + executeQuery, 단순 → dataApi.getTableData
- CRUD: save/update/remove → dataApi 래핑
- 자동 새로고침 (refreshInterval, 최소 5초)
- refetch 필터 병합 (overrideFilters + config.filters)
-
배럴 파일 (
frontend/hooks/pop/index.ts)- usePopEvent, cleanupScreen, useDataSource, MutationResult, DataSourceResult, buildAggregationSQL, validateDataSourceConfig re-export
검수 결과
- 린트 에러: 0건
- 중복 정의: 0건 (20개 함수/타입 전수 Grep)
- 미사용 import: 0건
- 가상 시뮬레이션 8시나리오: 전부 정상
- 기존 대시보드
dataFetcher.ts: 미수정 (안정성 우선)
수정 파일
| 파일 | 변경 내용 |
|---|---|
frontend/hooks/pop/usePopEvent.ts |
신규 - 이벤트 버스 훅 (190줄) |
frontend/hooks/pop/popSqlBuilder.ts |
신규 - SQL 빌더 유틸 (195줄) |
frontend/hooks/pop/useDataSource.ts |
신규 - 데이터 CRUD 훅 (383줄) |
frontend/hooks/pop/index.ts |
신규 - 배럴 파일 (15줄) |
Git
| 브랜치 | 커밋 | 작업 |
|---|---|---|
ksh-button |
300542d9 |
feat(pop): usePopEvent, useDataSource 공통 훅 구현 |
ksh-v2-work |
fast-forward merge | ksh-button 병합 |
origin/ksh-v2-work |
push 완료 | 원격 동기화 |
[2026-02-11] 브랜치 병합: ksh-dashboard -> ksh-v2-work (pop-icon + pop-dashboard 통합)
배경
ksh-v2-work 브랜치에서 pop-icon 컴포넌트를, ksh-dashboard 브랜치에서 pop-dashboard 컴포넌트를 각각 독립 개발.
두 브랜치가 공통 확장 포인트(타입 정의, 팔레트, 렌더러, 에디터 패널)를 동시에 수정하여 병합 충돌 발생.
병합 통계
- 충돌 파일: 7개 / 17개 충돌 지점
- 해결 전략: 양쪽 기능 통합(union) 14건, ksh-dashboard 채택 2건, ksh-v2-work 채택 1건
- 의존성 순서 해결: pop-layout.ts -> index.ts -> pop-text.tsx -> ComponentPalette.tsx -> PopRenderer.tsx -> ComponentEditorPanel.tsx -> PopDesigner.tsx
Merged (양쪽 통합)
- PopComponentType:
"pop-icon" | "pop-dashboard"양쪽 타입 통합 (pop-layout.ts) - DEFAULT_COMPONENT_GRID_SIZE: pop-icon(1x2) + pop-dashboard(6x3) 기본 크기 추가
- COMPONENT_TYPE_LABELS: PopRenderer, ComponentEditorPanel 양쪽에 4개 항목 완비
- PALETTE_ITEMS: 아이콘(MousePointer) + 대시보드(BarChart3) 팔레트 항목 추가
- PopRendererProps:
currentScreenId(아이콘용) +previewPageIndex(대시보드용) props 통합 - ComponentEditorPanelProps:
previewPageIndex+onPreviewPageprops 통합 - 컴포넌트 등록:
./pop-icon+./pop-dashboardimport 통합 (index.ts) - lucide-react import:
MousePointer+BarChart3통합 (ComponentPalette.tsx) - ComponentContent 렌더링: pop-icon pointer-events 허용 + previewPageIndex 전달 통합
Adopted from ksh-dashboard
- pop-text isRealtime:
isRealtime조건부 interval로 변경 (불필요한 timer 방지) - handleUpdateComponent: 함수적
setLayout(prev => ...)업데이트 (stale closure 방지)
Adopted from ksh-v2-work
- ComponentEditorPanel CSS:
overflow-hidden,min-h-0,m-0방어적 CSS (스크롤 안정성)
검증 결과
- 충돌 마커 잔여: 0건
- TypeScript 에러 (병합 파일): 0건
- 프론트엔드 빌드: 성공
- 백엔드 빌드 에러: 0건 (기존 2건은 패키지 미설치)
- 린트 에러: 0건
[2026-02-11] 대시보드 스타일 정리 + 페이지 미리보기 + 차트 디자인 개선
배경
이전 작업에서 구현한 글자 크기 3그룹 커스텀이 @container 반응형 자동 크기와 충돌하여 정보 잘림 발생.
또한 handleUpdateComponent의 stale closure 버그로 빠른 연속 설정 변경 시 값 유실.
추가로 디자이너 캔버스에서 페이지별 미리보기 기능 부재.
Changed
-
글자 크기 커스텀 제거 (types.ts, KpiCard, StatCard, GaugeItem, ChartItem)
FONT_SIZE_PX상수 삭제ItemStyleConfig를{ labelAlign?: TextAlign }으로 단순화- 기존
@container반응형 자동 크기 복원 (text-xs @[250px]:text-sm등)
-
라벨 정렬 기능 (4개 아이템 + PopDashboardConfig.tsx)
TEXT_ALIGN_CLASSES[itemStyle?.labelAlign ?? "center"]로 라벨만 정렬- 값/보조 텍스트는 항상 가운데 정렬 고정
ItemStyleEditor컴포넌트에 접기/펼치기(Collapsible) 지원
-
페이지 미리보기 (PopDashboardComponent, PopDashboardConfig, PopDesigner, PopCanvas, PopRenderer, ComponentEditorPanel)
- 각 페이지 옆에 Eye 버튼 → 클릭 시 해당 페이지만 디자이너 캔버스에 렌더링
previewPageIndexprop 전달 체인: PopDesigner → PopCanvas → PopRenderer → ComponentContent → PopDashboardComponent- 스타일 변경 시 자동으로 해당 페이지 미리보기 활성화
-
차트 디자인 개선 (ChartItem.tsx)
CartesianGrid추가 (얇은 격자선)abbreviateNumber적용 (Y축 + 파이 라벨 + 툴팁)- X축 라벨 7자 이상 시 대각선 표시 (
angle: -45) - 긴 라벨 시 하단 여백 자동 확보
Fixed
-
stale closure 버그 (PopDesigner.tsx)
handleUpdateComponent에서layout직접 참조 →setLayout(prev => ...)함수적 업데이트- 의존성 배열에서
layout제거 →[saveToHistory]만 유지
-
불필요 코드 제거 (PopDashboardComponent.tsx)
setRenderTickstate +itemStyleKey변수 + 관련 useEffect 삭제
-
디버그 console.log 전량 제거 (8개)
- PopDashboardComponent(3), PopDesigner(3), ChartItem(1), PopDashboardConfig(1)
-
.next 빌드 캐시 꼬임 (Docker)
- Docker 익명 볼륨에 캐시된
.next가 호스트 삭제와 독립적인 문제 docker-compose down -v로 볼륨 포함 삭제 후--build재시작
- Docker 익명 볼륨에 캐시된
[2026-02-10] 디자이너 캔버스 UX 개선 (헤더 제거 + 실제 데이터 렌더링 + 컴포넌트 목록)
배경
디자이너 캔버스와 실제 뷰어 간의 시각적 차이 해소 요청:
- 디자이너에서 각 컴포넌트마다 5px 헤더 바가 표시되어 실제 뷰어와 다름
- 대시보드가 더미 아이콘(PreviewComponent)으로만 표시됨
- 헤더 제거 후 컴포넌트 식별 수단 필요
Changed
-
디자인모드 실제 데이터 렌더링 (PopRenderer.tsx)
- 헤더(5px) + 위치 정보 div 완전 삭제
PreviewComponent대신ActualComp(실제 컴포넌트)로 렌더링pointer-events-none으로 내부 클릭 차단 (그리드 선택은 정상 작동)
-
컴포넌트 목록 UI (ComponentEditorPanel.tsx)
- "위치" 탭에 "배치된 컴포넌트" 목록 추가 (Layers 아이콘 + 카운트)
- 목록에서 클릭하면 해당 컴포넌트 선택 (그리드 클릭과 동일 효과)
COMPONENT_TYPE_LABELS에pop-sample,pop-text,pop-dashboard키 추가
-
Props 연결 (PopDesigner.tsx)
allComponents,onSelectComponent,selectedComponentId3개 props 전달
Fixed
- 미사용 import 제거 (ComponentEditorPanel.tsx)
COMPONENT_TYPE_LABELS타입 변경 후PopComponentTypeimport 누락 정리
[2026-02-10] pop-dashboard 차트/게이지/UI 디자인 개선
배경 (왜 이 작업이 필요했는가)
문제 상황:
- 파이 차트(Chart 7)가 표시되지 않음 (fetch 기반 API 간헐 실패 + bigint 문자열 타입 문제)
- 파이 차트 슬라이스에 카테고리명/레전드 없어 의미 파악 불가
- 게이지 최소/최대/목표 값 변경이 적용되지 않음 (스프레드 연산자 순서 버그)
- 게이지가 가로 레이아웃에서 너무 작게 표시됨 (고정 max-width 제한)
- 좌우 버튼/인디케이터가 별도 영역 차지해서 콘텐츠 공간 부족 + 상하 마진 불균형
- KPI 카드/통계 카드만 왼쪽 정렬 (게이지/차트는 가운데)
- 차트 설정에서 "X축 컬럼"과 "그룹핑(X축)" 중복으로 혼동
Fixed
-
파이 차트 미표시 (dataFetcher.ts)
- fetch 기반 API가 iframe에서 간헐 실패 -> apiClient(axios) 우선 사용, fetch 폴백
- PostgreSQL bigint 반환값이 문자열("79") ->
Number()변환 추가
-
파이 차트 라벨 없음 (ChartItem.tsx)
Legend컴포넌트 추가,label커스텀 포맷 (name value (percent%))Tooltipformatter로 이름+값 표시
-
gaugeConfig 값 변경 안 됨 (PopDashboardConfig.tsx)
- 스프레드 연산자 순서 버그:
{ max: newValue, ...item.gaugeConfig }->{ ...item.gaugeConfig, max: newValue } - min/max/target 3개 모두 동일 패턴 수정
- 스프레드 연산자 순서 버그:
-
게이지 가로 레이아웃 비율 (GaugeItem.tsx)
max-w-[200px]고정 ->h-full w-auto max-w-full높이 기반 스케일링- SVG 래퍼를
flex-1 min-h-0으로 변경해 가용 높이 최대 활용
Changed
-
좌우 버튼/인디케이터 오버레이 (ArrowsMode.tsx, AutoSlideMode.tsx)
- 버튼:
px-12패딩 제거, 콘텐츠 위에 겹침 (absolute,bg-background/70 backdrop-blur-sm) - 인디케이터: 별도 영역 ->
absolute bottom-1로 콘텐츠 하단 오버레이 - 상하 마진 불균형 해소
- 버튼:
-
KPI/통계 카드 가운데 정렬 (KpiCard.tsx, StatCard.tsx)
- KPI:
items-center추가 - 통계:
items-center justify-center추가 - 4개 아이템 모드(KPI/Chart/Gauge/Stat) 정렬 통일
- KPI:
-
차트 X/Y축 입력 필드 제거 (PopDashboardConfig.tsx)
- "X축 컬럼"/"Y축 컬럼" 수동 입력 제거 (groupBy와 중복, 혼동 유발)
- "X축: 그룹핑(X축)에서 선택한 컬럼 자동 적용 / Y축: 집계 결과(value) 자동 적용" 안내 텍스트로 교체
수정 파일
| 파일 | 변경 내용 |
|---|---|
PopDashboardConfig.tsx |
gaugeConfig 스프레드 순서 수정, X/Y축 입력 제거 + 안내 텍스트 |
utils/dataFetcher.ts |
apiClient 우선 사용, bigint 문자열 -> 숫자 변환 |
items/ChartItem.tsx |
PieChart Legend/custom label 추가 |
items/GaugeItem.tsx |
SVG 스케일링 높이 기반 변경 |
items/KpiCard.tsx |
items-center 추가 |
items/StatCard.tsx |
items-center justify-center 추가 |
modes/ArrowsMode.tsx |
좌우 버튼 + 인디케이터 오버레이 |
modes/AutoSlideMode.tsx |
인디케이터 오버레이 |
[2026-02-10] pop-dashboard 아이템 모드 완성 + SQL 방어 로직 + 레이아웃/라벨 수정
배경 (왜 이 작업이 필요했는가)
문제 상황:
- 대시보드 아이템 4개 모드(KPI, Chart, Gauge, Stat Card)가 실제 데이터와 연동되어 동작하려면 설정 UI가 부족함
- Chart에 groupBy(X축) 설정 UI 없음, StatCard에 카테고리 편집 UI 없음
- 설정 폼 중간 상태(집계 유형만 선택, 컬럼 미선택)에서
SUM(),COUNT()같은 잘못된 SQL이 백엔드로 전송되어 장애 유발 - 2열 설정이 1열로 렌더링되고, 라벨/단위가 잘려서 안 보임
Added
-
groupBy(X축) 설정 Combobox (PopDashboardConfig.tsx)
- DataSourceEditor에 "그룹핑(X축)" Popover Combobox 추가
- 집계 활성화 시 표시, 차트 X축 카테고리 컬럼 선택
-
차트 xAxisColumn / yAxisColumn 입력 UI (PopDashboardConfig.tsx)
- Chart 아이템 전용 X축/Y축 컬럼 입력 필드
-
StatCard 카테고리 인라인 편집기 (PopDashboardConfig.tsx)
- 카테고리별 라벨, 필터 조건(컬럼/연산자/값), 색상 편집
- 카테고리 추가/삭제
-
validateDataSourceConfig()함수 (dataFetcher.ts)- 테이블/컬럼/조인 미완료 상태 검증
- 미완료 시 SQL 생성 차단, 에러 메시지 반환
Changed
-
Chart xAxisColumn 자동 보정 (PopDashboardComponent.tsx)
- groupBy 설정 있지만 xAxisColumn 미설정 시 첫 번째 groupBy 컬럼 자동 적용
-
StatCard 카테고리별 독립 데이터 필터링 (PopDashboardComponent.tsx)
- 전체 rows를 카테고리 filter 조건으로 각각 필터링하여 개별 건수 계산
-
useEffect 의존성 안정화 (PopDashboardComponent.tsx)
visibleItems배열 참조 ->visibleItemIdsJSON 문자열로 교체- 매 렌더마다 새 배열 참조 생성으로 인한 불필요한 재호출 방지
-
refreshInterval 최소 5초 강제 (PopDashboardComponent.tsx)
- 5초 미만 설정 시 5초로 강제
-
fetchTableColumns API 우선순위 (dataFetcher.ts)
- tableManagementApi(axios) 우선, dashboardApi(fetch) 폴백
-
buildWhereClause 빈 필터 무시 (dataFetcher.ts)
- 컬럼명이 빈 필터 조건 건너뜀 (설정 중간 상태 방어)
-
buildAggregationSQL COUNT(*) 처리 (dataFetcher.ts)
- COUNT는 컬럼 없이도 COUNT(*)로 처리, 불완전한 조인 건너뜀
Fixed
-
2열 설정이 1열로 렌더링 (GridMode.tsx)
- MIN_CELL_WIDTH 160px -> 80px
- 초기 containerWidth=300에서 (300-8)/2=146 < 160이라 1열로 축소되던 문제
-
라벨/단위 잘림 (KpiCard, GaugeItem, StatCard, ChartItem)
truncate클래스 제거 (text-overflow: ellipsis 비활성)hidden @[120px]:inline등 조건부 숨김 제거- 기본 폰트 크기 text-[10px] -> text-xs (12px)
- 내부 패딩 p-2 -> p-3 (여유 공간 확보)
-
백엔드 unhealthy 유발하는 잘못된 SQL (dataFetcher.ts)
- 설정 중간 상태에서
SUM(),COUNT()같은 빈 괄호 SQL 전송 차단 validateDataSourceConfig()으로 사전 검증
- 설정 중간 상태에서
수정 파일
| 파일 | 변경 내용 |
|---|---|
PopDashboardConfig.tsx |
groupBy Combobox, 차트 축 입력, 통계 카테고리 편집기 |
PopDashboardComponent.tsx |
차트 자동 보정, StatCard 필터링, useEffect 안정화, refreshInterval 최소값 |
utils/dataFetcher.ts |
validateDataSourceConfig, buildWhereClause/buildAggregationSQL 방어, fetchTableColumns API 우선순위 |
modes/GridMode.tsx |
MIN_CELL_WIDTH 160 -> 80 |
items/KpiCard.tsx |
truncate 제거, hidden 제거, 폰트/패딩 상향 |
items/GaugeItem.tsx |
truncate 제거, hidden 제거, 폰트/패딩 상향 |
items/StatCard.tsx |
truncate 제거, hidden 제거, 폰트/패딩 상향 |
items/ChartItem.tsx |
truncate 제거, 폰트/패딩 상향 |
[2026-02-10] pop-dashboard 페이지(슬라이드) 구조 재설계
배경 (왜 이 작업이 필요했는가)
문제 상황:
- 기존 대시보드는 아이템이 평면 리스트 -> 슬라이드 하나에 아이템 하나만 표시 가능
- "한 화면에 4개 차트, 다음 화면에 1개 차트" 같은 구성 불가
useGridLayout옵션은 전체 아이템을 하나의 그리드에 넣는 것만 가능
해결 방향:
DashboardPage개념 도입: 각 페이지가 독립적인 그리드 레이아웃(열/행/셀 배치) 보유- 표시 모드(arrows/auto-slide/scroll)는 페이지 간 전환 방식을 결정
- 기존
useGridLayout,gridCells,gridColumns,gridRows속성 폐기 ->pages배열로 대체
Added
-
DashboardPage인터페이스 (types.ts)id,label,gridColumns,gridRows,gridCells속성- 각 페이지가 독립적 그리드 레이아웃 보유
-
migrateConfig()함수 (PopDashboardComponent.tsx)- 레거시 config(displayMode="grid", useGridLayout=true)를 pages 기반으로 런타임 변환
- 저장된 config는 변경하지 않고 런타임에서만 적용
-
PageEditor컴포넌트 (PopDashboardConfig.tsx)- 페이지별 열/행/셀 배치 편집 UI
- 기존
GridLayoutEditor재사용
-
아이템 라벨 인라인 편집 (PopDashboardConfig.tsx)
ItemEditor헤더에서 직접 라벨 편집 가능 (접힌 상태에서도)
Changed
-
PopDashboardConfig타입 구조 변경 (types.ts)- 삭제:
useGridLayout,gridCells,gridColumns,gridRows - 추가:
pages?: DashboardPage[]
- 삭제:
-
"레이아웃" 탭 -> "페이지" 탭 (PopDashboardConfig.tsx)
- 페이지 추가/삭제 UI
- 페이지별 독립 그리드 편집
-
렌더링 로직 전면 교체 (PopDashboardComponent.tsx)
migrateConfig()-> pages 기반 -> 각 모드 컴포넌트에 페이지 단위 전달GridModeComponent를 페이지 내부 렌더링에 재사용
-
미리보기 로직 변경 (PopDashboardPreview.tsx)
- 첫 번째 페이지의 그리드 미리보기 + "N페이지" 배지 표시
-
defaultProps 업데이트 (index.tsx)
useGridLayout: false제거,pages: []추가
Fixed
- 설정 탭 세로 스크롤 불가 (ComponentEditorPanel.tsx)
- Flexbox
min-height: auto문제로overflow-auto미작동 Tabs/TabsContent에min-h-0추가,TabsList에shrink-0추가
- Flexbox
수정 파일
| 파일 | 변경 내용 |
|---|---|
types.ts |
DashboardPage 추가, PopDashboardConfig 구조 변경 |
PopDashboardComponent.tsx |
migrateConfig() 추가, 페이지 기반 렌더링 |
PopDashboardPreview.tsx |
migrateConfig 적용, 페이지 미리보기 |
PopDashboardConfig.tsx |
"페이지" 탭, PageEditor, 인라인 라벨 편집 |
pop-dashboard/index.tsx |
defaultProps 업데이트 |
ComponentEditorPanel.tsx |
Tabs/TabsContent min-h-0 추가 (스크롤 수정) |
popdocs/PROBLEMS.md |
스크롤 버그 상세 기록 |
[2026-02-09] POP 뷰어 스크롤 수정
배경 (왜 이 작업이 필요했는가)
문제 상황:
- 설계 화면(디자이너)에서 컴포넌트를 화면 높이 아래로 배치하면 스크롤로 볼 수 있음
- 뷰어(
/pop/screens/4114)에서는 화면 높이를 초과하는 컴포넌트가 잘려서 안 보임 - 스크롤 자체가 불가능한 상태
Fixed
-
최외곽 컨테이너
overflow-hidden제거 (page.tsx 185행)overflow-hidden이 뷰포트를 넘는 모든 콘텐츠를 잘라내고 있었음- 제거하여 자식 요소의 스크롤을 허용
-
overflow-auto공통 적용 (page.tsx 266행)- 기존: 프리뷰 모드에서만
overflow-auto적용 - 수정: 조건문 밖으로 이동하여 일반 뷰어 모드에서도 스크롤 가능
- 기존: 프리뷰 모드에서만
-
min-h-full추가 (page.tsx 275행)- 일반 뷰어 모드에서 짧은 콘텐츠일 때 백색 배경이 전체 높이를 채우도록 보장
수정 파일
| 파일 | 변경 내용 |
|---|---|
frontend/app/(pop)/pop/screens/[screenId]/page.tsx |
CSS 클래스 3곳 수정 (overflow-hidden 제거, overflow-auto 공통 적용, min-h-full 추가) |
[2026-02-09] POP 뷰어 실제 컴포넌트 렌더링 수정
배경 (왜 이 작업이 필요했는가)
문제 상황:
- 설계 화면(디자이너)에서는 이미지/텍스트/타이틀이 정상 표시
- 뷰어(
/pop/screens/4114)에 접속하면 "pop-text 1" 같은 라벨만 보이는 플레이스홀더 상태 renderActualComponent()함수가 레지스트리의 실제 컴포넌트를 무시하고 라벨 문자열만 반환- 뷰어 페이지에서 컴포넌트 레지스트리 초기화 import 누락
Fixed
-
뷰어 컴포넌트 레지스트리 미초기화 (page.tsx)
import "@/lib/registry/pop-components"추가PopRendererimport 앞에 배치 (순서 중요)
-
renderActualComponent()플레이스홀더만 반환 (PopRenderer.tsx)PopComponentRegistry.getComponent()로 실제 컴포넌트 조회- 등록된 컴포넌트가 있으면
config/labelprops 전달하여 실제 렌더링 - 미등록 컴포넌트는 기존 플레이스홀더를 fallback으로 유지
발견된 추가 문제 (미수정)
- datetime 실시간 업데이트 기본값 불일치
- 설정 패널:
config?.isRealtime ?? true(기본 켜짐) - 뷰어 컴포넌트:
if (!config?.isRealtime) return(undefined = 꺼짐) - DB에
isRealtime미저장 시 시간이 멈춰 보임 - 별도 작업으로 수정 예정
- 설정 패널:
수정 파일
| 파일 | 변경 내용 |
|---|---|
frontend/app/(pop)/pop/screens/[screenId]/page.tsx |
레지스트리 초기화 import 추가 (+2줄) |
frontend/components/pop/designer/renderers/PopRenderer.tsx |
renderActualComponent() 실제 컴포넌트 렌더링으로 교체 (-8줄 +19줄) |
[2026-02-09] pop-dashboard 상세 설계 토의
배경 (왜 이 작업이 필요했는가)
상황:
- 컴포넌트 정의서 v8.0에서 pop-dashboard가 "숫자를 집계해서 보여줌"으로 정의되어 있으나, 구체적인 데이터 구조/표시 모드/설정 패널 등 상세 설계가 필요
- Phase 0 공통 인프라와 Phase 1 pop-dashboard를 실제 구현하기 위한 세부 사항 결정 필요
- 기존 POP 대시보드 프로토타입(
frontend/components/pop/dashboard/)과의 관계 정리 필요
토의에서 결정된 사항
| # | 결정 항목 | 결정 내용 | 근거 |
|---|---|---|---|
| 1 | 컴포넌트 구조 | 1개 pop-dashboard = 여러 DashboardItem 묶음 (멀티 아이템 컨테이너) | 시스템 옵션에서 각 아이템별 보이기/숨기기 가능해야 함 |
| 2 | 서브타입 범위 | 4개 전부 Phase 1에서 구현 (kpi-card, chart, gauge, stat-card) | "시간이 걸리겠지만 4개 결국 전부 필요" |
| 3 | 표시 모드 | arrows, auto-slide, grid, scroll 4가지 | 전부 가능하게, 디자이너가 옵션으로 선택 |
| 4 | 그리드 배치 | 디자이너가 아이템별 행/열 위치 직접 지정 | "행열 그리드 배치"에서 수동 지정 |
| 5 | 계산식 | formula 지원 (값A/값B, A+B, A/B*100 등) | "생산량/총재고량" 같은 복합 표현 필요 |
| 6 | 설정 패널 | 드롭다운 기반 쉬운 집계 설정 (SQL 불필요) | "집계 및 계산 설정이 쉽게 이루어져야 함" |
| 7 | 백엔드 호환성 | 기존 API만 사용, 신규 백엔드 개발 불필요 | dataApi, dashboardApi, entityJoinApi 호환 확인 완료 |
| 8 | POP/데스크탑 분리 | POP 전용 훅은 frontend/hooks/pop/ 에 완전 분리 |
"분리 명확하게 해야해" |
| 9 | 기존 대시보드 | frontend/components/pop/dashboard/ 폐기 |
정적 하드코딩된 홈 화면, 새 컴포넌트로 완전 대체 |
| 10 | 표시 형태 | value, fraction(1,234/5,678), percent(21.7%), ratio(1,234:5,678) | 계산식 결과 다양한 표현 |
보류/미결 사항
| 항목 | 상태 | 비고 |
|---|---|---|
| Recharts 라이브러리 | 확인 필요 | chart 서브타입에 필요, 프로젝트에 이미 있는지 확인 후 추가 |
| 자동 슬라이드 터치 재개 시간 | 미정 | 구현 시 결정 (3~5초 추천) |
| 그리드 모드 겹침 검사 | 미정 | 설정 패널 구현 시 상세 설계 |
변경 파일
| 파일 | 변경 내용 |
|---|---|
POPUPDATE_2.md |
pop-dashboard 섹션 전면 개편 (멀티 아이템, 표시 모드, 계산식, 백엔드 API, 훅 분리) |
popdocs/PLAN.md |
Phase 1 상세 업데이트, 파일 경로, 백엔드 API, 함정 경고 |
popdocs/STATUS.md |
토의 결과 반영, 다음 작업 업데이트 |
popdocs/README.md |
마지막 대화 요약 업데이트 |
popdocs/CHANGELOG.md |
본 항목 추가 |
.cursor/plans/pop-dashboard_*.plan.md |
상세 설계 plan 파일 (별도 유지) |
[2026-02-09] POP 컴포넌트 정의서 v8.0 확정
배경 (왜 이 작업이 필요했는가)
상황:
- POP 시스템에 넣을 컴포넌트의 역할, 데이터 흐름, 통신 방식을 사전에 정의해야 함
- 영업팀으로부터 받은 참조 화면(HTML 샘플)을 기반으로 필요한 컴포넌트 목록 도출
- 모달 화면 설계 방식에 대한 결정 필요
Added
-
POP 컴포넌트 정의서 v8.0 (
POPUPDATE_2.md)- 9개 컴포넌트 정의: pop-text(완성), pop-dashboard, pop-table, pop-button, pop-icon, pop-search, pop-field, pop-lookup, pop-system
- POP 헌법 9조 (공통 규칙)
- 공통 인프라 설계: DataSourceConfig, ColumnBinding, JoinConfig, useDataSource, usePopEvent, PopActionConfig
- 컴포넌트 간 통신 시퀀스 다이어그램 5개
- 구현 우선순위 7단계 (Phase 0~6)
-
모달 화면 설계 방식 (v8.0 추가)
- 방식 A (인라인 모달): DataSourceConfig 기반 단순 목록 선택
- 방식 B (외부 화면 참조): 별도 screen_id 연결, 복잡한 화면/재사용
- POP 헌법 제9조: 모달 화면의 설계 원칙
- PopActionConfig modal 타입 구체화
-
기존 시스템 호환성 검증 결과 (v8.0 추가)
- DB: layout_data JSONB로 modalConfig 저장 가능 (마이그레이션 불필요)
- 백엔드: saveLayoutPop/getLayoutPop API 그대로 사용 가능
- 프론트: TabsWidget의 screenId 참조 패턴 차용 가능
주요 설계 결정
| 결정 | 내용 |
|---|---|
| 컴포넌트 9개 확정 | pop-text~pop-system |
| 역할 분리 | 조회용(search) vs 저장용(field), 이동(icon) vs 값 선택(lookup) |
| 시스템 설정 = 컴포넌트 | pop-system으로 통합 |
| 모달 이중 방식 | 인라인 + 외부 참조 |
| 이벤트 격리 | 화면 단위 (같은 화면 내 자유 통신) |
| 컬럼별 CRUD | read/write/readwrite/hidden 개별 설정 |
수정 파일
| 파일 | 변경 내용 |
|---|---|
POPUPDATE_2.md |
v7.0 -> v8.0 (모달 설계, 헌법 제9조, 호환성 검증) |
[2026-02-09] origin/main 병합 (ksh-v2-work-merge-test)
배경 (왜 이 작업이 필요했는가)
상황:
ksh-v2-work브랜치에서 POP 디자이너 개발이 진행되는 동안,main브랜치에서 데스크톱 ScreenDesigner 관련 대규모 업데이트(feature/v2-unified-renewalPR #386)가 병합됨- 두 브랜치가
ScreenDesigner.tsx를 동시에 수정하여 병합 충돌 발생 - 안전한 병합을 위해
ksh-v2-work-merge-test테스트 브랜치에서 작업
병합 통계:
- 소스:
origin/main(86 커밋) - 대상:
ksh-v2-work-merge-test(ksh-v2-work에서 분기, 14 커밋) - 분기점:
3fca677f(feat: V2Media 컴포넌트 추가) - 변경 파일: 207개 (43,535줄 추가, 3,547줄 삭제)
- 충돌 파일: 1개 (
ScreenDesigner.tsx)
Merged (origin/main에서 가져온 주요 변경)
-
ScreenDesigner 데스크톱 기능 강화
- 그룹 정렬/분배/크기 맞춤 (handleGroupAlign, handleGroupDistribute, handleMatchSize)
- 라벨 토글 (handleToggleAllLabels)
- 단축키 도움말 모달 (showShortcutsModal)
- 디버그 console.log 정리
-
백엔드 신규 기능
- 스케줄 관리 API (scheduleController, scheduleRoutes, scheduleService)
- 파일 관리 개선 (fileController, fileRoutes)
- 테이블 관리 확장 (tableManagementController)
- 넘버링 규칙 개선 (numberingRuleController)
-
프론트엔드 신규/수정
- 레이어 매니저 패널, 레이어 조건 패널
- 화면 복사 모달, 편집 모달
- InteractiveDataTable, InteractiveScreenViewer
- 넘버링 규칙 디자이너
- 화면 그룹 트리뷰, 화면 관계 플로우
충돌 해결 (ScreenDesigner.tsx)
3건의 충돌을 수동 해결:
| 충돌 | 영역 | 해결 방식 |
|---|---|---|
| 1. 함수 시그니처 | isPop, defaultDevicePreview props 추가 |
ksh-v2-work 유지 (POP 모드 지원), 중복 usePanelState 제거 |
| 2. 저장 로직 | POP/V2/Legacy 3단계 분기 | ksh-v2-work 유지 (3단계 분기), console.log 제거 |
| 3. 툴바 props | 정렬/분배/크기맞춤/라벨토글/단축키 | origin/main 채택 (데스크톱 신규 기능 모두 포함) |
검증 결과
| 항목 | 결과 |
|---|---|
| 충돌 마커 잔존 | 없음 |
| TypeScript 컴파일 | 신규 에러 없음 (기존 에러만) |
| 프론트엔드 빌드 | 성공 |
| 백엔드 빌드 | 신규 에러 없음 (docx/bwip-js 기존 이슈만) |
| 시맨틱 충돌 | 없음 |
| 린트 | 기능 에러 없음 (들여쓰기 차이만) |
주의사항
- Conflict 3 영역 들여쓰기: origin/main에서 가져온 툴바 JSX(L5745~6631)의 들여쓰기가 ksh-v2-work와 2칸 차이. 기능에는 영향 없으나, 추후 포매팅 정리 권장
- 기존 타입 에러:
GridSettings/GridUtilSettings불일치,SCREEN_RESOLUTIONSexport type 문제 등은 병합 이전부터 존재하던 기술 부채
수정 파일
| 파일 | 변경 내용 |
|---|---|
ScreenDesigner.tsx |
3건 충돌 수동 해결 (함수 시그니처, 저장 로직, 툴바 props) |
| 외 207개 파일 | origin/main에서 자동 병합 |
[2026-02-06] v5.2.1 그리드 셀 크기 강제 고정
배경 (왜 이 작업이 필요했는가)
문제 상황:
- 4칸 모드에서 특정 행의 가이드 셀이 다른 행보다 작게 표시됨
gridAutoRows는 최소 높이만 보장하여, 컴포넌트 콘텐츠가 행 높이를 밀어내면 인접 빈 셀도 영향받음- "셀의 크기 = 컴포넌트의 크기"라는 핵심 설계 원칙이 시각적으로 깨짐
Changed
-
gridAutoRows → gridTemplateRows (PopRenderer.tsx)
// 변경 전: 최소 높이만 보장 (콘텐츠에 따라 늘어남) gridAutoRows: `${breakpoint.rowHeight}px` // 변경 후: 행 높이 강제 고정 gridTemplateRows: `repeat(${dynamicRowCount}, ${breakpoint.rowHeight}px)` gridAutoRows: `${breakpoint.rowHeight}px` // 동적 추가행 대비 유지 -
dynamicRowCount 분리 (PopRenderer.tsx)
- gridCells 내부 → 독립 useMemo로 분리
- gridStyle과 gridCells에서 공유
-
컴포넌트 overflow 변경 (PopRenderer.tsx)
overflow-visible→overflow-hidden- 컴포넌트 콘텐츠가 셀 경계를 벗어나지 않도록 강제
Fixed
-
PopRenderer dynamicRowCount에서 숨김 컴포넌트 포함 문제
- PopCanvas는 숨김 제외하여 높이 계산, PopRenderer는 포함하여 계산 → 기준 불일치
- PopRenderer에도 숨김 필터 추가, 여유행 +5 → +3으로 통일
-
디버깅 console.log 잔존 (PopCanvas.tsx)
- reviewComponents useMemo 내 console.log 2개 삭제
-
뷰어 viewportWidth 선언 순서 (page.tsx)
- currentModeKey보다 뒤에 선언되어 있던 viewportWidth를 앞으로 이동
수정 파일
| 파일 | 변경 내용 |
|---|---|
PopRenderer.tsx |
gridTemplateRows 강제 고정, dynamicRowCount 분리, overflow-hidden, 숨김 필터 추가 |
PopCanvas.tsx |
디버깅 console.log 삭제 |
page.tsx (뷰어) |
viewportWidth 선언 순서 수정 |
[2026-02-06] v5.2 브레이크포인트 재설계 + 세로 자동 확장
배경 (왜 이 작업이 필요했는가)
문제 상황:
- 뷰어에서 브라우저 수동 리사이즈 시 768~839px 구간에서 모드 불일치
- useResponsiveMode 훅과 GRID_BREAKPOINTS 상수 간 기준 불일치
- 기존 브레이크포인트가 실제 기기 뷰포트와 맞지 않음
사용자 요구사항:
- "현장 모바일 기기 8~14인치, 핸드폰은 아이폰 미니 ~ 갤럭시 울트라"
- "세로는 신경쓸 필요 없고 무한 스크롤 가능해야 함"
Changed
-
브레이크포인트 재설계 (pop-layout.ts)
모드 변경 전 변경 후 근거 mobile_portrait ~599px ~479px 스마트폰 세로 최대 440px mobile_landscape 600~839px 480~767px 스마트폰 가로 tablet_portrait 840~1023px 768~1023px iPad Mini 768px 포함 tablet_landscape 1024px+ 동일 - -
detectGridMode() 조건 수정 (pop-layout.ts)
if (viewportWidth < 480) return "mobile_portrait"; // was 600 if (viewportWidth < 768) return "mobile_landscape"; // was 840 if (viewportWidth < 1024) return "tablet_portrait"; -
BREAKPOINTS.TABLET_MIN 변경 (useDeviceOrientation.ts)
- 768 (was 840)
-
VIEWPORT_PRESETS에서 height 제거 (PopCanvas.tsx)
- width만 유지, 세로는 무한 스크롤
Added
-
세로 자동 확장 (PopCanvas.tsx)
MIN_CANVAS_HEIGHT = 600: 최소 캔버스 높이CANVAS_EXTRA_ROWS = 3: 항상 유지되는 여유 행 수dynamicCanvasHeight: 컴포넌트 배치 기반 동적 계산
-
격자 셀 동적 계산 (PopRenderer.tsx)
- 고정 20행 → maxRowEnd + 5 동적 계산
-
뷰어 일관성 확보 (page.tsx)
- 프리뷰 모드: useResponsiveModeWithOverride 유지
- 일반 모드: detectGridMode(viewportWidth) 직접 사용
Fixed
-
뷰어 반응형 모드 불일치
- 768~839px 구간에서 6칸/8칸 모드 불일치 해결
-
hiddenComponentIds 중복 정의 에러
- 라인 410-412 중복 useMemo 제거
Technical Details
브레이크포인트 재설계 근거 (실제 기기 CSS 뷰포트):
| 기기 | CSS 뷰포트 너비 |
|------|----------------|
| iPhone SE | 375px |
| iPhone 16 Pro | 402px |
| Galaxy S25 Ultra | 440px |
| iPad Mini 7 | 768px |
| iPad Pro 11 | 834px (세로), 1194px (가로) |
| iPad Pro 13 | 1024px (세로), 1366px (가로) |
→ 768px, 1024px가 업계 표준 (Tailwind, Bootstrap 동일)
세로 자동 확장 로직:
const dynamicCanvasHeight = useMemo(() => {
const maxRowEnd = visibleComps.reduce((max, comp) => {
return Math.max(max, comp.row + comp.rowSpan);
}, 1);
const totalRows = maxRowEnd + CANVAS_EXTRA_ROWS; // +3행 여유
const height = totalRows * (rowHeight + gap) + padding * 2;
return Math.max(MIN_CANVAS_HEIGHT, height); // 최소 600px
}, [...]);
수정 파일
| 파일 | 변경 내용 |
|---|---|
pop-layout.ts |
GRID_BREAKPOINTS 값 수정, detectGridMode() 조건 수정 |
useDeviceOrientation.ts |
BREAKPOINTS.TABLET_MIN = 768 |
PopCanvas.tsx |
VIEWPORT_PRESETS height 제거, dynamicCanvasHeight 추가 |
PopRenderer.tsx |
gridCells 동적 행 수 계산 |
page.tsx (뷰어) |
detectGridMode() 사용 |
[2026-02-06] v5.1 자동 줄바꿈 + 검토 필요 시스템
배경 (왜 이 작업이 필요했는가)
문제 상황:
- 12칸에서 배치한 컴포넌트가 4칸 모드로 전환하면 "화면 밖" 패널로 이동하여 뷰어에서 안 보임
- 사용자가 모든 모드를 수동으로 편집해야 하는 부담
- "화면 밖" 개념이 실제로는 "검토 필요" 알림 역할이었음
해결 방향:
- 자동 줄바꿈: col > maxCol인 컴포넌트를 자동으로 맨 아래에 배치
- 정보 손실 방지: 모든 컴포넌트가 항상 그리드 안에 표시됨
- 검토 필요 알림: 오버라이드 없으면 "검토 필요" 표시 (자동 배치 상태)
Added
-
자동 줄바꿈 로직 (gridUtils.ts)
convertAndResolvePositions()수정- 원본 col 보존 로직 추가
- 정상 컴포넌트 vs 초과 컴포넌트 분리
- 초과 컴포넌트를 맨 아래에 순차 배치 (col=1, row=맨아래+1)
- colSpan 자동 축소 (targetColumns 초과 방지)
-
검토 필요 판별 함수 (gridUtils.ts)
needsReview()신규 함수- 기준: 12칸 아니고 + 오버라이드 없으면 → 검토 필요
- 간단한 로직: "이 모드에서 편집했냐 안 했냐"
-
검토 필요 패널 (PopCanvas.tsx)
ReviewPanel: "화면 밖" → "검토 필요"로 이름 변경ReviewItem: 클릭 시 해당 컴포넌트 선택 (드래그 없음)- 자동 배치 뱃지 표시
- 파란색 테마 (경고 아닌 안내 느낌)
Changed
-
isOutOfBounds() Deprecated (gridUtils.ts)
@deprecated주석 추가- needsReview()로 대체 권장
- 하위 호환을 위해 함수는 유지
-
"화면 밖" 패널 역할 변경 (PopCanvas.tsx)
- 기존: col > maxCol → 화면 밖 (드래그로 복원)
- 변경: 오버라이드 없음 → 검토 필요 (클릭으로 선택)
- 숨김 기능과 완전히 분리 (별도 유지)
Fixed
- 정보 손실 문제 해결
- 모든 컴포넌트가 항상 그리드 안에 배치됨
- 뷰어에서도 자동 배치가 적용되어 모두 표시됨
Technical Details
자동 줄바꿈 로직:
1. convertAndResolvePositions() 호출
components: [ {id: "A", position: {col:1, ...}}, {id: "B", position: {col:5, ...}} ]
targetMode: "mobile_portrait" (4칸)
2. 비율 변환 + 원본 col 보존
converted: [
{id: "A", position: {col:1, ...}, originalCol: 1},
{id: "B", position: {col:2, ...}, originalCol: 5} // col은 변환됨, 원본은 5
]
3. 정상 vs 초과 분리
normalComponents: [A] // originalCol ≤ 4
overflowComponents: [B] // originalCol > 4
4. 맨 아래 배치
maxRow = A의 (row + rowSpan - 1) = 1
B: col=1, row=2 (맨 아래에 자동 배치)
5. 겹침 해결
resolveOverlaps([A, B], 4) // 최종 위치 확정
6. 검토 필요 판별
needsReview("mobile_portrait", false) // 오버라이드 없음 → true
→ ReviewPanel에 B 표시
검토 필요 vs 숨김:
구분 | 검토 필요 | 숨김
------------- | ---------------------- | -------------------
역할 | 자동 배치 알림 | 의도적 숨김
뷰어에서 | 보임 (자동 배치) | 안 보임
디자이너에서 | ReviewPanel 표시 | HiddenPanel 표시
판단 기준 | 오버라이드 없음 | hidden 배열에 ID
색상 테마 | 파란색 (안내) | 회색 (제외)
수정 파일
| 파일 | 변경 내용 |
|---|---|
gridUtils.ts |
convertAndResolvePositions 자동 줄바꿈, needsReview 추가, isOutOfBounds deprecated |
PopCanvas.tsx |
OutOfBoundsPanel → ReviewPanel 변경, needsReview 필터링 |
PopRenderer.tsx |
isOutOfBounds import 제거 (사용 안 함) |
README.md |
v5.1 버전 표시, 최신 기능 요약 |
CHANGELOG.md |
v5.1 항목 추가 |
[2026-02-05 심야] 반응형 레이아웃 + 숨김 기능 완성
배경 (왜 이 작업이 필요했는가)
문제 상황:
- 12칸 모드에서 배치한 컴포넌트가 4칸 모드에서 초과됨
- 모드별로 컴포넌트 위치/크기를 다르게 설정할 방법 없음
- 특정 모드에서만 컴포넌트를 숨길 방법 없음
해결 방향:
- 모드별 오버라이드 시스템으로 위치/크기 개별 저장
- 화면 밖 컴포넌트를 별도 패널에 표시하고 드래그로 재배치
- 숨김 기능으로 특정 모드에서 컴포넌트 제외
Added
-
모드별 오버라이드 시스템 (PopDesigner.tsx, pop-layout.ts)
PopModeOverrideV5.positions: 모드별 컴포넌트 위치 저장PopModeOverrideV5.hidden: 모드별 숨김 컴포넌트 ID 배열getEffectiveComponentPosition(): 오버라이드된 위치 반환- 드래그/리사이즈 시 자동으로 오버라이드 저장
-
화면 밖 컴포넌트 패널 (PopCanvas.tsx)
OutOfBoundsPanel: 현재 모드에서 초과하는 컴포넌트 표시OutOfBoundsItem: 드래그 가능한 회색 컴포넌트 카드isOutOfBounds(): 컴포넌트가 현재 모드 칸 수 초과 여부 판단- 클릭하면 숨김 패널로 이동
-
숨김 기능 (PopDesigner.tsx, PopCanvas.tsx)
HiddenPanel: 숨김 처리된 컴포넌트 표시HiddenItem: 드래그로 숨김 해제 가능handleHideComponent(): 컴포넌트 숨김 처리handleUnhideComponent(): 숨김 해제 (handleMoveComponent에 통합)- 숨김 방법 3가지:
- 그리드 → 숨김패널 드래그
- H키 단축키
- 화면밖 컴포넌트 클릭
-
리사이즈 겹침 검사 (PopRenderer.tsx)
checkResizeOverlap(): 리사이즈 시 다른 컴포넌트와 겹침 검사- 겹치면 리사이즈 취소 및 toast 알림
-
원본으로 되돌리기 (PopDesigner.tsx)
handleResetToDefault(): 현재 모드 오버라이드 삭제- 자동 위치 계산으로 복원
Fixed
-
숨김 컴포넌트 드래그 안됨 버그
- 원인:
onUnhideComponent와onMoveComponent가 별도로 호출되어 상태 충돌 - 해결:
handleMoveComponent에서 숨김 해제 로직 통합 (단일 상태 업데이트)
- 원인:
-
그리드 범위 초과 에러
- 원인: 드롭 위치 + colSpan이 칸 수 초과
- 해결: 드롭 시
adjustedCol계산하여 자동으로 왼쪽으로 밀어서 배치
-
getAllEffectivePositions에 숨김 컴포넌트 포함
- 해결: 숨김 및 화면밖 컴포넌트를 결과에서 제외
-
Expected drag drop context 에러 (뷰어 페이지)
- 원인:
DraggableComponent에서useDrag훅이DndProvider없이 호출됨 - 해결:
isDesignMode=false일 때DraggableComponent대신 일반div로 렌더링
- 원인:
Changed
-
PopModeOverrideV5 타입 확장
interface PopModeOverrideV5 { positions?: Record<string, Partial<PopGridPosition>>; // 위치 오버라이드 hidden?: string[]; // 숨김 컴포넌트 ID 배열 } -
12칸 모드(tablet_landscape) 제한
- 기본 모드이므로 숨김 기능 비활성화
- 화면밖 패널 표시 안함
- 위치 변경은 기본 position에 직접 저장
-
패널 레이아웃 재구성 (PopCanvas.tsx)
- 오른쪽에 화면밖 패널 + 숨김 패널 세로 배치
- 12칸 모드에서는 패널 숨김
Technical Details
오버라이드 데이터 흐름:
1. 컴포넌트 드래그/리사이즈
↓
2. currentMode 확인
↓
3-a. tablet_landscape → layout.components[id].position 직접 수정
3-b. 다른 모드 → layout.overrides[mode].positions[id]에 저장
↓
4. getEffectiveComponentPosition()이 우선순위대로 반환
우선순위: overrides > autoResolved > 기본 position
숨김 기능 흐름:
1. 숨김 요청 (드래그/H키/클릭)
↓
2. layout.overrides[mode].hidden 배열에 ID 추가
↓
3. PopRenderer에서 hidden 체크 → 렌더링 제외
↓
4. HiddenPanel에서 표시
↓
5. 드래그로 그리드에 복원 → hidden 배열에서 제거 + 위치 업데이트 (단일 상태 업데이트)
수정 파일
| 파일 | 변경 내용 |
|---|---|
pop-layout.ts |
PopModeOverrideV5.hidden 추가 |
PopDesigner.tsx |
handleHideComponent, handleUnhideComponent 통합, 오버라이드 저장 |
PopCanvas.tsx |
OutOfBoundsPanel, HiddenPanel 추가, 드롭 위치 자동 조정 |
PopRenderer.tsx |
숨김 필터링, 리사이즈 겹침 검사 |
gridUtils.ts |
getAllEffectivePositions에서 숨김/화면밖 제외, isOutOfBounds 함수 |
[2026-02-05 저녁] 드래그앤드롭 완전 수정
배경 (왜 좌표 계산이 틀렸는가)
문제 상황:
- 컴포넌트를 아래로 드래그해도 위로 올라감
- Row 92 같은 비정상적인 좌표로 배치됨
- 드래그 이동/리사이즈가 전혀 작동하지 않음
핵심 원인: 캔버스에 transform: scale(0.8) 적용 시 좌표 계산 불일치
문제:
- getBoundingClientRect() → 스케일 적용된 크기 반환 (예: 1024px → 819px)
- getClientOffset() → 뷰포트 기준 실제 마우스 좌표
- 이 둘을 그대로 계산하면 좌표가 완전히 틀림
해결: 단순한 상대 좌표 + 스케일 보정
// 캔버스 내 상대 좌표 (스케일 보정)
const relX = (마우스X - 캔버스left) / canvasScale;
const relY = (마우스Y - 캔버스top) / canvasScale;
calcGridPosition(relX, relY, customWidth, ...); // 실제 캔버스 크기 사용
Added
-
calcGridPosition()함수 (PopCanvas.tsx)- 캔버스 내 상대 좌표를 그리드 좌표로 변환
- 패딩, gap, 셀 너비를 고려한 정확한 계산
-
공통 DND 상수 (constants/dnd.ts)
DND_ITEM_TYPES.COMPONENT: 팔레트에서 새 컴포넌트DND_ITEM_TYPES.MOVE_COMPONENT: 기존 컴포넌트 이동- 3개 파일에서 중복 정의되던 것을 통합
Fixed
-
스케일 보정 누락
- 캔버스 줌(scale)이 적용된 상태에서 좌표 계산 오류
(offset - rect.left) / scale로 보정
-
DND 타입 상수 불일치
- PopCanvas:
"component","MOVE_COMPONENT" - PopRenderer:
"MOVE_COMPONENT"(하드코딩) - ComponentPalette:
"component"(로컬 정의) - 모두 공통 상수로 통합
- PopCanvas:
-
컴포넌트 중첩(겹침) 문제
- 원인:
toastimport 누락으로 겹침 감지 로직이 실행 안됨 - 해결:
sonner에서 toast import 추가 - 겹침 시
findNextEmptyPosition()으로 자동 재배치
- 원인:
-
리사이즈 핸들 작동 안됨
- 원인:
useDrop훅 2개가 같은canvasRef에 중복 적용 - 해결: 단일
useDrop으로 통합 (COMPONENT+MOVE_COMPONENT모두 처리)
- 원인:
-
불필요한 toast 메시지 제거
- "컴포넌트가 이동되었습니다" 알림 삭제
Changed
- mouseToGridPosition 단순화
- 복잡한 DOMRect 전달 대신 필요한 값만 직접 전달
- gridUtils.ts의 함수는 유지 (다른 곳에서 사용)
Technical Details
좌표 변환 흐름 (수정 후):
1. 마우스 드롭
offset = monitor.getClientOffset() // 뷰포트 기준 {x: 500, y: 300}
2. 캔버스 위치
canvasRect = canvasRef.getBoundingClientRect() // {left: 250, top: 100}
3. 스케일 보정된 상대 좌표
relX = (500 - 250) / 0.8 = 312.5 // 캔버스 내 실제 X
relY = (300 - 100) / 0.8 = 250 // 캔버스 내 실제 Y
4. 그리드 좌표 계산
calcGridPosition(312.5, 250, 1024, 12, 48, 16, 24)
→ { col: 5, row: 4 }
수정 파일
| 파일 | 변경 내용 |
|---|---|
PopCanvas.tsx |
calcGridPosition 추가, 스케일 보정 적용 |
PopDesigner.tsx |
toast 메시지 제거 |
PopRenderer.tsx |
DND 상수 import |
ComponentPalette.tsx |
DND 상수 import |
constants/dnd.ts |
새 파일 (DND 타입 상수) |
constants/index.ts |
새 파일 (export) |
[2026-02-05 오후] 그리드 가이드 CSS Grid 통합
배경 (왜 재설계했는가)
문제 상황:
- GridGuide.tsx(SVG 기반)와 PopRenderer.tsx(CSS Grid)가 좌표계 불일치
- 격자선과 컴포넌트가 정렬되지 않음 ("무늬가 따로 논다")
- 행/열 라벨이 4부터 시작하는 등 오류
핵심 원칙:
"격자선은 컴포넌트와 같은 좌표계에서 태어나야 한다"
결정: SVG 격자 삭제, CSS Grid 기반 통합 → 상세: decisions/004-grid-guide-integration.md
Breaking Changes
GridGuide.tsx삭제 (SVG 기반 격자)
Added
-
CSS Grid 기반 격자 셀 (PopRenderer.tsx)
gridCells: 12x20 = 240개 실제 DOM 셀border-dashed border-blue-300/40스타일- 컴포넌트는
z-index:10으로 위에 표시 showGridGuideprop으로 ON/OFF
-
행/열 라벨 (PopCanvas.tsx)
- 열 라벨: 1~12 (캔버스 상단)
- 행 라벨: 1~20 (캔버스 좌측)
- absolute positioning으로 정확한 정렬
- 줌/패닝에 연동
-
그리드 토글 버튼 (PopCanvas.tsx)
- "그리드 ON/OFF" 버튼 추가
- 격자 표시 상태 관리
Changed
- 컴포넌트 타입 단순화
PopComponentType:pop-sample1개로 단순화DEFAULT_COMPONENT_GRID_SIZE:pop-sample전용ComponentPalette.tsx: 샘플 박스 1개만 표시PopRenderer.tsx: 샘플 박스 렌더링으로 단순화
Technical Details
역할 분담:
- PopRenderer: 격자 셀(div) + 컴포넌트 (같은 CSS Grid 좌표계)
- PopCanvas: 라벨 + 줌/패닝 + 토글
- GridGuide: 삭제
격자 셀 구조:
┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐
│1,1│2,1│3,1│4,1│5,1│6,1│7,1│8,1│9,1│10│11│12 │ ← col
├───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┼───┤
│1,2│... │
└───┴───────────────────────────────────────────┘
↑ row
[2026-02-05] v5 그리드 시스템 완전 통합
배경 (왜 v5로 전환했는가)
문제 상황:
- v4 Flexbox로 반응형 구현 시도 → 배치가 예측 불가능
- 캔버스에 "그리듯이" 배치하면 화면 크기별로 깨짐
상급자 피드백:
"이런 식이면 나중에 문제가 생긴다." "스크린의 픽셀 규격과 마진 간격 규칙을 설정해라. 큰 화면 디자인의 전체 프레임 규격과 사이즈 간격 규칙을 정한 다음에 거기에 컴포넌트를 끼워 맞추듯 우리의 규칙 내로 움직이게 바탕을 잡아라."
연구 내용:
- Softr: 블록 기반, 제약 기반 레이아웃
- Ant Design: 24열 그리드, 8px 간격
- Material Design: 4/8/12열, 반응형 브레이크포인트
결정: CSS Grid 기반 그리드 시스템 (v5) 채택 → 상세: decisions/003-v5-grid-system.md
popdocs 문서 구조 재정비
배경: 문서가 AI 에이전트 진입점 역할을 못함, 컨텍스트 효율화 필요
적용 기법: Progressive Disclosure (점진적 공개), Token as Currency
추가된 파일:
SAVE_RULES.md: AI 저장/조회 규칙, 템플릿STATUS.md: 현재 진행 상태, 중단점PROBLEMS.md: 문제-해결 색인INDEX.md: 기능별 색인sessions/: 날짜별 작업 기록
문서 계층:
- Layer 1 (진입점): README, STATUS, SAVE_RULES
- Layer 2 (상세): CHANGELOG, PROBLEMS, INDEX, FILES, ARCHITECTURE
- Layer 3 (심화): decisions/, sessions/, archive/
Breaking Changes
- v1, v2, v3, v4 레이아웃 완전 삭제
- 기존 POP 화면 데이터 전체 초기화 필요
- 레거시 컴포넌트 및 타입 삭제
Added
-
CSS Grid 기반 그리드 시스템 (v5)
- 4개 모드별 칸 수: 4/6/8/12칸
- 명시적 위치 지정 (col, row, colSpan, rowSpan)
- 모드별 오버라이드 지원
- 자동 위치 변환 (12칸 기준 → 다른 모드)
-
통합된 파일 구조
PopCanvas.tsx: 그리드 캔버스 (DnD + 줌 + 모드 전환)PopRenderer.tsx: 그리드 렌더링ComponentEditorPanel.tsx: 속성 편집pop-layout.ts: v5 전용 타입 정의gridUtils.ts: 그리드 유틸리티 함수
Removed
PopCanvasV4.tsx,PopCanvas.tsx (v3)PopFlexRenderer.tsx,PopLayoutRenderer.tsxComponentEditorPanelV4.tsx,PopPanel.tsx- v1, v2, v3, v4 타입 정의 및 유틸리티 함수
test-v4테스트 페이지
Changed
screenManagementService.ts: v5 전용으로 단순화screen_layouts_pop테이블: 기존 데이터 삭제, v5 전용PopDesigner.tsx: v5 전용으로 리팩토링- 뷰어 페이지: v5 렌더러 전용
Technical Details
// v5 그리드 모드
type GridMode = "mobile_portrait" | "mobile_landscape" | "tablet_portrait" | "tablet_landscape";
// 그리드 설정
const GRID_BREAKPOINTS = {
mobile_portrait: { columns: 4, rowHeight: 48, gap: 8, padding: 12 },
mobile_landscape: { columns: 6, rowHeight: 44, gap: 8, padding: 16 },
tablet_portrait: { columns: 8, rowHeight: 52, gap: 12, padding: 20 },
tablet_landscape: { columns: 12, rowHeight: 56, gap: 12, padding: 24 },
};
// 컴포넌트 위치
interface PopGridPosition {
col: number; // 시작 열 (1부터)
row: number; // 시작 행 (1부터)
colSpan: number; // 열 크기
rowSpan: number; // 행 크기
}
[2026-02-04] Phase 2.1 완료 - 배치 고정 기능
Added
-
현재 모드 추적 (PopDesigner.tsx)
currentViewportMode상태 추가- PopCanvasV4와 양방향 동기화
- 모드 변경 시 자동 업데이트
-
배치 고정 기능
- "고정" 버튼 추가 (기본 모드 제외)
handleLockLayoutV4()- 현재 배치를 오버라이드에 저장- 배치 정보: direction, wrap, gap, alignItems, justifyContent, children 순서
-
오버라이드 초기화 기능
handleResetOverrideV4()- 오버라이드 삭제- "자동으로 되돌리기" 버튼 (편집된 모드만 표시)
- 자동 계산으로 되돌림
Changed
-
PopCanvasV4 Props 구조 변경
currentModeprop 추가 (외부에서 제어)onModeChange콜백 추가onLockLayout콜백 추가- 내부
activeViewport상태 제거 (부모가 관리)
-
프리셋 버튼 동작
- 클릭 시 부모 상태 업데이트 (
onModeChange) currentModeprop 기반으로 활성 상태 표시
- 클릭 시 부모 상태 업데이트 (
Technical Details
// 고정 로직
const handleLockLayoutV4 = () => {
const newLayout = {
...layoutV4,
overrides: {
...layoutV4.overrides,
[currentViewportMode]: {
containers: {
root: {
direction: layoutV4.root.direction,
wrap: layoutV4.root.wrap,
gap: layoutV4.root.gap,
children: layoutV4.root.children, // 순서 고정
// ... 기타 배치 속성
}
}
}
}
};
};
// 초기화 로직
const handleResetOverrideV4 = (mode) => {
const newOverrides = { ...layoutV4.overrides };
delete newOverrides[mode];
// overrides가 비면 undefined로 설정
};
UI 변경
툴바:
[모바일↕] [모바일↔] [태블릿↕] [태블릿↔(기본)] [고정] [자동으로 되돌리기]
조건부 표시:
- "고정" 버튼: 기본 모드가 아닐 때
- "자동으로 되돌리기": 오버라이드가 있을 때
주의사항
- 크기는 고정하지 않음 (여전히 자동 스케일링)
- 배치만 오버라이드 (순서, 방향, 정렬)
- 최소/최대값 기능은 별도 구현 필요
[2026-02-04] Phase 2 시작 - 오버라이드 UI 표시
Added
-
오버라이드 데이터 구조 (pop-layout.ts)
PopModeOverride인터페이스 추가PopLayoutDataV4.overrides필드 추가- 3개 모드 오버라이드 지원 (mobile_portrait, mobile_landscape, tablet_portrait)
-
프리셋 버튼 상태 표시 (PopCanvasV4.tsx)
- 기본 모드: "(기본)" 텍스트 표시
- 편집된 모드: "(편집)" 텍스트 + 노란색 강조
- 자동 모드: 기본 스타일
Changed
- hasOverride 함수 구현
layout.overrides필드 체크- 컴포넌트/컨테이너 오버라이드 존재 여부 확인
[2026-02-04] 비율 스케일링 시스템 구현
Added
-
비율 스케일링 시스템 (업계 표준 Scale with Fixed Aspect Ratio)
- 기준 너비: 1024px (10인치 태블릿 가로)
- 최대 너비: 1366px (12인치 태블릿)
- 8~12인치 화면에서 배치 유지, 크기만 비례 조정
-
뷰포트 감지 (page.tsx)
viewportWidthstate 추가- resize 이벤트 리스너로 실시간 감지
Math.min(window.innerWidth, 1366)최대값 제한
Changed
-
PopFlexRenderer.tsx
BASE_VIEWPORT_WIDTH = 1024상수 추가scale = viewportWidth / BASE_VIEWPORT_WIDTH계산calculateSizeStyle()함수에 scale 파라미터 추가- 컴포넌트 크기 (fixedWidth, fixedHeight) 스케일 적용
- 컨테이너 gap, padding 스케일 적용
- 디자인 모드: scale = 1 (원본), 뷰어 모드: 실제 scale 적용
-
ComponentRendererV4
viewportWidthprop 추가- 내부에서 scale 계산하여 sizeStyle에 적용
-
ContainerRenderer
- scaledGap, scaledPadding 계산하여 containerStyle에 적용
Technical Details
비율 스케일링 계산:
scale = 실제 화면 너비 / 기준 너비 (1024px)
예시:
- 800px (8인치): scale = 0.78 → 200px 컴포넌트 → 156px
- 1024px (10인치): scale = 1.00 → 200px 컴포넌트 → 200px (기준)
- 1366px (12인치): scale = 1.33 → 200px 컴포넌트 → 266px
- 1920px (데스크톱): max-width 1366px 적용 → 12인치와 동일 + 여백
Fixed
- DndProvider 에러 (뷰어 페이지)
- 원인: isDesignMode=false일 때 useDrag/useDrop 훅 호출
- 해결: DraggableComponentWrapper에서 isDesignMode 체크 후 early return
[2026-02-04] Flexbox 가로 배치 + Spacer + Undo/Redo 개선
Added
-
Spacer 컴포넌트 (
pop-spacer)- 빈 공간을 차지하여 레이아웃 정렬에 사용
- 기본 크기:
width: fill,height: 48px - 디자인 모드에서 점선 배경으로 표시
- 실제 모드에서는 투명 (공간만 차지)
-
컴포넌트 순서 변경 (드래그 앤 드롭)
- 같은 컨테이너 내에서 컴포넌트 순서 변경 가능
- 드래그 중인 컴포넌트는 반투명하게 표시
- 드롭 위치는 파란색 테두리로 표시
handleReorderComponentV4핸들러 추가
Changed
-
기본 레이아웃 방향 변경 (Flexbox 가로 배치)
direction: "vertical"→direction: "horizontal"wrap: false→wrap: true(자동 줄바꿈)alignItems: "stretch"→alignItems: "start"- 컴포넌트가 가로로 나열되고, 공간 부족 시 다음 줄로 이동
-
컴포넌트 기본 크기 타입별 설정
- 필드: 200x48px (fixed)
- 버튼: 120x48px (fixed)
- 리스트: fill x 200px
- 인디케이터: 120x80px (fixed)
- 스캐너: 200x48px (fixed)
- 숫자패드: 200x280px (fixed)
- Spacer: fill x 48px
-
Undo/Redo 방식 개선 (데스크탑 모드와 동일)
useLayoutHistory훅 제거- 별도
history[],historyIndex상태로 관리 saveToHistoryV4()함수로 명시적 히스토리 저장- 컴포넌트 추가/삭제/수정/순서변경 시 히스토리 저장
-
디바이스 스크린 스크롤
overflow: auto추가 (컴포넌트가 넘치면 스크롤)height→minHeight변경 (컨텐츠에 따라 높이 증가)
Technical Details
업계 표준 레이아웃 방식 (Figma, Webflow, FlutterFlow):
1. Flexbox 기반 Row/Column 배치
2. 크기 제어: Fill / Fixed / Hug
3. Spacer 컴포넌트로 정렬 조정
4. 화면 크기별 조건 분기 (반응형)
사용 예시:
[버튼A] [Spacer(fill)] [버튼B] → 버튼B가 오른쪽 끝으로
[Spacer] [컴포넌트] [Spacer] → 컴포넌트가 가운데로
[2026-02-04] 드래그 리사이즈 + Undo/Redo 기능
Added
-
useLayoutHistory.ts - Undo/Redo 히스토리 훅
- 최대 50개 히스토리 저장
undo(),redo(),canUndo,canRedoreset()- 새 레이아웃 로드 시 히스토리 초기화
-
드래그 리사이즈 핸들 (PopFlexRenderer)
- 오른쪽 핸들: 너비 조정 (cursor: ew-resize)
- 아래쪽 핸들: 높이 조정 (cursor: ns-resize)
- 오른쪽 아래 핸들: 너비+높이 동시 조정 (cursor: nwse-resize)
- 선택된 컴포넌트에만 표시
- 최소 크기 보장 (너비 48px, 높이 touchTargetMin)
Changed
-
PopDesigner.tsx
useLayoutHistory훅 통합 (v3, v4 각각 독립적)- Undo/Redo 버튼 추가 (툴바 오른쪽)
- 단축키 등록:
Ctrl+Z/Cmd+Z: 실행 취소Ctrl+Shift+Z/Cmd+Shift+Z/Ctrl+Y: 다시 실행
handleResizeComponentV4핸들러 추가
-
PopCanvasV4.tsx
onResizeComponentprop 추가- PopFlexRenderer에 전달
-
PopFlexRenderer.tsx
onComponentResizeprop 추가- ComponentRendererV4에 리사이즈 핸들 추가
- 드래그 이벤트 처리 (mousemove, mouseup)
단축키 목록
| 단축키 | 기능 |
|---|---|
Delete / Backspace |
선택된 컴포넌트 삭제 |
Ctrl+Z / Cmd+Z |
실행 취소 (Undo) |
Ctrl+Shift+Z / Ctrl+Y |
다시 실행 (Redo) |
Space + 드래그 |
캔버스 패닝 |
Ctrl + 휠 |
줌 인/아웃 |
[2026-02-04] v4 통합 설계 모드 Phase 1 완료
목표
v4를 기본 레이아웃 모드로 통합하고, 새 화면은 자동으로 v4로 시작
Added
- ComponentPaletteV4.tsx - v4 전용 컴포넌트 팔레트
- 6개 컴포넌트 (필드, 버튼, 리스트, 인디케이터, 스캐너, 숫자패드)
- 드래그 앤 드롭 지원
Changed
-
PopDesigner.tsx - v3/v4 통합 디자이너로 리팩토링
- v3/v4 탭 제거 (자동 판별)
- 새 화면 → v4로 시작
- 기존 v3 화면 → v3로 로드 (하위 호환)
- 빈 레이아웃 → v4로 시작 (컴포넌트 유무로 판별)
- 레이아웃 버전 텍스트 표시 ("자동 레이아웃 (v4)" / "4모드 레이아웃 (v3)")
-
PopCanvasV4.tsx - 4개 프리셋으로 변경
- 기존: [모바일] [태블릿] [데스크톱]
- 변경: [모바일↕] [모바일↔] [태블릿↕] [태블릿↔]
- 기본 프리셋: 태블릿 가로 (1024x768)
- 슬라이더 범위: 320~1200px
- 비율 유지: 슬라이더 조절 시 높이도 비율에 맞게 자동 조정
Fixed
- 새 화면이 v3로 열리는 문제
- 원인: 백엔드가 빈 v2 레이아웃 반환 (version 필드 있음)
- 해결: 컴포넌트 유무로 빈 레이아웃 판별 → v4로 시작
Technical Details
레이아웃 로드 로직:
1. version 필드 확인
2. components 존재 여부 확인
3. version 있고 components 있음 → 해당 버전으로 로드
4. version 없거나 components 없음 → v4로 새로 시작
[2026-02-04] Phase 2.1 완료 - 배치 고정 기능 (버그 수정)
🔥 주요 버그 수정
- layoutV4.root 오염 문제 해결: 다른 모드에서 편집 시 기본 레이아웃이 변경되던 버그 수정
- tempLayout 도입: 고정 전 임시 배치를 별도 상태로 관리하여 root를 보호
- 렌더러 병합 로직:
PopFlexRenderer에 오버라이드 자동 병합 기능 추가
데이터 흐름 개선
-
기본 모드 (태블릿 가로)
- 드래그/속성 변경 →
layoutV4.root직접 수정 ✅ - 모든 다른 모드의 기본값으로 사용
- 드래그/속성 변경 →
-
다른 모드 (모바일 세로 등)
- 드래그 →
tempLayout임시 저장 (화면에만 표시) - "고정" 버튼 →
layoutV4.overrides[mode]에 저장 - 속성 패널 → 비활성화 + 안내 메시지
- 드래그 →
-
렌더링
tempLayout있으면 최우선 표시 (고정 전 미리보기)- 오버라이드 있으면
root와 병합 - 없으면
root그대로 표시
수정 파일
PopDesigner.tsx: tempLayout 상태 추가, 핸들러 수정PopFlexRenderer.tsx: 병합 로직 추가 (getMergedRoot)PopCanvasV4.tsx: tempLayout props 전달ComponentEditorPanelV4.tsx: 속성 패널 비활성화 로직
[2026-02-04] Phase 3 완료 - visibility + 줄바꿈 컴포넌트
추가 기능
- visibility 속성: 모드별 컴포넌트 표시/숨김 제어
- pop-break 컴포넌트: 강제 줄바꿈 (flex-basis: 100%)
- 컴포넌트 오버라이드 병합: 모드별 컴포넌트 설정 변경 가능
타입 정의
interface PopComponentDefinitionV4 {
// 기존 속성...
// 🆕 모드별 표시/숨김
visibility?: {
tablet_landscape?: boolean;
tablet_portrait?: boolean;
mobile_landscape?: boolean;
mobile_portrait?: boolean;
};
}
// 🆕 줄바꿈 컴포넌트
type PopComponentType =
| "pop-field"
| "pop-button"
| "pop-list"
| "pop-indicator"
| "pop-scanner"
| "pop-numpad"
| "pop-spacer"
| "pop-break"; // 새로 추가
렌더러 개선
isComponentVisible(): visibility 체크 로직getMergedComponent(): 컴포넌트 오버라이드 병합- pop-break 전용 렌더링 (디자인 모드: 점선, 실제: 높이 0)
삭제 함수 개선
cleanupOverridesAfterDelete(): 컴포넌트 삭제 시 모든 오버라이드 정리- containers.root.children 정리
- components 오버라이드 정리
- 빈 오버라이드 자동 제거
UI 개선
- 속성 패널에 "표시" 탭 추가 (Eye 아이콘)
- 모드별 체크박스 UI
- 반응형 숨김 (hideBelow) 유지
- 팔레트에 "줄바꿈" 컴포넌트 추가
사용 예시
태블릿 가로:
[A] [B] [C] [D] [E] ← 한 줄
모바일 세로:
[A] [B]
─────── ← 줄바꿈 (visibility: mobile만 true)
[C] [D] [E]
수정 파일
pop-layout.ts: 타입 추가, 삭제 함수 수정PopFlexRenderer.tsx: visibility, 병합, pop-break 렌더링ComponentEditorPanelV4.tsx: 표시 탭 추가ComponentPaletteV4.tsx: 줄바꿈 추가
[2026-02-04] v4 타입 및 렌더러
Added
-
v4 타입 정의 (간결 버전)
PopLayoutDataV4- 단일 소스 레이아웃PopContainerV4- 스택 컨테이너 (direction, wrap, gap, alignItems)PopComponentDefinitionV4- 크기 제약 기반 (size: fixed/fill/hug)PopSizeConstraintV4- 크기 규칙PopResponsiveRuleV4- 반응형 규칙 (breakpoint별 변경)PopGlobalSettingsV4- 전역 설정createEmptyPopLayoutV4()- 생성 함수isV4Layout()- 타입 가드- CRUD 함수들 (add, remove, update, find)
-
PopFlexRenderer.tsx - v4 Flexbox 렌더러
- 컨테이너 재귀 렌더링
- 반응형 규칙 적용
- 크기 제약 → CSS 변환
-
ComponentEditorPanelV4.tsx - v4 속성 편집 패널
- 크기 제약 편집 UI
- 컨테이너 설정 UI
-
PopCanvasV4.tsx - v4 전용 캔버스
- 뷰포트 프리셋
- 너비 슬라이더
- 줌/패닝
[2026-02-04] (earlier)
Added
- 저장/조회 시스템 구축
- rangraph: AI 장기 기억 (시맨틱 검색, 요약)
- popdocs: 상세 기록 (파일 기반, 히스토리)
- 이중 저장 체계로 검색 + 기록 분리
Changed
- popdocs 문서 구조 정리
- README.md: 저장/조회 규칙 추가
- 기존 문서 archive/로 이동
- 문서 관리 전략 확정
- 저장 시: 파일 형식 자동 파악 → 형식 맞춰 추가 → rangraph 요약
- 조회 시: rangraph 시맨틱 검색
Removed
- .cursorrules 변경 계획 철회 (Git 커밋 영향)
[2026-02-03]
Added
- v4 제약조건 기반 레이아웃 계획
- 단일 소스 + 자동 적응
- 3가지 규칙 (크기, 배치, 반응형)
- ADR:
decisions/001-v4-constraint-based.md
[2026-02-02]
Fixed
- 캔버스 rowSpan 문제
- 원인: gridTemplateRows 고정 px
- 해결:
1fr사용
[2026-02-01]
Fixed
- 4모드 자동 전환 문제
- 해결: useResponsiveMode 훅 추가
[2026-01-31]
Added
- v3 섹션 제거, 순수 그리드 구조
- 4개 모드 독립 그리드
[2026-01-30]
Added
- POP 디자이너 기본 구조
- PopDesigner, PopCanvas 컴포넌트
[2026-01-29]
Added
- screen_layouts_pop 테이블
- POP 레이아웃 API (CRUD)
최신이 위, 시간순 역순