summaryrefslogtreecommitdiff
path: root/lib/docu-list-rule/document-class/table/document-class-options-table.tsx
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-07-28 09:19:42 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-07-28 09:19:42 +0000
commit50ae0b8f02c034e60d4cbb504620dfa1575a836f (patch)
tree24c661a0c7354e15ad56e2bded4d300bd7fd2b41 /lib/docu-list-rule/document-class/table/document-class-options-table.tsx
parent738f956aa61264ffa761e30398eca23393929f8c (diff)
(박서영) 설계 document Numbering Rule 개발-최겸 업로드
Diffstat (limited to 'lib/docu-list-rule/document-class/table/document-class-options-table.tsx')
-rw-r--r--lib/docu-list-rule/document-class/table/document-class-options-table.tsx176
1 files changed, 176 insertions, 0 deletions
diff --git a/lib/docu-list-rule/document-class/table/document-class-options-table.tsx b/lib/docu-list-rule/document-class/table/document-class-options-table.tsx
new file mode 100644
index 00000000..644e3599
--- /dev/null
+++ b/lib/docu-list-rule/document-class/table/document-class-options-table.tsx
@@ -0,0 +1,176 @@
+"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 } from "@/types/table"
+
+import { getDocumentClassSubOptions } from "@/lib/docu-list-rule/document-class/service"
+import { getColumns } from "./document-class-options-table-columns"
+import { DocumentClassOptionEditSheet } from "./document-class-option-edit-sheet"
+import { DeleteDocumentClassOptionDialog } from "./delete-document-class-option-dialog"
+import { DocumentClassOptionsTableToolbarActions } from "./document-class-options-table-toolbar"
+import { documentClasses, documentClassOptions } from "@/db/schema/docu-list-rule"
+
+type DocumentClass = typeof documentClasses.$inferSelect
+
+interface DocumentClassOptionsTableProps {
+ selectedDocumentClass: DocumentClass | null
+ documentClasses: DocumentClass[]
+ onSelectDocumentClass: (documentClass: DocumentClass) => void
+}
+
+export function DocumentClassOptionsTable({
+ selectedDocumentClass,
+ documentClasses,
+ onSelectDocumentClass
+}: DocumentClassOptionsTableProps) {
+ const [rowAction, setRowAction] = React.useState<DataTableRowAction<typeof documentClassOptions.$inferSelect> | null>(null)
+
+ // 선택된 Document Class의 옵션 데이터 로드
+ const [options, setOptions] = React.useState<typeof documentClassOptions.$inferSelect[]>([])
+
+ // DB 등록 순서대로 정렬된 Document Classes
+ const sortedDocumentClasses = React.useMemo(() => {
+ return [...documentClasses].sort((a, b) => a.id - b.id)
+ }, [documentClasses])
+
+ const handleSuccess = React.useCallback(async () => {
+ // 옵션 테이블 새로고침
+ if (selectedDocumentClass) {
+ try {
+ const result = await getDocumentClassSubOptions(selectedDocumentClass.id)
+ if (result.success && result.data) {
+ setOptions(result.data)
+ }
+ } catch (error) {
+ console.error("Error refreshing options:", error)
+ }
+ }
+ }, [selectedDocumentClass])
+
+ const columns = React.useMemo(() => getColumns({ setRowAction }), [setRowAction])
+
+ // 고급 필터 필드 설정
+ const advancedFilterFields: DataTableAdvancedFilterField<typeof documentClassOptions.$inferSelect>[] = [
+ { id: "optionCode", label: "코드", type: "text" },
+ { id: "optionValue", label: "옵션 값", type: "text" },
+ { id: "createdAt", label: "생성일", type: "date" },
+ ]
+
+ const { table } = useDataTable({
+ data: options,
+ columns,
+ pageCount: 1,
+ enablePinning: true,
+ enableAdvancedFilter: true,
+ manualSorting: false,
+ initialState: {
+ sorting: [{ id: "id", desc: false }],
+ columnPinning: { right: ["actions"] },
+ },
+ getRowId: (originalRow) => String(originalRow.id),
+ shallow: false,
+ clearOnDefault: true,
+ })
+
+ React.useEffect(() => {
+ const loadOptions = async () => {
+ if (!selectedDocumentClass) {
+ setOptions([])
+ return
+ }
+
+ try {
+ const result = await getDocumentClassSubOptions(selectedDocumentClass.id)
+ if (result.success && result.data) {
+ setOptions(result.data)
+ }
+ } catch (error) {
+ console.error("Error loading options:", error)
+ setOptions([])
+ }
+ }
+
+ loadOptions()
+ }, [selectedDocumentClass])
+
+ if (!selectedDocumentClass) {
+ return (
+ <div className="space-y-4">
+ <div className="flex gap-2">
+ {sortedDocumentClasses.map((documentClass) => (
+ <button
+ key={documentClass.id}
+ onClick={() => onSelectDocumentClass(documentClass)}
+ className={`px-4 py-2 text-sm font-medium rounded-md transition-colors ${
+ selectedDocumentClass?.id === documentClass.id
+ ? "bg-primary text-primary-foreground"
+ : "bg-muted text-muted-foreground hover:bg-muted/80"
+ }`}
+ >
+ {documentClass.value}
+ </button>
+ ))}
+ </div>
+ <div className="text-center text-muted-foreground py-4">
+ Document Class를 선택하면 옵션을 관리할 수 있습니다.
+ </div>
+ </div>
+ )
+ }
+
+ return (
+ <>
+ <div className="space-y-2">
+ <div className="flex gap-2">
+ {sortedDocumentClasses.map((documentClass) => (
+ <button
+ key={documentClass.id}
+ onClick={() => onSelectDocumentClass(documentClass)}
+ className={`px-4 py-2 text-sm font-medium rounded-md transition-colors ${
+ selectedDocumentClass?.id === documentClass.id
+ ? "bg-primary text-primary-foreground"
+ : "bg-muted text-muted-foreground hover:bg-muted/80"
+ }`}
+ >
+ {documentClass.value}
+ </button>
+ ))}
+ </div>
+
+ <DataTable table={table}>
+ <DataTableAdvancedToolbar
+ table={table}
+ filterFields={advancedFilterFields}
+ >
+ <DocumentClassOptionsTableToolbarActions
+ table={table}
+ selectedDocumentClass={selectedDocumentClass}
+ onSuccess={handleSuccess}
+ />
+ </DataTableAdvancedToolbar>
+ </DataTable>
+ </div>
+
+ <DeleteDocumentClassOptionDialog
+ open={rowAction?.type === "delete"}
+ onOpenChange={() => setRowAction(null)}
+ options={rowAction?.row.original ? [rowAction?.row.original] : []}
+ showTrigger={false}
+ onSuccess={() => {
+ rowAction?.row.toggleSelected(false)
+ handleSuccess()
+ }}
+ />
+
+ <DocumentClassOptionEditSheet
+ open={rowAction?.type === "update"}
+ onOpenChange={() => setRowAction(null)}
+ data={rowAction?.row.original ?? null}
+ onSuccess={handleSuccess}
+ />
+ </>
+ )
+} \ No newline at end of file