From 3f293c90beb58ce206a66ff444d7acfc41b56429 Mon Sep 17 00:00:00 2001 From: joonhoekim <26rote@gmail.com> Date: Sun, 14 Sep 2025 13:27:37 +0000 Subject: (김준회) Vendor Pool 구현 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/vendor-pool/table/columns.tsx | 1687 +++++++++++++++++++++++++++++++++++++ 1 file changed, 1687 insertions(+) create mode 100644 lib/vendor-pool/table/columns.tsx (limited to 'lib/vendor-pool/table/columns.tsx') diff --git a/lib/vendor-pool/table/columns.tsx b/lib/vendor-pool/table/columns.tsx new file mode 100644 index 00000000..0a6b0c8f --- /dev/null +++ b/lib/vendor-pool/table/columns.tsx @@ -0,0 +1,1687 @@ +import { Checkbox } from "@/components/ui/checkbox" +import { Button } from "@/components/ui/button" +import { MoreHorizontal, Eye, Edit, Trash2 } from "lucide-react" +import { type ColumnDef, TableMeta } from "@tanstack/react-table" +import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" +import { EditableCell } from "@/components/data-table/editable-cell" + +// 수정 여부 확인 헬퍼 함수 +const getIsModified = (table: any, rowId: string, fieldName: string) => { + const pendingChanges = table.options.meta?.getPendingChanges?.() || {} + return String(rowId) in pendingChanges && fieldName in pendingChanges[String(rowId)] +} + +// 테이블 메타 타입 확장 +declare module "@tanstack/react-table" { + interface TableMeta { + onCellUpdate?: (id: string, field: keyof TData, newValue: any) => Promise + onCellCancel?: (id: string, field: keyof TData) => void + onAction?: (action: string, data?: any) => void + onSaveEmptyRow?: (tempId: string) => Promise + onCancelEmptyRow?: (tempId: string) => void + isEmptyRow?: (id: string) => boolean + onTaxIdChange?: (id: string, taxId: string) => Promise + onMaterialGroupCodeChange?: (id: string, materialGroupCode: string) => Promise + } +} + +// Vendor Pool 데이터 타입 +export type VendorPoolItem = { + id: string + no: number + selected: boolean + constructionSector: string // 공사부문: 조선 또는 해양 + htDivision: string // H/T구분: H 또는 T + designCategoryCode: string // 설계기능(공종) 코드: 2자리 영문대문자 + designCategory: string // 설계기능(공종): 전장 등 + equipBulkDivision: string // Equip/Bulk 구분: E 또는 B + // 패키지 정보 (스키마: packageCode, packageName) + packageCode: string + packageName: string + // 자재그룹 (스키마: materialGroupCode, materialGroupName) + materialGroupCode: string + materialGroupName: string + smCode: string // SM Code + similarMaterialNamePurchase: string // 유사자재명 (구매) + similarMaterialNameOther: string // 유사자재명 (구매 외) + // 협력업체 정보 (스키마: vendorCode, vendorName) + vendorCode: string + vendorName: string + taxId: string // 사업자번호(Tax ID) + faTarget: boolean // FA대상 + faStatus: string // FA현황 + faRemark: string // FA상세(Remark) + tier: string // 등급(Tier) + isAgent: boolean // Agent 여부 + // 계약서명주체 (스키마: contractSignerCode, contractSignerName) + contractSignerCode: string + contractSignerName: string + headquarterLocation: string // 본사 위치(국가) + manufacturingLocation: string // 제작/선적지(국가) + avlVendorName: string // AVL 등재업체명 + similarVendorName: string // 유사업체명(기술영업) + hasAvl: boolean // AVL: 존재여부 + isBlacklist: boolean // Blacklist + isBcc: boolean // BCC + purchaseOpinion: string // 구매의견 + // AVL 적용 선종(조선) + shipTypeCommon: boolean // 공통 + shipTypeAmax: boolean // A-max + shipTypeSmax: boolean // S-max + shipTypeVlcc: boolean // VLCC + shipTypeLngc: boolean // LNGC + shipTypeCont: boolean // CONT + // AVL 적용 선종(해양) + offshoreTypeCommon: boolean // 공통 + offshoreTypeFpso: boolean // FPSO + offshoreTypeFlng: boolean // FLNG + offshoreTypeFpu: boolean // FPU + offshoreTypePlatform: boolean // Platform + offshoreTypeWtiv: boolean // WTIV + offshoreTypeGom: boolean // GOM + // eVCP 미등록 정보 + picName: string // PIC(담당자) + picEmail: string // PIC(E-mail) + picPhone: string // PIC(Phone) + agentName: string // Agent(담당자) + agentEmail: string // Agent(E-mail) + agentPhone: string // Agent(Phone) + // 업체 실적 현황 + recentQuoteDate: string // 최근견적일 + recentQuoteNumber: string // 최근견적번호 + recentOrderDate: string // 최근발주일 + recentOrderNumber: string // 최근발주번호 + // 업데이트 히스토리 + registrationDate: string // 등재일 + registrant: string // 등재자 + lastModifiedDate: string // 최종변경일 + lastModifier: string // 최종변경자 +} + +// 테이블 컬럼 정의 +export const columns: ColumnDef[] = [ + // 기본 정보 그룹 + { + header: "기본 정보", + columns: [ + { + id: "select", + header: ({ table }) => ( + table.toggleAllPageRowsSelected(!!value)} + aria-label="Select all" + /> + ), + cell: ({ row }) => ( + row.toggleSelected(!!value)} + aria-label="Select row" + /> + ), + enableSorting: false, + enableHiding: false, + size: 40, + }, + { + accessorKey: "id", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const id = String(row.original.id) + + // 빈 행의 경우 No. 표시하지 않음 + if (id.startsWith('temp-')) { + return
신규
+ } + + // vendor_pool 테이블의 실제 id 표시 + return
{id}
+ }, + size: 60, + }, + { + accessorKey: "constructionSector", + header: ({ column }) => ( + 공사부문 *} /> + ), + cell: ({ row, table }) => { + const value = row.getValue("constructionSector") + const isEmptyRow = String(row.original.id).startsWith('temp-') + + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "constructionSector", newValue) + } + } + + // 수정 여부 확인 + const isModified = getIsModified(table, row.original.id, "constructionSector") + + return ( + + ) + }, + size: 100, + }, + { + accessorKey: "htDivision", + header: ({ column }) => ( + H/T구분 *} /> + ), + cell: ({ row, table }) => { + const value = row.getValue("htDivision") + const isEmptyRow = String(row.original.id).startsWith('temp-') + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "htDivision", newValue) + } + } + + // 수정 여부 확인 + const isModified = getIsModified(table, row.original.id, "htDivision") + + return ( + + ) + }, + size: 80, + }, + { + accessorKey: "designCategoryCode", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("designCategoryCode") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "designCategoryCode", newValue) + } + } + + // 수정 여부 확인 + const isModified = getIsModified(table, row.original.id, "designCategoryCode") + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "designCategory", + header: ({ column }) => ( + 설계기능(공종) *} /> + ), + cell: ({ row, table }) => { + const value = row.getValue("designCategory") + const isEmptyRow = String(row.original.id).startsWith('temp-') + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "designCategory", newValue) + } + } + + // 수정 여부 확인 + const isModified = getIsModified(table, row.original.id, "designCategory") + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "equipBulkDivision", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("equipBulkDivision") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "equipBulkDivision", newValue) + } + } + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "packageCode", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("packageCode") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "packageCode", newValue) + } + } + + // 수정 여부 확인 + const isModified = getIsModified(table, row.original.id, "packageCode") + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "packageName", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("packageName") + const isEmptyRow = String(row.original.id).startsWith('temp-') + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "packageName", newValue) + } + } + + // 수정 여부 확인 + const isModified = getIsModified(table, row.original.id, "packageName") + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "materialGroupCode", + header: ({ column }) => ( + 자재그룹 코드 *} /> + ), + cell: ({ row, table }) => { + const value = row.getValue("materialGroupCode") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "materialGroupCode", newValue) + } + } + + // 수정 여부 확인 + const isModified = getIsModified(table, row.original.id, "materialGroupCode") + + const onChange = async (newValue: any) => { + if (table.options.meta?.onMaterialGroupCodeChange) { + await table.options.meta.onMaterialGroupCodeChange(row.original.id, newValue) + } + } + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "materialGroupName", + header: ({ column }) => ( + 자재그룹 명 *} /> + ), + cell: ({ row, table }) => { + const value = row.getValue("materialGroupName") + const isEmptyRow = String(row.original.id).startsWith('temp-') + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "materialGroupName", newValue) + } + } + + // 수정 여부 확인 + const isModified = getIsModified(table, row.original.id, "materialGroupName") + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "smCode", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("smCode") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "smCode", newValue) + } + } + + return ( + + ) + }, + size: 100, + }, + ] + }, + // 자재 정보 그룹 + { + header: "자재 정보", + columns: [ + { + accessorKey: "similarMaterialNamePurchase", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("similarMaterialNamePurchase") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "similarMaterialNamePurchase", newValue) + } + } + + return ( + + ) + }, + size: 140, + }, + { + accessorKey: "similarMaterialNameOther", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("similarMaterialNameOther") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "similarMaterialNameOther", newValue) + } + } + + return ( + + ) + }, + size: 140, + }, + ] + }, + // 협력업체 정보 그룹 + { + header: "협력업체 정보", + columns: [ + { + accessorKey: "vendorCode", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("vendorCode") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "vendorCode", newValue) + } + } + + // 수정 여부 확인 + const isModified = getIsModified(table, row.original.id, "vendorCode") + + return ( + + ) + }, + size: 130, + }, + { + accessorKey: "vendorName", + header: ({ column }) => ( + 협력업체 명 *} /> + ), + cell: ({ row, table }) => { + const value = row.getValue("vendorName") + const isEmptyRow = String(row.original.id).startsWith('temp-') + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "vendorName", newValue) + } + } + + // 수정 여부 확인 + const isModified = getIsModified(table, row.original.id, "vendorName") + + return ( + + ) + }, + size: 130, + }, + { + accessorKey: "taxId", + header: ({ column }) => ( + 사업자번호 *} /> + ), + cell: ({ row, table }) => { + const value = row.getValue("taxId") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "taxId", newValue) + } + } + + const onChange = async (newValue: any) => { + if (table.options.meta?.onTaxIdChange) { + await table.options.meta.onTaxIdChange(row.original.id, newValue) + } + } + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "faTarget", + header: "FA대상", + cell: ({ row, table }) => { + const value = row.getValue("faTarget") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "faTarget", newValue) + } + } + + // 수정 여부 확인 + const isModified = getIsModified(table, row.original.id, "faTarget") + + return ( + + ) + }, + enableSorting: false, + size: 80, + }, + { + accessorKey: "faStatus", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("faStatus") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "faStatus", newValue) + } + } + + return ( + + ) + }, + size: 100, + }, + { + accessorKey: "faRemark", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("faRemark") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "faRemark", newValue) + } + } + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "tier", + header: ({ column }) => ( + 등급 *} /> + ), + cell: ({ row, table }) => { + const value = row.getValue("tier") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "tier", newValue) + } + } + + return ( + + ) + }, + size: 80, + }, + { + accessorKey: "isAgent", + header: "Agent 여부", + cell: ({ row, table }) => { + const value = row.getValue("isAgent") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "isAgent", newValue) + } + } + + return ( + + ) + }, + enableSorting: false, + size: 100, + }, + { + accessorKey: "contractSignerCode", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("contractSignerCode") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "contractSignerCode", newValue) + } + } + + // 수정 여부 확인 + const isModified = getIsModified(table, row.original.id, "contractSignerCode") + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "contractSignerName", + header: ({ column }) => ( + 계약서명주체 명 *} /> + ), + cell: ({ row, table }) => { + const value = row.getValue("contractSignerName") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "contractSignerName", newValue) + } + } + + // 수정 여부 확인 + const isModified = getIsModified(table, row.original.id, "contractSignerName") + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "headquarterLocation", + header: ({ column }) => ( + 본사 위치 *} /> + ), + cell: ({ row, table }) => { + const value = row.getValue("headquarterLocation") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "headquarterLocation", newValue) + } + } + + return ( + + ) + }, + size: 100, + }, + { + accessorKey: "manufacturingLocation", + header: ({ column }) => ( + 제작/선적지 *} /> + ), + cell: ({ row, table }) => { + const value = row.getValue("manufacturingLocation") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "manufacturingLocation", newValue) + } + } + + return ( + + ) + }, + size: 110, + }, + { + accessorKey: "avlVendorName", + header: ({ column }) => ( + AVL 등재업체명 *} /> + ), + cell: ({ row, table }) => { + const value = row.getValue("avlVendorName") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "avlVendorName", newValue) + } + } + + return ( + + ) + }, + size: 140, + }, + { + accessorKey: "similarVendorName", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("similarVendorName") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "similarVendorName", newValue) + } + } + + return ( + + ) + }, + size: 130, + }, + { + accessorKey: "hasAvl", + header: "AVL", + cell: ({ row, table }) => { + const value = row.getValue("hasAvl") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "hasAvl", newValue) + } + } + + return ( + + ) + }, + enableSorting: false, + size: 60, + }, + { + accessorKey: "isBlacklist", + header: "Blacklist", + cell: ({ row, table }) => { + const value = row.getValue("isBlacklist") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "isBlacklist", newValue) + } + } + + return ( + + ) + }, + enableSorting: false, + size: 100, + }, + { + accessorKey: "isBcc", + header: "BCC", + cell: ({ row, table }) => { + const value = row.getValue("isBcc") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "isBcc", newValue) + } + } + + return ( + + ) + }, + enableSorting: false, + size: 80, + }, + { + accessorKey: "purchaseOpinion", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("purchaseOpinion") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "purchaseOpinion", newValue) + } + } + + return ( + + ) + }, + size: 120, + }, + ] + }, + // AVL 적용 선종(조선) 그룹 + { + header: "AVL 적용 선종(조선)", + columns: [ + { + accessorKey: "shipTypeCommon", + header: "공통", + cell: ({ row, table }) => { + const value = row.getValue("shipTypeCommon") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "shipTypeCommon", newValue) + } + } + + return ( + + ) + }, + enableSorting: false, + size: 80, + }, + { + accessorKey: "shipTypeAmax", + header: "A-max", + cell: ({ row, table }) => { + const value = row.getValue("shipTypeAmax") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "shipTypeAmax", newValue) + } + } + + return ( + + ) + }, + enableSorting: false, + size: 80, + }, + { + accessorKey: "shipTypeSmax", + header: "S-max", + cell: ({ row, table }) => { + const value = row.getValue("shipTypeSmax") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "shipTypeSmax", newValue) + } + } + + return ( + + ) + }, + enableSorting: false, + size: 80, + }, + { + accessorKey: "shipTypeVlcc", + header: "VLCC", + cell: ({ row, table }) => { + const value = row.getValue("shipTypeVlcc") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "shipTypeVlcc", newValue) + } + } + + return ( + + ) + }, + enableSorting: false, + size: 80, + }, + { + accessorKey: "shipTypeLngc", + header: "LNGC", + cell: ({ row, table }) => { + const value = row.getValue("shipTypeLngc") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "shipTypeLngc", newValue) + } + } + + return ( + + ) + }, + size: 80, + }, + { + accessorKey: "shipTypeCont", + header: "CONT", + cell: ({ row, table }) => { + const value = row.getValue("shipTypeCont") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "shipTypeCont", newValue) + } + } + + return ( + + ) + }, + size: 80, + }, + ] + }, + // AVL 적용 선종(해양) 그룹 + { + header: "AVL 적용 선종(해양)", + columns: [ + { + accessorKey: "offshoreTypeCommon", + header: "공통", + cell: ({ row, table }) => { + const value = row.getValue("offshoreTypeCommon") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "offshoreTypeCommon", newValue) + } + } + + return ( + + ) + }, + size: 80, + }, + { + accessorKey: "offshoreTypeFpso", + header: "FPSO", + cell: ({ row, table }) => { + const value = row.getValue("offshoreTypeFpso") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "offshoreTypeFpso", newValue) + } + } + + return ( + + ) + }, + size: 80, + }, + { + accessorKey: "offshoreTypeFlng", + header: "FLNG", + cell: ({ row, table }) => { + const value = row.getValue("offshoreTypeFlng") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "offshoreTypeFlng", newValue) + } + } + + return ( + + ) + }, + size: 80, + }, + { + accessorKey: "offshoreTypeFpu", + header: "FPU", + cell: ({ row, table }) => { + const value = row.getValue("offshoreTypeFpu") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "offshoreTypeFpu", newValue) + } + } + + return ( + + ) + }, + size: 80, + }, + { + accessorKey: "offshoreTypePlatform", + header: "Platform", + cell: ({ row, table }) => { + const value = row.getValue("offshoreTypePlatform") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "offshoreTypePlatform", newValue) + } + } + + return ( + + ) + }, + size: 100, + }, + { + accessorKey: "offshoreTypeWtiv", + header: "WTIV", + cell: ({ row, table }) => { + const value = row.getValue("offshoreTypeWtiv") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "offshoreTypeWtiv", newValue) + } + } + + return ( + + ) + }, + size: 80, + }, + { + accessorKey: "offshoreTypeGom", + header: "GOM", + cell: ({ row, table }) => { + const value = row.getValue("offshoreTypeGom") as boolean + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "offshoreTypeGom", newValue) + } + } + + return ( + + ) + }, + size: 80, + }, + ] + }, + // eVCP 미등록 정보 그룹 + { + header: "eVCP 미등록 정보", + columns: [ + { + accessorKey: "picName", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("picName") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "picName", newValue) + } + } + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "picEmail", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("picEmail") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "picEmail", newValue) + } + } + + return ( + + ) + }, + size: 140, + }, + { + accessorKey: "picPhone", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("picPhone") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "picPhone", newValue) + } + } + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "agentName", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("agentName") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "agentName", newValue) + } + } + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "agentEmail", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("agentEmail") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "agentEmail", newValue) + } + } + + return ( + + ) + }, + size: 140, + }, + { + accessorKey: "agentPhone", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("agentPhone") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "agentPhone", newValue) + } + } + + return ( + + ) + }, + size: 120, + }, + ] + }, + // 업체 실적 현황 그룹 + { + header: "업체 실적 현황", + columns: [ + { + accessorKey: "recentQuoteDate", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("recentQuoteDate") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "recentQuoteDate", newValue) + } + } + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "recentQuoteNumber", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("recentQuoteNumber") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "recentQuoteNumber", newValue) + } + } + + return ( + + ) + }, + size: 130, + }, + { + accessorKey: "recentOrderDate", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("recentOrderDate") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "recentOrderDate", newValue) + } + } + + return ( + + ) + }, + size: 120, + }, + { + accessorKey: "recentOrderNumber", + header: ({ column }) => ( + + ), + cell: ({ row, table }) => { + const value = row.getValue("recentOrderNumber") + const onSave = async (newValue: any) => { + if (table.options.meta?.onCellUpdate) { + await table.options.meta.onCellUpdate(row.original.id, "recentOrderNumber", newValue) + } + } + + return ( + + ) + }, + size: 130, + }, + ] + }, + // 업데이트 히스토리 그룹 + { + header: "업데이트 히스토리", + columns: [ + { + accessorKey: "registrationDate", + header: ({ column }) => ( + + ), + size: 120, + }, + { + accessorKey: "registrant", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const value = row.getValue("registrant") as string + return
{value || ""}
+ }, + size: 100, + }, + { + accessorKey: "lastModifiedDate", + header: ({ column }) => ( + + ), + size: 120, + }, + { + accessorKey: "lastModifier", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const value = row.getValue("lastModifier") as string + return
{value || ""}
+ }, + size: 120, + }, + ] + }, + // 액션 그룹 + { + id: "actions", + header: "액션", + cell: ({ row, table }) => { + const data = row.original + const isEmptyRow = (table.options.meta as any)?.isEmptyRow?.(String(data.id)) + + if (isEmptyRow) { + // 빈 행의 경우 저장/취소 버튼 표시 + return ( +
+ + +
+ ) + } + + // 일반 행의 경우 기존 액션 버튼들 표시 + return ( +
+ +
+ ) + }, + size: 120, + enableSorting: false, + enableHiding: false, + }, +] -- cgit v1.2.3