From 14f61e24947fb92dd71ec0a7196a6e815f8e66da Mon Sep 17 00:00:00 2001 From: dujinkim Date: Mon, 21 Jul 2025 07:54:26 +0000 Subject: (최겸)기술영업 RFQ 담당자 초대, 요구사항 반영 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/techsales-rfq/table/rfq-table-column.tsx | 831 +++++++++++++-------------- 1 file changed, 412 insertions(+), 419 deletions(-) (limited to 'lib/techsales-rfq/table/rfq-table-column.tsx') diff --git a/lib/techsales-rfq/table/rfq-table-column.tsx b/lib/techsales-rfq/table/rfq-table-column.tsx index 89054d0e..f41857cd 100644 --- a/lib/techsales-rfq/table/rfq-table-column.tsx +++ b/lib/techsales-rfq/table/rfq-table-column.tsx @@ -1,420 +1,413 @@ -"use client" - -import * as React from "react" -import { ColumnDef } from "@tanstack/react-table" -import { formatDate, formatDateTime } from "@/lib/utils" -import { Checkbox } from "@/components/ui/checkbox" -import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" -import { DataTableRowAction } from "@/types/table" -import { Paperclip, Package, FileText, BarChart3 } from "lucide-react" -import { Button } from "@/components/ui/button" - -// 기본적인 RFQ 타입 정의 (rfq-table.tsx 파일과 일치해야 함) -type TechSalesRfq = { - id: number - rfqCode: string | null - description: string | null - dueDate: Date - rfqSendDate: Date | null - status: "RFQ Created" | "RFQ Vendor Assignned" | "RFQ Sent" | "Quotation Analysis" | "Closed" - picCode: string | null - remark: string | null - cancelReason: string | null - createdAt: Date - updatedAt: Date - createdBy: number | null - createdByName: string - updatedBy: number | null - updatedByName: string - sentBy: number | null - sentByName: string | null - pspid: string - projNm: string - sector: string - projMsrm: number - ptypeNm: string - attachmentCount: number - hasTbeAttachments: boolean - hasCbeAttachments: boolean - quotationCount: number - itemCount: number - // 나머지 필드는 사용할 때마다 추가 - [key: string]: unknown -} - -interface GetColumnsProps { - setRowAction: React.Dispatch | null>>; - openAttachmentsSheet: (rfqId: number, attachmentType?: 'RFQ_COMMON' | 'TBE_RESULT' | 'CBE_RESULT') => void; - openItemsDialog: (rfq: TechSalesRfq) => void; -} - -export function getColumns({ - setRowAction, - openAttachmentsSheet, - openItemsDialog, -}: GetColumnsProps): ColumnDef[] { - return [ - { - id: "select", - // Remove the "Select all" checkbox in header since we're doing single-select - header: () => Select, - cell: ({ row, table }) => ( - { - // If selecting this row - if (value) { - // First deselect all rows (to ensure single selection) - table.toggleAllRowsSelected(false) - // Then select just this row - row.toggleSelected(true) - // Trigger the same action that was in the "Select" button - setRowAction({ row, type: "select" as const }) - } else { - // Just deselect this row - row.toggleSelected(false) - } - }} - aria-label="Select row" - className="translate-y-0.5" - /> - ), - enableSorting: false, - enableHiding: false, - enableResizing: false, - size: 40, - minSize: 40, - maxSize: 40, - }, - - { - accessorKey: "status", - header: ({ column }) => ( - - ), - cell: ({ row }) =>
{row.getValue("status")}
, - meta: { - excelHeader: "진행상태" - }, - enableResizing: true, - minSize: 80, - size: 100, - }, - { - accessorKey: "rfqCode", - header: ({ column }) => ( - - ), - cell: ({ row }) =>
{row.getValue("rfqCode")}
, - meta: { - excelHeader: "RFQ No." - }, - enableResizing: true, - size: 120, - }, - { - accessorKey: "description", - header: ({ column }) => ( - - ), - cell: ({ row }) =>
{row.getValue("description")}
, - meta: { - excelHeader: "RFQ Title" - }, - enableResizing: true, - size: 200, - }, - { - accessorKey: "projNm", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - const projNm = row.getValue("projNm") as string; - return ( - - ); - }, - meta: { - excelHeader: "프로젝트명" - }, - enableResizing: true, - size: 160, - }, - // { - // accessorKey: "projMsrm", - // header: ({ column }) => ( - // - // ), - // cell: ({ row }) =>
{row.getValue("projMsrm")}
, - // meta: { - // excelHeader: "척수" - // }, - // enableResizing: true, - // minSize: 60, - // size: 80, - // }, - // { - // accessorKey: "ptypeNm", - // header: ({ column }) => ( - // - // ), - // cell: ({ row }) =>
{row.getValue("ptypeNm")}
, - // meta: { - // excelHeader: "선종" - // }, - // enableResizing: true, - // size: 120, - // }, - // { - // accessorKey: "quotationCount", - // header: ({ column }) => ( - // - // ), - // cell: ({ row }) =>
{row.getValue("quotationCount")}
, - // meta: { - // excelHeader: "견적수" - // }, - // enableResizing: true, - // size: 80, - // }, - { - accessorKey: "rfqSendDate", - header: ({ column }) => ( - - ), - cell: ({ cell }) => { - const value = cell.getValue(); - return value ? formatDate(value as Date, "KR") : ""; - }, - meta: { - excelHeader: "최초 전송일" - }, - enableResizing: true, - size: 120, - }, - { - accessorKey: "dueDate", - header: ({ column }) => ( - - ), - cell: ({ cell }) => { - const value = cell.getValue(); - return value ? formatDate(value as Date, "KR") : ""; - }, - meta: { - excelHeader: "RFQ 마감일" - }, - enableResizing: true, - minSize: 80, - size: 120, - }, - { - accessorKey: "createdByName", - header: ({ column }) => ( - - ), - cell: ({ row }) =>
{row.getValue("createdByName")}
, - meta: { - excelHeader: "요청자" - }, - enableResizing: true, - size: 120, - }, - { - accessorKey: "createdAt", - header: ({ column }) => ( - - ), - cell: ({ cell }) => { - const value = cell.getValue(); - return value ? formatDateTime(value as Date, "KR") : ""; - }, - meta: { - excelHeader: "등록일" - }, - enableResizing: true, - size: 160, - }, - { - accessorKey: "updatedAt", - header: ({ column }) => ( - - ), - cell: ({ cell }) => { - const value = cell.getValue(); - return value ? formatDateTime(value as Date, "KR") : ""; - }, - meta: { - excelHeader: "수정일" - }, - enableResizing: true, - size: 160, - }, - // 우측 고정 컬럼들 - { - id: "items", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - const rfq = row.original - const itemCount = rfq.itemCount || 0 - - const handleClick = () => { - openItemsDialog(rfq) - } - - return ( - - ) - }, - enableSorting: false, - enableResizing: false, - size: 80, - meta: { - excelHeader: "아이템" - }, - }, - { - id: "attachments", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - const rfq = row.original - const attachmentCount = rfq.attachmentCount || 0 - - const handleClick = () => { - openAttachmentsSheet(rfq.id, 'RFQ_COMMON') - } - - return ( - - ) - }, - enableSorting: false, - enableResizing: false, - size: 80, - meta: { - excelHeader: "첨부파일" - }, - }, - { - id: "tbe-attachments", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - const rfq = row.original - const hasTbeAttachments = rfq.hasTbeAttachments - - const handleClick = () => { - openAttachmentsSheet(rfq.id, 'TBE_RESULT') - } - - return ( - - ) - }, - enableSorting: false, - enableResizing: false, - size: 80, - meta: { - excelHeader: "TBE 결과" - }, - }, - { - id: "cbe-attachments", - header: ({ column }) => ( - - ), - cell: ({ row }) => { - const rfq = row.original - const hasCbeAttachments = rfq.hasCbeAttachments - - const handleClick = () => { - openAttachmentsSheet(rfq.id, 'CBE_RESULT') - } - - return ( - - ) - }, - enableSorting: false, - enableResizing: false, - size: 80, - meta: { - excelHeader: "CBE 결과" - }, - }, - ] +"use client" + +import * as React from "react" +import { ColumnDef } from "@tanstack/react-table" +import { formatDate, formatDateTime } from "@/lib/utils" +import { Checkbox } from "@/components/ui/checkbox" +import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header" +import { DataTableRowAction } from "@/types/table" +import { Paperclip, Package, FileText, BarChart3 } from "lucide-react" +import { Button } from "@/components/ui/button" +import { TechSalesRfq } from "./rfq-table" + +interface GetColumnsProps { + setRowAction: React.Dispatch | null>>; + openAttachmentsSheet: (rfqId: number, attachmentType?: 'RFQ_COMMON' | 'TBE_RESULT' | 'CBE_RESULT') => void; + openItemsDialog: (rfq: TechSalesRfq) => void; +} + +export function getColumns({ + setRowAction, + openAttachmentsSheet, + openItemsDialog, +}: GetColumnsProps): ColumnDef[] { + return [ + { + id: "select", + // Remove the "Select all" checkbox in header since we're doing single-select + header: () => Select, + cell: ({ row, table }) => ( + { + // If selecting this row + if (value) { + // First deselect all rows (to ensure single selection) + table.toggleAllRowsSelected(false) + // Then select just this row + row.toggleSelected(true) + // Trigger the same action that was in the "Select" button + setRowAction({ row, type: "select" as const }) + } else { + // Just deselect this row + row.toggleSelected(false) + } + }} + aria-label="Select row" + className="translate-y-0.5" + /> + ), + enableSorting: false, + enableHiding: false, + enableResizing: false, + size: 40, + minSize: 40, + maxSize: 40, + }, + + { + accessorKey: "status", + header: ({ column }) => ( + + ), + cell: ({ row }) =>
{row.getValue("status")}
, + meta: { + excelHeader: "진행상태" + }, + enableResizing: true, + minSize: 80, + size: 100, + }, + { + accessorKey: "rfqCode", + header: ({ column }) => ( + + ), + cell: ({ row }) =>
{row.getValue("rfqCode")}
, + meta: { + excelHeader: "RFQ No." + }, + enableResizing: true, + size: 120, + }, + { + accessorKey: "description", + header: ({ column }) => ( + + ), + cell: ({ row }) =>
{row.getValue("description")}
, + meta: { + excelHeader: "RFQ Title" + }, + enableResizing: true, + size: 200, + }, + { + accessorKey: "projNm", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const projNm = row.getValue("projNm") as string; + return ( + + ); + }, + meta: { + excelHeader: "프로젝트명" + }, + enableResizing: true, + size: 160, + }, + { + accessorKey: "workTypes", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const workTypes = row.getValue("workTypes") as string | null; + return ( +
+ {workTypes ? ( + + {workTypes} + + ) : ( + - + )} +
+ ); + }, + meta: { + excelHeader: "공종" + }, + enableResizing: true, + size: 120, + }, + // { + // accessorKey: "projMsrm", + // header: ({ column }) => ( + // + // ), + // cell: ({ row }) =>
{row.getValue("projMsrm")}
, + // meta: { + // excelHeader: "척수" + // }, + // enableResizing: true, + // minSize: 60, + // size: 80, + // }, + // { + // accessorKey: "ptypeNm", + // header: ({ column }) => ( + // + // ), + // cell: ({ row }) =>
{row.getValue("ptypeNm")}
, + // meta: { + // excelHeader: "선종" + // }, + // enableResizing: true, + // size: 120, + // }, + // { + // accessorKey: "quotationCount", + // header: ({ column }) => ( + // + // ), + // cell: ({ row }) =>
{row.getValue("quotationCount")}
, + // meta: { + // excelHeader: "견적수" + // }, + // enableResizing: true, + // size: 80, + // }, + { + accessorKey: "rfqSendDate", + header: ({ column }) => ( + + ), + cell: ({ cell }) => { + const value = cell.getValue(); + return value ? formatDate(value as Date, "KR") : ""; + }, + meta: { + excelHeader: "최초 전송일" + }, + enableResizing: true, + size: 120, + }, + { + accessorKey: "dueDate", + header: ({ column }) => ( + + ), + cell: ({ cell }) => { + const value = cell.getValue(); + return value ? formatDate(value as Date, "KR") : ""; + }, + meta: { + excelHeader: "RFQ 마감일" + }, + enableResizing: true, + minSize: 80, + size: 120, + }, + { + accessorKey: "createdByName", + header: ({ column }) => ( + + ), + cell: ({ row }) =>
{row.getValue("createdByName")}
, + meta: { + excelHeader: "요청자" + }, + enableResizing: true, + size: 120, + }, + { + accessorKey: "createdAt", + header: ({ column }) => ( + + ), + cell: ({ cell }) => { + const value = cell.getValue(); + return value ? formatDateTime(value as Date, "KR") : ""; + }, + meta: { + excelHeader: "등록일" + }, + enableResizing: true, + size: 160, + }, + { + accessorKey: "updatedAt", + header: ({ column }) => ( + + ), + cell: ({ cell }) => { + const value = cell.getValue(); + return value ? formatDateTime(value as Date, "KR") : ""; + }, + meta: { + excelHeader: "수정일" + }, + enableResizing: true, + size: 160, + }, + // 우측 고정 컬럼들 + { + id: "items", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const rfq = row.original + const itemCount = rfq.itemCount || 0 + + const handleClick = () => { + openItemsDialog(rfq) + } + + return ( + + ) + }, + enableSorting: false, + enableResizing: false, + size: 80, + meta: { + excelHeader: "아이템" + }, + }, + { + id: "attachments", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const rfq = row.original + const attachmentCount = rfq.attachmentCount || 0 + + const handleClick = () => { + openAttachmentsSheet(rfq.id, 'RFQ_COMMON') + } + + return ( + + ) + }, + enableSorting: false, + enableResizing: false, + size: 80, + meta: { + excelHeader: "첨부파일" + }, + }, + { + id: "tbe-attachments", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const rfq = row.original + const hasTbeAttachments = rfq.hasTbeAttachments + + const handleClick = () => { + openAttachmentsSheet(rfq.id, 'TBE_RESULT') + } + + return ( + + ) + }, + enableSorting: false, + enableResizing: false, + size: 80, + meta: { + excelHeader: "TBE 결과" + }, + }, + { + id: "cbe-attachments", + header: ({ column }) => ( + + ), + cell: ({ row }) => { + const rfq = row.original + const hasCbeAttachments = rfq.hasCbeAttachments + + const handleClick = () => { + openAttachmentsSheet(rfq.id, 'CBE_RESULT') + } + + return ( + + ) + }, + enableSorting: false, + enableResizing: false, + size: 80, + meta: { + excelHeader: "CBE 결과" + }, + }, + ] } \ No newline at end of file -- cgit v1.2.3