ERP-node/docs/FINAL_GRID_MIGRATION_ROADMA...

15 KiB

🗺️ 화면 관리 시스템 - 최종 그리드 마이그레이션 로드맵

🎯 최종 목표

"Tailwind CSS 12컬럼 그리드 기반의 제한된 자유도 시스템"

  • 픽셀 기반 width 완전 제거
  • 컬럼 스팬(1-12)으로만 너비 제어
  • 행(Row) 기반 레이아웃 구조
  • 정형화된 디자인 패턴 제공

📊 현재 시스템 vs 새 시스템

Before (현재)

// 픽셀 기반 절대 위치 시스템
interface ComponentData {
  position: { x: number; y: number }; // 픽셀 좌표
  size: { width: number; height: number }; // 픽셀 크기
}

// 사용자 입력
<Input type="number" value={width} onChange={...} />
// → 예: 850px 입력 가능 (자유롭지만 일관성 없음)

After (새 시스템)

// 행 기반 그리드 시스템
interface ComponentData {
  gridRowIndex: number; // 몇 번째 행인가
  gridColumnSpan: ColumnSpanPreset; // 너비 (컬럼 수)
  gridColumnStart?: number; // 시작 위치 (선택)
  size: { height: number }; // 높이만 픽셀 지정
}

// 사용자 선택
<Select value={columnSpan}>
  <SelectItem value="full">전체 (12/12)</SelectItem>
  <SelectItem value="half">절반 (6/12)</SelectItem>
  <SelectItem value="third">1/3 (4/12)</SelectItem>
  // ... 정해진 옵션만
</Select>;
// → 예: "half" 선택 → 정확히 50% 너비 (일관성 보장)

🏗️ 새 시스템 구조

1. 화면 구성 방식

화면 (Screen)
  ├─ 행 1 (Row 1) [12 컬럼 그리드]
  │   ├─ 컴포넌트 A (3 컬럼)
  │   ├─ 컴포넌트 B (9 컬럼)
  │   └─ [자동 배치]
  │
  ├─ 행 2 (Row 2) [12 컬럼 그리드]
  │   ├─ 컴포넌트 C (4 컬럼)
  │   ├─ 컴포넌트 D (4 컬럼)
  │   ├─ 컴포넌트 E (4 컬럼)
  │   └─ [자동 배치]
  │
  └─ 행 3 (Row 3) [12 컬럼 그리드]
      └─ 컴포넌트 F (12 컬럼 - 전체)

2. 허용되는 컬럼 스팬

프리셋 컬럼 수 백분율 용도
full 12 100% 전체 너비 (테이블, 제목 등)
threeQuarters 9 75% 입력 필드
twoThirds 8 67% 큰 컴포넌트
half 6 50% 2분할 레이아웃
third 4 33% 3분할 레이아웃
quarter 3 25% 라벨, 4분할
label 3 25% 폼 라벨 전용
input 9 75% 폼 입력 전용
small 2 17% 아이콘, 체크박스
medium 4 33% 보통 크기
large 8 67% 큰 컴포넌트

3. 사용자 워크플로우

1. 새 행 추가
   ↓
2. 행에 컴포넌트 드래그 & 드롭
   ↓
3. 컴포넌트 선택 → 컬럼 스팬 선택
   ↓
4. 필요시 시작 위치 조정 (고급 설정)
   ↓
5. 행 간격, 정렬 등 설정

📅 구현 단계 (4주 계획)

Week 1: 기반 구축

Day 1-2: 타입 시스템

  • Size 인터페이스에서 width 제거
  • BaseComponentgridColumnSpan, gridRowIndex 추가
  • ColumnSpanPreset 타입 및 상수 정의
  • LayoutRow 인터페이스 정의

Day 3-4: 핵심 UI 컴포넌트

  • PropertiesPanel - width 입력 → 컬럼 스팬 선택 UI로 변경
  • 시각적 그리드 프리뷰 추가 (12컬럼 미니 그리드)
  • RowSettingsPanel 신규 생성 (행 설정)
  • ComponentGridPanel 신규 생성 (컴포넌트 너비 설정)

Day 5: 렌더링 로직

  • LayoutRowRenderer 신규 생성
  • ContainerComponent - gridColumn 계산 로직 수정
  • RealtimePreview - 그리드 클래스 적용

