Files
vexplor/docs/screen-implementation-guide/00_analysis/next-component-development-plan.md
kjs 6505df8555 feat: enhance v2-timeline-scheduler component functionality
- Updated the v2-timeline-scheduler documentation to reflect the latest implementation status and enhancements.
- Improved the TimelineSchedulerComponent by integrating conflict detection and milestone rendering features.
- Refactored ResourceRow and ScheduleBar components to support new props for handling conflicts and milestones.
- Added visual indicators for conflicts and milestones to enhance user experience and clarity in scheduling.

These changes aim to improve the functionality and usability of the timeline scheduler within the ERP system.

Made-with: Cursor
2026-03-16 10:40:10 +09:00

19 KiB

다음 구현 필요 컴포넌트 개발 계획

작성일: 2026-01-30 상태: 계획 수립 완료 우선순위: v2-table-grouped (1순위) → v2-timeline-scheduler (2순위)


개요

생산계획관리 화면의 정식 버전 구현을 위해 필요한 2개의 신규 컴포넌트 개발 계획입니다.

컴포넌트 용도 난이도 예상 작업량
v2-table-grouped 그룹화 테이블 (접기/펼치기) 2-3일
v2-timeline-scheduler 타임라인/간트차트 스케줄러 5-7일

1. v2-table-grouped (그룹화 테이블)

1.1 컴포넌트 개요

항목 내용
컴포넌트 ID v2-table-grouped
카테고리 DISPLAY
용도 데이터를 특정 컬럼 기준으로 그룹화하여 접기/펼치기 기능 제공
기반 컴포넌트 v2-table-list 확장
참고 UI Excel 그룹화, VS Code 파일 그룹화

1.2 핵심 기능

기능 설명 우선순위
그룹화 지정된 컬럼 기준으로 데이터 그룹핑 필수
접기/펼치기 그룹 행 클릭 시 하위 항목 토글 필수
그룹 요약 그룹별 합계/개수 표시 필수
다중 그룹 여러 컬럼 기준 중첩 그룹화 선택
그룹 선택 그룹 체크박스로 하위 전체 선택 필수
전체 펼치기/접기 모든 그룹 일괄 토글 필수

1.3 UI 목업

┌─────────────────────────────────────────────────────────────────┐
│ [전체 펼치기] [전체 접기]                              [3개 그룹] │
├─────────────────────────────────────────────────────────────────┤
│ ▼ □ 품목A (P001)                           수량: 150  3건      │
│   ├─ □ 2026-01-15  생산계획001  50개   설비A                   │
│   ├─ □ 2026-01-16  생산계획002  50개   설비B                   │
│   └─ □ 2026-01-17  생산계획003  50개   설비A                   │
├─────────────────────────────────────────────────────────────────┤
│ ► □ 품목B (P002)                           수량: 200  2건      │  ← 접힌 상태
├─────────────────────────────────────────────────────────────────┤
│ ▼ □ 품목C (P003)                           수량: 100  1건      │
│   └─ □ 2026-01-18  생산계획004  100개  설비C                   │
└─────────────────────────────────────────────────────────────────┘

1.4 타입 정의 (types.ts)

import { ColumnConfig } from "../v2-table-list/types";

/**
 * 그룹화 설정
 */
export interface GroupConfig {
  /** 그룹화 기준 컬럼 */
  groupByColumn: string;
  
  /** 그룹 표시 형식 (예: "{item_name} ({item_code})") */
  groupLabelFormat?: string;
  
  /** 그룹 요약 설정 */
  summary?: {
    /** 합계 컬럼 */
    sumColumns?: string[];
    /** 개수 표시 여부 */
    showCount?: boolean;
  };
  
  /** 초기 펼침 상태 */
  defaultExpanded?: boolean;
  
  /** 중첩 그룹 (다중 그룹화) */
  nestedGroup?: GroupConfig;
}

/**
 * 그룹화 테이블 설정
 */
