From f071777131268e4549ae75d15b6904d416b584e0 Mon Sep 17 00:00:00 2001 From: DDD1542 Date: Wed, 11 Mar 2026 14:50:02 +0900 Subject: [PATCH] [agent-pipeline] pipe-20260311052455-y968 round-4 --- .../components/common/ConfigPanelBuilder.tsx | 171 ++++++++++++------ .../components/common/ConfigPanelTypes.ts | 3 + 2 files changed, 123 insertions(+), 51 deletions(-) diff --git a/frontend/lib/registry/components/common/ConfigPanelBuilder.tsx b/frontend/lib/registry/components/common/ConfigPanelBuilder.tsx index 5e7509f1..ba921b06 100644 --- a/frontend/lib/registry/components/common/ConfigPanelBuilder.tsx +++ b/frontend/lib/registry/components/common/ConfigPanelBuilder.tsx @@ -1,75 +1,144 @@ "use client"; import React from "react"; -import { ConfigPanelBuilderProps } from "./ConfigPanelTypes"; +import { ConfigPanelBuilderProps, ConfigSectionDefinition } from "./ConfigPanelTypes"; import { ConfigSection } from "./ConfigSection"; import { ConfigField } from "./ConfigField"; +import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"; + +function renderSections>( + sections: ConfigSectionDefinition[], + config: T, + onChange: (key: string, value: any) => void, + tableColumns?: any[], +) { + return sections.map((section) => { + if (section.condition && !section.condition(config)) { + return null; + } + + const visibleFields = section.fields.filter( + (field) => !field.condition || field.condition(config), + ); + + if (visibleFields.length === 0) { + return null; + } + + return ( + + {visibleFields.map((field) => ( + + ))} + + ); + }); +} export function ConfigPanelBuilder>({ config, onChange, + onConfigChange, sections, presets, tableColumns, children, + mode = "flat", + context, }: ConfigPanelBuilderProps) { - return ( -
- {/* 프리셋 버튼 */} - {presets && presets.length > 0 && ( -
-

- 빠른 설정 -

-
- {presets.map((preset, idx) => ( - - ))} -
+ const effectiveTableColumns = tableColumns || context?.tableColumns; + + const presetSection = presets && presets.length > 0 && ( +
+

+ 빠른 설정 +

+
+ {presets.map((preset, idx) => ( + + ))} +
+
+ ); + + if (mode === "tabs") { + const groupMap = new Map[]>(); + const ungrouped: ConfigSectionDefinition[] = []; + + for (const section of sections) { + if (section.group) { + const existing = groupMap.get(section.group) || []; + existing.push(section); + groupMap.set(section.group, existing); + } else { + ungrouped.push(section); + } + } + + const tabGroups = Array.from(groupMap.entries()); + + if (tabGroups.length === 0) { + return ( +
+ {presetSection} + {renderSections(sections, config, onChange, effectiveTableColumns)} + {children}
- )} + ); + } - {/* 섹션 렌더링 */} - {sections.map((section) => { - if (section.condition && !section.condition(config)) { - return null; - } + const defaultTab = tabGroups[0]?.[0] || "general"; - const visibleFields = section.fields.filter( - (field) => !field.condition || field.condition(config), - ); + return ( +
+ {presetSection} - if (visibleFields.length === 0) { - return null; - } + {ungrouped.length > 0 && renderSections(ungrouped, config, onChange, effectiveTableColumns)} - return ( - - {visibleFields.map((field) => ( - + + + {tabGroups.map(([groupName]) => ( + + {groupName} + ))} - - ); - })} + + {tabGroups.map(([groupName, groupSections]) => ( + + {renderSections(groupSections, config, onChange, effectiveTableColumns)} + + ))} + - {/* 커스텀 children */} + {children} +
+ ); + } + + return ( +
+ {presetSection} + {renderSections(sections, config, onChange, effectiveTableColumns)} {children}
); diff --git a/frontend/lib/registry/components/common/ConfigPanelTypes.ts b/frontend/lib/registry/components/common/ConfigPanelTypes.ts index 3a23f537..15179583 100644 --- a/frontend/lib/registry/components/common/ConfigPanelTypes.ts +++ b/frontend/lib/registry/components/common/ConfigPanelTypes.ts @@ -48,6 +48,7 @@ export interface ConfigSectionDefinition { export interface ConfigPanelBuilderProps { config: T; onChange: (key: string, value: any) => void; + onConfigChange?: (config: Record) => void; sections: ConfigSectionDefinition[]; presets?: Array<{ label: string; @@ -56,6 +57,8 @@ export interface ConfigPanelBuilderProps { }>; tableColumns?: ConfigOption[]; children?: React.ReactNode; + mode?: "flat" | "tabs"; + context?: ConfigPanelContext; } /**