summaryrefslogtreecommitdiff
path: root/components/form-data-plant
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-12-01 00:58:23 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-12-01 00:58:23 +0000
commit8440ac29c7dcbef992039678ecc0fabff2fd04ec (patch)
tree59092b8dcd22135009bf70d5863ffde444e5bed2 /components/form-data-plant
parent748f68bb7b5d02450664651ae5025c9a38fb71a5 (diff)
(대표님) S-EDP 관련 대표님 작업사항
Diffstat (limited to 'components/form-data-plant')
-rw-r--r--components/form-data-plant/delete-form-data-dialog.tsx9
-rw-r--r--components/form-data-plant/form-data-report-batch-dialog.tsx21
-rw-r--r--components/form-data-plant/form-data-report-dialog.tsx21
-rw-r--r--components/form-data-plant/form-data-report-temp-upload-dialog.tsx12
-rw-r--r--components/form-data-plant/form-data-report-temp-upload-tab.tsx7
-rw-r--r--components/form-data-plant/form-data-report-temp-uploaded-list-tab.tsx19
-rw-r--r--components/form-data-plant/form-data-table.tsx91
-rw-r--r--components/form-data-plant/import-excel-form.tsx13
-rw-r--r--components/form-data-plant/publish-dialog.tsx226
-rw-r--r--components/form-data-plant/spreadJS-dialog.tsx15
-rw-r--r--components/form-data-plant/update-form-sheet.tsx9
11 files changed, 244 insertions, 199 deletions
diff --git a/components/form-data-plant/delete-form-data-dialog.tsx b/components/form-data-plant/delete-form-data-dialog.tsx
index 6ac8f67c..2406407e 100644
--- a/components/form-data-plant/delete-form-data-dialog.tsx
+++ b/components/form-data-plant/delete-form-data-dialog.tsx
@@ -40,7 +40,8 @@ interface DeleteFormDataDialogProps
extends React.ComponentPropsWithoutRef<typeof Dialog> {
formData: GenericData[]
formCode: string
- contractItemId: number
+ projectCode: string
+ packageCode: string
projectId?: number
showTrigger?: boolean
onSuccess?: () => void
@@ -50,7 +51,8 @@ interface DeleteFormDataDialogProps
export function DeleteFormDataDialog({
formData,
formCode,
- contractItemId,
+ projectCode,
+ packageCode,
projectId,
showTrigger = true,
onSuccess,
@@ -77,7 +79,8 @@ export function DeleteFormDataDialog({
const result = await deleteFormDataByTags({
formCode,
- contractItemId,
+ projectCode,
+ packageCode,
tagIdxs,
projectId,
})
diff --git a/components/form-data-plant/form-data-report-batch-dialog.tsx b/components/form-data-plant/form-data-report-batch-dialog.tsx
index 24b5827b..ba41a3c2 100644
--- a/components/form-data-plant/form-data-report-batch-dialog.tsx
+++ b/components/form-data-plant/form-data-report-batch-dialog.tsx
@@ -71,7 +71,8 @@ interface FormDataReportBatchDialogProps {
setOpen: Dispatch<SetStateAction<boolean>>;
columnsJSON: DataTableColumnJSON[];
reportData: ReportData[];
- packageId: number;
+ projectCode: string;
+ packageCode: string;
formId: number;
formCode: string;
}
@@ -81,7 +82,8 @@ export const FormDataReportBatchDialog: FC<FormDataReportBatchDialogProps> = ({
setOpen,
columnsJSON,
reportData,
- packageId,
+ projectCode,
+ packageCode,
formId,
formCode,
}) => {
@@ -100,8 +102,8 @@ export const FormDataReportBatchDialog: FC<FormDataReportBatchDialogProps> = ({
const [generatedFileBlob, setGeneratedFileBlob] = useState<Blob | null>(null);
useEffect(() => {
- updateReportTempList(packageId, formId, setTempList);
- }, [packageId, formId]);
+ updateReportTempList(projectCode, packageCode, formId, setTempList);
+ }, [projectCode, packageCode, formId]);
const onClose = () => {
if (isUploading) {
@@ -361,7 +363,8 @@ export const FormDataReportBatchDialog: FC<FormDataReportBatchDialogProps> = ({
<PublishDialog
open={publishDialogOpen}
onOpenChange={setPublishDialogOpen}
- packageId={packageId}
+ projectCode={projectCode}
+ packageCode={packageCode}
formCode={formCode}
fileBlob={generatedFileBlob || undefined}
/>
@@ -409,17 +412,19 @@ const UploadFileItem: FC<UploadFileItemProps> = ({
};
type UpdateReportTempList = (
- packageId: number,
+ projectCode: string,
+ packageCode: string,
formId: number,
setPrevReportTemp: Dispatch<SetStateAction<tempFile[]>>
) => void;
const updateReportTempList: UpdateReportTempList = async (
- packageId,
+ projectCode,
+ packageCode,
formId,
setTempList
) => {
- const tempList = await getReportTempList(packageId, formId);
+ const tempList = await getReportTempList(projectCode,packageCode, formId);
setTempList(
tempList.map((c) => {
diff --git a/components/form-data-plant/form-data-report-dialog.tsx b/components/form-data-plant/form-data-report-dialog.tsx
index 9177ab36..2413fc28 100644
--- a/components/form-data-plant/form-data-report-dialog.tsx
+++ b/components/form-data-plant/form-data-report-dialog.tsx
@@ -49,7 +49,8 @@ interface FormDataReportDialogProps {
columnsJSON: DataTableColumnJSON[];
reportData: ReportData[];
setReportData: Dispatch<SetStateAction<ReportData[]>>;
- packageId: number;
+ projectCode: string;
+ packageCode: string;
formId: number;
formCode: string;
}
@@ -58,7 +59,8 @@ export const FormDataReportDialog: FC<FormDataReportDialogProps> = ({
columnsJSON,
reportData,
setReportData,
- packageId,
+ projectCode,
+ packageCode,
formId,
formCode,
}) => {
@@ -76,8 +78,8 @@ export const FormDataReportDialog: FC<FormDataReportDialogProps> = ({
const [generatedFileBlob, setGeneratedFileBlob] = useState<Blob | null>(null);
useEffect(() => {
- updateReportTempList(packageId, formId, setTempList);
- }, [packageId, formId]);
+ updateReportTempList(projectCode, packageCode, formId, setTempList);
+ }, [projectCode,packageCode, formId]);
const onClose = async (value: boolean) => {
if (fileLoading) {
@@ -197,7 +199,8 @@ export const FormDataReportDialog: FC<FormDataReportDialogProps> = ({
<PublishDialog
open={publishDialogOpen}
onOpenChange={setPublishDialogOpen}
- packageId={packageId}
+ projectCode={projectCode}
+ packageCode={packageCode}
formCode={formCode}
fileBlob={generatedFileBlob || undefined}
/>
@@ -394,17 +397,19 @@ const importReportData: ImportReportData = async (
};
type UpdateReportTempList = (
- packageId: number,
+ projectCode: string,
+ packageCode: string,
formId: number,
setPrevReportTemp: Dispatch<SetStateAction<tempFile[]>>
) => void;
const updateReportTempList: UpdateReportTempList = async (
- packageId,
+ projectCode,
+ packageCode,
formId,
setTempList
) => {
- const tempList = await getReportTempList(packageId, formId);
+ const tempList = await getReportTempList(projectCode,packageCode, formId);
setTempList(
tempList.map((c) => {
diff --git a/components/form-data-plant/form-data-report-temp-upload-dialog.tsx b/components/form-data-plant/form-data-report-temp-upload-dialog.tsx
index 59ea6ade..66915198 100644
--- a/components/form-data-plant/form-data-report-temp-upload-dialog.tsx
+++ b/components/form-data-plant/form-data-report-temp-upload-dialog.tsx
@@ -23,7 +23,8 @@ interface FormDataReportTempUploadDialogProps {
columnsJSON: DataTableColumnJSON[];
open: boolean;
setOpen: Dispatch<SetStateAction<boolean>>;
- packageId: number;
+ projectCode: string;
+ packageCode: string;
formCode: string;
formId: number;
uploaderType: string;
@@ -35,7 +36,8 @@ export const FormDataReportTempUploadDialog: FC<
columnsJSON,
open,
setOpen,
- packageId,
+ projectCode,
+ packageCode,
formId,
formCode,
uploaderType,
@@ -83,14 +85,16 @@ export const FormDataReportTempUploadDialog: FC<
</div>
<TabsContent value="upload">
<FormDataReportTempUploadTab
- packageId={packageId}
+ projectCode={projectCode}
+ packageCode={packageCode}
formId={formId}
uploaderType={uploaderType}
/>
</TabsContent>
<TabsContent value="uploaded">
<FormDataReportTempUploadedListTab
- packageId={packageId}
+ projectCode={projectCode}
+ packageCode={packageCode}
formId={formId}
/>
</TabsContent>
diff --git a/components/form-data-plant/form-data-report-temp-upload-tab.tsx b/components/form-data-plant/form-data-report-temp-upload-tab.tsx
index 81186ba4..41466f90 100644
--- a/components/form-data-plant/form-data-report-temp-upload-tab.tsx
+++ b/components/form-data-plant/form-data-report-temp-upload-tab.tsx
@@ -36,14 +36,15 @@ import { uploadReportTemp } from "@/lib/forms-plant/services";
const MAX_FILE_SIZE = 3000000;
interface FormDataReportTempUploadTabProps {
- packageId: number;
+ projectCode: string;
+ packageCode: string;
formId: number;
uploaderType: string;
}
export const FormDataReportTempUploadTab: FC<
FormDataReportTempUploadTabProps
-> = ({ packageId, formId, uploaderType }) => {
+> = ({ projectCode,packageCode, formId, uploaderType }) => {
const { toast } = useToast();
const params = useParams();
const lng = (params?.lng as string) || "ko";
@@ -94,7 +95,7 @@ export const FormDataReportTempUploadTab: FC<
formData.append("customFileName", file.name);
formData.append("uploaderType", uploaderType);
- await uploadReportTemp(packageId, formId, formData);
+ await uploadReportTemp(projectCode, packageCode, formId, formData);
successCount++;
setUploadProgress(Math.round((successCount / totalFiles) * 100));
diff --git a/components/form-data-plant/form-data-report-temp-uploaded-list-tab.tsx b/components/form-data-plant/form-data-report-temp-uploaded-list-tab.tsx
index 4cfbad69..1b6cefaf 100644
--- a/components/form-data-plant/form-data-report-temp-uploaded-list-tab.tsx
+++ b/components/form-data-plant/form-data-report-temp-uploaded-list-tab.tsx
@@ -39,13 +39,14 @@ import { getReportTempList, deleteReportTempFile } from "@/lib/forms-plant/servi
import { VendorDataReportTemps } from "@/db/schema/vendorData";
interface FormDataReportTempUploadedListTabProps {
- packageId: number;
+ projectCode: string;
+ packageCode: string;
formId: number;
}
export const FormDataReportTempUploadedListTab: FC<
FormDataReportTempUploadedListTabProps
-> = ({ packageId, formId }) => {
+> = ({ projectCode,packageCode , formId }) => {
const params = useParams();
const lng = (params?.lng as string) || "ko";
const { t } = useTranslation(lng, "engineering");
@@ -57,12 +58,12 @@ export const FormDataReportTempUploadedListTab: FC<
useEffect(() => {
const getTempFiles = async () => {
- await updateReportTempList(packageId, formId, setPrevReportTemp);
+ await updateReportTempList(projectCode,packageCode, formId, setPrevReportTemp);
setIsLoading(false);
};
getTempFiles();
- }, [packageId, formId]);
+ }, [projectCode,packageCode, formId]);
return (
<div>
@@ -70,7 +71,7 @@ export const FormDataReportTempUploadedListTab: FC<
<UploadedTempFiles
prevReportTemp={prevReportTemp}
updateReportTempList={() =>
- updateReportTempList(packageId, formId, setPrevReportTemp)
+ updateReportTempList(projectCode,packageCode, formId, setPrevReportTemp)
}
isLoading={isLoading}
t={t}
@@ -80,17 +81,19 @@ export const FormDataReportTempUploadedListTab: FC<
};
type UpdateReportTempList = (
- packageId: number,
+ projectCode: string,
+ packageCode: string,
formId: number,
setPrevReportTemp: Dispatch<SetStateAction<VendorDataReportTemps[]>>
) => Promise<void>;
const updateReportTempList: UpdateReportTempList = async (
- packageId,
+ projectCode,
+ packageCode,
formId,
setPrevReportTemp
) => {
- const tempList = await getReportTempList(packageId, formId);
+ const tempList = await getReportTempList(projectCode, packageCode, formId);
setPrevReportTemp(tempList);
};
diff --git a/components/form-data-plant/form-data-table.tsx b/components/form-data-plant/form-data-table.tsx
index 30c176bd..c6c79a69 100644
--- a/components/form-data-plant/form-data-table.tsx
+++ b/components/form-data-plant/form-data-table.tsx
@@ -76,7 +76,8 @@ interface GenericData {
export interface DynamicTableProps {
dataJSON: GenericData[];
columnsJSON: DataTableColumnJSON[];
- contractItemId: number;
+ projectCode: string;
+ packageCode: string;
formCode: string;
formId: number;
projectId: number;
@@ -89,7 +90,8 @@ export interface DynamicTableProps {
export default function DynamicTable({
dataJSON,
columnsJSON,
- contractItemId,
+ projectCode,
+ packageCode,
formCode,
formId,
projectId,
@@ -156,7 +158,8 @@ export default function DynamicTable({
// 서버 액션 호출
const result = await excludeFormDataByTags({
formCode,
- contractItemId,
+ projectCode,
+ packageCode,
tagNumbers,
});
@@ -288,7 +291,7 @@ export default function DynamicTable({
try {
setIsLoadingStats(true);
// getFormStatusByVendor 서버 액션 직접 호출
- const data = await getFormStatusByVendor(projectId, contractItemId, formCode);
+ const data = await getFormStatusByVendor(projectId, projectCode, packageCode,formCode);
if (data && data.length > 0) {
setFormStats(data[0]);
@@ -339,9 +342,7 @@ export default function DynamicTable({
// SEDP compare dialog state
const [sedpCompareOpen, setSedpCompareOpen] = React.useState(false);
- const [projectCode, setProjectCode] = React.useState<string>('');
- const [projectType, setProjectType] = React.useState<string>('plant');
- const [packageCode, setPackageCode] = React.useState<string>('');
+ const projectType = "plant";
// 새로 추가된 Template 다이얼로그 상태
const [templateDialogOpen, setTemplateDialogOpen] = React.useState(false);
@@ -374,43 +375,13 @@ const [isLoadingRegisters, setIsLoadingRegisters] = React.useState(false);
React.useEffect(() => {
const getTempCount = async () => {
- const tempList = await getReportTempList(contractItemId, formId);
+ const tempList = await getReportTempList(projectCode, packageCode, formId);
setTempCount(tempList.length);
};
getTempCount();
- }, [contractItemId, formId, tempUpDialog]);
+ }, [projectCode,packageCode, formId, tempUpDialog]);
- React.useEffect(() => {
- const getPackageCode = async () => {
- try {
- const packageCode = await getPackageCodeById(contractItemId);
- setPackageCode(packageCode || ''); // 빈 문자열이나 다른 기본값
- } catch (error) {
- console.error('패키지 조회 실패:', error);
- setPackageCode('');
- }
- };
-
- getPackageCode();
- }, [contractItemId])
- // Get project code when component mounts
- React.useEffect(() => {
- const getProjectCode = async () => {
- try {
- const project = await getProjectById(projectId);
- setProjectCode(project.code);
- setProjectType(project.type);
- } catch (error) {
- console.error("Error fetching project code:", error);
- toast.error("Failed to fetch project code");
- }
- };
-
- if (projectId) {
- getProjectCode();
- }
- }, [projectId]);
// 선택된 행들의 실제 데이터 가져오기
const getSelectedRowsData = React.useCallback(() => {
@@ -529,7 +500,7 @@ React.useEffect(() => {
async function handleSyncTags() {
try {
setIsSyncingTags(true);
- const result = await syncMissingTags(contractItemId, formCode);
+ const result = await syncMissingTags(projectCode,packageCode, formCode);
// Prepare the toast messages based on what changed
const changes = [];
@@ -562,9 +533,9 @@ React.useEffect(() => {
setIsLoadingTags(true);
// API 엔드포인트 호출 - 작업 시작만 요청
- const response = await fetch('/api/cron/form-tags/start', {
+ const response = await fetch('/api/cron/form-tags-plant/start', {
method: 'POST',
- body: JSON.stringify({ projectCode, formCode, contractItemId })
+ body: JSON.stringify({ projectCode, formCode, packageCode })
});
if (!response.ok) {
@@ -603,7 +574,7 @@ React.useEffect(() => {
// 5초마다 상태 확인
pollingRef.current = setInterval(async () => {
try {
- const response = await fetch(`/api/cron/form-tags/status?id=${id}`);
+ const response = await fetch(`/api/cron/form-tags-plant/status?id=${id}`);
if (!response.ok) {
throw new Error('Failed to get tag import status');
@@ -666,7 +637,8 @@ React.useEffect(() => {
tableData,
columnsJSON,
formCode,
- contractItemId,
+ projectCode,
+ packageCode,
editableFieldsMap, // 추가: 편집 가능 필드 정보 전달
onPendingChange: setIsImporting, // Let importExcelData handle loading state
onDataUpdate: (newData) => {
@@ -747,7 +719,8 @@ React.useEffect(() => {
const sedpResult = await sendFormDataToSEDP(
formCode, // Send formCode instead of formName
projectId, // Project ID
- contractItemId,
+ projectCode,
+ packageCode,
tableData.filter(v=>v.status !== 'excluded'), // Table data
columnsJSON // Column definitions
);
@@ -1226,7 +1199,8 @@ React.useEffect(() => {
columns={columnsJSON}
rowData={rowAction?.row.original ?? null}
formCode={formCode}
- contractItemId={contractItemId}
+ projectCode={projectCode}
+ packageCode={packageCode}
editableFieldsMap={editableFieldsMap}
onUpdateSuccess={(updatedValues) => {
// Update the specific row in tableData when a single row is updated
@@ -1244,7 +1218,8 @@ React.useEffect(() => {
<DeleteFormDataDialog
formData={deleteTarget}
formCode={formCode}
- contractItemId={contractItemId}
+ projectCode={projectCode}
+ packageCode={packageCode}
projectId={projectId}
open={deleteDialogOpen}
onOpenChange={(open) => {
@@ -1257,16 +1232,6 @@ React.useEffect(() => {
showTrigger={false}
/>
- {/* Dialog for adding tags */}
- {/* <AddFormTagDialog
- projectId={projectId}
- formCode={formCode}
- formName={`Form ${formCode}`}
- contractItemId={contractItemId}
- packageCode={packageCode}
- open={addTagDialogOpen}
- onOpenChange={setAddTagDialogOpen}
- /> */}
{/* 새로 추가된 Template 다이얼로그 */}
<TemplateViewDialog
@@ -1276,7 +1241,8 @@ React.useEffect(() => {
selectedRow={selectedRowsData[0]} // SPR_ITM_LST_SETUP용
tableData={tableData} // SPR_LST_SETUP용 - 새로 추가
formCode={formCode}
- contractItemId={contractItemId}
+ projectCode={projectCode}
+ packageCode={packageCode}
editableFieldsMap={editableFieldsMap}
columnsJSON={columnsJSON}
onUpdateSuccess={(updatedValues) => {
@@ -1344,7 +1310,8 @@ React.useEffect(() => {
columnsJSON={columnsJSON}
open={tempUpDialog}
setOpen={setTempUpDialog}
- packageId={contractItemId}
+ projectCode={projectCode}
+ packageCode={packageCode}
formCode={formCode}
formId={formId}
uploaderType="vendor"
@@ -1356,7 +1323,8 @@ React.useEffect(() => {
columnsJSON={columnsJSON}
reportData={reportData}
setReportData={setReportData}
- packageId={contractItemId}
+ projectCode={projectCode}
+ packageCode={packageCode}
formCode={formCode}
formId={formId}
/>
@@ -1368,7 +1336,8 @@ React.useEffect(() => {
setOpen={setBatchDownDialog}
columnsJSON={columnsJSON}
reportData={selectedRowCount > 0 ? getSelectedRowsData() : tableData}
- packageId={contractItemId}
+ projectCode={projectCode}
+ packageCode={packageCode}
formCode={formCode}
formId={formId}
/>
diff --git a/components/form-data-plant/import-excel-form.tsx b/components/form-data-plant/import-excel-form.tsx
index ffc6f2f9..8ac70c59 100644
--- a/components/form-data-plant/import-excel-form.tsx
+++ b/components/form-data-plant/import-excel-form.tsx
@@ -23,7 +23,8 @@ export interface ImportExcelOptions {
tableData: GenericData[];
columnsJSON: DataTableColumnJSON[];
formCode?: string;
- contractItemId?: number;
+ projectCode: string;
+ packageCode: string;
editableFieldsMap?: Map<string, string[]>; // 새로 추가
onPendingChange?: (isPending: boolean) => void;
onDataUpdate?: (updater: ((prev: GenericData[]) => GenericData[]) | GenericData[]) => void;
@@ -218,7 +219,8 @@ export async function importExcelData({
tableData,
columnsJSON,
formCode,
- contractItemId,
+ projectCode,
+ packageCode,
editableFieldsMap = new Map(), // 새로 추가
onPendingChange,
onDataUpdate
@@ -527,14 +529,14 @@ export async function importExcelData({
}
});
- // If formCode and contractItemId are provided, save directly to DB
// importExcelData 함수에서 DB 저장 부분
- if (formCode && contractItemId) {
+ if (formCode && projectCode && packageCode) {
try {
// 배치 업데이트 함수 호출
const result = await updateFormDataBatchInDB(
formCode,
- contractItemId,
+ projectCode,
+ packageCode,
importedData // 모든 imported rows를 한번에 전달
);
@@ -633,7 +635,6 @@ export async function importExcelData({
}
} else {
- // formCode나 contractItemId가 없는 경우 - 로컬 업데이트만
if (onDataUpdate) {
onDataUpdate(() => mergedData);
}
diff --git a/components/form-data-plant/publish-dialog.tsx b/components/form-data-plant/publish-dialog.tsx
index a3a2ef0b..f63c2db8 100644
--- a/components/form-data-plant/publish-dialog.tsx
+++ b/components/form-data-plant/publish-dialog.tsx
@@ -37,19 +37,21 @@ import { Loader2, Check, ChevronsUpDown } from "lucide-react";
import { toast } from "sonner";
import { cn } from "@/lib/utils";
import {
- createRevisionAction,
- fetchDocumentsByPackageId,
- fetchStagesByDocumentId,
- fetchRevisionsByStageParams,
- Document,
- IssueStage,
- Revision
+ createSubmissionAction, // 새로운 액션 이름
+ fetchDocumentsByProjectAndPackage, // 업데이트된 액션
+ fetchStagesByDocumentIdPlant,
+ fetchSubmissionsByStageParams, // revisions 대신 submissions
} from "@/lib/vendor-document/service";
+import type {
+ StageDocument,
+ StageIssueStage,
+} from "@/db/schema/vendorDocu";
interface PublishDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
- packageId: number;
+ projectCode: string;
+ packageCode: string;
formCode: string;
fileBlob?: Blob;
}
@@ -57,7 +59,8 @@ interface PublishDialogProps {
export const PublishDialog: React.FC<PublishDialogProps> = ({
open,
onOpenChange,
- packageId,
+ projectCode,
+ packageCode,
formCode,
fileBlob,
}) => {
@@ -65,9 +68,10 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
const { data: session } = useSession();
// State for form data
- const [documents, setDocuments] = useState<Document[]>([]);
- const [stages, setStages] = useState<IssueStage[]>([]);
- const [latestRevision, setLatestRevision] = useState<string>("");
+ const [documents, setDocuments] = useState<StageDocument[]>([]);
+ const [stages, setStages] = useState<StageIssueStage[]>([]);
+ const [latestRevisionCode, setLatestRevisionCode] = useState<string>("");
+ const [latestRevisionNumber, setLatestRevisionNumber] = useState<number>(0);
// State for document search
const [openDocumentCombobox, setOpenDocumentCombobox] = useState(false);
@@ -77,9 +81,10 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
const [selectedDocId, setSelectedDocId] = useState<string>("");
const [selectedDocumentDisplay, setSelectedDocumentDisplay] = useState<string>("");
const [selectedStage, setSelectedStage] = useState<string>("");
- const [revisionInput, setRevisionInput] = useState<string>("");
- const [uploaderName, setUploaderName] = useState<string>("");
- const [comment, setComment] = useState<string>("");
+ const [revisionCodeInput, setRevisionCodeInput] = useState<string>("");
+ const [submitterName, setSubmitterName] = useState<string>("");
+ const [submissionTitle, setSubmissionTitle] = useState<string>("");
+ const [submissionDescription, setSubmissionDescription] = useState<string>("");
const [customFileName, setCustomFileName] = useState<string>(`${formCode}_document.docx`);
// Loading states
@@ -94,10 +99,10 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
)
: documents;
- // Set uploader name from session when dialog opens
+ // Set submitter name from session when dialog opens
useEffect(() => {
if (open && session?.user?.name) {
- setUploaderName(session.user.name);
+ setSubmitterName(session.user.name);
}
}, [open, session]);
@@ -107,24 +112,26 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
setSelectedDocId("");
setSelectedDocumentDisplay("");
setSelectedStage("");
- setRevisionInput("");
- // Only set uploaderName if not already set from session
- if (!session?.user?.name) setUploaderName("");
- setComment("");
- setLatestRevision("");
+ setRevisionCodeInput("");
+ setSubmissionTitle("");
+ setSubmissionDescription("");
+ // Only set submitterName if not already set from session
+ if (!session?.user?.name) setSubmitterName("");
+ setLatestRevisionCode("");
+ setLatestRevisionNumber(0);
setCustomFileName(`${formCode}_document.docx`);
setDocumentSearchValue("");
}
}, [open, formCode, session]);
- // Fetch documents based on packageId
+ // Fetch documents based on projectCode and packageCode
useEffect(() => {
async function loadDocuments() {
- if (packageId && open) {
+ if (projectCode && packageCode && open) {
setIsLoading(true);
try {
- const docs = await fetchDocumentsByPackageId(packageId);
+ const docs = await fetchDocumentsByProjectAndPackage(projectCode, packageCode);
setDocuments(docs);
} catch (error) {
console.error("Error fetching documents:", error);
@@ -136,7 +143,7 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
}
loadDocuments();
- }, [packageId, open]);
+ }, [projectCode, packageCode, open]);
// Fetch stages when document is selected
useEffect(() => {
@@ -146,11 +153,12 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
// Reset dependent fields
setSelectedStage("");
- setRevisionInput("");
- setLatestRevision("");
+ setRevisionCodeInput("");
+ setLatestRevisionCode("");
+ setLatestRevisionNumber(0);
try {
- const stagesList = await fetchStagesByDocumentId(parseInt(selectedDocId, 10));
+ const stagesList = await fetchStagesByDocumentIdPlant(parseInt(selectedDocId, 10));
setStages(stagesList);
} catch (error) {
console.error("Error fetching stages:", error);
@@ -166,65 +174,78 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
loadStages();
}, [selectedDocId]);
- // Fetch latest revision when stage is selected (for reference)
+ // Fetch latest submission (revision) when stage is selected
useEffect(() => {
- async function loadLatestRevision() {
+ async function loadLatestSubmission() {
if (selectedDocId && selectedStage) {
setIsLoading(true);
try {
- const revsList = await fetchRevisionsByStageParams(
+ const submissionsList = await fetchSubmissionsByStageParams(
parseInt(selectedDocId, 10),
selectedStage
);
- // Find the latest revision (assuming revisions are sorted by revision number)
- if (revsList.length > 0) {
- // Sort revisions if needed
- const sortedRevisions = [...revsList].sort((a, b) => {
- return b.revision.localeCompare(a.revision, undefined, { numeric: true });
- });
+ // Find the latest submission (assuming sorted by revision number)
+ if (submissionsList.length > 0) {
+ // Sort submissions by revision number descending
+ const sortedSubmissions = [...submissionsList].sort((a, b) =>
+ b.revisionNumber - a.revisionNumber
+ );
- setLatestRevision(sortedRevisions[0].revision);
+ const latestSubmission = sortedSubmissions[0];
+ setLatestRevisionCode(latestSubmission.revisionCode);
+ setLatestRevisionNumber(latestSubmission.revisionNumber);
- // Pre-fill the revision input with an incremented value if possible
- if (sortedRevisions[0].revision.match(/^\d+$/)) {
+ // Auto-increment revision code
+ if (latestSubmission.revisionCode.match(/^\d+$/)) {
// If it's a number, increment it
- const nextRevision = String(parseInt(sortedRevisions[0].revision, 10) + 1);
- setRevisionInput(nextRevision);
- } else if (sortedRevisions[0].revision.match(/^[A-Za-z]$/)) {
+ const nextRevision = String(parseInt(latestSubmission.revisionCode, 10) + 1);
+ setRevisionCodeInput(nextRevision);
+ } else if (latestSubmission.revisionCode.match(/^[A-Za-z]$/)) {
// If it's a single letter, get the next letter
- const currentChar = sortedRevisions[0].revision.charCodeAt(0);
+ const currentChar = latestSubmission.revisionCode.charCodeAt(0);
const nextChar = String.fromCharCode(currentChar + 1);
- setRevisionInput(nextChar);
+ setRevisionCodeInput(nextChar);
+ } else if (latestSubmission.revisionCode.toLowerCase().startsWith("rev")) {
+ // Handle "Rev0", "Rev1" format
+ const numMatch = latestSubmission.revisionCode.match(/\d+$/);
+ if (numMatch) {
+ const nextNum = parseInt(numMatch[0], 10) + 1;
+ setRevisionCodeInput(`Rev${nextNum}`);
+ } else {
+ setRevisionCodeInput("");
+ }
} else {
// For other formats, just show the latest as reference
- setRevisionInput("");
+ setRevisionCodeInput("");
}
} else {
- // If no revisions exist, set default values
- setLatestRevision("");
- setRevisionInput("0");
+ // If no submissions exist, set default values
+ setLatestRevisionCode("");
+ setLatestRevisionNumber(0);
+ setRevisionCodeInput("Rev0"); // Start with Rev0
}
} catch (error) {
- console.error("Error fetching revisions:", error);
- toast.error("Failed to load revision information");
+ console.error("Error fetching submissions:", error);
+ toast.error("Failed to load submission information");
} finally {
setIsLoading(false);
}
} else {
- setLatestRevision("");
- setRevisionInput("");
+ setLatestRevisionCode("");
+ setLatestRevisionNumber(0);
+ setRevisionCodeInput("");
}
}
- loadLatestRevision();
+ loadLatestSubmission();
}, [selectedDocId, selectedStage]);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
- if (!selectedDocId || !selectedStage || !revisionInput || !fileBlob) {
+ if (!selectedDocId || !selectedStage || !revisionCodeInput || !fileBlob) {
toast.error("Please fill in all required fields");
return;
}
@@ -235,17 +256,30 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
// Create FormData
const formData = new FormData();
formData.append("documentId", selectedDocId);
- formData.append("stage", selectedStage);
- formData.append("revision", revisionInput);
+ formData.append("stageName", selectedStage);
+ formData.append("revisionCode", revisionCodeInput);
formData.append("customFileName", customFileName);
- formData.append("uploaderType", "vendor"); // Default value
- if (uploaderName) {
- formData.append("uploaderName", uploaderName);
+ if (submitterName) {
+ formData.append("submittedBy", submitterName);
}
- if (comment) {
- formData.append("comment", comment);
+ if (session?.user?.email) {
+ formData.append("submittedByEmail", session.user.email);
+ }
+
+ if (submissionTitle) {
+ formData.append("submissionTitle", submissionTitle);
+ }
+
+ if (submissionDescription) {
+ formData.append("submissionDescription", submissionDescription);
+ }
+
+ // Get vendor info from selected document
+ const selectedDoc = documents.find(doc => doc.id === parseInt(selectedDocId, 10));
+ if (selectedDoc) {
+ formData.append("vendorId", String(selectedDoc.vendorId));
}
// Append file as attachment
@@ -256,12 +290,14 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
formData.append("attachment", file);
}
- // Call server action directly
- const result = await createRevisionAction(formData);
+ // Call server action
+ const result = await createSubmissionAction(formData);
- if (result) {
+ if (result.success) {
toast.success("Document published successfully!");
onOpenChange(false);
+ } else {
+ toast.error(result.error || "Failed to publish document");
}
} catch (error) {
console.error("Error publishing document:", error);
@@ -301,7 +337,6 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
className="w-full justify-between"
disabled={isLoading || documents.length === 0}
>
- {/* Add text-overflow handling for selected document display */}
<span className="truncate">
{selectedDocumentDisplay
? selectedDocumentDisplay
@@ -338,7 +373,6 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
: "opacity-0"
)}
/>
- {/* Add text-overflow handling for document items */}
<span className="truncate">{doc.docNumber} - {doc.title}</span>
</CommandItem>
))}
@@ -366,7 +400,6 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
<SelectContent>
{stages.map((stage) => (
<SelectItem key={stage.id} value={stage.stageName}>
- {/* Add text-overflow handling for stage names */}
<span className="truncate">{stage.stageName}</span>
</SelectItem>
))}
@@ -375,28 +408,42 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
</div>
</div>
- {/* Revision Input */}
+ {/* Revision Code Input */}
<div className="grid grid-cols-4 items-center gap-4">
- <Label htmlFor="revision" className="text-right">
+ <Label htmlFor="revisionCode" className="text-right">
Revision
</Label>
<div className="col-span-3">
<Input
- id="revision"
- value={revisionInput}
- onChange={(e) => setRevisionInput(e.target.value)}
- placeholder="Enter revision"
+ id="revisionCode"
+ value={revisionCodeInput}
+ onChange={(e) => setRevisionCodeInput(e.target.value)}
+ placeholder="Enter revision code (e.g., Rev0, A, 1)"
disabled={isLoading || !selectedStage}
/>
- {latestRevision && (
+ {latestRevisionCode && (
<p className="text-xs text-muted-foreground mt-1">
- Latest revision: {latestRevision}
+ Latest revision: {latestRevisionCode} (#{latestRevisionNumber})
</p>
)}
</div>
</div>
<div className="grid grid-cols-4 items-center gap-4">
+ <Label htmlFor="submissionTitle" className="text-right">
+ Title
+ </Label>
+ <div className="col-span-3">
+ <Input
+ id="submissionTitle"
+ value={submissionTitle}
+ onChange={(e) => setSubmissionTitle(e.target.value)}
+ placeholder="Optional submission title"
+ />
+ </div>
+ </div>
+
+ <div className="grid grid-cols-4 items-center gap-4">
<Label htmlFor="fileName" className="text-right">
File Name
</Label>
@@ -411,16 +458,15 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
</div>
<div className="grid grid-cols-4 items-center gap-4">
- <Label htmlFor="uploaderName" className="text-right">
- Uploader
+ <Label htmlFor="submitterName" className="text-right">
+ Submitter
</Label>
<div className="col-span-3">
<Input
- id="uploaderName"
- value={uploaderName}
- onChange={(e) => setUploaderName(e.target.value)}
+ id="submitterName"
+ value={submitterName}
+ onChange={(e) => setSubmitterName(e.target.value)}
placeholder="Your name"
- // Disable input but show a filled style
className={session?.user?.name ? "opacity-70" : ""}
readOnly={!!session?.user?.name}
/>
@@ -433,15 +479,15 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
</div>
<div className="grid grid-cols-4 items-center gap-4">
- <Label htmlFor="comment" className="text-right">
- Comment
+ <Label htmlFor="description" className="text-right">
+ Description
</Label>
<div className="col-span-3">
<Textarea
- id="comment"
- value={comment}
- onChange={(e) => setComment(e.target.value)}
- placeholder="Optional comment"
+ id="description"
+ value={submissionDescription}
+ onChange={(e) => setSubmissionDescription(e.target.value)}
+ placeholder="Optional submission description"
className="resize-none"
/>
</div>
@@ -451,7 +497,7 @@ export const PublishDialog: React.FC<PublishDialogProps> = ({
<DialogFooter>
<Button
type="submit"
- disabled={isSubmitting || !selectedDocId || !selectedStage || !revisionInput}
+ disabled={isSubmitting || !selectedDocId || !selectedStage || !revisionCodeInput}
>
{isSubmitting ? (
<>
diff --git a/components/form-data-plant/spreadJS-dialog.tsx b/components/form-data-plant/spreadJS-dialog.tsx
index 2eb2c8ba..9f972676 100644
--- a/components/form-data-plant/spreadJS-dialog.tsx
+++ b/components/form-data-plant/spreadJS-dialog.tsx
@@ -92,7 +92,8 @@ interface TemplateViewDialogProps {
tableData?: GenericData[];
formCode: string;
columnsJSON: DataTableColumnJSON[]
- contractItemId: number;
+ projectCode: string;
+ packageCode: string;
editableFieldsMap?: Map<string, string[]>;
onUpdateSuccess?: (updatedValues: Record<string, any> | GenericData[]) => void;
}
@@ -142,7 +143,8 @@ export function TemplateViewDialog({
selectedRow,
tableData = [],
formCode,
- contractItemId,
+ projectCode,
+ packageCode,
columnsJSON,
editableFieldsMap = new Map(),
onUpdateSuccess
@@ -1435,7 +1437,8 @@ export function TemplateViewDialog({
const { success, message } = await updateFormDataInDB(
formCode,
- contractItemId,
+ projectCode,
+ packageCode,
dataToSave
);
@@ -1500,7 +1503,8 @@ export function TemplateViewDialog({
try {
const { success, message } = await updateFormDataInDB(
formCode,
- contractItemId,
+ projectCode,
+ packageCode,
dataToSave
);
@@ -1551,7 +1555,8 @@ export function TemplateViewDialog({
selectedRow,
tableData,
formCode,
- contractItemId,
+ projectCode,
+ packageCode,
onUpdateSuccess,
cellMappings,
columnsJSON,
diff --git a/components/form-data-plant/update-form-sheet.tsx b/components/form-data-plant/update-form-sheet.tsx
index bd75d8f3..b7f56f7e 100644
--- a/components/form-data-plant/update-form-sheet.tsx
+++ b/components/form-data-plant/update-form-sheet.tsx
@@ -65,7 +65,8 @@ interface UpdateTagSheetProps extends React.ComponentPropsWithoutRef<typeof Shee
columns: DataTableColumnJSON[];
rowData: Record<string, any> | null;
formCode: string;
- contractItemId: number;
+ projectCode: string;
+ packageCode: string;
editableFieldsMap?: Map<string, string[]>; // 새로 추가
/** 업데이트 성공 시 호출될 콜백 */
onUpdateSuccess?: (updatedValues: Record<string, any>) => void;
@@ -77,7 +78,8 @@ export function UpdateTagSheet({
columns,
rowData,
formCode,
- contractItemId,
+ projectCode,
+ packageCode,
editableFieldsMap = new Map(),
onUpdateSuccess,
...props
@@ -219,7 +221,8 @@ export function UpdateTagSheet({
const { success, message } = await updateFormDataInDB(
formCode,
- contractItemId,
+ projectCode,
+ packageCode,
finalValues,
);