export interface TableGroupedConfig {
  /** 테이블명 */
  selectedTable?: string;
  
  /** 커스텀 테이블 사용 */
  useCustomTable?: boolean;
  customTableName?: string;
  
  /** 그룹화 설정 */
  groupConfig: GroupConfig;
  
  /** 컬럼 설정 (v2-table-list와 동일) */
  columns?: ColumnConfig[];
  
  /** 체크박스 표시 */
  showCheckbox?: boolean;
  
  /** 체크박스 모드 */
  checkboxMode?: "single" | "multi";
  
  /** 페이지네이션 (그룹 단위) */
  pagination?: {
    enabled: boolean;
    pageSize: number;
  };
  
  /** 정렬 설정 */
  defaultSort?: {
    column: string;
    direction: "asc" | "desc";
  };
}

/**
 * 그룹 상태
 */
export interface GroupState {
  /** 그룹 키 (groupByColumn 값) */
  groupKey: string;
  
  /** 펼침 여부 */
  expanded: boolean;
  
  /** 그룹 내 데이터 */
  items: any[];
  
  /** 그룹 요약 데이터 */
  summary?: Record<string, number>;
}

1.5 파일 구조

frontend/lib/registry/components/v2-table-grouped/
├── index.ts                      # Definition (V2TableGroupedDefinition)
├── types.ts                      # 타입 정의
├── config.ts                     # 기본 설정값
├── TableGroupedComponent.tsx     # 메인 컴포넌트
├── TableGroupedConfigPanel.tsx   # 설정 패널
├── TableGroupedRenderer.tsx      # 레지스트리 등록
├── components/
│   ├── GroupHeader.tsx           # 그룹 헤더 (펼치기/접기)
│   ├── GroupSummary.tsx          # 그룹 요약
│   └── GroupCheckbox.tsx         # 그룹 체크박스
├── hooks/
│   └── useGroupedData.ts         # 그룹화 로직 훅
└── README.md

1.6 구현 단계

단계 작업 내용 예상 시간
1 타입 정의 및 기본 구조 생성 2시간
2 useGroupedData 훅 구현 (데이터 그룹화 로직) 4시간
3 GroupHeader 컴포넌트 (펼치기/접기 UI) 2시간
4 TableGroupedComponent 메인 구현 6시간
5 그룹 체크박스 연동 2시간
6 그룹 요약 (합계/개수) 2시간
7 TableGroupedConfigPanel 설정 패널 4시간
8 테스트 및 문서화 2시간

총 예상: 24시간 (약 3일)

1.7 v2-table-list와의 차이점

항목 v2-table-list v2-table-grouped
데이터 구조 플랫 리스트 계층 구조 (그룹 > 아이템)
렌더링 행 단위 그룹 헤더 + 상세 행
선택 개별 행 그룹 단위 / 개별 단위
요약 전체 합계 (선택) 그룹별 요약
페이지네이션 행 단위 그룹 단위

2. v2-timeline-scheduler (타임라인 스케줄러)

2.1 컴포넌트 개요

항목 내용
컴포넌트 ID v2-timeline-scheduler
카테고리 DISPLAY
용도 간트차트 형태의 일정/계획 시각화 및 편집
참고 UI MS Project, Jira Timeline, dhtmlxGantt
외부 라이브러리 고려 중: @tanstack/react-virtual (가상 스크롤)

2.2 핵심 기능

기능 설명 우선순위
타임라인 그리드 날짜 기준 그리드 표시 (일/주/월) 필수
스케줄 바 시작~종료 기간 바 렌더링 필수
리소스 행 설비/작업자별 행 구분 필수
드래그 이동 스케줄 바 드래그로 날짜 변경 필수
리사이즈 바 양쪽 핸들로 기간 조정 필수
줌 레벨 일/주/월 단위 전환 필수
충돌 표시 같은 리소스 시간 겹침 경고 선택
진행률 표시 바 내부 진행률 표시 선택
마일스톤 단일 일정 마커 선택