Day 6-7: 마이그레이션 준비

  • widthToColumnSpan.ts 유틸리티 작성
  • 기존 데이터 변환 함수 작성
  • Y 좌표 → 행 인덱스 변환 로직

Week 2: 레이아웃 시스템

Day 1-2: GridLayoutBuilder

  • GridLayoutBuilder 메인 컴포넌트
  • 행 추가/삭제/순서 변경 기능
  • 행 선택 및 하이라이트

Day 3-4: 드래그앤드롭

  • 컴포넌트를 행에 드롭하는 기능
  • 행 내에서 컴포넌트 순서 변경
  • 행 간 컴포넌트 이동
  • 드롭 가이드라인 표시

Day 5-7: StyleEditor 정리

  • StyleEditor에서 width 옵션 완전 제거
  • ScreenDesigner에서 width 관련 로직 제거
  • 높이 설정만 남기기

Week 3: 템플릿 및 패턴

Day 1-3: 템플릿 시스템

  • TemplateComponent 타입 수정
  • 기본 폼 템플릿 업데이트
  • 검색 + 테이블 템플릿
  • 대시보드 템플릿
  • 마스터-디테일 템플릿

Day 4-5: 레이아웃 패턴

  • 정형화된 레이아웃 패턴 정의
  • 패턴 선택 UI
  • 패턴 적용 로직
  • 빠른 패턴 삽입 버튼

Day 6-7: 반응형 기반 (선택)

  • 브레이크포인트별 컬럼 스팬 설정
  • 반응형 편집 UI
  • 반응형 프리뷰

Week 4: 마이그레이션 및 안정화

Day 1-2: 자동 마이그레이션

  • 화면 로드 시 자동 변환 로직
  • 마이그레이션 로그 및 검증
  • 에러 처리 및 fallback

Day 3-4: 통합 테스트

  • 새 컴포넌트 생성 테스트
  • 기존 화면 로드 테스트
  • 템플릿 적용 테스트
  • 드래그앤드롭 테스트
  • 속성 편집 테스트

Day 5: Tailwind 설정

  • tailwind.config.js safelist 추가
  • 불필요한 유틸리티 제거
  • 빌드 테스트

Day 6-7: 문서화 및 배포

  • 사용자 가이드 작성
  • 개발자 문서 업데이트
  • 릴리즈 노트 작성
  • 점진적 배포

📁 수정/생성 파일 전체 목록

🆕 신규 생성 파일 (15개)

  1. frontend/types/grid-system.ts - 그리드 시스템 타입
  2. frontend/lib/constants/columnSpans.ts - 컬럼 스팬 상수
  3. frontend/lib/utils/widthToColumnSpan.ts - 마이그레이션 유틸
  4. frontend/lib/utils/gridLayoutUtils.ts - 그리드 레이아웃 헬퍼
  5. frontend/components/screen/GridLayoutBuilder.tsx - 메인 빌더
  6. frontend/components/screen/LayoutRowRenderer.tsx - 행 렌더러
  7. frontend/components/screen/AddRowButton.tsx - 행 추가 버튼
  8. frontend/components/screen/GridGuides.tsx - 그리드 가이드라인
  9. frontend/components/screen/GridDropZone.tsx - 드롭존
  10. frontend/components/screen/panels/RowSettingsPanel.tsx - 행 설정
  11. frontend/components/screen/panels/ComponentGridPanel.tsx - 컴포넌트 너비
  12. frontend/components/screen/panels/ResponsivePanel.tsx - 반응형 설정
  13. frontend/lib/templates/layoutPatterns.ts - 레이아웃 패턴
  14. frontend/hooks/useGridLayout.ts - 그리드 레이아웃 훅
  15. frontend/hooks/useRowManagement.ts - 행 관리 훅

