diff options
Diffstat (limited to 'lib/rfqs/table/rfqs-table.tsx')
| -rw-r--r-- | lib/rfqs/table/rfqs-table.tsx | 263 |
1 files changed, 0 insertions, 263 deletions
diff --git a/lib/rfqs/table/rfqs-table.tsx b/lib/rfqs/table/rfqs-table.tsx deleted file mode 100644 index 287f1d53..00000000 --- a/lib/rfqs/table/rfqs-table.tsx +++ /dev/null @@ -1,263 +0,0 @@ -"use client" - -import * as React from "react" -import type { - DataTableAdvancedFilterField, - DataTableFilterField, - DataTableRowAction, -} from "@/types/table" - -import { toSentenceCase } from "@/lib/utils" -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 { getRFQStatusIcon } from "@/lib/tasks/utils" -import { useFeatureFlags } from "./feature-flags-provider" -import { getColumns } from "./rfqs-table-columns" -import { fetchRfqAttachments, fetchRfqItems, getRfqs, getRfqStatusCounts } from "../service" -import { RfqItem, RfqWithItemCount, rfqs } from "@/db/schema/rfq" -import { RfqsTableFloatingBar } from "./rfqs-table-floating-bar" -import { UpdateRfqSheet } from "./update-rfq-sheet" -import { DeleteRfqsDialog } from "./delete-rfqs-dialog" -import { RfqsTableToolbarActions } from "./rfqs-table-toolbar-actions" -import { RfqsItemsDialog } from "./ItemsDialog" -import { getAllItems } from "@/lib/items/service" -import { RfqAttachmentsSheet } from "./attachment-rfq-sheet" -import { useRouter } from "next/navigation" -import { RfqType } from "../validations" - -interface RfqsTableProps { - promises: Promise< - [ - Awaited<ReturnType<typeof getRfqs>>, - Awaited<ReturnType<typeof getRfqStatusCounts>>, - Awaited<ReturnType<typeof getAllItems>>, - ] - >; - rfqType?: RfqType; // rfqType props 추가 -} - -export interface ExistingAttachment { - id: number; - fileName: string; - filePath: string; - createdAt?: Date; - vendorId?: number | null; - size?: number; -} - -export interface ExistingItem { - id?: number; - itemCode: string; - description: string | null; - quantity: number | null; - uom: string | null; -} - -export function RfqsTable({ promises, rfqType = RfqType.PURCHASE }: RfqsTableProps) { - const { featureFlags } = useFeatureFlags() - - const [{ data, pageCount }, statusCounts, items] = React.use(promises) - const [attachmentsOpen, setAttachmentsOpen] = React.useState(false) - const [selectedRfqIdForAttachments, setSelectedRfqIdForAttachments] = React.useState<number | null>(null) - const [attachDefault, setAttachDefault] = React.useState<ExistingAttachment[]>([]) - const [itemsDefault, setItemsDefault] = React.useState<ExistingItem[]>([]) - - const router = useRouter() - - const itemsList = items?.map((v) => ({ - code: v.itemCode ?? "", - name: v.itemName ?? "", - })); - - const [rowAction, setRowAction] = - React.useState<DataTableRowAction<RfqWithItemCount> | null>(null) - - const [rowData, setRowData] = React.useState<RfqWithItemCount[]>(() => data) - - const [itemsModalOpen, setItemsModalOpen] = React.useState(false); - const [selectedRfqId, setSelectedRfqId] = React.useState<number | null>(null); - - - const selectedRfq = React.useMemo(() => { - return rowData.find(row => row.rfqId === selectedRfqId) || null; - }, [rowData, selectedRfqId]); - - // rfqType에 따른 제목 계산 - const getRfqTypeTitle = () => { - return rfqType === RfqType.PURCHASE ? "Purchase RFQ" : "Budgetary RFQ"; - }; - - async function openItemsModal(rfqId: number) { - const itemList = await fetchRfqItems(rfqId) - setItemsDefault(itemList) - setSelectedRfqId(rfqId); - setItemsModalOpen(true); - } - - async function openAttachmentsSheet(rfqId: number) { - // 4.1) Fetch current attachments from server (server action) - const list = await fetchRfqAttachments(rfqId) // returns ExistingAttachment[] - setAttachDefault(list) - setSelectedRfqIdForAttachments(rfqId) - setAttachmentsOpen(true) - setSelectedRfqId(rfqId); - } - - function handleAttachmentsUpdated(rfqId: number, newCount: number, newList?: ExistingAttachment[]) { - // 5.1) update rowData itemCount - setRowData(prev => - prev.map(r => - r.rfqId === rfqId - ? { ...r, itemCount: newCount } - : r - ) - ) - // 5.2) if newList is provided, store it - if (newList) { - setAttachDefault(newList) - } - } - - const columns = React.useMemo(() => getColumns({ - setRowAction, router, - // we pass openItemsModal as a prop so the itemsColumn can call it - openItemsModal, - openAttachmentsSheet, - rfqType - }), [setRowAction, router, rfqType]); - - /** - * This component can render either a faceted filter or a search filter based on the `options` prop. - */ - const filterFields: DataTableFilterField<RfqWithItemCount>[] = [ - { - id: "rfqCode", - label: "RFQ Code", - placeholder: "Filter RFQ Code...", - }, - { - id: "status", - label: "Status", - options: rfqs.status.enumValues?.map((status) => { - // 명시적으로 status를 허용된 리터럴 타입으로 변환 - const s = status as "DRAFT" | "PUBLISHED" | "EVALUATION" | "AWARDED"; - return { - label: toSentenceCase(s), - value: s, - icon: getRFQStatusIcon(s), - count: statusCounts[s], - }; - }), - - } - ] - - /** - * Advanced filter fields for the data table. - */ - const advancedFilterFields: DataTableAdvancedFilterField<RfqWithItemCount>[] = [ - { - id: "rfqCode", - label: "RFQ Code", - type: "text", - }, - { - id: "description", - label: "Description", - type: "text", - }, - { - id: "projectCode", - label: "Project Code", - type: "text", - }, - { - id: "dueDate", - label: "Due Date", - type: "date", - }, - { - id: "status", - label: "Status", - type: "multi-select", - options: rfqs.status.enumValues?.map((status) => { - // 명시적으로 status를 허용된 리터럴 타입으로 변환 - const s = status as "DRAFT" | "PUBLISHED" | "EVALUATION" | "AWARDED"; - return { - label: toSentenceCase(s), - value: s, - icon: getRFQStatusIcon(s), - count: statusCounts[s], - }; - }), - - }, - ] - - const { table } = useDataTable({ - data, - columns, - pageCount, - filterFields, - enablePinning: true, - enableAdvancedFilter: true, - initialState: { - sorting: [{ id: "createdAt", desc: true }], - columnPinning: { right: ["actions"] }, - }, - getRowId: (originalRow) => String(originalRow.rfqId), - shallow: false, - clearOnDefault: true, - }) - - return ( - <div style={{ maxWidth: '100vw' }}> - <DataTable - table={table} - // floatingBar={<RfqsTableFloatingBar table={table} />} - > - <DataTableAdvancedToolbar - table={table} - filterFields={advancedFilterFields} - shallow={false} - > - <RfqsTableToolbarActions table={table} rfqType={rfqType} /> - </DataTableAdvancedToolbar> - </DataTable> - - <UpdateRfqSheet - open={rowAction?.type === "update"} - onOpenChange={() => setRowAction(null)} - rfq={rowAction?.row.original ?? null} - /> - - <DeleteRfqsDialog - open={rowAction?.type === "delete"} - onOpenChange={() => setRowAction(null)} - rfqs={rowAction?.row.original ? [rowAction?.row.original] : []} - showTrigger={false} - onSuccess={() => rowAction?.row.toggleSelected(false)} - /> - - <RfqsItemsDialog - open={itemsModalOpen} - onOpenChange={setItemsModalOpen} - rfq={selectedRfq ?? null} - itemsList={itemsList} - defaultItems={itemsDefault} - rfqType={rfqType} - /> - - <RfqAttachmentsSheet - open={attachmentsOpen} - onOpenChange={setAttachmentsOpen} - defaultAttachments={attachDefault} - rfqType={rfqType} - rfq={selectedRfq ?? null} - onAttachmentsUpdated={handleAttachmentsUpdated} - /> - </div> - ) -}
\ No newline at end of file |