2.3 UI 목업

┌──────────────────────────────────────────────────────────────────────────────┐
│ [◀ 이전] [오늘] [다음 ▶]  2026년 1월           [일] [주] [월]   [+ 추가]     │
├────────────┬─────────────────────────────────────────────────────────────────┤
│            │ 15(수) │ 16(목) │ 17(금) │ 18(토) │ 19(일) │ 20(월) │ 21(화) │
├────────────┼─────────────────────────────────────────────────────────────────┤
│ 설비A      │ ████████████████                                               │
│            │ [생산계획001]   │                                               │
├────────────┼─────────────────────────────────────────────────────────────────┤
│ 설비B      │        █████████████████████████                               │
│            │        [생산계획002        ]                                    │
├────────────┼─────────────────────────────────────────────────────────────────┤
│ 설비C      │                        ████████████████                        │
│            │                        [생산계획003]                            │
└────────────┴─────────────────────────────────────────────────────────────────┘

범례: ██ 진행중  ██ 완료  ██ 지연  ◆ 마일스톤

2.4 타입 정의 (types.ts)

/**
 * 줌 레벨
 */
export type ZoomLevel = "day" | "week" | "month";

/**
 * 스케줄 상태
 */
export type ScheduleStatus = "planned" | "in_progress" | "completed" | "delayed" | "cancelled";

/**
 * 스케줄 항목
 */
export interface ScheduleItem {
  /** 고유 ID */
  id: string;
  
  /** 리소스 ID (설비/작업자) */
  resourceId: string;
  
  /** 표시 제목 */
  title: string;
  
  /** 시작 일시 */
  startDate: string;  // ISO 8601 format
  
  /** 종료 일시 */
  endDate: string;
  
  /** 상태 */
  status: ScheduleStatus;
  
  /** 진행률 (0-100) */
  progress?: number;
  
  /** 색상 (CSS color) */
  color?: string;
  
  /** 추가 데이터 */
  data?: Record<string, any>;
}

/**
 * 리소스 (행)
 */
export interface Resource {
  /** 리소스 ID */
  id: string;
  
  /** 표시명 */
  name: string;
  
  /** 그룹 (선택) */
  group?: string;
  
  /** 아이콘 (선택) */
  icon?: string;
  
  /** 용량 (선택, 충돌 계산용) */
  capacity?: number;
}

/**
 * 타임라인 설정
 */
export interface TimelineSchedulerConfig {
  /** 테이블명 (스케줄 데이터) */
  selectedTable?: string;
  
  /** 리소스 테이블명 */
  resourceTable?: string;
  
  /** 필드 매핑 */
  fieldMapping: {
    id: string;
    resourceId: string;
    title: string;
    startDate: string;
    endDate: string;
    status?: string;
    progress?: string;
    color?: string;
  };
  
  /** 리소스 필드 매핑 */
  resourceFieldMapping?: {
    id: string;
    name: string;
    group?: string;
  };
  
  /** 초기 줌 레벨 */
  defaultZoomLevel?: ZoomLevel;
  
  /** 초기 표시 날짜 */
  initialDate?: string;
  
  /** 편집 가능 여부 */
  editable?: boolean;
  
  /** 드래그 이동 허용 */
  allowDrag?: boolean;
  
  /** 리사이즈 허용 */
  allowResize?: boolean;
  
  /** 충돌 체크 */
  checkConflicts?: boolean;
  
  /** 상태별 색상 */
  statusColors?: Record<ScheduleStatus, string>;
  
  /** 리소스 컬럼 너비 */
  resourceColumnWidth?: number;
  
  /** 행 높이 */
  rowHeight?: number;
  
  /** 셀 너비 (줌 레벨별) */
  cellWidth?: {
    day: number;
    week: number;
    month: number;
  };
  
  /** 툴바 표시 */
  showToolbar?: boolean;
  
