From 37611339fea096e47aaa42311a13a6313b4200db Mon Sep 17 00:00:00 2001 From: dujinkim Date: Mon, 2 Jun 2025 02:27:28 +0000 Subject: (대표님) 20250602 오전 작업사항 (코드프리징) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../table/enhanced-documents-table.tsx | 48 +++--- .../table/stage-revision-expanded-content.tsx | 171 +++++++++++---------- 2 files changed, 117 insertions(+), 102 deletions(-) (limited to 'lib/vendor-document-list') diff --git a/lib/vendor-document-list/table/enhanced-documents-table.tsx b/lib/vendor-document-list/table/enhanced-documents-table.tsx index 14c52455..f840a10c 100644 --- a/lib/vendor-document-list/table/enhanced-documents-table.tsx +++ b/lib/vendor-document-list/table/enhanced-documents-table.tsx @@ -468,26 +468,34 @@ export function EnhancedDocumentsTable({ {/* 메인 테이블 - 가로스크롤 문제 해결을 위한 구조 개선 */}
- ( - // ✅ 확장된 내용을 별도 컨테이너로 분리하여 가로스크롤 영향 차단 -
- handleStageToggle(String(document.documentId), stageId)} - /> -
- )} - // 확장된 행에 대한 특별한 스타일링 - expandedRowClassName="!p-0" - > + ( +
+ handleStageToggle(String(document.documentId), stageId)} + /> +
+ )} + expandedRowClassName="!p-0" + // clickableColumns={[ + // 'docNumber', + // 'title', + // 'currentStageStatus', + // 'progressPercentage', + // ]} + excludeFromClick={[ + 'actions', + 'select' + ]} + > { const getFileIconColor = (fileName: string) => { const ext = fileName.split('.').pop()?.toLowerCase() - switch(ext) { + switch (ext) { case 'pdf': return 'text-red-500' case 'doc': case 'docx': return 'text-blue-500' case 'xls': case 'xlsx': return 'text-green-500' @@ -105,7 +105,7 @@ interface StageRevisionExpandedContentProps { onStageToggle?: (stageId: number) => void } -export const StageRevisionExpandedContent = ({ +export const StageRevisionExpandedContent = ({ document: documentData, onUploadRevision, onStageStatusUpdate, @@ -117,7 +117,7 @@ export const StageRevisionExpandedContent = ({ // 로컬 상태 관리 const [localExpandedStages, setLocalExpandedStages] = React.useState>({}) const [expandedRevisions, setExpandedRevisions] = React.useState>(new Set()) - + // ✅ 문서 뷰어 상태 관리 const [viewerOpen, setViewerOpen] = React.useState(false) const [selectedRevisions, setSelectedRevisions] = React.useState([]) @@ -127,11 +127,11 @@ export const StageRevisionExpandedContent = ({ const viewer = React.useRef(null) const initialized = React.useRef(false) const isCancelled = React.useRef(false) - + // 상위에서 관리하는지 로컬에서 관리하는지 결정 const isExternallyManaged = onStageToggle !== undefined const currentExpandedStages = isExternallyManaged ? expandedStages : localExpandedStages - + const handleStageToggle = React.useCallback((stageId: number) => { if (isExternallyManaged && onStageToggle) { onStageToggle(stageId) @@ -157,7 +157,7 @@ export const StageRevisionExpandedContent = ({ // ✅ PDF 뷰어 정리 함수 const cleanupHtmlStyle = React.useCallback(() => { - const htmlElement = window.document.documentElement + const htmlElement = window.document.documentElement const originalStyle = htmlElement.getAttribute("style") || "" const colorSchemeStyle = originalStyle .split(";") @@ -185,12 +185,12 @@ export const StageRevisionExpandedContent = ({ console.log(attachment) try { // ID를 우선으로 사용, 없으면 filePath 사용 - const queryParam = attachment.id + const queryParam = attachment.id ? `id=${encodeURIComponent(attachment.id)}` : `path=${encodeURIComponent(attachment.filePath)}` - + const response = await fetch(`/api/document-download?${queryParam}`) - + if (!response.ok) { const errorData = await response.json() throw new Error(errorData.error || '파일 다운로드에 실패했습니다.') @@ -205,7 +205,7 @@ export const StageRevisionExpandedContent = ({ link.click() window.document.body.removeChild(link) window.URL.revokeObjectURL(url) - + console.log('✅ 파일 다운로드 완료:', attachment.fileName) } catch (error) { console.error('❌ 파일 다운로드 오류:', error) @@ -312,7 +312,7 @@ export const StageRevisionExpandedContent = ({ const handleCloseViewer = React.useCallback(async () => { if (!fileSetLoading) { isCancelled.current = true - + if (instance) { try { await instance.UI.dispose() @@ -342,7 +342,7 @@ export const StageRevisionExpandedContent = ({
) } - + return ( <>
e.stopPropagation()}> @@ -366,27 +366,28 @@ export const StageRevisionExpandedContent = ({ 새 리비전 업로드 */}
- +
{stagesWithRevisions.map((stage) => { const isExpanded = currentExpandedStages[stage.id] || false const revisions = stage.revisions || [] - + return (
- {/* 스테이지 헤더 */} -
+ {/* 스테이지 헤더 - 전체 영역 클릭 가능 */} +
{ + e.preventDefault() + e.stopPropagation() + handleStageToggle(stage.id) + }} + >
- - +
+
{stage.stageName}
@@ -417,7 +418,7 @@ export const StageRevisionExpandedContent = ({
- +
@@ -437,45 +438,51 @@ export const StageRevisionExpandedContent = ({
)}
- - {/* 스테이지 액션 메뉴 */} - - - - - - {onStageStatusUpdate && ( - <> - onStageStatusUpdate(stage.id, 'IN_PROGRESS')}> - 진행 시작 - - onStageStatusUpdate(stage.id, 'COMPLETED')}> - 완료 처리 - - - )} - onUploadRevision(documentData, stage.stageName)}> - 리비전 업로드 - - {/* ✅ 스테이지에 첨부파일이 있는 리비전이 있을 때만 문서 보기 버튼 표시 */} - {revisions.some(rev => rev.attachments && rev.attachments.length > 0) && ( - handleViewRevision(revisions.filter(rev => rev.attachments && rev.attachments.length > 0))}> - - 스테이지 문서 보기 + + {/* 스테이지 액션 메뉴 - 클릭 이벤트 전파 차단 */} +
{ + e.stopPropagation() // 액션 메뉴 클릭 시 스테이지 토글 방지 + }} + > + + + + + + {onStageStatusUpdate && ( + <> + onStageStatusUpdate(stage.id, 'IN_PROGRESS')}> + 진행 시작 + + onStageStatusUpdate(stage.id, 'COMPLETED')}> + 완료 처리 + + + )} + onUploadRevision(documentData, stage.stageName)}> + 리비전 업로드 - )} - - + {/* ✅ 스테이지에 첨부파일이 있는 리비전이 있을 때만 문서 보기 버튼 표시 */} + {revisions.some(rev => rev.attachments && rev.attachments.length > 0) && ( + handleViewRevision(revisions.filter(rev => rev.attachments && rev.attachments.length > 0))}> + + 스테이지 문서 보기 + + )} + + +
- + {/* 리비전 목록 - 테이블 형태 */} {isExpanded && (
@@ -499,29 +506,29 @@ export const StageRevisionExpandedContent = ({ {revisions.map((revision) => { const hasAttachments = revision.attachments && revision.attachments.length > 0 - + return ( {/* 리비전 */} - {revision.uploaderType ==="vendor"?"To SHI":"From SHI"} + {revision.uploaderType === "vendor" ? "To SHI" : "From SHI"} - + {revision.revision} - + {/* 상태 */} {getStatusText(revision.revisionStatus)} - + {/* 업로더 */}
@@ -529,20 +536,20 @@ export const StageRevisionExpandedContent = ({ {revision.uploaderName || '-'}
- {/* 제출일 */} + {/* 제출일 */} {revision.uploadedAt ? formatDate(revision.uploadedAt) : '-'} - + {/* 제출일 */} {revision.externalSentDate ? formatDate(revision.externalSentDate) : '-'} - + {/* 승인/반려일 */}
@@ -569,7 +576,7 @@ export const StageRevisionExpandedContent = ({ )}
- + {/* ✅ 첨부파일 - 클릭 시 다운로드, 별도 뷰어 버튼 */} {hasAttachments ? ( @@ -588,7 +595,7 @@ export const StageRevisionExpandedContent = ({ ))} {revision.attachments.length > 4 && ( - @@ -610,7 +617,7 @@ export const StageRevisionExpandedContent = ({ - )} - + {/* 액션 */}
@@ -647,7 +654,7 @@ export const StageRevisionExpandedContent = ({
- + {/* 코멘트 */} {revision.comment ? ( @@ -703,7 +710,7 @@ export const StageRevisionExpandedContent = ({ 문서 미리보기 - {selectedRevisions.length === 1 + {selectedRevisions.length === 1 ? `리비전 ${selectedRevisions[0]?.revision} 첨부파일` : `${selectedRevisions.length}개 리비전 첨부파일` } -- cgit v1.2.3