summaryrefslogtreecommitdiff
path: root/lib/procurement-rfqs/table/rfq-table.tsx
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-05-12 11:36:25 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-05-12 11:36:25 +0000
commita6b9cdaf9ea5ed548292632f821e36453f377a83 (patch)
tree1c07b92b4173bfe3a12eedba7188fba8dc6f94cb /lib/procurement-rfqs/table/rfq-table.tsx
parentdf91418cd28e98ce05845e476e51aa810202bf33 (diff)
(대표님) procurement-rfq 작업업
Diffstat (limited to 'lib/procurement-rfqs/table/rfq-table.tsx')
-rw-r--r--lib/procurement-rfqs/table/rfq-table.tsx209
1 files changed, 209 insertions, 0 deletions
diff --git a/lib/procurement-rfqs/table/rfq-table.tsx b/lib/procurement-rfqs/table/rfq-table.tsx
new file mode 100644
index 00000000..510f474d
--- /dev/null
+++ b/lib/procurement-rfqs/table/rfq-table.tsx
@@ -0,0 +1,209 @@
+"use client"
+
+import * as React from "react"
+import type {
+ DataTableAdvancedFilterField,
+ DataTableFilterField,
+ DataTableRowAction,
+} from "@/types/table"
+import { useDataTable } from "@/hooks/use-data-table"
+import { DataTable } from "@/components/data-table/data-table"
+import { getColumns, EditingCellState } from "./rfq-table-column"
+import { useEffect } from "react"
+import { DataTableAdvancedToolbar } from "@/components/data-table/data-table-advanced-toolbar"
+import { RFQTableToolbarActions } from "./rfq-table-toolbar-actions"
+import { ProcurementRfqsView } from "@/db/schema"
+import { getPORfqs } from "../services"
+import { toast } from "sonner"
+import { updateRfqRemark } from "@/lib/procurement-rfqs/services" // 구현 필요
+
+interface RFQListTableProps {
+ data?: Awaited<ReturnType<typeof getPORfqs>>;
+ onSelectRFQ?: (rfq: ProcurementRfqsView | null) => void;
+ // 데이터 새로고침을 위한 콜백 추가
+ onDataRefresh?: () => void;
+ maxHeight?: string | number; // Add this prop
+}
+
+// 보다 유연한 타입 정의
+type LocalDataType = Awaited<ReturnType<typeof getPORfqs>>;
+
+export function RFQListTable({
+ data,
+ onSelectRFQ,
+ onDataRefresh,
+ maxHeight
+}: RFQListTableProps) {
+ const [rowAction, setRowAction] = React.useState<DataTableRowAction<ProcurementRfqsView> | null>(null)
+ // 인라인 에디팅을 위한 상태 추가
+ const [editingCell, setEditingCell] = React.useState<EditingCellState | null>(null)
+ // 로컬 데이터를 관리하기 위한 상태 추가
+ const [localData, setLocalData] = React.useState<LocalDataType>(data || { data: [], pageCount: 0, total: 0 });
+
+ // 데이터가 변경될 때 로컬 데이터도 업데이트
+ useEffect(() => {
+ setLocalData(data || { data: [], pageCount: 0, total: 0 })
+ }, [data])
+
+
+ // 비고 업데이트 함수
+ const updateRemark = async (rfqId: number, remark: string) => {
+ try {
+ // 낙관적 UI 업데이트 (로컬 데이터 먼저 갱신)
+ if (localData && localData.data) {
+ // 로컬 데이터에서 해당 행 찾기
+ const rowIndex = localData.data.findIndex(row => row.id === rfqId);
+ if (rowIndex >= 0) {
+ // 불변성을 유지하면서 로컬 데이터 업데이트
+ const newData = [...localData.data];
+ newData[rowIndex] = { ...newData[rowIndex], remark };
+
+ // 전체 데이터 구조 복사하여 업데이트
+ setLocalData({ ...localData, data: newData } as typeof localData);
+ }
+ }
+
+ const result = await updateRfqRemark(rfqId, remark);
+
+ if (result.success) {
+ toast.success("비고가 업데이트되었습니다");
+
+ // 서버 데이터 리프레시 호출
+ if (onDataRefresh) {
+ onDataRefresh();
+ }
+ } else {
+ toast.error(result.message || "업데이트 중 오류가 발생했습니다");
+ }
+ } catch (error) {
+ console.error("비고 업데이트 오류:", error);
+ toast.error("업데이트 중 오류가 발생했습니다");
+ }
+ }
+
+ // 행 액션 처리
+ useEffect(() => {
+ if (rowAction) {
+ // 액션 유형에 따라 처리
+ switch (rowAction.type) {
+ case "select":
+ // 선택된 문서 처리
+ if (onSelectRFQ) {
+ onSelectRFQ(rowAction.row.original)
+ }
+ break;
+ case "update":
+ // 업데이트 처리 로직
+ console.log("Update rfq:", rowAction.row.original)
+ break;
+ case "delete":
+ // 삭제 처리 로직
+ console.log("Delete rfq:", rowAction.row.original)
+ break;
+ }
+
+ // 액션 처리 후 rowAction 초기화
+ setRowAction(null)
+ }
+ }, [rowAction, onSelectRFQ])
+
+ const columns = React.useMemo(
+ () => getColumns({
+ setRowAction,
+ editingCell,
+ setEditingCell,
+ updateRemark
+ }),
+ [setRowAction, editingCell, setEditingCell, updateRemark]
+ )
+
+
+ // Filter fields
+ const filterFields: DataTableFilterField<ProcurementRfqsView>[] = []
+
+ const advancedFilterFields: DataTableAdvancedFilterField<ProcurementRfqsView>[] = [
+ {
+ id: "rfqCode",
+ label: "RFQ No.",
+ type: "text",
+ },
+ {
+ id: "projectCode",
+ label: "프로젝트",
+ type: "text",
+ },
+ {
+ id: "itemCode",
+ label: "자재그룹",
+ type: "text",
+ },
+ {
+ id: "itemName",
+ label: "자재명",
+ type: "text",
+ },
+
+ {
+ id: "rfqSealedYn",
+ label: "RFQ 밀봉여부",
+ type: "text",
+ },
+ {
+ id: "majorItemMaterialCode",
+ label: "자재코드",
+ type: "text",
+ },
+ {
+ id: "rfqSendDate",
+ label: "RFQ 전송일",
+ type: "date",
+ },
+ {
+ id: "dueDate",
+ label: "RFQ 마감일",
+ type: "date",
+ },
+ {
+ id: "createdByUserName",
+ label: "요청자",
+ type: "text",
+ },
+ ]
+
+ // useDataTable 훅으로 react-table 구성 - 로컬 데이터 사용하도록 수정
+ const { table } = useDataTable({
+ data: localData?.data || [],
+ columns,
+ pageCount: localData?.pageCount || 0,
+ rowCount: localData?.total || 0, // 총 레코드 수 추가
+ filterFields,
+ enablePinning: true,
+ enableAdvancedFilter: true,
+ initialState: {
+ sorting: [{ id: "updatedAt", desc: true }],
+ },
+ getRowId: (originalRow) => String(originalRow.id),
+ shallow: false,
+ clearOnDefault: true,
+ columnResizeMode: "onEnd",
+ })
+
+ return (
+ <div className="w-full overflow-auto">
+ <DataTable table={table} maxHeight={maxHeight}>
+ <DataTableAdvancedToolbar
+ table={table}
+ filterFields={advancedFilterFields}
+ shallow={false}
+ >
+ <RFQTableToolbarActions
+ table={table}
+ localData={localData}
+ setLocalData={setLocalData}
+ onSuccess={onDataRefresh}
+ />
+ </DataTableAdvancedToolbar>
+ </DataTable>
+ </div>
+ )
+} \ No newline at end of file