summaryrefslogtreecommitdiff
path: root/lib/esg-check-list/table/esg-evaluations-table-columns.tsx
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-06-19 09:44:28 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-06-19 09:44:28 +0000
commit95bbe9c583ff841220da1267630e7b2025fc36dc (patch)
tree5e3d5bb3302530bbaa7f7abbe8c9cf8193ccbd4c /lib/esg-check-list/table/esg-evaluations-table-columns.tsx
parent0eb030580b5cbe5f03d570c3c9d8c519bac3b783 (diff)
(대표님) 20250619 1844 KST 작업사항
Diffstat (limited to 'lib/esg-check-list/table/esg-evaluations-table-columns.tsx')
-rw-r--r--lib/esg-check-list/table/esg-evaluations-table-columns.tsx357
1 files changed, 357 insertions, 0 deletions
diff --git a/lib/esg-check-list/table/esg-evaluations-table-columns.tsx b/lib/esg-check-list/table/esg-evaluations-table-columns.tsx
new file mode 100644
index 00000000..399f9f4a
--- /dev/null
+++ b/lib/esg-check-list/table/esg-evaluations-table-columns.tsx
@@ -0,0 +1,357 @@
+"use client"
+
+import * as React from "react"
+import { type DataTableRowAction } from "@/types/table"
+import { type ColumnDef } from "@tanstack/react-table"
+import { Ellipsis, InfoIcon, PenToolIcon, TrashIcon } from "lucide-react"
+
+import { formatDate } from "@/lib/utils"
+import { Button } from "@/components/ui/button"
+import { Checkbox } from "@/components/ui/checkbox"
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger,
+} from "@/components/ui/tooltip"
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu"
+import { Badge } from "@/components/ui/badge"
+
+import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"
+import { EsgEvaluationsView } from "@/db/schema"
+
+interface GetColumnsProps {
+ setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<EsgEvaluationsView> | null>>
+}
+
+/**
+ * ESG 평가표 테이블 컬럼 정의
+ */
+export function getColumns({ setRowAction }: GetColumnsProps): ColumnDef<EsgEvaluationsView>[] {
+
+ // ----------------------------------------------------------------
+ // 1) select 컬럼 (체크박스)
+ // ----------------------------------------------------------------
+ const selectColumn: ColumnDef<EsgEvaluationsView> = {
+ id: "select",
+ header: ({ table }) => (
+ <Checkbox
+ checked={
+ table.getIsAllPageRowsSelected() ||
+ (table.getIsSomePageRowsSelected() && "indeterminate")
+ }
+ onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
+ aria-label="Select all"
+ className="translate-y-0.5"
+ />
+ ),
+ cell: ({ row }) => (
+ <Checkbox
+ checked={row.getIsSelected()}
+ onCheckedChange={(value) => row.toggleSelected(!!value)}
+ aria-label="Select row"
+ className="translate-y-0.5"
+ />
+ ),
+ enableSorting: false,
+ enableHiding: false,
+ size: 40,
+ }
+
+ // ----------------------------------------------------------------
+ // 2) 기본 정보 컬럼들
+ // ----------------------------------------------------------------
+ const basicColumns: ColumnDef<EsgEvaluationsView>[] = [
+ {
+ accessorKey: "serialNumber",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="시리얼번호" />
+ ),
+ cell: ({ row }) => (
+ <div className="font-medium">
+ {row.getValue("serialNumber")}
+ </div>
+ ),
+ enableSorting: true,
+ enableHiding: true,
+ },
+
+ {
+ accessorKey: "category",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="분류" />
+ ),
+ cell: ({ row }) => (
+ <Badge variant="secondary">
+ {row.getValue("category")}
+ </Badge>
+ ),
+ },
+ {
+ accessorKey: "inspectionItem",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="점검항목" />
+ ),
+ cell: ({ row }) => (
+ <div className="max-w-[300px] truncate" title={row.getValue("inspectionItem")}>
+ {row.getValue("inspectionItem")}
+ </div>
+ ),
+ },
+ ]
+
+ // ----------------------------------------------------------------
+ // 3) 통계 정보 컬럼들
+ // ----------------------------------------------------------------
+ const statsColumns: ColumnDef<EsgEvaluationsView>[] = [
+ {
+ id: "evaluationItems",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="평가항목" />
+ ),
+ cell: ({ row }) => {
+ const evaluation = row.original;
+ const count = evaluation.totalEvaluationItems || 0;
+
+ // evaluationItemsList가 있다면 사용, 없다면 개수만 표시
+ const items = (evaluation as any).evaluationItemsList || [];
+
+ if (items.length > 0) {
+ return (
+ <div className="max-w-[250px]">
+ <TooltipProvider>
+ <Tooltip>
+ <TooltipTrigger asChild>
+ <div className="cursor-help">
+ <div className="flex flex-wrap gap-1">
+ {items.slice(0, 3).map((item: string, index: number) => (
+ <Badge key={index} variant="outline" className="text-xs">
+ {item.length > 15 ? `${item.substring(0, 15)}...` : item}
+ </Badge>
+ ))}
+ {items.length > 3 && (
+ <Badge variant="secondary" className="text-xs">
+ +{items.length - 3}개 더
+ </Badge>
+ )}
+ </div>
+ </div>
+ </TooltipTrigger>
+ <TooltipContent className="max-w-[300px]">
+ <div className="space-y-1">
+ <p className="font-medium">평가항목 목록:</p>
+ {items.map((item: string, index: number) => (
+ <p key={index} className="text-sm">
+ {index + 1}. {item}
+ </p>
+ ))}
+ </div>
+ </TooltipContent>
+ </Tooltip>
+ </TooltipProvider>
+ </div>
+ );
+ }
+
+ // 평가항목이 없는 경우
+ return (
+ <div className="text-center text-muted-foreground">
+ <Badge variant="outline">
+ {count > 0 ? `${count}개 항목` : "항목 없음"}
+ </Badge>
+ </div>
+ );
+ },
+ enableSorting: false,
+ },
+ {
+ accessorKey: "totalAnswerOptions",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="답변옵션" />
+ ),
+ cell: ({ row }) => (
+ <div className="text-center">
+ <Badge variant="outline">
+ {row.getValue("totalAnswerOptions") || 0}개
+ </Badge>
+ </div>
+ ),
+ },
+ ]
+
+ // ----------------------------------------------------------------
+ // 4) 메타데이터 컬럼들
+ // ----------------------------------------------------------------
+ const metaColumns: ColumnDef<EsgEvaluationsView>[] = [
+ {
+ accessorKey: "isActive",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="상태" />
+ ),
+ cell: ({ row }) => (
+ <Badge variant={row.getValue("isActive") ? "default" : "secondary"}>
+ {row.getValue("isActive") ? "활성" : "비활성"}
+ </Badge>
+ ),
+ },
+ {
+ accessorKey: "createdAt",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="생성일" />
+ ),
+ cell: ({ row }) => {
+ const date = row.getValue("createdAt") as Date
+ return formatDate(date)
+ },
+ },
+ {
+ accessorKey: "updatedAt",
+ header: ({ column }) => (
+ <DataTableColumnHeaderSimple column={column} title="수정일" />
+ ),
+ cell: ({ row }) => {
+ const date = row.getValue("updatedAt") as Date
+ return formatDate(date)
+ },
+ },
+ ]
+
+ // ----------------------------------------------------------------
+ // 5) actions 컬럼 (드롭다운 메뉴)
+ // ----------------------------------------------------------------
+ const actionsColumn: ColumnDef<EsgEvaluationsView> = {
+ id: "actions",
+ header: "작업",
+ enableHiding: false,
+ cell: function Cell({ row }) {
+ return (
+ <DropdownMenu>
+ <DropdownMenuTrigger asChild>
+ <Button variant="ghost" size="icon">
+ <Ellipsis className="h-4 w-4" />
+ </Button>
+ </DropdownMenuTrigger>
+ <DropdownMenuContent align="end">
+ <DropdownMenuItem
+ onClick={() => setRowAction({ row, type: "view" })}
+ >
+ <InfoIcon className="mr-2 h-4 w-4" />
+ 상세보기
+ </DropdownMenuItem>
+ <DropdownMenuItem
+ onClick={() => setRowAction({ row, type: "update" })}
+ >
+ <PenToolIcon className="mr-2 h-4 w-4" />
+ 수정하기
+ </DropdownMenuItem>
+ <DropdownMenuItem
+ onClick={() => setRowAction({ row, type: "delete" })}
+ className="text-destructive"
+ >
+ <TrashIcon className="mr-2 h-4 w-4" />
+ 삭제하기
+ </DropdownMenuItem>
+ </DropdownMenuContent>
+ </DropdownMenu>
+ )
+ },
+ size: 80,
+ }
+
+ // ----------------------------------------------------------------
+ // 6) 최종 컬럼 배열 (그룹화 버전)
+ // ----------------------------------------------------------------
+ return [
+ selectColumn,
+ {
+ id: "basicInfo",
+ header: "기본 정보",
+ columns: basicColumns,
+ },
+ {
+ id: "statistics",
+ header: "통계",
+ columns: statsColumns,
+ },
+ {
+ id: "metadata",
+ header: "메타데이터",
+ columns: metaColumns,
+ },
+ actionsColumn,
+ ]
+}
+
+// ----------------------------------------------------------------
+// 7) 컬럼 설정 (필터링용)
+// ----------------------------------------------------------------
+export const esgEvaluationsColumnsConfig = [
+ {
+ id: "serialNumber",
+ label: "시리얼번호",
+ group: "기본 정보",
+ type: "text",
+ excelHeader: "Serial Number",
+ },
+ {
+ id: "category",
+ label: "분류",
+ group: "기본 정보",
+ type: "text",
+ excelHeader: "Category",
+ },
+ {
+ id: "inspectionItem",
+ label: "점검항목",
+ group: "기본 정보",
+ type: "text",
+ excelHeader: "Inspection Item",
+ },
+ {
+ id: "totalEvaluationItems",
+ label: "평가항목 수",
+ group: "통계",
+ type: "number",
+ excelHeader: "Total Evaluation Items",
+ },
+ {
+ id: "totalAnswerOptions",
+ label: "답변옵션 수",
+ group: "통계",
+ type: "number",
+ excelHeader: "Total Answer Options",
+ },
+ // {
+ // id: "maxPossibleScore",
+ // label: "최대점수",
+ // group: "통계",
+ // type: "number",
+ // excelHeader: "Max Possible Score",
+ // },
+ {
+ id: "isActive",
+ label: "상태",
+ group: "메타데이터",
+ type: "boolean",
+ excelHeader: "Is Active",
+ },
+ {
+ id: "createdAt",
+ label: "생성일",
+ group: "메타데이터",
+ type: "date",
+ excelHeader: "Created At",
+ },
+ {
+ id: "updatedAt",
+ label: "수정일",
+ group: "메타데이터",
+ type: "date",
+ excelHeader: "Updated At",
+ },
+] as const; \ No newline at end of file