summaryrefslogtreecommitdiff
path: root/lib/techsales-rfq
diff options
context:
space:
mode:
Diffstat (limited to 'lib/techsales-rfq')
-rw-r--r--lib/techsales-rfq/service.ts40
-rw-r--r--lib/techsales-rfq/table/delete-vendors-dialog.tsx119
-rw-r--r--lib/techsales-rfq/table/detail-table/delete-vendors-dialog.tsx (renamed from lib/techsales-rfq/table/detail-table/delete-vendor-dialog.tsx)0
-rw-r--r--lib/techsales-rfq/table/detail-table/rfq-detail-column.tsx70
-rw-r--r--lib/techsales-rfq/table/detail-table/rfq-detail-table.tsx128
-rw-r--r--lib/techsales-rfq/table/rfq-table-column.tsx54
-rw-r--r--lib/techsales-rfq/table/rfq-table.tsx5
7 files changed, 302 insertions, 114 deletions
diff --git a/lib/techsales-rfq/service.ts b/lib/techsales-rfq/service.ts
index f7a30b3b..f3bb2e59 100644
--- a/lib/techsales-rfq/service.ts
+++ b/lib/techsales-rfq/service.ts
@@ -2490,6 +2490,46 @@ export interface TechSalesComment {
}
/**
+ * 특정 RFQ의 벤더별 읽지 않은 메시지 개수를 조회하는 함수
+ *
+ * @param rfqId RFQ ID
+ * @returns 벤더별 읽지 않은 메시지 개수 (vendorId: count)
+ */
+export async function getTechSalesUnreadMessageCounts(rfqId: number): Promise<Record<number, number>> {
+ try {
+ // 벤더가 보낸 읽지 않은 메시지를 벤더별로 카운트
+ const unreadCounts = await db
+ .select({
+ vendorId: techSalesRfqComments.vendorId,
+ count: sql<number>`count(*)`,
+ })
+ .from(techSalesRfqComments)
+ .where(
+ and(
+ eq(techSalesRfqComments.rfqId, rfqId),
+ eq(techSalesRfqComments.isVendorComment, true), // 벤더가 보낸 메시지
+ eq(techSalesRfqComments.isRead, false), // 읽지 않은 메시지
+ sql`${techSalesRfqComments.vendorId} IS NOT NULL` // vendorId가 null이 아닌 것
+ )
+ )
+ .groupBy(techSalesRfqComments.vendorId);
+
+ // Record<number, number> 형태로 변환
+ const result: Record<number, number> = {};
+ unreadCounts.forEach(item => {
+ if (item.vendorId) {
+ result[item.vendorId] = item.count;
+ }
+ });
+
+ return result;
+ } catch (error) {
+ console.error('techSales 읽지 않은 메시지 개수 조회 오류:', error);
+ return {};
+ }
+}
+
+/**
* 특정 RFQ와 벤더 간의 커뮤니케이션 메시지를 가져오는 서버 액션
*
* @param rfqId RFQ ID
diff --git a/lib/techsales-rfq/table/delete-vendors-dialog.tsx b/lib/techsales-rfq/table/delete-vendors-dialog.tsx
new file mode 100644
index 00000000..35c3b067
--- /dev/null
+++ b/lib/techsales-rfq/table/delete-vendors-dialog.tsx
@@ -0,0 +1,119 @@
+"use client"
+
+import * as React from "react"
+import { type RfqDetailView } from "./rfq-detail-column"
+import { Loader, Trash } from "lucide-react"
+
+import { useMediaQuery } from "@/hooks/use-media-query"
+import { Button } from "@/components/ui/button"
+import {
+ Dialog,
+ DialogClose,
+ DialogContent,
+ DialogDescription,
+ DialogFooter,
+ DialogHeader,
+ DialogTitle,
+} from "@/components/ui/dialog"
+import {
+ Drawer,
+ DrawerClose,
+ DrawerContent,
+ DrawerDescription,
+ DrawerFooter,
+ DrawerHeader,
+ DrawerTitle,
+} from "@/components/ui/drawer"
+
+interface DeleteVendorsDialogProps
+ extends React.ComponentPropsWithoutRef<typeof Dialog> {
+ vendors: RfqDetailView[]
+ onConfirm: () => void
+ isLoading?: boolean
+}
+
+export function DeleteVendorsDialog({
+ vendors,
+ onConfirm,
+ isLoading = false,
+ ...props
+}: DeleteVendorsDialogProps) {
+ const isDesktop = useMediaQuery("(min-width: 640px)")
+
+ const vendorNames = vendors.map(v => v.vendorName).filter(Boolean).join(", ")
+
+ if (isDesktop) {
+ return (
+ <Dialog {...props}>
+ <DialogContent>
+ <DialogHeader>
+ <DialogTitle>벤더 삭제 확인</DialogTitle>
+ <DialogDescription>
+ 정말로 선택한 <span className="font-medium">{vendors.length}개</span>의 벤더를 삭제하시겠습니까?
+ <br />
+ <br />
+ 삭제될 벤더: <span className="font-medium">{vendorNames}</span>
+ <br />
+ <br />
+ 이 작업은 되돌릴 수 없습니다.
+ </DialogDescription>
+ </DialogHeader>
+ <DialogFooter className="gap-2 sm:space-x-0">
+ <DialogClose asChild>
+ <Button variant="outline" disabled={isLoading}>취소</Button>
+ </DialogClose>
+ <Button
+ aria-label="선택한 벤더들 삭제"
+ variant="destructive"
+ onClick={onConfirm}
+ disabled={isLoading}
+ >
+ {isLoading && (
+ <Loader
+ className="mr-2 size-4 animate-spin"
+ aria-hidden="true"
+ />
+ )}
+ 삭제
+ </Button>
+ </DialogFooter>
+ </DialogContent>
+ </Dialog>
+ )
+ }
+
+ return (
+ <Drawer {...props}>
+ <DrawerContent>
+ <DrawerHeader>
+ <DrawerTitle>벤더 삭제 확인</DrawerTitle>
+ <DrawerDescription>
+ 정말로 선택한 <span className="font-medium">{vendors.length}개</span>의 벤더를 삭제하시겠습니까?
+ <br />
+ <br />
+ 삭제될 벤더: <span className="font-medium">{vendorNames}</span>
+ <br />
+ <br />
+ 이 작업은 되돌릴 수 없습니다.
+ </DrawerDescription>
+ </DrawerHeader>
+ <DrawerFooter className="gap-2 sm:space-x-0">
+ <DrawerClose asChild>
+ <Button variant="outline" disabled={isLoading}>취소</Button>
+ </DrawerClose>
+ <Button
+ aria-label="선택한 벤더들 삭제"
+ variant="destructive"
+ onClick={onConfirm}
+ disabled={isLoading}
+ >
+ {isLoading && (
+ <Loader className="mr-2 size-4 animate-spin" aria-hidden="true" />
+ )}
+ 삭제
+ </Button>
+ </DrawerFooter>
+ </DrawerContent>
+ </Drawer>
+ )
+} \ No newline at end of file
diff --git a/lib/techsales-rfq/table/detail-table/delete-vendor-dialog.tsx b/lib/techsales-rfq/table/detail-table/delete-vendors-dialog.tsx
index d7e3403b..d7e3403b 100644
--- a/lib/techsales-rfq/table/detail-table/delete-vendor-dialog.tsx
+++ b/lib/techsales-rfq/table/detail-table/delete-vendors-dialog.tsx
diff --git a/lib/techsales-rfq/table/detail-table/rfq-detail-column.tsx b/lib/techsales-rfq/table/detail-table/rfq-detail-column.tsx
index cfae0bd7..7d5c359e 100644
--- a/lib/techsales-rfq/table/detail-table/rfq-detail-column.tsx
+++ b/lib/techsales-rfq/table/detail-table/rfq-detail-column.tsx
@@ -4,21 +4,20 @@ import * as React from "react"
import type { ColumnDef, Row } from "@tanstack/react-table";
import { formatDate } from "@/lib/utils"
import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"
+import { Checkbox } from "@/components/ui/checkbox";
+import { MessageCircle, MoreHorizontal, Trash2 } from "lucide-react";
+import { Button } from "@/components/ui/button";
+import { Badge } from "@/components/ui/badge";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
-import { Checkbox } from "@/components/ui/checkbox";
-import { Ellipsis, MessageCircle } from "lucide-react";
-import { Button } from "@/components/ui/button";
-import { Badge } from "@/components/ui/badge";
-import { useRouter } from "next/navigation";
export interface DataTableRowAction<TData> {
row: Row<TData>;
- type: "delete" | "communicate";
+ type: "communicate" | "delete";
}
// 벤더 견적 데이터 타입 정의
@@ -128,7 +127,28 @@ export function getRfqDetailColumns({
header: ({ column }) => (
<DataTableColumnHeaderSimple column={column} title="벤더명" />
),
- cell: ({ row }) => <div>{row.getValue("vendorName")}</div>,
+ cell: ({ row }) => {
+ const vendorName = row.getValue("vendorName") as string | null;
+ const vendorId = row.original.vendorId;
+
+ if (!vendorName) return <div>-</div>;
+
+ if (vendorId) {
+ return (
+ <Button
+ variant="link"
+ className="p-0 h-auto font-normal text-left justify-start hover:underline"
+ onClick={() => {
+ window.open(`/ko/evcp/vendors/${vendorId}/info`, '_blank');
+ }}
+ >
+ {vendorName}
+ </Button>
+ );
+ }
+
+ return <div>{vendorName}</div>;
+ },
meta: {
excelHeader: "벤더명"
},
@@ -233,13 +253,8 @@ export function getRfqDetailColumns({
cell: function Cell({ row }) {
const vendorId = row.original.vendorId;
const unreadCount = vendorId ? unreadMessages[vendorId] || 0 : 0;
- const router = useRouter();
-
- const handleViewDetails = () => {
- if (vendorId) {
- router.push(`/ko/evcp/vendors/${vendorId}/info`);
- }
- };
+ const status = row.original.status;
+ const isDraft = status === "Draft";
return (
<div className="text-right flex items-center justify-end gap-1">
@@ -264,31 +279,26 @@ export function getRfqDetailColumns({
)}
</div>
- {/* 기존 드롭다운 메뉴 */}
+ {/* 컨텍스트 메뉴 */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="ghost"
- className="flex h-8 w-8 p-0 data-[state=open]:bg-muted"
+ size="sm"
+ className="h-8 w-8 p-0"
+ title="더 많은 작업"
>
- <Ellipsis className="h-4 w-4" />
- <span className="sr-only">메뉴 열기</span>
+ <MoreHorizontal className="h-4 w-4" />
</Button>
</DropdownMenuTrigger>
- <DropdownMenuContent align="end" className="w-[160px]">
- <DropdownMenuItem
- onClick={handleViewDetails}
- disabled={!vendorId}
- className="gap-2"
- >
- {/* <Eye className="h-4 w-4" /> */}
- 벤더 상세정보
- </DropdownMenuItem>
+ <DropdownMenuContent align="end">
<DropdownMenuItem
onClick={() => setRowAction({ row, type: "delete" })}
- className="text-destructive focus:text-destructive"
+ disabled={!isDraft}
+ className={!isDraft ? "opacity-50 cursor-not-allowed" : "text-destructive focus:text-destructive"}
>
- 벤더 제거
+ <Trash2 className="mr-2 h-4 w-4" />
+ 벤더 삭제
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
@@ -296,7 +306,7 @@ export function getRfqDetailColumns({
);
},
enableResizing: false,
- size: 80,
+ size: 120,
},
];
} \ No newline at end of file
diff --git a/lib/techsales-rfq/table/detail-table/rfq-detail-table.tsx b/lib/techsales-rfq/table/detail-table/rfq-detail-table.tsx
index a2f012ad..dbaeae0c 100644
--- a/lib/techsales-rfq/table/detail-table/rfq-detail-table.tsx
+++ b/lib/techsales-rfq/table/detail-table/rfq-detail-table.tsx
@@ -15,7 +15,7 @@ import { Button } from "@/components/ui/button"
import { Loader2, UserPlus, BarChart2, Send, Trash2 } from "lucide-react"
import { ClientDataTable } from "@/components/client-data-table/data-table"
import { AddVendorDialog } from "./add-vendor-dialog"
-import { DeleteVendorDialog } from "./delete-vendor-dialog"
+import { DeleteVendorsDialog } from "./delete-vendors-dialog"
import { VendorCommunicationDrawer } from "./vendor-communication-drawer"
import { VendorQuotationComparisonDialog } from "./vendor-quotation-comparison-dialog"
@@ -48,8 +48,6 @@ export function RfqDetailTables({ selectedRfq, maxHeight }: RfqDetailTablesProps
const [isLoading, setIsLoading] = useState(false)
const [details, setDetails] = useState<RfqDetailView[]>([])
const [vendorDialogOpen, setVendorDialogOpen] = React.useState(false)
- const [deleteDialogOpen, setDeleteDialogOpen] = React.useState(false)
- const [selectedDetail, setSelectedDetail] = React.useState<RfqDetailView | null>(null)
const [isAdddialogLoading, setIsAdddialogLoading] = useState(false)
@@ -70,6 +68,9 @@ export function RfqDetailTables({ selectedRfq, maxHeight }: RfqDetailTablesProps
const [isSendingRfq, setIsSendingRfq] = useState(false)
const [isDeletingVendors, setIsDeletingVendors] = useState(false)
+ // 벤더 삭제 확인 다이얼로그 상태 추가
+ const [deleteConfirmDialogOpen, setDeleteConfirmDialogOpen] = useState(false)
+
// selectedRfq ID 메모이제이션 (객체 참조 변경 방지)
const selectedRfqId = useMemo(() => selectedRfq?.id, [selectedRfq?.id])
@@ -83,12 +84,13 @@ export function RfqDetailTables({ selectedRfq, maxHeight }: RfqDetailTablesProps
if (!selectedRfqId) return;
try {
- // TODO: 기술영업용 읽지 않은 메시지 수 가져오기 함수 구현 필요
- // const unreadData = await fetchUnreadMessages(selectedRfqId);
- // setUnreadMessages(unreadData);
- setUnreadMessages({});
+ // 기술영업용 읽지 않은 메시지 수 가져오기 함수 구현
+ const { getTechSalesUnreadMessageCounts } = await import("@/lib/techsales-rfq/service");
+ const unreadData = await getTechSalesUnreadMessageCounts(selectedRfqId);
+ setUnreadMessages(unreadData);
} catch (error) {
console.error("읽지 않은 메시지 로드 오류:", error);
+ setUnreadMessages({});
}
}, [selectedRfqId]);
@@ -236,6 +238,21 @@ export function RfqDetailTables({ selectedRfq, maxHeight }: RfqDetailTablesProps
}
}, [selectedRows, selectedRfqId, handleRefreshData]);
+ // 벤더 삭제 확인 핸들러
+ const handleDeleteVendorsConfirm = useCallback(() => {
+ if (selectedRows.length === 0) {
+ toast.warning("삭제할 벤더를 선택해주세요.");
+ return;
+ }
+ setDeleteConfirmDialogOpen(true);
+ }, [selectedRows]);
+
+ // 벤더 삭제 확정 실행
+ const executeDeleteVendors = useCallback(async () => {
+ setDeleteConfirmDialogOpen(false);
+ await handleDeleteVendors();
+ }, [handleDeleteVendors]);
+
// 견적 비교 다이얼로그 열기 핸들러 메모이제이션
const handleOpenComparisonDialog = useCallback(() => {
// 제출된 견적이 있는 벤더가 최소 1개 이상 있는지 확인
@@ -281,11 +298,6 @@ export function RfqDetailTables({ selectedRfq, maxHeight }: RfqDetailTablesProps
)
// 계산된 값들 메모이제이션
- const totalUnreadMessages = useMemo(() =>
- Object.values(unreadMessages).reduce((sum, count) => sum + count, 0),
- [unreadMessages]
- );
-
const vendorsWithQuotations = useMemo(() =>
details.filter(detail => detail.status === "Submitted").length,
[details]
@@ -360,24 +372,45 @@ export function RfqDetailTables({ selectedRfq, maxHeight }: RfqDetailTablesProps
setSelectedVendor(rowAction.row.original);
setCommunicationDrawerOpen(true);
- // 해당 벤더의 읽지 않은 메시지를 0으로 설정 (메시지를 읽은 것으로 간주)
- const vendorId = rowAction.row.original.vendorId;
- if (vendorId) {
- setUnreadMessages(prev => ({
- ...prev,
- [vendorId]: 0
- }));
- }
-
// rowAction 초기화
setRowAction(null);
return;
}
- // 삭제 액션인 경우
+ // 삭제 액션인 경우 개별 벤더 삭제
if (rowAction.type === "delete") {
- setSelectedDetail(rowAction.row.original);
- setDeleteDialogOpen(true);
+ const vendor = rowAction.row.original;
+
+ if (!vendor.vendorId || !selectedRfqId) {
+ toast.error("벤더 정보가 없습니다.");
+ setRowAction(null);
+ return;
+ }
+
+ // Draft 상태 체크
+ if (vendor.status !== "Draft") {
+ toast.error("Draft 상태의 벤더만 삭제할 수 있습니다.");
+ setRowAction(null);
+ return;
+ }
+
+ // 개별 벤더 삭제
+ const { removeVendorFromTechSalesRfq } = await import("@/lib/techsales-rfq/service");
+
+ const result = await removeVendorFromTechSalesRfq({
+ rfqId: selectedRfqId,
+ vendorId: vendor.vendorId
+ });
+
+ if (result.error) {
+ toast.error(result.error);
+ } else {
+ toast.success(`${vendor.vendorName || '벤더'}가 성공적으로 삭제되었습니다.`);
+ // 데이터 새로고침
+ await handleRefreshData();
+ }
+
+ // rowAction 초기화
setRowAction(null);
return;
}
@@ -388,7 +421,7 @@ export function RfqDetailTables({ selectedRfq, maxHeight }: RfqDetailTablesProps
};
handleRowAction();
- }, [rowAction])
+ }, [rowAction, selectedRfqId, handleRefreshData])
// 선택된 행 변경 핸들러 메모이제이션
const handleSelectedRowsChange = useCallback((selectedRowsData: RfqDetailView[]) => {
@@ -398,9 +431,25 @@ export function RfqDetailTables({ selectedRfq, maxHeight }: RfqDetailTablesProps
// 커뮤니케이션 드로어 변경 핸들러 메모이제이션
const handleCommunicationDrawerChange = useCallback((open: boolean) => {
setCommunicationDrawerOpen(open);
- // 드로어가 닫힐 때 읽지 않은 메시지 개수 갱신
- if (!open) loadUnreadMessages();
- }, [loadUnreadMessages]);
+ // 드로어가 닫힐 때 해당 벤더의 메시지를 읽음 처리하고 읽지 않은 메시지 개수 갱신
+ if (!open && selectedVendor?.vendorId && selectedRfqId) {
+ // 메시지를 읽음으로 처리
+ import("@/lib/techsales-rfq/service").then(({ markTechSalesMessagesAsRead }) => {
+ markTechSalesMessagesAsRead(selectedRfqId, selectedVendor.vendorId || undefined).catch(error => {
+ console.error("메시지 읽음 처리 오류:", error);
+ });
+ });
+
+ // 해당 벤더의 읽지 않은 메시지를 0으로 즉시 업데이트
+ setUnreadMessages(prev => ({
+ ...prev,
+ [selectedVendor.vendorId!]: 0
+ }));
+
+ // 전체 읽지 않은 메시지 개수 갱신
+ loadUnreadMessages();
+ }
+ }, [selectedVendor, selectedRfqId, loadUnreadMessages]);
if (!selectedRfq) {
return (
@@ -439,11 +488,11 @@ export function RfqDetailTables({ selectedRfq, maxHeight }: RfqDetailTablesProps
{selectedRows.length}개 선택됨
</Badge>
)}
- {totalUnreadMessages > 0 && (
+ {/* {totalUnreadMessages > 0 && (
<Badge variant="destructive" className="h-6">
읽지 않은 메시지: {totalUnreadMessages}건
</Badge>
- )}
+ )} */}
{vendorsWithQuotations > 0 && (
<Badge variant="outline" className="h-6">
견적 제출: {vendorsWithQuotations}개 벤더
@@ -471,7 +520,7 @@ export function RfqDetailTables({ selectedRfq, maxHeight }: RfqDetailTablesProps
<Button
variant="outline"
size="sm"
- onClick={handleDeleteVendors}
+ onClick={handleDeleteVendorsConfirm}
disabled={selectedRows.length === 0 || isDeletingVendors}
className="gap-2"
>
@@ -549,14 +598,6 @@ export function RfqDetailTables({ selectedRfq, maxHeight }: RfqDetailTablesProps
onSuccess={handleRefreshData}
/>
- <DeleteVendorDialog
- open={deleteDialogOpen}
- onOpenChange={setDeleteDialogOpen}
- detail={selectedDetail}
- showTrigger={false}
- onSuccess={handleRefreshData}
- />
-
{/* 벤더 커뮤니케이션 드로어 */}
<VendorCommunicationDrawer
open={communicationDrawerOpen}
@@ -572,6 +613,15 @@ export function RfqDetailTables({ selectedRfq, maxHeight }: RfqDetailTablesProps
onOpenChange={setComparisonDialogOpen}
selectedRfq={selectedRfq}
/>
+
+ {/* 다중 벤더 삭제 확인 다이얼로그 */}
+ <DeleteVendorsDialog
+ open={deleteConfirmDialogOpen}
+ onOpenChange={setDeleteConfirmDialogOpen}
+ vendors={selectedRows}
+ onConfirm={executeDeleteVendors}
+ isLoading={isDeletingVendors}
+ />
</div>
)
} \ No newline at end of file
diff --git a/lib/techsales-rfq/table/rfq-table-column.tsx b/lib/techsales-rfq/table/rfq-table-column.tsx
index e1047fd1..4f7bd499 100644
--- a/lib/techsales-rfq/table/rfq-table-column.tsx
+++ b/lib/techsales-rfq/table/rfq-table-column.tsx
@@ -6,7 +6,7 @@ import { formatDate, formatDateTime } from "@/lib/utils"
import { Checkbox } from "@/components/ui/checkbox"
import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header"
import { DataTableRowAction } from "@/types/table"
-import { Info, Paperclip } from "lucide-react"
+import { Paperclip } from "lucide-react"
import { Button } from "@/components/ui/button"
// 기본적인 RFQ 타입 정의 (rfq-table.tsx 파일과 일치해야 함)
@@ -135,7 +135,7 @@ export function getColumns({
<DataTableColumnHeaderSimple column={column} title="자재명" />
),
cell: ({ row }) => {
- const itemName = row.getValue("itemName");
+ const itemName = row.getValue("itemName") as string | null;
return <div>{itemName || "자재명 없음"}</div>;
},
meta: {
@@ -145,23 +145,22 @@ export function getColumns({
size: 180,
},
{
- accessorKey: "pspid",
- header: ({ column }) => (
- <DataTableColumnHeaderSimple column={column} title="프로젝트 번호" />
- ),
- cell: ({ row }) => <div>{row.getValue("pspid")}</div>,
- meta: {
- excelHeader: "프로젝트 번호"
- },
- enableResizing: true,
- size: 120,
- },
- {
accessorKey: "projNm",
header: ({ column }) => (
<DataTableColumnHeaderSimple column={column} title="프로젝트명" />
),
- cell: ({ row }) => <div>{row.getValue("projNm")}</div>,
+ cell: ({ row }) => {
+ const projNm = row.getValue("projNm") as string;
+ return (
+ <Button
+ variant="link"
+ className="p-0 h-auto font-normal text-left justify-start hover:underline"
+ onClick={() => setRowAction({ row, type: "view" as const })}
+ >
+ {projNm}
+ </Button>
+ );
+ },
meta: {
excelHeader: "프로젝트명"
},
@@ -320,30 +319,5 @@ export function getColumns({
enableResizing: true,
size: 160,
},
- {
- id: "actions",
- header: ({ column }) => (
- <DataTableColumnHeaderSimple column={column} title="액션" />
- ),
- cell: ({ row }) => {
- return (
- <Button
- variant="ghost"
- size="sm"
- onClick={() => setRowAction({ row, type: "view" as const })}
- className="h-8 px-2 gap-1"
- >
- <Info className="h-4 w-4" />
- <span className="hidden sm:inline">프로젝트 상세</span>
- </Button>
- );
- },
- enableSorting: false,
- enableHiding: false,
- enableResizing: false,
- size: 120,
- minSize: 120,
- maxSize: 120,
- },
]
} \ No newline at end of file
diff --git a/lib/techsales-rfq/table/rfq-table.tsx b/lib/techsales-rfq/table/rfq-table.tsx
index 496d7901..c79e2ecf 100644
--- a/lib/techsales-rfq/table/rfq-table.tsx
+++ b/lib/techsales-rfq/table/rfq-table.tsx
@@ -331,11 +331,6 @@ export function RFQListTable({
type: "text",
},
{
- id: "pspid",
- label: "프로젝트 ID",
- type: "text",
- },
- {
id: "projNm",
label: "프로젝트명",
type: "text",