summaryrefslogtreecommitdiff
path: root/lib/evaluation/table/evaluation-columns.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'lib/evaluation/table/evaluation-columns.tsx')
-rw-r--r--lib/evaluation/table/evaluation-columns.tsx455
1 files changed, 338 insertions, 117 deletions
diff --git a/lib/evaluation/table/evaluation-columns.tsx b/lib/evaluation/table/evaluation-columns.tsx
index dca19ddb..e8b51b57 100644
--- a/lib/evaluation/table/evaluation-columns.tsx
+++ b/lib/evaluation/table/evaluation-columns.tsx
@@ -1,6 +1,4 @@
-// ================================================================
-// 1. PERIODIC EVALUATIONS COLUMNS
-// ================================================================
+// components/evaluation/evaluation-columns.tsx - 집계 모드 지원 업데이트
"use client";
import * as React from "react";
@@ -8,33 +6,69 @@ import { type ColumnDef } from "@tanstack/react-table";
import { Checkbox } from "@/components/ui/checkbox";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
-import { Pencil, Eye, MessageSquare, Check, X, Clock, FileText, Circle, Ellipsis } from "lucide-react";
+import { Pencil, Eye, MessageSquare, Check, X, Clock, FileText, Circle, Ellipsis, BarChart3 } from "lucide-react";
+import {
+ Tooltip,
+ TooltipContent,
+ TooltipProvider,
+ TooltipTrigger,
+} from "@/components/ui/tooltip";
import { DataTableColumnHeaderSimple } from "@/components/data-table/data-table-column-simple-header";
-import { PeriodicEvaluationView } from "@/db/schema";
+import { PeriodicEvaluationView, PeriodicEvaluationAggregatedView } from "@/db/schema";
import { DataTableRowAction } from "@/types/table";
import { vendortypeMap } from "@/types/evaluation";
-
-
interface GetColumnsProps {
- setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<PeriodicEvaluationView> | null>>;
+ setRowAction: React.Dispatch<React.SetStateAction<DataTableRowAction<PeriodicEvaluationView | PeriodicEvaluationAggregatedView> | null>>;
+ viewMode?: "detailed" | "aggregated";
}
-// 상태별 색상 매핑
+// 집계 모드용 division 배지
+const getDivisionBadgeWithAggregation = (
+ division: string,
+ evaluationCount?: number,
+ divisions?: string
+) => {
+ if (division === "BOTH") {
+ return (
+ <div className="flex items-center gap-1">
+ <Badge variant="outline" className="bg-purple-50 text-purple-700 border-purple-200">
+ 통합
+ </Badge>
+ {evaluationCount && evaluationCount > 1 && (
+ <TooltipProvider>
+ <Tooltip>
+ <TooltipTrigger>
+ <Badge variant="secondary" className="text-xs">
+ {evaluationCount}개
+ </Badge>
+ </TooltipTrigger>
+ <TooltipContent>
+ <p>{divisions?.replace(',', ', ')} 평가 통합</p>
+ </TooltipContent>
+ </Tooltip>
+ </TooltipProvider>
+ )}
+ </div>
+ );
+ }
+
+ return (
+ <Badge variant={division === "PLANT" ? "default" : "secondary"}>
+ {division === "PLANT" ? "해양" : "조선"}
+ </Badge>
+ );
+};
+
+// 기존 함수들은 그대로 유지...
const getStatusBadgeVariant = (status: string) => {
switch (status) {
- case "PENDING_SUBMISSION":
- return "outline";
- case "SUBMITTED":
- return "secondary";
- case "IN_REVIEW":
- return "default";
- case "REVIEW_COMPLETED":
- return "default";
- case "FINALIZED":
- return "default";
- default:
- return "outline";
+ case "PENDING_SUBMISSION": return "outline";
+ case "SUBMITTED": return "secondary";
+ case "IN_REVIEW": return "default";
+ case "REVIEW_COMPLETED": return "default";
+ case "FINALIZED": return "default";
+ default: return "outline";
}
};
@@ -54,7 +88,6 @@ const getStatusLabel = (status: string) => {
const getDepartmentStatusBadge = (status: string | null) => {
if (!status) return (
<div className="flex items-center gap-1">
- {/* <Circle className="w-4 h-4 fill-gray-300 text-gray-300" /> */}
<span className="text-xs text-gray-500">-</span>
</div>
);
@@ -63,7 +96,6 @@ const getDepartmentStatusBadge = (status: string | null) => {
case "NOT_ASSIGNED":
return (
<div className="flex items-center gap-1">
- {/* <Circle className="w-4 h-4 fill-gray-400 text-gray-400" /> */}
<span className="text-xs text-gray-600">미지정</span>
</div>
);
@@ -71,73 +103,44 @@ const getDepartmentStatusBadge = (status: string | null) => {
return (
<div className="flex items-center gap-1">
<div className="w-4 h-4 rounded-full bg-red-500 shadow-sm" />
-
- {/* <span className="text-xs text-red-600">시작전</span> */}
</div>
);
case "IN_PROGRESS":
return (
<div className="flex items-center gap-1">
<div className="w-4 h-4 rounded-full bg-yellow-500 shadow-sm" />
- {/* <span className="text-xs text-yellow-600">진행중</span> */}
</div>
);
case "COMPLETED":
return (
<div className="flex items-center gap-1">
<div className="w-4 h-4 rounded-full bg-green-500 shadow-sm" />
- {/* <span className="text-xs text-green-600">완료</span> */}
</div>
);
default:
return (
<div className="flex items-center gap-1">
- {/* <Circle className="w-4 h-4 fill-gray-300 text-gray-300" /> */}
<span className="text-xs text-gray-500">-</span>
</div>
);
}
};
-// 부서명 라벨
-const DEPARTMENT_LABELS = {
- ORDER_EVAL: "발주",
- PROCUREMENT_EVAL: "조달",
- QUALITY_EVAL: "품질",
- DESIGN_EVAL: "설계",
- CS_EVAL: "CS"
-} as const;
// 등급별 색상
const getGradeBadgeVariant = (grade: string | null) => {
if (!grade) return "outline";
switch (grade) {
- case "S":
- return "default";
- case "A":
- return "secondary";
- case "B":
- return "outline";
- case "C":
- return "destructive";
- case "D":
- return "destructive";
- default:
- return "outline";
+ case "S": return "default";
+ case "A": return "secondary";
+ case "B": return "outline";
+ case "C": return "destructive";
+ case "D": return "destructive";
+ default: return "outline";
}
};
-// 구분 배지
-const getDivisionBadge = (division: string) => {
- return (
- <Badge variant={division === "PLANT" ? "default" : "secondary"}>
- {division === "PLANT" ? "해양" : "조선"}
- </Badge>
- );
-};
-
// 자재구분 배지
const getMaterialTypeBadge = (materialType: string) => {
-
return <Badge variant="outline">{vendortypeMap[materialType] || materialType}</Badge>;
};
@@ -150,18 +153,12 @@ const getDomesticForeignBadge = (domesticForeign: string) => {
);
};
-// 진행률 배지
-const getProgressBadge = (completed: number, total: number) => {
- if (total === 0) return <Badge variant="outline">-</Badge>;
+export function getPeriodicEvaluationsColumns({
+ setRowAction,
+ viewMode = "detailed"
+}: GetColumnsProps): ColumnDef<PeriodicEvaluationView | PeriodicEvaluationAggregatedView>[] {
- const percentage = Math.round((completed / total) * 100);
- const variant = percentage === 100 ? "default" : percentage >= 50 ? "secondary" : "destructive";
-
- return <Badge variant={variant}>{completed}/{total} ({percentage}%)</Badge>;
-};
-
-export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps): ColumnDef<PeriodicEvaluationView>[] {
- return [
+ const baseColumns: ColumnDef<PeriodicEvaluationView | PeriodicEvaluationAggregatedView>[] = [
// ═══════════════════════════════════════════════════════════════
// 선택 및 기본 정보
// ═══════════════════════════════════════════════════════════════
@@ -196,24 +193,37 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="평가년도" />,
cell: ({ row }) => <span className="font-medium">{row.original.evaluationYear}</span>,
size: 100,
+ meta: {
+ excelHeader: "평가년도",
+ },
},
- // ░░░ 평가기간 ░░░
- // {
- // accessorKey: "evaluationPeriod",
- // header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="평가기간" />,
- // cell: ({ row }) => (
- // <Badge variant="outline">{row.getValue("evaluationPeriod")}</Badge>
- // ),
- // size: 100,
- // },
-
- // ░░░ 구분 ░░░
+ // ░░░ 구분 ░░░ - 집계 모드에 따라 다르게 렌더링
{
accessorKey: "division",
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="구분" />,
- cell: ({ row }) => getDivisionBadge(row.original.division || ""),
- size: 80,
+ cell: ({ row }) => {
+ const division =viewMode === "aggregated"?"BOTH": row.original.division || "";
+
+ if (viewMode === "aggregated") {
+ const aggregatedRow = row.original as PeriodicEvaluationAggregatedView;
+ return getDivisionBadgeWithAggregation(
+ division,
+ aggregatedRow.evaluationCount,
+ aggregatedRow.divisions
+ );
+ }
+
+ return (
+ <Badge variant={division === "PLANT" ? "default" : "secondary"}>
+ {division === "PLANT" ? "해양" : "조선"}
+ </Badge>
+ );
+ },
+ size: viewMode === "aggregated" ? 120 : 80,
+ meta: {
+ excelHeader: "구분",
+ },
},
{
@@ -221,9 +231,11 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="Status" />,
cell: ({ row }) => getStatusLabel(row.original.status || ""),
size: 80,
+ meta: {
+ excelHeader: "Status",
+ },
},
-
// ═══════════════════════════════════════════════════════════════
// 협력업체 정보
// ═══════════════════════════════════════════════════════════════
@@ -237,6 +249,9 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
<span className="font-mono text-sm">{row.original.vendorCode}</span>
),
size: 120,
+ meta: {
+ excelHeader: "벤더 코드",
+ },
},
{
@@ -248,6 +263,9 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
</div>
),
size: 200,
+ meta: {
+ excelHeader: "벤더명",
+ },
},
{
@@ -255,6 +273,9 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="내외자" />,
cell: ({ row }) => getDomesticForeignBadge(row.original.domesticForeign || ""),
size: 80,
+ meta: {
+ excelHeader: "내외자",
+ },
},
{
@@ -262,22 +283,87 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="자재구분" />,
cell: ({ row }) => getMaterialTypeBadge(row.original.materialType || ""),
size: 120,
+ meta: {
+ excelHeader: "자재구분",
+ },
},
]
},
+
+ // 집계 모드에서만 보이는 평가 개수 컬럼
+ ...(viewMode === "aggregated" ? [{
+ accessorKey: "evaluationCount",
+ header: ({ column }) => (
+ <div className="flex items-center gap-1">
+ <BarChart3 className="h-4 w-4" />
+ <DataTableColumnHeaderSimple column={column} title="평가수" />
+ </div>
+ ),
+ cell: ({ row }) => {
+ const aggregatedRow = row.original as PeriodicEvaluationAggregatedView;
+ const count = aggregatedRow.evaluationCount || 1;
+
+ return (
+ <div className="flex items-center gap-1">
+ <Badge variant={count > 1 ? "default" : "outline"} className="font-mono">
+ {count}개
+ </Badge>
+ {count > 1 && aggregatedRow.divisions && (
+ <TooltipProvider>
+ <Tooltip>
+ <TooltipTrigger>
+ <div className="text-xs text-muted-foreground cursor-help">
+ ({aggregatedRow.divisions.replace(',', ', ')})
+ </div>
+ </TooltipTrigger>
+ <TooltipContent>
+ <p>{aggregatedRow.divisions.replace(',', ', ')} 평가의 평균값</p>
+ </TooltipContent>
+ </Tooltip>
+ </TooltipProvider>
+ )}
+ </div>
+ );
+ },
+ size: 100,
+ meta: {
+ excelHeader: "평가수",
+ },
+ }] : []),
{
accessorKey: "finalScore",
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="확정점수" />,
cell: ({ row }) => {
const finalScore = row.getValue<number>("finalScore");
+ const isAggregated = viewMode === "aggregated" && (row.original as PeriodicEvaluationAggregatedView).evaluationCount > 1;
+
return finalScore ? (
- <span className="font-bold text-green-600">{Number(finalScore).toFixed(1)}</span>
+ <div className="flex items-center gap-1">
+ <span className={`font-bold ${isAggregated ? 'text-purple-600' : 'text-green-600'}`}>
+ {Number(finalScore).toFixed(1)}
+ </span>
+ {isAggregated && (
+ <TooltipProvider>
+ <Tooltip>
+ <TooltipTrigger>
+ <Badge variant="outline" className="text-xs bg-purple-50">평균</Badge>
+ </TooltipTrigger>
+ <TooltipContent>
+ <p>여러 평가의 평균값</p>
+ </TooltipContent>
+ </Tooltip>
+ </TooltipProvider>
+ )}
+ </div>
) : (
<span className="text-muted-foreground">-</span>
);
},
- size: 90,
+ size: viewMode === "aggregated" ? 120 : 90,
+ meta: {
+ excelHeader: "확정점수",
+ },
},
{
@@ -285,8 +371,13 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="확정등급" />,
cell: ({ row }) => {
const finalGrade = row.getValue<string>("finalGrade");
+ const isAggregated = viewMode === "aggregated" && (row.original as PeriodicEvaluationAggregatedView).evaluationCount > 1;
+
return finalGrade ? (
- <Badge variant={getGradeBadgeVariant(finalGrade)} className="bg-green-600">
+ <Badge
+ variant={getGradeBadgeVariant(finalGrade)}
+ className={isAggregated ? "bg-purple-600" : "bg-green-600"}
+ >
{finalGrade}
</Badge>
) : (
@@ -294,10 +385,13 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
);
},
size: 90,
+ meta: {
+ excelHeader: "확정등급",
+ },
},
- // ═══════════════════════════════════════════════════════════════
- // 진행 현황
+ // ═══════════════════════════════════════════════════════════════
+ // 진행 현황 - 집계 모드에서는 최고 진행 상태를 보여줌
// ═══════════════════════════════════════════════════════════════
{
header: "부서별 평가 현황",
@@ -307,6 +401,9 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="발주" />,
cell: ({ row }) => getDepartmentStatusBadge(row.getValue("orderEvalStatus")),
size: 60,
+ meta: {
+ excelHeader: "발주",
+ },
},
{
@@ -314,6 +411,9 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="조달" />,
cell: ({ row }) => getDepartmentStatusBadge(row.getValue("procurementEvalStatus")),
size: 70,
+ meta: {
+ excelHeader: "조달",
+ },
},
{
@@ -321,6 +421,9 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="품질" />,
cell: ({ row }) => getDepartmentStatusBadge(row.getValue("qualityEvalStatus")),
size: 70,
+ meta: {
+ excelHeader: "품질",
+ },
},
{
@@ -328,6 +431,9 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="설계" />,
cell: ({ row }) => getDepartmentStatusBadge(row.getValue("designEvalStatus")),
size: 70,
+ meta: {
+ excelHeader: "설계",
+ },
},
{
@@ -335,13 +441,24 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="CS" />,
cell: ({ row }) => getDepartmentStatusBadge(row.getValue("csEvalStatus")),
size: 70,
+ meta: {
+ excelHeader: "CS",
+ },
+ },
+
+ {
+ accessorKey: "adminEvalStatus",
+ header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="관리자" />,
+ cell: ({ row }) => getDepartmentStatusBadge(row.getValue("adminEvalStatus")),
+ size: 120,
+ meta: {
+ excelHeader: "관리자",
+ },
},
]
},
{
- // id: "평가상세",
- // accessorKey: "평가상세",
header: "평가상세",
enableHiding: true,
size: 80,
@@ -359,11 +476,11 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
>
<Ellipsis className="size-4" />
</Button>
-
</div>
);
},
},
+
// ═══════════════════════════════════════════════════════════════
// 제출 현황
// ═══════════════════════════════════════════════════════════════
@@ -375,13 +492,32 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="문서제출" />,
cell: ({ row }) => {
const submitted = row.getValue<boolean>("documentsSubmitted");
+ const isAggregated = viewMode === "aggregated" && (row.original as PeriodicEvaluationAggregatedView).evaluationCount > 1;
+
return (
- <Badge variant={submitted ? "default" : "destructive"}>
- {submitted ? "제출완료" : "미제출"}
- </Badge>
+ <div className="flex items-center gap-1">
+ <Badge variant={submitted ? "default" : "destructive"}>
+ {submitted ? "제출완료" : "미제출"}
+ </Badge>
+ {isAggregated && (
+ <TooltipProvider>
+ <Tooltip>
+ <TooltipTrigger>
+ <Badge variant="outline" className="text-xs">통합</Badge>
+ </TooltipTrigger>
+ <TooltipContent>
+ <p>모든 평가에서 제출 완료된 경우만 "제출완료"</p>
+ </TooltipContent>
+ </Tooltip>
+ </TooltipProvider>
+ )}
+ </div>
);
},
- size: 120,
+ size: viewMode === "aggregated" ? 140 : 120,
+ meta: {
+ excelHeader: "문서제출",
+ },
},
{
@@ -389,18 +525,37 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="제출일" />,
cell: ({ row }) => {
const submissionDate = row.getValue<Date>("submissionDate");
+ const isAggregated = viewMode === "aggregated" && (row.original as PeriodicEvaluationAggregatedView).evaluationCount > 1;
+
return submissionDate ? (
- <span className="text-sm">
- {new Intl.DateTimeFormat("ko-KR", {
- month: "2-digit",
- day: "2-digit",
- }).format(new Date(submissionDate))}
- </span>
+ <div className="flex items-center gap-1">
+ <span className="text-sm">
+ {new Intl.DateTimeFormat("ko-KR", {
+ month: "2-digit",
+ day: "2-digit",
+ }).format(new Date(submissionDate))}
+ </span>
+ {isAggregated && (
+ <TooltipProvider>
+ <Tooltip>
+ <TooltipTrigger>
+ <Badge variant="outline" className="text-xs">최신</Badge>
+ </TooltipTrigger>
+ <TooltipContent>
+ <p>가장 최근 제출일</p>
+ </TooltipContent>
+ </Tooltip>
+ </TooltipProvider>
+ )}
+ </div>
) : (
<span className="text-muted-foreground">-</span>
);
},
- size: 80,
+ size: viewMode === "aggregated" ? 110 : 80,
+ meta: {
+ excelHeader: "제출일",
+ },
},
{
@@ -423,30 +578,38 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
);
},
size: 80,
+ meta: {
+ excelHeader: "마감일",
+ },
},
]
},
-
-
// ═══════════════════════════════════════════════════════════════
- // 평가 점수
+ // 평가 점수 - 집계 모드에서는 평균임을 명시
// ═══════════════════════════════════════════════════════════════
{
- header: "평가 점수",
+ header: viewMode === "aggregated" ? "평가 점수 (평균)" : "평가 점수",
columns: [
{
accessorKey: "processScore",
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="공정" />,
cell: ({ row }) => {
const score = row.getValue("processScore");
+ const isAggregated = viewMode === "aggregated" && (row.original as PeriodicEvaluationAggregatedView).evaluationCount > 1;
+
return score ? (
- <span className="font-medium">{Number(score).toFixed(1)}</span>
+ <span className={`font-medium ${isAggregated ? 'text-purple-600' : ''}`}>
+ {Number(score).toFixed(1)}
+ </span>
) : (
<span className="text-muted-foreground">-</span>
);
},
size: 80,
+ meta: {
+ excelHeader: "공정",
+ },
},
{
@@ -454,13 +617,20 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="가격" />,
cell: ({ row }) => {
const score = row.getValue("priceScore");
+ const isAggregated = viewMode === "aggregated" && (row.original as PeriodicEvaluationAggregatedView).evaluationCount > 1;
+
return score ? (
- <span className="font-medium">{Number(score).toFixed(1)}</span>
+ <span className={`font-medium ${isAggregated ? 'text-purple-600' : ''}`}>
+ {Number(score).toFixed(1)}
+ </span>
) : (
<span className="text-muted-foreground">-</span>
);
},
size: 80,
+ meta: {
+ excelHeader: "가격",
+ },
},
{
@@ -468,13 +638,20 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="납기" />,
cell: ({ row }) => {
const score = row.getValue("deliveryScore");
+ const isAggregated = viewMode === "aggregated" && (row.original as PeriodicEvaluationAggregatedView).evaluationCount > 1;
+
return score ? (
- <span className="font-medium">{Number(score).toFixed(1)}</span>
+ <span className={`font-medium ${isAggregated ? 'text-purple-600' : ''}`}>
+ {Number(score).toFixed(1)}
+ </span>
) : (
<span className="text-muted-foreground">-</span>
);
},
size: 80,
+ meta: {
+ excelHeader: "납기",
+ },
},
{
@@ -482,13 +659,20 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="자율평가" />,
cell: ({ row }) => {
const score = row.getValue("selfEvaluationScore");
+ const isAggregated = viewMode === "aggregated" && (row.original as PeriodicEvaluationAggregatedView).evaluationCount > 1;
+
return score ? (
- <span className="font-medium">{Number(score).toFixed(1)}</span>
+ <span className={`font-medium ${isAggregated ? 'text-purple-600' : ''}`}>
+ {Number(score).toFixed(1)}
+ </span>
) : (
<span className="text-muted-foreground">-</span>
);
},
size: 80,
+ meta: {
+ excelHeader: "자율평가",
+ },
},
// ✅ 합계 - 4개 점수의 합으로 계산
@@ -502,9 +686,12 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
const selfEvaluationScore = Number(row.getValue("selfEvaluationScore") || 0);
const total = processScore + priceScore + deliveryScore + selfEvaluationScore;
+ const isAggregated = viewMode === "aggregated" && (row.original as PeriodicEvaluationAggregatedView).evaluationCount > 1;
return total > 0 ? (
- <span className="font-medium bg-blue-50 px-2 py-1 rounded">
+ <span className={`font-medium px-2 py-1 rounded ${
+ isAggregated ? 'bg-purple-50 text-purple-600' : 'bg-blue-50 text-blue-600'
+ }`}>
{total.toFixed(1)}
</span>
) : (
@@ -512,6 +699,9 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
);
},
size: 80,
+ meta: {
+ excelHeader: "합계",
+ },
},
{
@@ -519,13 +709,20 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="참여도(가점)" />,
cell: ({ row }) => {
const score = row.getValue("participationBonus");
+ const isAggregated = viewMode === "aggregated" && (row.original as PeriodicEvaluationAggregatedView).evaluationCount > 1;
+
return score ? (
- <span className="font-medium text-green-600">+{Number(score).toFixed(1)}</span>
+ <span className={`font-medium ${isAggregated ? 'text-purple-600' : 'text-green-600'}`}>
+ +{Number(score).toFixed(1)}
+ </span>
) : (
<span className="text-muted-foreground">-</span>
);
},
size: 100,
+ meta: {
+ excelHeader: "참여도(가점)",
+ },
},
{
@@ -533,16 +730,23 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="품질(감점)" />,
cell: ({ row }) => {
const score = row.getValue("qualityDeduction");
+ const isAggregated = viewMode === "aggregated" && (row.original as PeriodicEvaluationAggregatedView).evaluationCount > 1;
+
return score ? (
- <span className="font-medium text-red-600">-{Number(score).toFixed(1)}</span>
+ <span className={`font-medium ${isAggregated ? 'text-purple-600' : 'text-red-600'}`}>
+ -{Number(score).toFixed(1)}
+ </span>
) : (
<span className="text-muted-foreground">-</span>
);
},
size: 100,
+ meta: {
+ excelHeader: "품질(감점)",
+ },
},
- // ✅ 새로운 평가점수 컬럼 추가
+ // ✅ 평가점수 컬럼
{
id: "evaluationScore",
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="평가점수" />,
@@ -556,9 +760,12 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
const totalScore = processScore + priceScore + deliveryScore + selfEvaluationScore;
const evaluationScore = totalScore + participationBonus - qualityDeduction;
+ const isAggregated = viewMode === "aggregated" && (row.original as PeriodicEvaluationAggregatedView).evaluationCount > 1;
return totalScore > 0 ? (
- <span className="font-bold text-blue-600 bg-blue-50 px-2 py-1 rounded">
+ <span className={`font-bold px-2 py-1 rounded ${
+ isAggregated ? 'bg-purple-50 text-purple-600' : 'bg-blue-50 text-blue-600'
+ }`}>
{evaluationScore.toFixed(1)}
</span>
) : (
@@ -566,6 +773,9 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
);
},
size: 90,
+ meta: {
+ excelHeader: "평가점수",
+ },
},
{
@@ -573,16 +783,27 @@ export function getPeriodicEvaluationsColumns({setRowAction}: GetColumnsProps):
header: ({ column }) => <DataTableColumnHeaderSimple column={column} title="평가등급" />,
cell: ({ row }) => {
const grade = row.getValue<string>("evaluationGrade");
+ const isAggregated = viewMode === "aggregated" && (row.original as PeriodicEvaluationAggregatedView).evaluationCount > 1;
+
return grade ? (
- <Badge variant={getGradeBadgeVariant(grade)}>{grade}</Badge>
+ <Badge
+ variant={getGradeBadgeVariant(grade)}
+ className={isAggregated ? "bg-purple-600" : ""}
+ >
+ {grade}
+ </Badge>
) : (
<span className="text-muted-foreground">-</span>
);
},
minSize: 100,
+ meta: {
+ excelHeader: "평가등급",
+ },
},
-
]
},
];
+
+ return baseColumns;
} \ No newline at end of file