summaryrefslogtreecommitdiff
path: root/lib/compliance/responses/compliance-responses-table.tsx
blob: e42927190f2cadca057a3996fa46e08465354479 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
"use client";

import * as React from "react";
import { useDataTable } from "@/hooks/use-data-table";
import { DataTable } from "@/components/data-table/data-table";
import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar";
import type {
  DataTableAdvancedFilterField,
  DataTableRowAction,
  DataTableFilterField,
} from "@/types/table"
import { getComplianceResponsesWithPagination } from "../services";
import { getResponseColumns } from "./compliance-responses-columns";
import { ComplianceResponsesToolbarActions } from "./compliance-responses-toolbar";

interface ComplianceResponsesTableProps {
  templateId: number;
  promises?: Promise<[{ data: any[]; pageCount: number }]>;
}

export function ComplianceResponsesTable({ templateId, promises }: ComplianceResponsesTableProps) {
  // 페이지네이션 모드 데이터
  const paginationData = promises ? React.use(promises) : null;
  const [{ data: initialData = [], pageCount = 0 }] = paginationData || [{ data: [], pageCount: 0 }];

  const [rowAction, setRowAction] = React.useState<DataTableRowAction<any> | null>(null);
  const [data, setData] = React.useState(initialData);
  const [currentSorting, setCurrentSorting] = React.useState<{ id: string; desc: boolean }[]>([]);

  // 초기 데이터가 변경되면 data 상태 업데이트
  React.useEffect(() => {
    setData(initialData);
  }, [initialData]);

  // 컬럼 설정 - 외부 파일에서 가져옴
  const columns = React.useMemo(
    () => getResponseColumns({ setRowAction }),
    [setRowAction]
  )

  // 기본 필터 필드 설정
  const filterFields: DataTableFilterField<any>[] = [
    {
      id: "status",
      label: "상태",
      options: [
        { label: "진행중", value: "IN_PROGRESS" },
        { label: "완료", value: "COMPLETED" },
        { label: "검토완료", value: "REVIEWED" },
      ],
    },
  ];

  // 고급 필터 필드 설정
  const advancedFilterFields: DataTableAdvancedFilterField<any>[] = [
    { id: "vendorId", label: "Vendor ID", type: "text" },
    { id: "vendorName", label: "업체명", type: "text" },
    { id: "contractName", label: "계약서명", type: "text" },
    {
      id: "status", label: "상태", type: "select", options: [
        { label: "진행중", value: "IN_PROGRESS" },
        { label: "완료", value: "COMPLETED" },
        { label: "검토완료", value: "REVIEWED" },
      ]
    },
    { id: "answersCount", label: "답변 수", type: "text" },
    { id: "createdAt", label: "생성일", type: "date" },
    { id: "completedAt", label: "완료일", type: "date" },
  ];

  const { table } = useDataTable({
      data,
      columns,
      pageCount,
      filterFields,
      enablePinning: true,
      enableAdvancedFilter: true,
      enableRowSelection: true,
      initialState: {
        sorting: [{ id: "createdAt", desc: true }],
        columnPinning: { right: ["actions"] },
      },
      getRowId: (originalRow) => String(originalRow.id),
      shallow: false,
      clearOnDefault: true,
    })

  // 정렬 상태 변경 감지
  React.useEffect(() => {
    const newSorting = table.getState().sorting;
    if (JSON.stringify(newSorting) !== JSON.stringify(currentSorting)) {
      setCurrentSorting(newSorting);
    }
  }, [table.getState().sorting, currentSorting]);

  // 정렬이 변경될 때 데이터 다시 로드 (응답 데이터는 클라이언트 사이드 정렬)
  React.useEffect(() => {
    if (currentSorting && currentSorting.length > 0) {
      const sortedData = [...initialData].sort((a, b) => {
        for (const sort of currentSorting) {
          const aValue = a[sort.id];
          const bValue = b[sort.id];
          
          if (aValue === bValue) continue;
          
          if (aValue === null || aValue === undefined) return 1;
          if (bValue === null || bValue === undefined) return -1;
          
          if (typeof aValue === 'string' && typeof bValue === 'string') {
            return sort.desc ? bValue.localeCompare(aValue) : aValue.localeCompare(bValue);
          }
          
          if (aValue instanceof Date && bValue instanceof Date) {
            return sort.desc ? bValue.getTime() - aValue.getTime() : aValue.getTime() - bValue.getTime();
          }
          
          return sort.desc ? (bValue > aValue ? 1 : -1) : (aValue > bValue ? 1 : -1);
        }
        return 0;
      });
      
      setData(sortedData);
    } else {
      setData(initialData);
    }
  }, [currentSorting, initialData]);

  return (
    <>
      <DataTable table={table}>
        <DataTableAdvancedToolbar
          table={table}
          filterFields={advancedFilterFields}
          shallow={false}
        >
          <ComplianceResponsesToolbarActions table={table} />
        </DataTableAdvancedToolbar>
      </DataTable>
    </>
  );
}