분할 패널 및 반복 필드 그룹 컴포넌트

This commit is contained in:
kjs
2025-10-16 15:05:24 +09:00
parent 716cfcb2cf
commit a0dde51109
26 changed files with 1899 additions and 753 deletions

View File

@@ -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 }}

View File

@@ -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;