2025-12-05 15:18:55 +09:00
|
|
|
"use client";
|
|
|
|
|
|
|
|
|
|
import { memo } from "react";
|
2026-03-19 15:07:07 +09:00
|
|
|
import { NodeProps } from "reactflow";
|
|
|
|
|
import { BarChart3 } from "lucide-react";
|
|
|
|
|
import { CompactNodeShell } from "./CompactNodeShell";
|
|
|
|
|
import type { AggregateNodeData } from "@/types/node-editor";
|
2025-12-05 15:18:55 +09:00
|
|
|
|
|
|
|
|
export const AggregateNode = memo(({ data, selected }: NodeProps<AggregateNodeData>) => {
|
2026-03-19 15:07:07 +09:00
|
|
|
const opCount = data.operations?.length || 0;
|
|
|
|
|
const groupCount = data.groupByFields?.length || 0;
|
|
|
|
|
const summary = opCount > 0
|
|
|
|
|
? `${opCount}개 연산${groupCount > 0 ? `, ${groupCount}개 그룹` : ""}`
|
|
|
|
|
: "집계 연산을 설정해 주세요";
|
2025-12-05 15:18:55 +09:00
|
|
|
|
|
|
|
|
return (
|
2026-03-19 15:07:07 +09:00
|
|
|
<CompactNodeShell
|
|
|
|
|
color="#A855F7"
|
|
|
|
|
label={data.displayName || "집계"}
|
|
|
|
|
summary={summary}
|
|
|
|
|
icon={<BarChart3 className="h-3.5 w-3.5" />}
|
|
|
|
|
selected={selected}
|
2025-12-05 15:18:55 +09:00
|
|
|
>
|
2026-03-19 15:07:07 +09:00
|
|
|
{opCount > 0 && (
|
|
|
|
|
<div className="space-y-0.5">
|
|
|
|
|
{data.operations!.slice(0, 3).map((op: any, i: number) => (
|
|
|
|
|
<div key={i} className="flex items-center gap-1.5">
|
|
|
|
|
<span className="rounded bg-violet-500/20 px-1 py-0.5 font-mono text-[9px] font-semibold text-violet-400">
|
|
|
|
|
{op.function || op.operation}
|
|
|
|
|
</span>
|
|
|
|
|
<span>{op.field || op.sourceField}</span>
|
2025-12-05 15:18:55 +09:00
|
|
|
</div>
|
2026-03-19 15:07:07 +09:00
|
|
|
))}
|
|
|
|
|
</div>
|
|
|
|
|
)}
|
|
|
|
|
</CompactNodeShell>
|
2025-12-05 15:18:55 +09:00
|
|
|
);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
AggregateNode.displayName = "AggregateNode";
|