  /** 범례 표시 */
  showLegend?: boolean;
}

/**
 * 이벤트 핸들러
 */
export interface TimelineEvents {
  /** 스케줄 클릭 */
  onScheduleClick?: (schedule: ScheduleItem) => void;
  
  /** 스케줄 더블클릭 */
  onScheduleDoubleClick?: (schedule: ScheduleItem) => void;
  
  /** 드래그 완료 */
  onScheduleDrag?: (schedule: ScheduleItem, newStart: Date, newEnd: Date) => void;
  
  /** 리사이즈 완료 */
  onScheduleResize?: (schedule: ScheduleItem, newStart: Date, newEnd: Date) => void;
  
  /** 빈 영역 클릭 (새 스케줄 추가용) */
  onEmptyClick?: (resourceId: string, date: Date) => void;
}

2.5 파일 구조

frontend/lib/registry/components/v2-timeline-scheduler/
├── index.ts                          # Definition (V2TimelineSchedulerDefinition)
├── types.ts                          # 타입 정의
├── config.ts                         # 기본 설정값
├── TimelineSchedulerComponent.tsx    # 메인 컴포넌트
├── TimelineSchedulerConfigPanel.tsx  # 설정 패널
├── TimelineSchedulerRenderer.tsx     # 레지스트리 등록
├── components/
│   ├── TimelineHeader.tsx            # 날짜 헤더
│   ├── TimelineGrid.tsx              # 그리드 배경
│   ├── ResourceColumn.tsx            # 리소스 컬럼 (좌측)
│   ├── ScheduleBar.tsx               # 스케줄 바 (드래그/리사이즈)
│   ├── TimelineToolbar.tsx           # 툴바 (줌, 네비게이션)
│   ├── TimelineLegend.tsx            # 범례
│   └── ConflictIndicator.tsx         # 충돌 표시
├── hooks/
│   ├── useTimelineState.ts           # 타임라인 상태 관리
│   ├── useScheduleDrag.ts            # 드래그 로직
│   ├── useScheduleResize.ts          # 리사이즈 로직
│   └── useDateCalculation.ts         # 날짜/위치 계산
├── utils/
│   ├── dateUtils.ts                  # 날짜 유틸리티
│   └── conflictDetection.ts          # 충돌 감지
└── README.md

2.6 구현 단계

단계 작업 내용 예상 시간
1 타입 정의 및 기본 구조 생성 3시간
2 TimelineHeader (날짜 헤더, 줌 레벨) 4시간
3 TimelineGrid (그리드 배경) 3시간
4 ResourceColumn (리소스 목록) 2시간
5 ScheduleBar 기본 렌더링 4시간
6 드래그 이동 구현 6시간
7 리사이즈 구현 4시간
8 줌 레벨 전환 (일/주/월) 3시간
9 날짜 네비게이션 2시간
10 충돌 감지 및 표시 4시간
11 가상 스크롤 (대용량 데이터) 4시간
12 TimelineSchedulerConfigPanel 4시간
13 API 연동 (저장/로드) 4시간
14 테스트 및 문서화 3시간

총 예상: 50시간 (약 6-7일)

2.7 핵심 알고리즘

날짜 → 픽셀 위치 변환

function dateToPosition(date: Date, viewStart: Date, cellWidth: number, zoomLevel: ZoomLevel): number {
  const diffMs = date.getTime() - viewStart.getTime();
  
  switch (zoomLevel) {
    case "day":
      const diffDays = diffMs / (1000 * 60 * 60 * 24);
      return diffDays * cellWidth;
    case "week":
      const diffWeeks = diffMs / (1000 * 60 * 60 * 24 * 7);
      return diffWeeks * cellWidth;
    case "month":
      // 월 단위는 일수가 다르므로 별도 계산
      return calculateMonthPosition(date, viewStart, cellWidth);
  }
}

충돌 감지

