diff options
| author | 0-Zz-ang <s1998319@gmail.com> | 2025-08-22 13:47:37 +0900 |
|---|---|---|
| committer | 0-Zz-ang <s1998319@gmail.com> | 2025-08-22 13:47:37 +0900 |
| commit | fefca6304eefea94f41057f9f934b0e19ceb54bb (patch) | |
| tree | f4914faa83e242a68d27feac58ebf0c527302cd2 /lib/compliance/table/compliance-survey-templates-table.tsx | |
| parent | dbdae213e39b82ff8ee565df0774bd2f72f06140 (diff) | |
(박서영)Compliance 설문/응답 리스트 생성
Diffstat (limited to 'lib/compliance/table/compliance-survey-templates-table.tsx')
| -rw-r--r-- | lib/compliance/table/compliance-survey-templates-table.tsx | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/lib/compliance/table/compliance-survey-templates-table.tsx b/lib/compliance/table/compliance-survey-templates-table.tsx new file mode 100644 index 00000000..c2e441ec --- /dev/null +++ b/lib/compliance/table/compliance-survey-templates-table.tsx @@ -0,0 +1,156 @@ +"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 { getColumns } from "./compliance-survey-templates-columns"; +import { ComplianceTemplateEditSheet } from "./compliance-template-edit-sheet"; +import { DeleteComplianceTemplatesDialog } from "./delete-compliance-templates-dialog"; +import { ComplianceSurveyTemplatesToolbarActions } from "./compliance-survey-templates-toolbar"; +import { complianceSurveyTemplates } from "@/db/schema/compliance"; +import { getComplianceSurveyTemplatesWithSorting } from "../services"; + +interface ComplianceSurveyTemplatesTableProps { + promises?: Promise<[{ data: typeof complianceSurveyTemplates.$inferSelect[]; pageCount: number }] >; +} + +export function ComplianceSurveyTemplatesTable({ promises }: ComplianceSurveyTemplatesTableProps) { + // 페이지네이션 모드 데이터 + const paginationData = promises ? React.use(promises) : null; + const initialData = paginationData ? paginationData[0].data : []; + const pageCount = paginationData ? paginationData[0].pageCount : 0; + + + const [rowAction, setRowAction] = React.useState<DataTableRowAction<typeof complianceSurveyTemplates.$inferSelect> | 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( + () => getColumns({ setRowAction }), + [setRowAction] + ) + + // 기본 필터 필드 설정 + const filterFields: DataTableFilterField<typeof complianceSurveyTemplates.$inferSelect>[] = [ + { + id: "isActive", + label: "상태", + options: [ + { label: "활성", value: "true" }, + { label: "비활성", value: "false" }, + ], + }, + ]; + + // 고급 필터 필드 설정 + const advancedFilterFields: DataTableAdvancedFilterField<typeof complianceSurveyTemplates.$inferSelect>[] = [ + { id: "name", label: "템플릿명", type: "text" }, + { + id: "isActive", label: "상태", type: "select", options: [ + { label: "활성", value: "true" }, + { label: "비활성", value: "false" }, + ] + }, + { id: "version", label: "버전", type: "text" }, + { id: "createdAt", 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(() => { + const loadData = async () => { + try { + console.log("🔄 정렬 변경으로 데이터 다시 로드:", currentSorting); + + // 정렬 상태가 있으면 정렬된 데이터 가져오기 + if (currentSorting && currentSorting.length > 0) { + const result = await getComplianceSurveyTemplatesWithSorting(currentSorting); + setData(result.data); + } else { + // 기본 정렬로 데이터 가져오기 + const result = await getComplianceSurveyTemplatesWithSorting(); + setData(result.data); + } + } catch (error) { + console.error("데이터 로드 오류:", error); + } + }; + + if (currentSorting.length > 0) { + loadData(); + } + }, [currentSorting]); + + return ( + <> + <DataTable table={table}> + <DataTableAdvancedToolbar + table={table} + filterFields={advancedFilterFields} + shallow={false} + > + <ComplianceSurveyTemplatesToolbarActions table={table} /> + </DataTableAdvancedToolbar> + </DataTable> + + {/* Edit Sheet */} + {rowAction?.type === 'update' && rowAction.row && ( + <ComplianceTemplateEditSheet + template={rowAction.row.original} + open={true} + onOpenChange={(open) => { + if (!open) setRowAction(null); + }} + /> + )} + + {/* Delete Dialog */} + {rowAction?.type === 'delete' && rowAction.row && ( + <DeleteComplianceTemplatesDialog + templates={[rowAction.row.original]} + showTrigger={false} + open={true} + onOpenChange={(open) => { + if (!open) setRowAction(null); + }} + /> + )} + </> + ); +} |
