From 45f4c426c98d86a251644a4858740bec989edf83 Mon Sep 17 00:00:00 2001 From: dujinkim Date: Tue, 20 May 2025 09:01:22 +0000 Subject: (최겸) 기술영업 아이템리스트 수정 및 개발 0520 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/items-tech/table/top/import-item-handler.tsx | 36 ++----- lib/items-tech/table/top/item-excel-template.tsx | 33 +++--- .../table/top/offshore-top-table-columns.tsx | 116 +++------------------ .../top/offshore-top-table-toolbar-actions.tsx | 12 +-- lib/items-tech/table/top/offshore-top-table.tsx | 29 ++---- 5 files changed, 50 insertions(+), 176 deletions(-) (limited to 'lib/items-tech/table/top') diff --git a/lib/items-tech/table/top/import-item-handler.tsx b/lib/items-tech/table/top/import-item-handler.tsx index de1638a8..d6b81964 100644 --- a/lib/items-tech/table/top/import-item-handler.tsx +++ b/lib/items-tech/table/top/import-item-handler.tsx @@ -9,15 +9,11 @@ const TOP_WORK_TYPES = ["TM", "TS", "TE", "TP"] as const; // 아이템 데이터 검증을 위한 Zod 스키마 const itemSchema = z.object({ itemCode: z.string().min(1, "아이템 코드는 필수입니다"), - itemName: z.string().min(1, "아이템 명은 필수입니다"), workType: z.enum(TOP_WORK_TYPES, { required_error: "기능(공종)은 필수입니다", }), - description: z.string().nullable().optional(), - itemList1: z.string().nullable().optional(), - itemList2: z.string().nullable().optional(), - itemList3: z.string().nullable().optional(), - itemList4: z.string().nullable().optional(), + itemList: z.string().nullable().optional(), + subItemList: z.string().nullable().optional(), }); interface ProcessResult { @@ -30,7 +26,7 @@ interface ProcessResult { * Excel 파일에서 가져온 해양 TOP 아이템 데이터 처리하는 함수 */ export async function processTopFileImport( - jsonData: any[], + jsonData: Record[], progressCallback?: (current: number, total: number) => void ): Promise { // 결과 카운터 초기화 @@ -65,24 +61,16 @@ export async function processTopFileImport( try { // 필드 매핑 (한글/영문 필드명 모두 지원) const itemCode = row["아이템 코드"] || row["itemCode"] || ""; - const itemName = row["아이템 명"] || row["itemName"] || ""; const workType = row["기능(공종)"] || row["workType"] || ""; - const description = row["설명"] || row["description"] || null; - const itemList1 = row["항목1"] || row["itemList1"] || null; - const itemList2 = row["항목2"] || row["itemList2"] || null; - const itemList3 = row["항목3"] || row["itemList3"] || null; - const itemList4 = row["항목4"] || row["itemList4"] || null; + const itemList = row["아이템 리스트"] || row["itemList"] || null; + const subItemList = row["서브 아이템 리스트"] || row["subItemList"] || null; // 데이터 정제 const cleanedRow = { itemCode: typeof itemCode === 'string' ? itemCode.trim() : String(itemCode).trim(), - itemName: typeof itemName === 'string' ? itemName.trim() : String(itemName).trim(), workType: typeof workType === 'string' ? workType.trim() : String(workType).trim(), - description: description ? (typeof description === 'string' ? description : String(description)) : null, - itemList1: itemList1 ? (typeof itemList1 === 'string' ? itemList1 : String(itemList1)) : null, - itemList2: itemList2 ? (typeof itemList2 === 'string' ? itemList2 : String(itemList2)) : null, - itemList3: itemList3 ? (typeof itemList3 === 'string' ? itemList3 : String(itemList3)) : null, - itemList4: itemList4 ? (typeof itemList4 === 'string' ? itemList4 : String(itemList4)) : null, + itemList: itemList ? (typeof itemList === 'string' ? itemList : String(itemList)) : null, + subItemList: subItemList ? (typeof subItemList === 'string' ? subItemList : String(subItemList)) : null, }; // 데이터 유효성 검사 @@ -101,13 +89,11 @@ export async function processTopFileImport( // 해양 TOP 아이템 생성 const result = await createOffshoreTopItem({ itemCode: cleanedRow.itemCode, - itemName: cleanedRow.itemName, + itemName: "기술영업", // 기본값 사용 workType: cleanedRow.workType as "TM" | "TS" | "TE" | "TP", - description: cleanedRow.description, - itemList1: cleanedRow.itemList1, - itemList2: cleanedRow.itemList2, - itemList3: cleanedRow.itemList3, - itemList4: cleanedRow.itemList4, + description: null, + itemList: cleanedRow.itemList, + subItemList: cleanedRow.subItemList, }); if (result.success) { diff --git a/lib/items-tech/table/top/item-excel-template.tsx b/lib/items-tech/table/top/item-excel-template.tsx index 4514af59..f0e10d82 100644 --- a/lib/items-tech/table/top/item-excel-template.tsx +++ b/lib/items-tech/table/top/item-excel-template.tsx @@ -19,13 +19,10 @@ export async function exportTopItemTemplate() { // 컬럼 헤더 정의 및 스타일 적용 worksheet.columns = [ { header: '아이템 코드', key: 'itemCode', width: 15 }, - { header: '아이템 명', key: 'itemName', width: 30 }, { header: '기능(공종)', key: 'workType', width: 15 }, - { header: '설명', key: 'description', width: 50 }, - { header: '항목1', key: 'itemList1', width: 20 }, - { header: '항목2', key: 'itemList2', width: 20 }, - { header: '항목3', key: 'itemList3', width: 20 }, - { header: '항목4', key: 'itemList4', width: 20 }, + { header: '아이템 리스트', key: 'itemList', width: 20 }, + { header: '서브 아이템 리스트', key: 'subItemList', width: 20 }, + ]; // 헤더 스타일 적용 @@ -51,25 +48,18 @@ export async function exportTopItemTemplate() { // 샘플 데이터 추가 const sampleData = [ { - itemCode: 'TOP001', - itemName: 'TOP 샘플 아이템 1', + itemCode: 'TOP001', workType: 'TM', - description: '이것은 해양 TOP 샘플 아이템 1의 설명입니다.', - itemList1: '항목1 샘플 데이터', - itemList2: '항목2 샘플 데이터', - itemList3: '항목3 샘플 데이터', - itemList4: '항목4 샘플 데이터' + itemList: '항목1 샘플 데이터', + subItemList: '항목2 샘플 데이터', }, { - itemCode: 'TOP002', - itemName: 'TOP 샘플 아이템 2', + itemCode: 'TOP002', workType: 'TS', - description: '이것은 해양 TOP 샘플 아이템 2의 설명입니다.', - itemList1: '항목1 샘플 데이터', - itemList2: '항목2 샘플 데이터', - itemList3: '', - itemList4: '' + itemList: '항목1 샘플 데이터', + subItemList: '항목2 샘플 데이터', } + ]; // 데이터 행 추가 @@ -94,7 +84,8 @@ export async function exportTopItemTemplate() { // 워크시트에 공종 유형 관련 메모 추가 const infoRow = worksheet.addRow(['공종 유형 안내: ' + TOP_WORK_TYPES.join(', ')]); infoRow.font = { bold: true, color: { argb: 'FF0000FF' } }; - worksheet.mergeCells(`A${infoRow.number}:H${infoRow.number}`); + worksheet.mergeCells(`A${infoRow.number}:F${infoRow.number}`); + // 워크시트 보호 (선택적) worksheet.protect('', { diff --git a/lib/items-tech/table/top/offshore-top-table-columns.tsx b/lib/items-tech/table/top/offshore-top-table-columns.tsx index 4ccb2003..4746f226 100644 --- a/lib/items-tech/table/top/offshore-top-table-columns.tsx +++ b/lib/items-tech/table/top/offshore-top-table-columns.tsx @@ -23,10 +23,8 @@ interface OffshoreTopTableItem { id: number; itemId: number; workType: "TM" | "TS" | "TE" | "TP"; - itemList1: string | null; - itemList2: string | null; - itemList3: string | null; - itemList4: string | null; + itemList: string | null; + subItemList: string | null; itemCode: string; itemName: string; description: string | null; @@ -107,11 +105,10 @@ export function getOffshoreTopColumns({ setRowAction }: GetColumnsProps): Column } // ---------------------------------------------------------------- - // 3) 데이터 컬럼들을 그룹별로 구성 + // 3) 데이터 컬럼들 정의 // ---------------------------------------------------------------- - // 3-1) 기본 정보 그룹 컬럼 - const basicInfoColumns: ColumnDef[] = [ + const dataColumns: ColumnDef[] = [ { accessorKey: "itemCode", header: ({ column }) => ( @@ -122,20 +119,6 @@ export function getOffshoreTopColumns({ setRowAction }: GetColumnsProps): Column enableHiding: true, meta: { excelHeader: "Material Group", - group: "기본 정보", - }, - }, - { - accessorKey: "itemName", - header: ({ column }) => ( - - ), - cell: ({ row }) =>
{row.original.itemName}
, - enableSorting: true, - enableHiding: true, - meta: { - excelHeader: "Description", - group: "기본 정보", }, }, { @@ -148,82 +131,32 @@ export function getOffshoreTopColumns({ setRowAction }: GetColumnsProps): Column enableHiding: true, meta: { excelHeader: "기능(공종)", - group: "기본 정보", - }, - }, - { - accessorKey: "description", - header: ({ column }) => ( - - ), - cell: ({ row }) =>
{row.original.description || "-"}
, - enableSorting: true, - enableHiding: true, - meta: { - excelHeader: "Size/Dimension", - group: "기본 정보", - }, - }, - ] - - // 3-2) 아이템 리스트 그룹 컬럼 - const itemListColumns: ColumnDef[] = [ - { - accessorKey: "itemList1", - header: ({ column }) => ( - - ), - cell: ({ row }) =>
{row.original.itemList1 || "-"}
, - enableSorting: true, - enableHiding: true, - meta: { - excelHeader: "아이템 리스트 1", - group: "아이템 리스트", - }, - }, - { - accessorKey: "itemList2", - header: ({ column }) => ( - - ), - cell: ({ row }) =>
{row.original.itemList2 || "-"}
, - enableSorting: true, - enableHiding: true, - meta: { - excelHeader: "아이템 리스트 2", - group: "아이템 리스트", }, }, { - accessorKey: "itemList3", + accessorKey: "itemList", header: ({ column }) => ( - + ), - cell: ({ row }) =>
{row.original.itemList3 || "-"}
, + cell: ({ row }) =>
{row.original.itemList || "-"}
, enableSorting: true, enableHiding: true, meta: { - excelHeader: "아이템 리스트 3", - group: "아이템 리스트", + excelHeader: "아이템 리스트", }, }, { - accessorKey: "itemList4", + accessorKey: "subItemList", header: ({ column }) => ( - + ), - cell: ({ row }) =>
{row.original.itemList4 || "-"}
, + cell: ({ row }) =>
{row.original.subItemList || "-"}
, enableSorting: true, enableHiding: true, meta: { - excelHeader: "아이템 리스트 4", - group: "아이템 리스트", + excelHeader: "서브 아이템 리스트", }, }, - ] - - // 3-3) 메타데이터 그룹 컬럼 - const metadataColumns: ColumnDef[] = [ { accessorKey: "createdAt", header: ({ column }) => ( @@ -234,7 +167,6 @@ export function getOffshoreTopColumns({ setRowAction }: GetColumnsProps): Column enableHiding: true, meta: { excelHeader: "생성일", - group: "Metadata", }, }, { @@ -247,36 +179,16 @@ export function getOffshoreTopColumns({ setRowAction }: GetColumnsProps): Column enableHiding: true, meta: { excelHeader: "수정일", - group: "Metadata", }, } ] - - // 3-4) 그룹별 컬럼 구성 - const groupedColumns: ColumnDef[] = [ - { - id: "기본 정보", - header: "기본 정보", - columns: basicInfoColumns, - }, - { - id: "아이템 리스트", - header: "아이템 리스트", - columns: itemListColumns, - }, - { - id: "Metadata", - header: "Metadata", - columns: metadataColumns, - } - ] // ---------------------------------------------------------------- - // 4) 최종 컬럼 배열: select, groupedColumns, actions + // 4) 최종 컬럼 배열: select, dataColumns, actions // ---------------------------------------------------------------- return [ selectColumn, - ...groupedColumns, + ...dataColumns, actionsColumn, ] } \ No newline at end of file diff --git a/lib/items-tech/table/top/offshore-top-table-toolbar-actions.tsx b/lib/items-tech/table/top/offshore-top-table-toolbar-actions.tsx index 324312aa..f91adf96 100644 --- a/lib/items-tech/table/top/offshore-top-table-toolbar-actions.tsx +++ b/lib/items-tech/table/top/offshore-top-table-toolbar-actions.tsx @@ -24,10 +24,8 @@ interface OffshoreTopItem { id: number; itemId: number; workType: "TM" | "TS" | "TE" | "TP"; - itemList1: string | null; - itemList2: string | null; - itemList3: string | null; - itemList4: string | null; + itemList: string | null; + subItemList: string | null; itemCode: string; itemName: string; description: string | null; @@ -76,10 +74,8 @@ export function OffshoreTopTableToolbarActions({ table }: OffshoreTopTableToolba { key: 'itemName', header: '아이템 명' }, { key: 'description', header: '설명' }, { key: 'workType', header: '기능(공종)' }, - { key: 'itemList1', header: '아이템 리스트 1' }, - { key: 'itemList2', header: '아이템 리스트 2' }, - { key: 'itemList3', header: '아이템 리스트 3' }, - { key: 'itemList4', header: '아이템 리스트 4' } + { key: 'itemList', header: '아이템 리스트' }, + { key: 'subItemList', header: '서브 아이템 리스트' }, ].filter(header => !excludeColumns.includes(header.key)); console.log("내보내기 헤더:", headers); diff --git a/lib/items-tech/table/top/offshore-top-table.tsx b/lib/items-tech/table/top/offshore-top-table.tsx index dedf766a..689f1db3 100644 --- a/lib/items-tech/table/top/offshore-top-table.tsx +++ b/lib/items-tech/table/top/offshore-top-table.tsx @@ -21,10 +21,8 @@ type OffshoreTopItem = { id: number; itemId: number; workType: "TM" | "TS" | "TE" | "TP"; - itemList1: string | null; - itemList2: string | null; - itemList3: string | null; - itemList4: string | null; + itemList: string | null; + subItemList: string | null; itemCode: string; itemName: string; description: string | null; @@ -56,8 +54,8 @@ export function OffshoreTopTable({ promises }: OffshoreTopTableProps) { label: "기능(공종)", }, { - id: "itemList1", - label: "아이템 리스트 1", + id: "itemList", + label: "아이템 리스트", }, ] @@ -83,25 +81,16 @@ export function OffshoreTopTable({ promises }: OffshoreTopTableProps) { type: "text", }, { - id: "itemList1", - label: "아이템 리스트 1", + id: "itemList", + label: "아이템 리스트", type: "text", }, { - id: "itemList2", - label: "아이템 리스트 2", - type: "text", - }, - { - id: "itemList3", - label: "아이템 리스트 3", - type: "text", - }, - { - id: "itemList4", - label: "아이템 리스트 4", + id: "subItemList", + label: "서브 아이템 리스트", type: "text", }, + ] const { table } = useDataTable({ -- cgit v1.2.3