function detectConflicts(schedules: ScheduleItem[], resourceId: string): ScheduleItem[][] {
  const resourceSchedules = schedules
    .filter(s => s.resourceId === resourceId)
    .sort((a, b) => new Date(a.startDate).getTime() - new Date(b.startDate).getTime());
  
  const conflicts: ScheduleItem[][] = [];
  
  for (let i = 0; i < resourceSchedules.length; i++) {
    const current = resourceSchedules[i];
    const overlapping = resourceSchedules.filter(s => 
      s.id !== current.id &&
      new Date(s.startDate) < new Date(current.endDate) &&
      new Date(s.endDate) > new Date(current.startDate)
    );
    
    if (overlapping.length > 0) {
      conflicts.push([current, ...overlapping]);
    }
  }
  
  return conflicts;
}

3. 구현 우선순위 및 일정

3.1 권장 순서

1단계: v2-table-grouped (2-3일)
  ↓
2단계: v2-timeline-scheduler (5-7일)
  ↓
3단계: 생산계획관리 정식 버전 화면 구성 (1-2일)

3.2 이유

  1. v2-table-grouped 먼저:

    • v2-table-list 기반 확장으로 난이도 낮음
    • 생산계획 외 다른 화면(BOM, 수주 등)에서도 활용 가능
    • 타임라인 개발 중에도 테스트용으로 사용 가능
  2. v2-timeline-scheduler 나중:

    • 복잡도가 높아 집중 개발 필요
    • 드래그/리사이즈 등 인터랙션 테스트 필요
    • 생산계획관리 전용 컴포넌트

3.3 체크리스트

v2-table-grouped 구현 완료 (2026-01-30)

  • 타입 정의 완료
  • 기본 구조 생성
  • useGroupedData 훅 구현
  • GroupHeader 컴포넌트
  • 메인 컴포넌트 구현
  • 그룹 체크박스 연동
  • 그룹 요약 (합계/개수)
  • 설정 패널 구현
  • 레지스트리 등록
  • 문서화 (README.md)

v2-timeline-scheduler 구현 완료 (2026-01-30, 업데이트: 2026-03-13)

  • 타입 정의 완료
  • 기본 구조 생성
  • TimelineHeader (날짜)
  • TimelineGrid (배경)
  • ResourceColumn (리소스)
  • ScheduleBar 기본 렌더링
  • 드래그 이동 (실제 로직: deltaX → 날짜 계산 → API 저장 → toast)
  • 리사이즈 (실제 로직: 시작/종료 핸들 → 기간 변경 → API 저장 → toast)
  • 줌 레벨 전환
  • 날짜 네비게이션
  • 충돌 감지 (같은 리소스 겹침 → ring-destructive + AlertTriangle)
  • 마일스톤 표시 (시작일 = 종료일 → 다이아몬드 마커)
  • 범례 표시 (TimelineLegend: 상태별 색상 + 마일스톤 + 충돌)
  • 반응형 공통 CSS 적용 (text-[10px] sm:text-sm 패턴)
  • staticFilters 지원 (커스텀 테이블 필터링)
  • 가상 스크롤 (향후 - 대용량 100+ 리소스)
  • 설정 패널 구현
  • API 연동
  • 레지스트리 등록
  • 테스트 완료
  • 문서화 (README.md)

4. 참고 자료

기존 V2 컴포넌트 참고

  • v2-table-list: 테이블 렌더링, 체크박스, 페이지네이션
  • v2-pivot-grid: 복잡한 그리드 렌더링, 가상 스크롤
  • v2-split-panel-layout: 커스텀 모드 컴포넌트 배치

외부 라이브러리 검토

라이브러리 용도 고려 사항
@tanstack/react-virtual 가상 스크롤 이미 사용 중, 확장 용이
date-fns 날짜 계산 이미 사용 중
react-dnd 드래그앤드롭 검토 필요, 현재 네이티브 구현

관련 문서


작성자: Claude AI 최종 수정: 2026-01-30