summaryrefslogtreecommitdiff
path: root/lib/po/table/po-table-columns.tsx
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-03-26 00:37:41 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-03-26 00:37:41 +0000
commite0dfb55c5457aec489fc084c4567e791b4c65eb1 (patch)
tree68543a65d88f5afb3a0202925804103daa91bc6f /lib/po/table/po-table-columns.tsx
3/25 까지의 대표님 작업사항
Diffstat (limited to 'lib/po/table/po-table-columns.tsx')
-rw-r--r--lib/po/table/po-table-columns.tsx155
1 files changed, 155 insertions, 0 deletions
diff --git a/lib/po/table/po-table-columns.tsx b/lib/po/table/po-table-columns.tsx
new file mode 100644
index 00000000..c2c01136
--- /dev/null
+++ b/lib/po/table/po-table-columns.tsx
@@ -0,0 +1,155 @@
+"use client"
+
+import * as React from "react"
+import { type DataTableRowAction } from "@/types/table"
+import { type ColumnDef } from "@tanstack/react-table"
+import { InfoIcon, PenIcon } from "lucide-react"
+
+import { formatDate } from "@/lib/utils"
+import { Button } from "@/components/ui/button"
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger,
+} from "@/components/ui/tooltip"
+
+import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"
+import { poColumnsConfig } from "@/config/poColumnsConfig"
+import { ContractDetail } from "@/db/schema/contract"
+
+interface GetColumnsProps {
+ setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<ContractDetail> | null>>
+}
+
+/**
+ * tanstack table column definitions with nested headers
+ */
+export function getColumns({ setRowAction }: GetColumnsProps): ColumnDef<ContractDetail>[] {
+ // ----------------------------------------------------------------
+ // 1) select column (checkbox) - if needed
+ // ----------------------------------------------------------------
+
+ // ----------------------------------------------------------------
+ // 2) actions column (buttons for item info and signature request)
+ // ----------------------------------------------------------------
+ const actionsColumn: ColumnDef<ContractDetail> = {
+ id: "actions",
+ enableHiding: false,
+ cell: function Cell({ row }) {
+ // Check if this contract already has a signature envelope
+ const hasSignature = row.original.hasSignature;
+
+ return (
+ <div className="flex items-center space-x-1">
+ {/* Item Info Button */}
+ <TooltipProvider>
+ <Tooltip>
+ <TooltipTrigger asChild>
+ <Button
+ variant="ghost"
+ size="icon"
+ onClick={() => setRowAction({ row, type: "items" })}
+ >
+ <InfoIcon className="h-4 w-4" aria-hidden="true" />
+ </Button>
+ </TooltipTrigger>
+ <TooltipContent>
+ View Item Info
+ </TooltipContent>
+ </Tooltip>
+ </TooltipProvider>
+
+ {/* Signature Request Button - only show if no signature exists */}
+ {!hasSignature && (
+ <TooltipProvider>
+ <Tooltip>
+ <TooltipTrigger asChild>
+ <Button
+ variant="ghost"
+ size="icon"
+ onClick={() => setRowAction({ row, type: "signature" })}
+ >
+ <PenIcon className="h-4 w-4" aria-hidden="true" />
+ </Button>
+ </TooltipTrigger>
+ <TooltipContent>
+ Request Electronic Signature
+ </TooltipContent>
+ </Tooltip>
+ </TooltipProvider>
+ )}
+ </div>
+ );
+ },
+ size: 80, // Increased width to accommodate both buttons
+ };
+
+ // ----------------------------------------------------------------
+ // 3) Regular columns grouped by group name
+ // ----------------------------------------------------------------
+ // 3-1) groupMap: { [groupName]: ColumnDef<ContractDetail>[] }
+ const groupMap: Record<string, ColumnDef<ContractDetail>[]> = {};
+
+ poColumnsConfig.forEach((cfg) => {
+ // Use "_noGroup" if no group is specified
+ const groupName = cfg.group || "_noGroup";
+
+ if (!groupMap[groupName]) {
+ groupMap[groupName] = [];
+ }
+
+ // Child column definition
+ const childCol: ColumnDef<ContractDetail> = {
+ accessorKey: cfg.id,
+ enableResizing: true,
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title={cfg.label} />
+ ),
+ meta: {
+ excelHeader: cfg.excelHeader,
+ group: cfg.group,
+ type: cfg.type,
+ },
+ cell: ({ row, cell }) => {
+ if (cfg.id === "createdAt" || cfg.id === "updatedAt") {
+ const dateVal = cell.getValue() as Date;
+ return formatDate(dateVal);
+ }
+
+ return row.getValue(cfg.id) ?? "";
+ },
+ };
+
+ groupMap[groupName].push(childCol);
+ });
+
+ // ----------------------------------------------------------------
+ // 3-2) Create actual parent columns (groups) from the groupMap
+ // ----------------------------------------------------------------
+ const nestedColumns: ColumnDef<ContractDetail>[] = [];
+
+ // Order can be fixed by pre-defining group order or sorting
+ // Here we just use Object.entries order
+ Object.entries(groupMap).forEach(([groupName, colDefs]) => {
+ if (groupName === "_noGroup") {
+ // No group → Add as top-level columns
+ nestedColumns.push(...colDefs);
+ } else {
+ // Parent column
+ nestedColumns.push({
+ id: groupName,
+ header: groupName, // "Basic Info", "Metadata", etc.
+ columns: colDefs,
+ });
+ }
+ });
+
+ // ----------------------------------------------------------------
+ // 4) Final column array: nestedColumns + actionsColumn
+ // ----------------------------------------------------------------
+ return [
+ ...nestedColumns,
+ actionsColumn,
+ ];
+} \ No newline at end of file