✏️ 수정 파일 (20개)

  1. frontend/types/screen-management.ts - Size에서 width 제거
  2. frontend/components/screen/panels/PropertiesPanel.tsx - UI 대폭 수정
  3. frontend/components/screen/StyleEditor.tsx - width 옵션 제거
  4. frontend/components/screen/ScreenDesigner.tsx - 전체 로직 수정
  5. frontend/components/screen/RealtimePreviewDynamic.tsx - 그리드 클래스
  6. frontend/components/screen/InteractiveScreenViewerDynamic.tsx - 그리드 클래스
  7. frontend/components/screen/layout/ContainerComponent.tsx - 렌더링 수정
  8. frontend/components/screen/layout/ColumnComponent.tsx - 렌더링 수정
  9. frontend/components/screen/layout/RowComponent.tsx - 렌더링 수정
  10. frontend/components/screen/panels/TemplatesPanel.tsx - 템플릿 수정
  11. frontend/components/screen/panels/DataTableConfigPanel.tsx - 모달 크기 유지
  12. frontend/components/screen/panels/DetailSettingsPanel.tsx - 검토 필요
  13. frontend/components/screen/panels/ComponentsPanel.tsx - 컴포넌트 생성
  14. frontend/components/screen/panels/LayoutsPanel.tsx - 레이아웃 적용
  15. frontend/components/screen/templates/DataTableTemplate.tsx - 템플릿 수정
  16. frontend/lib/api/screen.ts - 마이그레이션 로직 추가
  17. tailwind.config.js - safelist 추가
  18. frontend/components/screen/FloatingPanel.tsx - 검토 (패널 width 유지)
  19. frontend/components/screen/SaveModal.tsx - 검토
  20. frontend/components/screen/EditModal.tsx - 검토

🎨 핵심 UI 변경사항

1. 컴포넌트 너비 설정 (Before → After)

Before:

<Label>너비</Label>
<Input
  type="number"
  value={width}
  onChange={(e) => setWidth(e.target.value)}
/>
// 사용자가 아무 숫자나 입력 가능 (850, 1234 등)

After:

<Label>컴포넌트 너비</Label>
<Select value={columnSpan} onValueChange={setColumnSpan}>
  <SelectItem value="full">전체 (12/12 - 100%)</SelectItem>
  <SelectItem value="half">절반 (6/12 - 50%)</SelectItem>
  <SelectItem value="third">1/3 (4/12 - 33%)</SelectItem>
  {/* ... 정해진 옵션만 */}
</Select>

{/* 시각적 프리뷰 */}
<div className="grid grid-cols-12 gap-1 h-6">
  {Array.from({ length: 12 }).map((_, i) => (
    <div className={i < spanValue ? "bg-blue-500" : "bg-gray-100"} />
  ))}
</div>
<p>6 / 12 컬럼</p>

2. 행(Row) 관리 UI (신규)

{
  /* 각 행에 설정 가능한 옵션 */
}
<RowSettings>
  <Label> 높이</Label>
  <Select>
    <SelectItem value="auto">자동</SelectItem>
    <SelectItem value="fixed">고정</SelectItem>
  </Select>

  <Label>컴포넌트 간격</Label>
  <ButtonGroup>
    <Button>없음</Button>
    <Button>작게 (16px)</Button>
    <Button>보통 (24px)</Button>
    <Button>크게 (32px)</Button>
  </ButtonGroup>

  <Label>정렬</Label>
  <ButtonGroup>
    <Button>왼쪽</Button>
    <Button>중앙</Button>
    <Button>오른쪽</Button>
    <Button>늘림</Button>
  </ButtonGroup>
</RowSettings>;

3. 드래그앤드롭 경험 개선

{
  /* 빈 행 */
}
<div className="border-dashed border-2 p-8">
  컴포넌트를 여기에 드래그하세요
  {/* 빠른 패턴 버튼 */}
  <div className="mt-4 flex gap-2">
    <Button size="sm">  추가</Button>
    <Button size="sm">2분할 추가</Button>
    <Button size="sm">3분할 추가</Button>
  </div>
</div>;

{
  /* 드롭 시 그리드 가이드라인 표시 */
}
<div className="absolute inset-0 pointer-events-none">
  {/* 12개 컬럼 구분선 */}
  {Array.from({ length: 12 }).map((_, i) => (
    <div className="border-l border-dashed border-blue-300" />
  ))}
</div>;

🔍 마이그레이션 상세 전략

1. 자동 변환 알고리즘

