summaryrefslogtreecommitdiff
path: root/lib/swp/table/swp-table-toolbar.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/swp/table/swp-table-toolbar.tsx')
-rw-r--r--lib/swp/table/swp-table-toolbar.tsx81
1 files changed, 75 insertions, 6 deletions
diff --git a/lib/swp/table/swp-table-toolbar.tsx b/lib/swp/table/swp-table-toolbar.tsx
index add69666..013b4a13 100644
--- a/lib/swp/table/swp-table-toolbar.tsx
+++ b/lib/swp/table/swp-table-toolbar.tsx
@@ -19,6 +19,8 @@ import {
validateFileName
} from "./swp-upload-validation-dialog";
import { SwpUploadedFilesDialog } from "./swp-uploaded-files-dialog";
+import { getProjectDocumentClassStages } from "@/lib/docu-list-rule/document-class/service";
+import type { DocumentListItem } from "@/lib/swp/document-service";
interface SwpTableFilters {
docNo?: string;
@@ -38,7 +40,7 @@ interface SwpTableToolbarProps {
vendorCode?: string;
droppedFiles?: File[];
onFilesProcessed?: () => void;
- documents?: Array<{ OWN_DOC_NO: string | null }>; // 업로드 권한 검증용 문서 목록 (OWN_DOC_NO 기준)
+ documents?: DocumentListItem[]; // 업로드 권한 검증 + DOC_TYPE 확인용 문서 목록
userId?: string; // 파일 취소 시 필요
}
@@ -80,6 +82,10 @@ export function SwpTableToolbar({
}>>([]);
const [showValidationDialog, setShowValidationDialog] = useState(false);
+ // Document Class-Stage 매핑 (프로젝트별)
+ const [documentClassStages, setDocumentClassStages] = useState<Record<string, string[]>>({});
+ const [isLoadingDocClassStages, setIsLoadingDocClassStages] = useState(false);
+
/**
* 업로드 가능한 문서번호 목록 추출 (OWN_DOC_NO 기준)
*/
@@ -90,11 +96,62 @@ export function SwpTableToolbar({
}, [documents]);
/**
+ * 문서번호 → DOC_TYPE 매핑 (Stage 검증용)
+ */
+ const docNoToDocTypeMap = useMemo(() => {
+ const map: Record<string, string> = {};
+ for (const doc of documents) {
+ if (doc.OWN_DOC_NO && doc.DOC_TYPE) {
+ map[doc.OWN_DOC_NO] = doc.DOC_TYPE;
+ }
+ }
+ return map;
+ }, [documents]);
+
+ /**
* 벤더 모드 여부 (벤더 코드가 있으면 벤더 모드)
*/
const isVendorMode = !!vendorCode;
/**
+ * 프로젝트 변경 시 Document Class-Stage 매핑 로드
+ */
+ useEffect(() => {
+ if (!projNo) {
+ setDocumentClassStages({});
+ return;
+ }
+
+ let isCancelled = false;
+
+ const loadDocumentClassStages = async () => {
+ try {
+ setIsLoadingDocClassStages(true);
+ const stages = await getProjectDocumentClassStages(projNo);
+ if (!isCancelled) {
+ setDocumentClassStages(stages);
+ console.log(`[SwpTableToolbar] Document Class-Stage 매핑 로드 완료:`, stages);
+ }
+ } catch (error) {
+ if (!isCancelled) {
+ console.error('[SwpTableToolbar] Document Class-Stage 매핑 로드 실패:', error);
+ setDocumentClassStages({});
+ }
+ } finally {
+ if (!isCancelled) {
+ setIsLoadingDocClassStages(false);
+ }
+ }
+ };
+
+ loadDocumentClassStages();
+
+ return () => {
+ isCancelled = true;
+ };
+ }, [projNo]);
+
+ /**
* 드롭된 파일 처리 - useEffect로 감지하여 자동 검증
*/
useEffect(() => {
@@ -120,9 +177,15 @@ export function SwpTableToolbar({
return;
}
- // 파일명 검증 (문서번호 권한 포함)
+ // 파일명 검증 (문서번호 권한 + Stage 검증 포함)
const results = droppedFiles.map((file) => {
- const validation = validateFileName(file.name, availableDocNos, isVendorMode);
+ const validation = validateFileName(
+ file.name,
+ availableDocNos,
+ isVendorMode,
+ docNoToDocTypeMap,
+ documentClassStages
+ );
return {
file,
valid: validation.valid,
@@ -135,7 +198,7 @@ export function SwpTableToolbar({
setShowValidationDialog(true);
onFilesProcessed?.();
}
- }, [droppedFiles, projNo, vendorCode, toast, onFilesProcessed, availableDocNos, isVendorMode]);
+ }, [droppedFiles, projNo, vendorCode, toast, onFilesProcessed, availableDocNos, isVendorMode, docNoToDocTypeMap, documentClassStages]);
/**
* 파일 업로드 핸들러
@@ -171,9 +234,15 @@ export function SwpTableToolbar({
return;
}
- // 각 파일의 파일명 검증 (문서번호 권한 포함)
+ // 각 파일의 파일명 검증 (문서번호 권한 + Stage 검증 포함)
const results = Array.from(selectedFiles).map((file) => {
- const validation = validateFileName(file.name, availableDocNos, isVendorMode);
+ const validation = validateFileName(
+ file.name,
+ availableDocNos,
+ isVendorMode,
+ docNoToDocTypeMap,
+ documentClassStages
+ );
return {
file,
valid: validation.valid,