diff --git a/claudedocs/[REVIEW] MD-to-PPTX 자동화 파이프라인 검토서.md b/claudedocs/[REVIEW] MD-to-PPTX 자동화 파이프라인 검토서.md new file mode 100644 index 00000000..7c7af6db --- /dev/null +++ b/claudedocs/[REVIEW] MD-to-PPTX 자동화 파이프라인 검토서.md @@ -0,0 +1,313 @@ +# MD 기반 MES/ERP 기획서 자동화 파이프라인 검토서 + +> **작성일**: 2026-02-10 +> **작성**: 류병철 / Claude Code +> **목적**: 회의록/인터뷰 → MD → PPTX → 프론트엔드 자동화 파이프라인의 실현 가능성 검증 및 팀 검토 +> **PoC 대상**: 주일기업 MES (자동방화셔터 시공 관리 시스템) + +--- + +## 1. 배경 및 목적 + +### 1.1 해결하려는 문제 + +MES/ERP 프로젝트에서 반복되는 비효율: + +| 단계 | 현재 문제 | +|------|----------| +| 요구사항 수집 | 인터뷰/회의 내용이 구두로만 전달, 누락 빈번 | +| 기획서 작성 | 수작업 PPTX 제작에 1~2주 소요 | +| 고객 확인 | 기획서 수정 → PPTX 재작업의 반복 | +| 개발 착수 | 기획서와 실제 구현 간 해석 차이 발생 | +| 변경 관리 | 기획서-코드 간 동기화 안 됨 | + +### 1.2 제안 개념 + +**MD 파일을 Single Source of Truth로** 사용하여, 하나의 문서에서 기획서(PPTX)와 코드(프론트엔드)를 모두 파생시키는 자동화 파이프라인. + +``` +인터뷰/녹음 → MD 명세서 → PPTX 기획서 (고객 확인용) + → 프론트엔드 코드 (개발용) + → API 구조 설계 (백엔드용) +``` + +--- + +## 2. 파이프라인 설계 + +### 2.1 전체 흐름 + +``` +┌─────────────────────────────────────────────────────────────────┐ +│ 1단계: 요구사항 수집 │ +│ 인터뷰 / 현장 방문 / 녹음 → 녹취록 + 원본 자료 │ +└──────────────────────────┬──────────────────────────────────────┘ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ 2단계: MD 명세서 작성 │ +│ 녹취록 + 업종 체크리스트 → 구조화된 MD 파일 │ +│ (화면 구성, 데이터 모델, 상태 머신, API 엔드포인트 포함) │ +└──────────────────────────┬──────────────────────────────────────┘ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ 3단계: PPTX 기획서 자동 생성 │ +│ MD → Claude → python-pptx 스크립트 → 와이어프레임 PPTX │ +│ 고객과 화면 단위로 검토 및 승인 │ +└──────────────────────────┬──────────────────────────────────────┘ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ 4단계: 프론트엔드 + API 구조 설계 │ +│ 승인된 MD + 기존 컴포넌트 라이브러리 → 화면 코드 생성 │ +│ Mock API로 즉시 동작 가능한 프로토타입 구성 │ +└──────────────────────────┬──────────────────────────────────────┘ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ 5단계: 프로토타입 테스트 │ +│ Mock API 기반 프로토타입으로 고객/내부 테스트 │ +│ 피드백 → MD 역반영 → 영향 범위 파악 │ +└──────────────────────────┬──────────────────────────────────────┘ + ▼ +┌─────────────────────────────────────────────────────────────────┐ +│ 6단계: 실 API 연동 + 최종 검수 │ +│ Mock → 실제 API 교체 → 통합 테스트 → 고객 최종 검수 │ +└─────────────────────────────────────────────────────────────────┘ +``` + +### 2.2 각 단계 상세 + +#### 1단계: 요구사항 수집 + +| 항목 | 내용 | +|------|------| +| 입력 | 고객 인터뷰, 현장 녹음, 기존 시스템 스크린샷, 업무 매뉴얼 | +| 출력 | 녹취록 + 수집 자료 원본 | +| 담당 | 기획자 / PM | +| 도구 | 녹음 앱, 스크린샷 도구 | + +#### 2단계: MD 명세서 작성 + +| 항목 | 내용 | +|------|------| +| 입력 | 녹취록 + 업종별 체크리스트 | +| 출력 | 구조화된 MD 파일 (단일 파일) | +| 담당 | 기획자 + Claude 보조 | +| 도구 | Claude Code, 텍스트 에디터 | + +**MD에 포함되어야 할 섹션:** +- 시스템 개요 (목적, 모듈 구성) +- 역할/권한 시스템 +- 화면별 상세 명세 (레이아웃, 컴포넌트, 데이터) +- 상태 머신 (비즈니스 흐름) +- 데이터 모델 +- API 엔드포인트 목록 +- PPTX 레이아웃 규격 (색상, 치수, 컴포넌트 정의) + +#### 3단계: PPTX 자동 생성 + +| 항목 | 내용 | +|------|------| +| 입력 | 2단계 MD 파일 | +| 출력 | 와이어프레임 기반 PPTX (python-pptx) | +| 담당 | Claude Code (자동) | +| 도구 | Python + python-pptx | + +#### 4단계: 프론트엔드 + API 설계 + +| 항목 | 내용 | +|------|------| +| 입력 | 승인된 MD + 기존 컴포넌트 라이브러리 | +| 출력 | 동작하는 프론트엔드 코드 + Mock API | +| 담당 | Claude Code + 개발자 검수 | +| 도구 | Next.js, 기존 organisms/molecules 컴포넌트 | + +#### 5단계: 프로토타입 테스트 + +| 항목 | 내용 | +|------|------| +| 입력 | Mock API 기반 프로토타입 | +| 출력 | 피드백 목록 + MD 수정 사항 | +| 담당 | 고객 + QA + 기획자 | +| 도구 | 브라우저, 피드백 시트 | + +#### 6단계: 실 API 연동 + 검수 + +| 항목 | 내용 | +|------|------| +| 입력 | 테스트 완료된 프론트 + 백엔드 API | +| 출력 | 운영 배포 가능한 시스템 | +| 담당 | 프론트엔드 + 백엔드 개발자 | +| 도구 | Laravel API, Next.js | + +--- + +## 3. PoC 검증 결과 (주일기업 MES) + +### 3.1 검증 범위 + +주일기업 MES(자동방화셔터 시공 관리 시스템)를 대상으로 **2단계 → 3단계** 구간을 검증. + +``` +실제 동작하는 화면 스크린샷 22장 + → 역기획서 MD 작성 (역기획서_주일기업MES.md) + → python-pptx 스크립트 생성 (generate_pptx.py, 약 71KB) + → PPTX 기획서 자동 생성 (22슬라이드, 102KB) + → PPTX 내용을 독립 MD 명세서로 변환 (주일기업_MES_PPTX_명세서.md, 891줄) + → 새 세션에서 MD만으로 PPTX 재생성 시도 (진행 중) +``` + +### 3.2 검증된 사항 + +| 검증 항목 | 결과 | 비고 | +|-----------|------|------| +| MD → Python 스크립트 생성 | 성공 | Claude가 MD를 읽고 python-pptx 코드 자동 생성 | +| 와이어프레임 PPTX 출력 | 성공 | 도형 기반 UI를 22슬라이드로 렌더링 | +| PPTX → MD 역변환 | 성공 | 891줄 명세서로 구조화 | +| MD만으로 PPTX 재생성 (새 세션) | 진행 중 | 이전 컨텍스트 없이 MD만으로 동일 품질 생성 가능한지 검증 | + +### 3.3 생성된 산출물 + +``` +~/Desktop/역기획서_스크린샷/ +├── 01~22_*.png # 원본 스크린샷 22장 +└── 역기획서_주일기업MES.md # 역기획서 (439줄) + +~/Desktop/주일기업_MES_기획서/ +├── generate_pptx.py # PPTX 생성 스크립트 (71KB) +├── 주일기업_MES_Storyboard_D1.0_260210.pptx # 생성된 PPTX (102KB) +├── preview/ # 슬라이드 미리보기 PNG 17장 +└── preview_markers.py # 마커 미리보기 스크립트 + +~/Desktop/주일 md to pptx test/ +└── 주일기업_MES_PPTX_명세서.md # 독립 MD 명세서 (891줄) +``` + +--- + +## 4. 비판적 분석 + +### 4.1 강점 + +| 강점 | 설명 | +|------|------| +| MD 중심 일관성 | 하나의 문서에서 기획서와 코드가 파생되므로 "기획서와 코드가 다른" 문제 원천 차단 | +| 기획서 작업 시간 단축 | 수작업 1~2주 → MD 작성 후 자동 생성으로 수 시간 내 완료 가능 | +| 기존 자산 재활용 | SAM 프로젝트의 organisms/molecules 컴포넌트를 그대로 활용 | +| 반복 가능한 프로세스 | 동일 파이프라인을 다른 고객사에도 적용 가능 | +| Mock-first 개발 | API 완성 전 프로토타입으로 빠른 피드백 가능 | + +### 4.2 리스크 및 대응 방안 + +#### 리스크 1: 1→2단계 정보 손실 (심각도: 높음) + +**문제**: 인터뷰/녹음에서 MD로 변환할 때 정보 손실이 가장 큼. MES/ERP 현장에는 "당연히 그렇게 하는" 암묵적 프로세스가 많아 인터뷰에서 언급되지 않는 경우가 빈번함. + +**예시**: "납기일 변경 시 관련 공정 전체 재계산", "특정 조건에서만 나타나는 승인 단계" 등 + +**대응 방안**: +- 업종별 필수 프로세스 체크리스트 사전 준비 +- 인터뷰 후 체크리스트 대조 → 누락 항목 2차 확인 +- MD 초안을 고객에게 텍스트 레벨로 먼저 검토받는 단계 추가 (2.5단계) + +#### 리스크 2: 고객의 와이어프레임 이해도 (심각도: 중간) + +**문제**: MES/ERP 사용자는 대부분 비개발자. 정적 와이어프레임만으로는 동적 흐름(상태 전환, 조건부 UI)을 파악하지 못하고, "확인했습니다" 후 프로토타입을 보고 "이게 아닌데요"가 발생. + +**대응 방안**: +- PPTX에 상태 머신, 시나리오 흐름을 명시 (PoC에서 이미 적용) +- 3단계와 5단계를 가까이 배치하여 클릭 가능한 프로토타입으로 보완 +- 주요 흐름은 슬라이드 여러 장으로 상태 변화를 시각적으로 나열 + +#### 리스크 3: API 설계 시점 (심각도: 중간) + +**문제**: API 구조 설계가 4단계에서 시작되면, 백엔드 제약사항(기존 DB 스키마, 외부 연동)이 프론트 설계를 뒤집을 수 있음. + +**대응 방안**: +- 2단계 MD에 데이터 모델 + API 엔드포인트 목록을 포함 (PoC에서 이미 적용) +- 백엔드 개발자가 2단계 MD 리뷰에 참여 +- API 제약사항을 3단계 이전에 확인 + +#### 리스크 4: 변경의 역전파 (심각도: 중간) + +**문제**: 5단계 테스트에서 변경 요청 발생 시, MD → PPTX → 코드 전체가 연쇄 수정되어야 함. 현재 파이프라인은 단방향이라 역방향 반영 체계가 없음. + +**대응 방안**: +- MD 버전 관리 (Git) +- 변경 요청 시 MD 먼저 수정 → PPTX/코드 재생성 순서 준수 +- 변경 영향 범위를 MD 섹션 단위로 추적 + +#### 리스크 5: 동시 다중 프로젝트 (심각도: 낮음, 현재) + +**문제**: 1~2단계(인터뷰 → MD)는 자동화가 어려워, 동시에 3~5개 고객 프로젝트를 진행하면 병목 발생. + +**대응 방안**: +- 업종별 MD 템플릿 사전 구축으로 2단계 작업량 감소 +- 3단계 이후는 자동화 비율이 높으므로 병목은 1~2단계에 집중 → 기획 인력 확보 + +--- + +## 5. 개선된 파이프라인 (제안) + +기존 6단계에 검증 게이트를 추가한 버전: + +``` +1단계 인터뷰/녹음 → 녹취록 + 원본 자료 + │ +2단계 녹취록 + 업종 체크리스트 → MD 명세서 (데이터 모델 + API 포함) + │ + ┌───── 2.5단계 고객 + 백엔드 개발자 MD 텍스트 리뷰 ──────┐ + │ (화면 만들기 전에 내용의 정확성 먼저 확인) │ + │ 승인 ✓ 수정 요청 → 2단계로 복귀 │ + └───────┬───────────────────────────────────────────────────┘ + │ +3단계 MD → PPTX 와이어프레임 자동 생성 + │ + ┌───── 3.5단계 고객 화면 검토 (서명) ──────────────────────┐ + │ 승인 ✓ 수정 요청 → MD 수정 → 재생성│ + └───────┬───────────────────────────────────────────────────┘ + │ +4단계 MD + 기존 컴포넌트 → 프론트엔드 + Mock API 프로토타입 + │ +5단계 프로토타입 테스트 (고객 + 내부) + │ + ┌───── 5.5단계 피드백 반영 ────────────────────────────────┐ + │ 피드백 → MD 수정 → 영향 범위 확인 → 코드 반영 │ + │ 완료 ✓ │ + └───────┬───────────────────────────────────────────────────┘ + │ +6단계 Mock → 실 API 교체 → 통합 테스트 → 최종 검수 +``` + +--- + +## 6. 필요 사전 작업 + +파이프라인을 실전에 적용하기 위해 준비해야 할 것: + +| 항목 | 설명 | 우선순위 | +|------|------|----------| +| MD 템플릿 표준화 | PPTX 레이아웃 규격, 색상, 컴포넌트 정의를 포함한 MD 작성 가이드 | 높음 | +| 업종별 체크리스트 | MES/ERP 업종별 필수 프로세스 목록 (제조, 시공, 물류 등) | 높음 | +| 컴포넌트 라이브러리 정리 | 4단계에서 활용할 organisms/molecules 카탈로그 | 중간 | +| Mock API 규격 | 프론트 프로토타입에서 사용할 Mock 데이터 구조 표준 | 중간 | +| 변경 관리 프로세스 | MD 수정 → 영향 범위 파악 → 재생성 절차 문서화 | 낮음 (초기) | + +--- + +## 7. 검토 요청 사항 + +팀원들에게 확인받고 싶은 사항: + +1. **기획자**: 1→2단계에서 인터뷰 내용을 MD로 구조화하는 과정이 현실적인가? 어떤 보조 도구가 필요한가? +2. **프론트엔드 개발자**: 4단계에서 MD 명세서만으로 화면 구현이 가능한 수준인가? 기존 컴포넌트 재활용 범위는? +3. **백엔드 개발자**: 2단계 MD에 포함된 데이터 모델/API 명세가 백엔드 설계에 충분한가? 추가로 필요한 정보는? +4. **PM**: 이 파이프라인의 단계별 소요 시간 예측이 가능한가? 고객 커뮤니케이션 포인트는 적절한가? + +--- + +## 8. 다음 단계 + +- [ ] MD만으로 PPTX 재생성 PoC 완료 (현재 진행 중) +- [ ] 팀 검토 미팅 일정 확정 +- [ ] 검토 결과 반영하여 파이프라인 확정 +- [ ] MD 템플릿 표준 초안 작성 +- [ ] 실 고객 프로젝트 파일럿 적용 대상 선정 diff --git a/src/app/[locale]/(protected)/[...slug]/page.tsx b/src/app/[locale]/(protected)/[...slug]/page.tsx index a5b12478..948f274f 100644 --- a/src/app/[locale]/(protected)/[...slug]/page.tsx +++ b/src/app/[locale]/(protected)/[...slug]/page.tsx @@ -39,7 +39,6 @@ export default function CatchAllPage({ params }: PageProps) { // localStorage에서 메뉴 데이터 가져오기 const userStr = localStorage.getItem('user'); if (!userStr) { - console.log('❌ localStorage에 user 정보 없음'); setIsValidPath(false); return; } @@ -50,17 +49,13 @@ export default function CatchAllPage({ params }: PageProps) { // slug를 경로로 변환 (예: ['base', 'product', 'lists'] → '/base/product/lists') const requestedPath = `/${slug.join('/')}`; - console.log('🔍 요청된 경로:', requestedPath); - console.log('📋 메뉴 데이터:', menus); // 메뉴 구조를 재귀적으로 탐색하여 경로 확인 const isPathInMenu = (menuItems: MenuItem[], path: string): boolean => { for (const item of menuItems) { - console.log(' - 비교 중:', item.path, 'vs', path); // path가 요청된 경로와 일치하는지 확인 if (item.path === path) { - console.log(' ✅ 일치!'); return true; } @@ -75,7 +70,6 @@ export default function CatchAllPage({ params }: PageProps) { }; const pathExists = isPathInMenu(menus, requestedPath); - console.log('📌 경로 존재 여부:', pathExists); setIsValidPath(pathExists); }; diff --git a/src/app/[locale]/(protected)/hr/attendance/page.tsx b/src/app/[locale]/(protected)/hr/attendance/page.tsx index b7895d8f..23d7a935 100644 --- a/src/app/[locale]/(protected)/hr/attendance/page.tsx +++ b/src/app/[locale]/(protected)/hr/attendance/page.tsx @@ -60,11 +60,9 @@ export default function AttendancePage() { const loadSettings = async () => { try { const result = await getAttendanceSetting(); - console.log('[AttendancePage] API 응답:', result); if (result.success && result.data) { const radius = result.data.allowedRadius; - console.log('[AttendancePage] API 반경값:', radius); // TODO: 주소/좌표 설정 UI 추가 후 아래 주석 해제 // 현재는 테스트를 위해 좌표는 하드코딩, 반경만 API 연동 @@ -75,10 +73,8 @@ export default function AttendancePage() { radius: (radius != null && Number(radius) > 0) ? Number(radius) : DEFAULT_SITE_LOCATION.radius, }; - console.log('[AttendancePage] 최종 위치:', finalLocation); setSiteLocation(finalLocation); } else { - console.log('[AttendancePage] API 실패, 기본값 사용'); } } catch (error) { console.error('[AttendancePage] loadSettings error:', error); diff --git a/src/app/[locale]/(protected)/hr/employee-management/csv-upload/page.tsx b/src/app/[locale]/(protected)/hr/employee-management/csv-upload/page.tsx index c5d83887..dcac80c4 100644 --- a/src/app/[locale]/(protected)/hr/employee-management/csv-upload/page.tsx +++ b/src/app/[locale]/(protected)/hr/employee-management/csv-upload/page.tsx @@ -6,7 +6,6 @@ import type { Employee } from '@/components/hr/EmployeeManagement/types'; export default function EmployeeCSVUploadPage() { const handleUpload = (employees: Employee[]) => { // TODO: API 연동 - console.log('Upload employees:', employees); }; return ; diff --git a/src/app/[locale]/(protected)/production/screen-production/create/page.tsx b/src/app/[locale]/(protected)/production/screen-production/create/page.tsx index a14c0810..3182055f 100644 --- a/src/app/[locale]/(protected)/production/screen-production/create/page.tsx +++ b/src/app/[locale]/(protected)/production/screen-production/create/page.tsx @@ -79,8 +79,7 @@ export default function CreateItemPage() { } // 성공 시 DynamicItemForm 내부에서 /items로 리다이렉트 처리됨 - // console.log('[CreateItemPage] 품목 등록 성공:', result.data); - + // // 생성된 품목 ID를 포함한 데이터 반환 (파일 업로드용) return { id: result.data.id, ...result.data }; }; diff --git a/src/app/[locale]/(protected)/quality/qms/components/DayTabs.tsx b/src/app/[locale]/(protected)/quality/qms/components/DayTabs.tsx index 78883914..0ac4521c 100644 --- a/src/app/[locale]/(protected)/quality/qms/components/DayTabs.tsx +++ b/src/app/[locale]/(protected)/quality/qms/components/DayTabs.tsx @@ -33,7 +33,7 @@ export function DayTabs({ activeDay, onDayChange, day1Progress, day2Progress }: type="button" onClick={() => onDayChange(1)} className={cn( - 'flex-1 flex items-center justify-center gap-1 sm:gap-2 py-2 sm:py-3 px-2 sm:px-4 rounded-lg border-2 transition-all', + 'flex-1 flex items-center justify-center gap-1 sm:gap-2 py-1.5 sm:py-2 px-2 sm:px-3 rounded-lg border-2 transition-all', activeDay === 1 ? 'bg-blue-600 border-blue-600 text-white shadow-lg' : 'bg-white border-gray-200 text-gray-700 hover:border-blue-300 hover:bg-blue-50' @@ -57,7 +57,7 @@ export function DayTabs({ activeDay, onDayChange, day1Progress, day2Progress }: type="button" onClick={() => onDayChange(2)} className={cn( - 'flex-1 flex items-center justify-center gap-1 sm:gap-2 py-2 sm:py-3 px-2 sm:px-4 rounded-lg border-2 transition-all', + 'flex-1 flex items-center justify-center gap-1 sm:gap-2 py-1.5 sm:py-2 px-2 sm:px-3 rounded-lg border-2 transition-all', activeDay === 2 ? 'bg-blue-600 border-blue-600 text-white shadow-lg' : 'bg-white border-gray-200 text-gray-700 hover:border-blue-300 hover:bg-blue-50' diff --git a/src/app/[locale]/(protected)/quality/qms/components/Filters.tsx b/src/app/[locale]/(protected)/quality/qms/components/Filters.tsx index dd93f4a3..b1a56ee5 100644 --- a/src/app/[locale]/(protected)/quality/qms/components/Filters.tsx +++ b/src/app/[locale]/(protected)/quality/qms/components/Filters.tsx @@ -47,7 +47,7 @@ export const Filters = ({ className="w-full pl-10 pr-4 py-2 border border-gray-200 rounded-md text-sm focus:outline-none focus:border-blue-500 focus:ring-1 focus:ring-blue-500" /> - diff --git a/src/app/[locale]/(protected)/quality/qms/components/InspectionModal.tsx b/src/app/[locale]/(protected)/quality/qms/components/InspectionModal.tsx index 0d495285..002ba4c8 100644 --- a/src/app/[locale]/(protected)/quality/qms/components/InspectionModal.tsx +++ b/src/app/[locale]/(protected)/quality/qms/components/InspectionModal.tsx @@ -451,12 +451,10 @@ export const InspectionModal = ({ isOpen, onClose, document: doc, documentItem } // 품질관리서 PDF 업로드 핸들러 const handleQualityFileUpload = (file: File) => { - console.log('[InspectionModal] 품질관리서 PDF 업로드:', file.name); // TODO: 실제 API 연동 시 파일 업로드 로직 구현 }; const handleQualityFileDelete = () => { - console.log('[InspectionModal] 품질관리서 PDF 삭제'); // TODO: 실제 API 연동 시 파일 삭제 로직 구현 }; diff --git a/src/app/[locale]/(protected)/quality/qms/components/InspectionModalV2.tsx b/src/app/[locale]/(protected)/quality/qms/components/InspectionModalV2.tsx index e910d9ef..0b443a26 100644 --- a/src/app/[locale]/(protected)/quality/qms/components/InspectionModalV2.tsx +++ b/src/app/[locale]/(protected)/quality/qms/components/InspectionModalV2.tsx @@ -338,7 +338,6 @@ export const InspectionModalV2 = ({ setIsSaving(true); try { // TODO: 실제 저장 API 연동 - console.log('[InspectionModalV2] 수입검사 저장 데이터:', data); toast.success('검사 데이터가 저장되었습니다.'); } catch { toast.error('저장 중 오류가 발생했습니다.'); @@ -356,11 +355,9 @@ export const InspectionModalV2 = ({ // 품질관리서 PDF 업로드 핸들러 const handleQualityFileUpload = (file: File) => { - console.log('[InspectionModalV2] 품질관리서 PDF 업로드:', file.name); }; const handleQualityFileDelete = () => { - console.log('[InspectionModalV2] 품질관리서 PDF 삭제'); }; // 작업일지 공정별 렌더링 @@ -474,7 +471,6 @@ export const InspectionModalV2 = ({ // 다운로드 핸들러 (TODO: 실제 구현) const handleDownload = () => { - console.log('[InspectionModalV2] 다운로드 요청:', doc.type); }; // 수입검사 저장 버튼 (toolbarExtra) - readOnly일 때 숨김 diff --git a/src/app/[locale]/(protected)/quality/qms/page.tsx b/src/app/[locale]/(protected)/quality/qms/page.tsx index 4828ea23..f480e80b 100644 --- a/src/app/[locale]/(protected)/quality/qms/page.tsx +++ b/src/app/[locale]/(protected)/quality/qms/page.tsx @@ -249,7 +249,7 @@ export default function QualityInspectionPage() { - - - )} + + - ), + ) : null, tableHeaderActions: (
diff --git a/src/components/approval/DocumentDetail/index.tsx b/src/components/approval/DocumentDetail/index.tsx index b3d94c54..b00858a0 100644 --- a/src/components/approval/DocumentDetail/index.tsx +++ b/src/components/approval/DocumentDetail/index.tsx @@ -73,19 +73,15 @@ export function DocumentDetailModal({ }; const handleSharePdf = () => { - console.log('PDF 다운로드'); }; const handleShareEmail = () => { - console.log('이메일 공유'); }; const handleShareFax = () => { - console.log('팩스 전송'); }; const handleShareKakao = () => { - console.log('카카오톡 공유'); }; const renderDocument = () => { diff --git a/src/components/approval/DraftBox/index.tsx b/src/components/approval/DraftBox/index.tsx index 7aab9c4d..85f34280 100644 --- a/src/components/approval/DraftBox/index.tsx +++ b/src/components/approval/DraftBox/index.tsx @@ -546,32 +546,8 @@ export function DraftBox() { ]; }, - headerActions: ({ selectedItems, onClearSelection }) => ( + headerActions: () => (
- {selectedItems.size > 0 && ( - <> - - - - )}
), + selectionActions: ({ selectedItems, onClearSelection }) => ( + <> + + + + ), + tableHeaderActions: (