// 기존 컴포넌트 변환 프로세스
function migrateComponent(oldComponent: OldComponentData): ComponentData {
  // Step 1: 픽셀 width → 컬럼 스팬
  const gridColumnSpan = convertWidthToColumnSpan(
    oldComponent.size.width,
    1920 // 기준 캔버스 너비
  );

  // Step 2: Y 좌표 → 행 인덱스
  const gridRowIndex = calculateRowIndex(
    oldComponent.position.y,
    allComponents
  );

  // Step 3: X 좌표 → 시작 컬럼 (같은 행 내)
  const gridColumnStart = calculateColumnStart(
    oldComponent.position.x,
    rowComponents
  );

  return {
    ...oldComponent,
    gridColumnSpan,
    gridRowIndex,
    gridColumnStart,
    size: {
      height: oldComponent.size.height, // 높이만 유지
      // width 제거
    },
  };
}

2. 변환 정확도 보장

// 변환 전후 비교
const before = {
  position: { x: 100, y: 50 },
  size: { width: 960, height: 40 }, // 50% 너비
};

const after = {
  gridRowIndex: 0,
  gridColumnSpan: "half", // 정확히 50%
  gridColumnStart: 1, // 자동 계산
  size: { height: 40 },
};

// 시각적으로 동일한 결과 보장

3. 예외 처리

// 변환 불가능한 경우 처리
function migrateWithFallback(component: OldComponentData): ComponentData {
  try {
    return migrateComponent(component);
  } catch (error) {
    console.error("마이그레이션 실패:", error);

    // Fallback: 기본값 사용
    return {
      ...component,
      gridColumnSpan: "half", // 안전한 기본값
      gridRowIndex: 0,
      size: { height: component.size.height },
    };
  }
}

⚠️ 주의사항 및 제약

1. 제거되는 기능

  • 픽셀 단위 정밀 너비 조정
  • 자유로운 width 숫자 입력
  • 커스텀 width 값

2. 유지되는 기능

  • 높이(height) 픽셀 입력
  • 위치(Y 좌표) 조정
  • 모든 스타일 옵션 (width 제외)

3. 특수 케이스 처리

3.1 모달/팝업

// 모달은 컬럼 스팬 사용 안 함
interface ModalConfig {
  width: "sm" | "md" | "lg" | "xl" | "2xl" | "full"; // 기존 유지
}

3.2 FloatingPanel

// 편집 패널 자체는 픽셀 width 유지
<FloatingPanel width={360} height={400} />

3.3 사이드바

// 사이드바도 컬럼 스팬으로 변경
interface SidebarConfig {
  sidebarSpan: ColumnSpanPreset; // "quarter" | "third" | "half"
}

🎯 완료 기준

기능 완성도

  • 모든 기존 화면이 새 시스템에서 정상 표시
  • 새 컴포넌트 생성 및 배치 정상 동작
  • 템플릿 적용 정상 동작
  • 드래그앤드롭 정상 동작

코드 품질

  • TypeScript 에러 0개
  • Linter 경고 0개
  • 불필요한 width 관련 코드 완전 제거
  • 주석 및 문서화 완료

성능

  • 렌더링 성능 저하 없음
  • 마이그레이션 속도 < 1초 (화면당)
  • 메모리 사용량 증가 없음

사용자 경험

  • 직관적인 UI
  • 시각적 프리뷰 제공
  • 빠른 패턴 적용
  • 에러 메시지 명확

📊 예상 효과

정량적 효과

  • 코드 라인 감소: ~500줄 (width 계산 로직 제거)
  • 버그 감소: width 관련 버그 100% 제거
  • 개발 속도: 화면 구성 시간 30% 단축
  • 유지보수: width 관련 이슈 0건

정성적 효과

  • 일관된 디자인 시스템
  • 학습 곡선 감소
  • Tailwind 표준 준수
  • 반응형 자동 대응 (추후)
  • 디자인 품질 향상

🚀 다음 단계

즉시 시작 가능

  1. Phase 1 타입 정의 작성
  2. PropertiesPanel UI 목업
  3. 마이그레이션 유틸리티 스켈레톤

추후 확장

  1. 반응형 브레이크포인트
  2. 커스텀 레이아웃 패턴 저장
  3. AI 기반 레이아웃 추천
  4. 컴포넌트 자동 정렬

📚 관련 문서


이 로드맵을 따라 진행하면 4주 내에 완전히 새로운 그리드 시스템을 구축할 수 있습니다! 🎉

준비되셨나요? 어디서부터 시작하시겠습니까? 💪