diff options
Diffstat (limited to 'lib/techsales-rfq/table/rfq-table-column.tsx')
| -rw-r--r-- | lib/techsales-rfq/table/rfq-table-column.tsx | 178 |
1 files changed, 59 insertions, 119 deletions
diff --git a/lib/techsales-rfq/table/rfq-table-column.tsx b/lib/techsales-rfq/table/rfq-table-column.tsx index caaa1c97..125e800b 100644 --- a/lib/techsales-rfq/table/rfq-table-column.tsx +++ b/lib/techsales-rfq/table/rfq-table-column.tsx @@ -6,10 +6,8 @@ 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 { Check, Pencil, X, Info } from "lucide-react" +import { Info, Paperclip } from "lucide-react" import { Button } from "@/components/ui/button" -import { toast } from "sonner" -import { Input } from "@/components/ui/input" // 기본적인 RFQ 타입 정의 (rfq-table.tsx 파일과 일치해야 함) type TechSalesRfq = { @@ -32,8 +30,8 @@ type TechSalesRfq = { updatedByName: string sentBy: number | null sentByName: string | null - projectSnapshot: any - seriesSnapshot: any + projectSnapshot: Record<string, unknown> + seriesSnapshot: Record<string, unknown> pspid: string projNm: string sector: string @@ -42,28 +40,22 @@ type TechSalesRfq = { attachmentCount: number quotationCount: number // 나머지 필드는 사용할 때마다 추가 - [key: string]: any + [key: string]: unknown } +// 프로젝트 상세정보 타입 추가를 위한 확장 +// interface ExtendedDataTableRowAction<TData> extends DataTableRowAction<TData> { +// type: DataTableRowAction<TData>["type"] | "project-detail" +// } + interface GetColumnsProps { setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<TechSalesRfq> | null>>; - // 상태와 상태 설정 함수를 props로 받음 - editingCell: EditingCellState | null; - setEditingCell: (state: EditingCellState | null) => void; - updateRemark: (rfqId: number, remark: string) => Promise<void>; -} - -export interface EditingCellState { - rowId: string | number; - value: string; + openAttachmentsSheet: (rfqId: number) => void; } - export function getColumns({ setRowAction, - editingCell, - setEditingCell, - updateRemark, + openAttachmentsSheet, }: GetColumnsProps): ColumnDef<TechSalesRfq>[] { return [ { @@ -81,7 +73,7 @@ export function getColumns({ // Then select just this row row.toggleSelected(true) // Trigger the same action that was in the "Select" button - setRowAction({ row, type: "select" }) + setRowAction({ row, type: "select" as const }) } else { // Just deselect this row row.toggleSelected(false) @@ -142,7 +134,10 @@ export function getColumns({ header: ({ column }) => ( <DataTableColumnHeaderSimple column={column} title="자재명" /> ), - cell: ({ row }) => <div>{row.getValue("itemName")}</div>, + cell: ({ row }) => { + const itemName = row.getValue("itemName"); + return <div>{itemName || "자재명 없음"}</div>; + }, meta: { excelHeader: "자재명" }, @@ -211,6 +206,48 @@ export function getColumns({ size: 80, }, { + id: "attachments", + header: ({ column }) => ( + <DataTableColumnHeaderSimple column={column} title="첨부파일" /> + ), + cell: ({ row }) => { + const rfq = row.original + const attachmentCount = rfq.attachmentCount || 0 + + const handleClick = () => { + openAttachmentsSheet(rfq.id) + } + + return ( + <Button + variant="ghost" + size="sm" + className="relative h-8 w-8 p-0 group" + onClick={handleClick} + aria-label={ + attachmentCount > 0 ? `View ${attachmentCount} attachments` : "Add attachments" + } + > + <Paperclip className="h-4 w-4 text-muted-foreground group-hover:text-primary transition-colors" /> + {attachmentCount > 0 && ( + <span className="pointer-events-none absolute -top-1 -right-1 inline-flex h-4 min-w-[1rem] items-center justify-center rounded-full bg-primary px-1 text-[0.625rem] font-medium leading-none text-primary-foreground"> + {attachmentCount} + </span> + )} + <span className="sr-only"> + {attachmentCount > 0 ? `${attachmentCount} 첨부파일` : "첨부파일 추가"} + </span> + </Button> + ) + }, + enableSorting: false, + enableResizing: true, + size: 80, + meta: { + excelHeader: "첨부파일" + }, + }, + { accessorKey: "rfqSendDate", header: ({ column }) => ( <DataTableColumnHeaderSimple column={column} title="RFQ 전송일" /> @@ -283,103 +320,6 @@ export function getColumns({ enableResizing: true, size: 160, }, - // { - // accessorKey: "remark", - // header: ({ column }) => ( - // <DataTableColumnHeaderSimple column={column} title="비고" /> - // ), - // cell: ({ row }) => { - // const id = row.original.id; - // const value = row.getValue("remark") as string; - - // const isEditing = - // editingCell?.rowId === row.id && - // editingCell.value !== undefined; - - // const startEditing = () => { - // setEditingCell({ - // rowId: row.id, - // value: value || "" - // }); - // }; - - // const cancelEditing = () => { - // setEditingCell(null); - // }; - - // const saveChanges = async () => { - // if (!editingCell) return; - - // try { - // await updateRemark(id, editingCell.value); - // setEditingCell(null); - // } catch (error) { - // toast.error("비고 업데이트 중 오류가 발생했습니다."); - // console.error("Error updating remark:", error); - // } - // }; - - // const handleKeyDown = (e: React.KeyboardEvent) => { - // if (e.key === "Enter") { - // saveChanges(); - // } else if (e.key === "Escape") { - // cancelEditing(); - // } - // }; - - // if (isEditing) { - // return ( - // <div className="flex items-center gap-1"> - // <Input - // value={editingCell?.value || ""} - // onChange={(e) => setEditingCell({ - // rowId: row.id, - // value: e.target.value - // })} - // onKeyDown={handleKeyDown} - // autoFocus - // className="h-8 w-full" - // /> - // <Button - // variant="ghost" - // size="icon" - // onClick={saveChanges} - // className="h-8 w-8" - // > - // <Check className="h-4 w-4" /> - // </Button> - // <Button - // variant="ghost" - // size="icon" - // onClick={cancelEditing} - // className="h-8 w-8" - // > - // <X className="h-4 w-4" /> - // </Button> - // </div> - // ); - // } - - // return ( - // <div className="flex items-center gap-1 group"> - // <span className="truncate">{value || ""}</span> - // <Button - // variant="ghost" - // size="icon" - // onClick={startEditing} - // className="h-6 w-6 opacity-0 group-hover:opacity-100 transition-opacity" - // > - // <Pencil className="h-3 w-3" /> - // </Button> - // </div> - // ); - // }, - // meta: { - // excelHeader: "비고" - // }, - // enableResizing: true, - // size: 200, - // }, { id: "actions", header: ({ column }) => ( @@ -390,7 +330,7 @@ export function getColumns({ <Button variant="ghost" size="sm" - onClick={() => setRowAction({ row, type: "project-detail" })} + onClick={() => setRowAction({ row, type: "view" as const })} className="h-8 px-2 gap-1" > <Info className="h-4 w-4" /> |
