분할 패널 및 반복 필드 그룹 컴포넌트
This commit is contained in:
@@ -10,7 +10,9 @@ import { NODE_CATEGORIES, getNodesByCategory } from "./nodePaletteConfig";
|
||||
import type { NodePaletteItem } from "@/types/node-editor";
|
||||
|
||||
export function NodePalette() {
|
||||
const [expandedCategories, setExpandedCategories] = useState<Set<string>>(new Set(["source", "transform", "action"]));
|
||||
const [expandedCategories, setExpandedCategories] = useState<Set<string>>(
|
||||
new Set(["source", "transform", "action", "utility"]),
|
||||
);
|
||||
|
||||
const toggleCategory = (categoryId: string) => {
|
||||
setExpandedCategories((prev) => {
|
||||
@@ -25,7 +27,7 @@ export function NodePalette() {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex h-full flex-col">
|
||||
<div className="flex h-full flex-col bg-white">
|
||||
{/* 헤더 */}
|
||||
<div className="border-b bg-gray-50 p-4">
|
||||
<h3 className="text-sm font-semibold text-gray-900">노드 라이브러리</h3>
|
||||
@@ -46,7 +48,6 @@ export function NodePalette() {
|
||||
className="flex w-full items-center gap-2 rounded px-2 py-1.5 text-left text-sm font-medium text-gray-700 hover:bg-gray-100"
|
||||
>
|
||||
{isExpanded ? <ChevronDown className="h-4 w-4" /> : <ChevronRight className="h-4 w-4" />}
|
||||
<span>{category.icon}</span>
|
||||
<span>{category.label}</span>
|
||||
<span className="ml-auto text-xs text-gray-400">{nodes.length}</span>
|
||||
</button>
|
||||
@@ -89,13 +90,8 @@ function NodePaletteItemComponent({ node }: { node: NodePaletteItem }) {
|
||||
title={node.description}
|
||||
>
|
||||
<div className="flex items-start gap-2">
|
||||
{/* 아이콘 */}
|
||||
<div
|
||||
className="flex h-8 w-8 flex-shrink-0 items-center justify-center rounded text-lg"
|
||||
style={{ backgroundColor: `${node.color}20` }}
|
||||
>
|
||||
{node.icon}
|
||||
</div>
|
||||
{/* 색상 인디케이터 (좌측) */}
|
||||
<div className="h-8 w-1 flex-shrink-0 rounded" style={{ backgroundColor: node.color }} />
|
||||
|
||||
{/* 라벨 및 설명 */}
|
||||
<div className="min-w-0 flex-1">
|
||||
@@ -104,7 +100,7 @@ function NodePaletteItemComponent({ node }: { node: NodePaletteItem }) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 색상 인디케이터 */}
|
||||
{/* 하단 색상 인디케이터 (hover 시) */}
|
||||
<div
|
||||
className="mt-2 h-1 w-full rounded-full opacity-0 transition-opacity group-hover:opacity-100"
|
||||
style={{ backgroundColor: node.color }}
|
||||
|
||||
@@ -11,7 +11,7 @@ export const NODE_PALETTE: NodePaletteItem[] = [
|
||||
{
|
||||
type: "tableSource",
|
||||
label: "테이블",
|
||||
icon: "📊",
|
||||
icon: "",
|
||||
description: "내부 데이터베이스 테이블에서 데이터를 읽어옵니다",
|
||||
category: "source",
|
||||
color: "#3B82F6", // 파란색
|
||||
@@ -19,7 +19,7 @@ export const NODE_PALETTE: NodePaletteItem[] = [
|
||||
{
|
||||
type: "externalDBSource",
|
||||
label: "외부 DB",
|
||||
icon: "🔌",
|
||||
icon: "",
|
||||
description: "외부 데이터베이스에서 데이터를 읽어옵니다",
|
||||
category: "source",
|
||||
color: "#F59E0B", // 주황색
|
||||
@@ -27,7 +27,7 @@ export const NODE_PALETTE: NodePaletteItem[] = [
|
||||
{
|
||||
type: "restAPISource",
|
||||
label: "REST API",
|
||||
icon: "📁",
|
||||
icon: "",
|
||||
description: "REST API를 호출하여 데이터를 가져옵니다",
|
||||
category: "source",
|
||||
color: "#10B981", // 초록색
|
||||
@@ -35,7 +35,7 @@ export const NODE_PALETTE: NodePaletteItem[] = [
|
||||
{
|
||||
type: "referenceLookup",
|
||||
label: "참조 조회",
|
||||
icon: "🔗",
|
||||
icon: "",
|
||||
description: "다른 테이블에서 데이터를 조회합니다 (내부 DB 전용)",
|
||||
category: "source",
|
||||
color: "#A855F7", // 보라색
|
||||
@@ -47,7 +47,7 @@ export const NODE_PALETTE: NodePaletteItem[] = [
|
||||
{
|
||||
type: "condition",
|
||||
label: "조건 분기",
|
||||
icon: "⚡",
|
||||
icon: "",
|
||||
description: "조건에 따라 데이터 흐름을 분기합니다",
|
||||
category: "transform",
|
||||
color: "#EAB308", // 노란색
|
||||
@@ -55,7 +55,7 @@ export const NODE_PALETTE: NodePaletteItem[] = [
|
||||
{
|
||||
type: "dataTransform",
|
||||
label: "데이터 변환",
|
||||
icon: "🔧",
|
||||
icon: "",
|
||||
description: "데이터를 변환하거나 가공합니다",
|
||||
category: "transform",
|
||||
color: "#06B6D4", // 청록색
|
||||
@@ -67,7 +67,7 @@ export const NODE_PALETTE: NodePaletteItem[] = [
|
||||
{
|
||||
type: "insertAction",
|
||||
label: "INSERT",
|
||||
icon: "➕",
|
||||
icon: "",
|
||||
description: "데이터를 삽입합니다",
|
||||
category: "action",
|
||||
color: "#22C55E", // 초록색
|
||||
@@ -75,7 +75,7 @@ export const NODE_PALETTE: NodePaletteItem[] = [
|
||||
{
|
||||
type: "updateAction",
|
||||
label: "UPDATE",
|
||||
icon: "✏️",
|
||||
icon: "",
|
||||
description: "데이터를 수정합니다",
|
||||
category: "action",
|
||||
color: "#3B82F6", // 파란색
|
||||
@@ -83,7 +83,7 @@ export const NODE_PALETTE: NodePaletteItem[] = [
|
||||
{
|
||||
type: "deleteAction",
|
||||
label: "DELETE",
|
||||
icon: "❌",
|
||||
icon: "",
|
||||
description: "데이터를 삭제합니다",
|
||||
category: "action",
|
||||
color: "#EF4444", // 빨간색
|
||||
@@ -91,7 +91,7 @@ export const NODE_PALETTE: NodePaletteItem[] = [
|
||||
{
|
||||
type: "upsertAction",
|
||||
label: "UPSERT",
|
||||
icon: "🔄",
|
||||
icon: "",
|
||||
description: "데이터를 삽입하거나 수정합니다",
|
||||
category: "action",
|
||||
color: "#8B5CF6", // 보라색
|
||||
@@ -103,7 +103,7 @@ export const NODE_PALETTE: NodePaletteItem[] = [
|
||||
{
|
||||
type: "comment",
|
||||
label: "주석",
|
||||
icon: "💬",
|
||||
icon: "",
|
||||
description: "주석을 추가합니다",
|
||||
category: "utility",
|
||||
color: "#6B7280", // 회색
|
||||
@@ -111,7 +111,7 @@ export const NODE_PALETTE: NodePaletteItem[] = [
|
||||
{
|
||||
type: "log",
|
||||
label: "로그",
|
||||
icon: "🔍",
|
||||
icon: "",
|
||||
description: "로그를 출력합니다",
|
||||
category: "utility",
|
||||
color: "#6B7280", // 회색
|
||||
@@ -122,22 +122,22 @@ export const NODE_CATEGORIES = [
|
||||
{
|
||||
id: "source",
|
||||
label: "데이터 소스",
|
||||
icon: "📂",
|
||||
icon: "",
|
||||
},
|
||||
{
|
||||
id: "transform",
|
||||
label: "변환/조건",
|
||||
icon: "🔀",
|
||||
icon: "",
|
||||
},
|
||||
{
|
||||
id: "action",
|
||||
label: "액션",
|
||||
icon: "⚡",
|
||||
icon: "",
|
||||
},
|
||||
{
|
||||
id: "utility",
|
||||
label: "유틸리티",
|
||||
icon: "🛠️",
|
||||
icon: "",
|
||||
},
|
||||
] as const;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user