diff options
Diffstat (limited to 'lib/docu-list-rule/document-class/table/document-class-options-detail-sheet.tsx')
| -rw-r--r-- | lib/docu-list-rule/document-class/table/document-class-options-detail-sheet.tsx | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/lib/docu-list-rule/document-class/table/document-class-options-detail-sheet.tsx b/lib/docu-list-rule/document-class/table/document-class-options-detail-sheet.tsx new file mode 100644 index 00000000..50e79d89 --- /dev/null +++ b/lib/docu-list-rule/document-class/table/document-class-options-detail-sheet.tsx @@ -0,0 +1,152 @@ +"use client" + +import * as React from "react" +import { useReactTable, getCoreRowModel, getSortedRowModel, getFilteredRowModel, getPaginationRowModel } from "@tanstack/react-table" +import { DataTableDetail } from "@/components/data-table/data-table-detail" +import { DataTableAdvancedToolbarDetail } from "@/components/data-table/data-table-advanced-toolbar-detail" +import type { DataTableAdvancedFilterField, DataTableRowAction } from "@/types/table" +import { + Sheet, + SheetContent, +} from "@/components/ui/sheet" +import { getDocumentClassSubOptions } from "@/lib/docu-list-rule/document-class/service" +import { getColumns } from "@/lib/docu-list-rule/document-class/table/document-class-options-table-columns" +import { DocumentClassOptionEditSheet } from "@/lib/docu-list-rule/document-class/table/document-class-option-edit-sheet" +import { DeleteDocumentClassOptionDialog } from "@/lib/docu-list-rule/document-class/table/delete-document-class-option-dialog" +import { DocumentClassOptionsTableToolbarActions } from "@/lib/docu-list-rule/document-class/table/document-class-options-table-toolbar" +import { documentClasses, documentClassOptions } from "@/db/schema/docu-list-rule" + +type DocumentClassOption = typeof documentClassOptions.$inferSelect + +interface DocumentClassOptionsDetailSheetProps { + open: boolean + onOpenChange: (open: boolean) => void + documentClass: typeof documentClasses.$inferSelect | null + onSuccess?: () => void + promises?: Promise<[{ data: DocumentClassOption[]; pageCount: number }]> +} + +export function DocumentClassOptionsDetailSheet({ + open, + onOpenChange, + documentClass, + promises, +}: DocumentClassOptionsDetailSheetProps) { + const [rowAction, setRowAction] = React.useState<DataTableRowAction<DocumentClassOption> | null>(null) + const [rawData, setRawData] = React.useState<{ data: DocumentClassOption[]; pageCount: number }>({ data: [], pageCount: 0 }) + + React.useEffect(() => { + if (promises) { + promises.then(([result]) => { + setRawData(result) + }) + } else if (open && documentClass) { + // fallback: 클라이언트에서 직접 fetch (CSR) + (async () => { + try { + const result = await getDocumentClassSubOptions(documentClass.id) + if (result.success && result.data) { + setRawData({ + data: result.data, + pageCount: 1 + }) + } + } catch (error) { + console.error("Error refreshing data:", error) + } + })() + } + }, [promises, open, documentClass]) + + const refreshData = React.useCallback(async () => { + if (!documentClass) return + + try { + const result = await getDocumentClassSubOptions(documentClass.id, { + page: 1, + perPage: 10, + }) + if (result.success && result.data) { + setRawData({ + data: result.data, + pageCount: 1 + }) + } + } catch (error) { + console.error("Error refreshing data:", error) + } + }, [documentClass]) + + const columns = React.useMemo(() => getColumns({ setRowAction }), [setRowAction]) + + // 고급 필터 필드 설정 + const advancedFilterFields: DataTableAdvancedFilterField<DocumentClassOption>[] = [ + { id: "optionCode", label: "코드", type: "text" }, + { id: "description", label: "설명", type: "text" }, + { id: "createdAt", label: "생성일", type: "date" }, + ] + + const table = useReactTable({ + data: rawData.data, + columns, + getCoreRowModel: getCoreRowModel(), + getSortedRowModel: getSortedRowModel(), + getFilteredRowModel: getFilteredRowModel(), + getPaginationRowModel: getPaginationRowModel(), + initialState: { + sorting: [{ id: "optionCode", desc: false }], + pagination: { + pageSize: 10, + }, + }, + getRowId: (originalRow) => String(originalRow.id), + }) + + if (!documentClass) return null + + return ( + <Sheet open={open} onOpenChange={onOpenChange}> + <SheetContent className="flex flex-col gap-6 sm:max-w-4xl"> + <div className="flex items-center justify-between"> + <div> + <h3 className="text-lg font-medium">{documentClass.value} 옵션 관리</h3> + <p className="text-sm text-muted-foreground"> + {documentClass.value}의 Document Class 옵션들을 관리합니다. + </p> + </div> + </div> + + <DocumentClassOptionsTableToolbarActions + table={table} + documentClassId={documentClass.id} + onSuccess={refreshData} + /> + + <DataTableDetail table={table}> + <DataTableAdvancedToolbarDetail + table={table} + filterFields={advancedFilterFields} + /> + </DataTableDetail> + + <DeleteDocumentClassOptionDialog + open={rowAction?.type === "delete"} + onOpenChange={() => setRowAction(null)} + options={rowAction?.row.original ? [rowAction?.row.original] : []} + showTrigger={false} + onSuccess={() => { + rowAction?.row.toggleSelected(false) + refreshData() + }} + /> + + <DocumentClassOptionEditSheet + open={rowAction?.type === "update"} + onOpenChange={() => setRowAction(null)} + data={rowAction?.row.original ?? null} + onSuccess={refreshData} + /> + </SheetContent> + </Sheet> + ) +}
\ No newline at end of file |
