feat: move pipeline nodes into model toolbar

This commit is contained in:
jerryW123
2026-05-11 22:17:58 +08:00
parent 0bb7b46360
commit 5b4c973812
+36 -23
View File
@@ -170,6 +170,7 @@ const OmniEditor: React.FC = () => {
const [dragState, setDragState] = useState<{ id: string; startX: number; startY: number; nodeX: number; nodeY: number } | null>(null);
const [bottomTab, setBottomTab] = useState<'agents' | 'variables' | 'sensing' | 'internalModels' | 'schedule' | 'data' | 'io' | 'validation'>('variables');
const [isDetailOpen, setIsDetailOpen] = useState(false);
const [isPipelineMenuOpen, setIsPipelineMenuOpen] = useState(false);
const [showInitModal, setShowInitModal] = useState(!!location.state?.fromLanding);
const [selectedSpaceType, setSelectedSpaceType] = useState<InitialSpaceType>('grid');
const [canvasSize, setCanvasSize] = useState({ width: 0, height: 0 });
@@ -575,28 +576,6 @@ const OmniEditor: React.FC = () => {
: '当前默认收起 AI:先把右侧图形化模型编辑器作为主工作区。'}
</p>
</div>
<div className="p-3 rounded-lg bg-white border border-slate-200 shadow-sm">
<div className="text-[10px] font-black uppercase tracking-widest text-slate-400 mb-3">Pipeline Nodes</div>
<div className="grid grid-cols-2 gap-2">
{[
['Data Source', Database, 'Excel / raw data entry'],
['Parameter Table', Table2, 'Model-ready parameters'],
['Validation', CheckCircle, 'Rules and checks'],
['Model Output', Layers3, 'Simulation outputs'],
].map(([label, Icon, desc]) => (
<button
key={label as string}
onClick={() => handleAction(label as string)}
className="text-left p-3 rounded-lg border border-slate-200 bg-slate-50 hover:bg-white hover:border-blue-200 transition-all"
title={desc as string}
>
<Icon className="w-4 h-4 text-blue-600 mb-2" />
<div className="text-[11px] font-black text-slate-800">{label as string}</div>
<div className="text-[10px] text-slate-400 mt-1 leading-snug">{desc as string}</div>
</button>
))}
</div>
</div>
{messages.map((msg, index) => (
<div key={`${msg.role}-${index}`} className={`flex flex-col gap-1 ${msg.role === 'user' ? 'items-end' : ''}`}>
<span className="text-[10px] text-slate-400 font-black uppercase tracking-wider">
@@ -649,10 +628,44 @@ const OmniEditor: React.FC = () => {
</span>
<div>
<span className="block text-[10px] font-black uppercase tracking-[0.2em] text-slate-500">Model Subjects</span>
<span className="block text-[10px] text-slate-400">Environment, space, agents, observation and behaviors</span>
</div>
</div>
<div className="flex items-center gap-2">
<div className="relative">
<button
onClick={() => setIsPipelineMenuOpen((open) => !open)}
className="px-3 py-1.5 bg-white hover:bg-slate-50 text-blue-600 text-[10px] font-black rounded-md border border-slate-200 shadow-sm transition-all uppercase flex items-center gap-2"
>
<Workflow className="w-3.5 h-3.5" /> Pipeline Nodes
<ChevronDown className={`w-3.5 h-3.5 text-slate-400 transition-transform ${isPipelineMenuOpen ? 'rotate-180' : ''}`} />
</button>
{isPipelineMenuOpen && (
<div className="absolute right-0 top-10 z-30 w-64 rounded-lg border border-slate-200 bg-white p-2 shadow-xl">
{[
['Data Source', Database, 'Excel / raw data entry'],
['Parameter Table', Table2, 'Model-ready parameters'],
['Validation', CheckCircle, 'Rules and checks'],
['Model Output', Layers3, 'Simulation outputs'],
].map(([label, Icon, desc]) => (
<button
key={label as string}
onClick={() => {
setIsPipelineMenuOpen(false);
handleAction(label as string);
}}
className="w-full text-left p-3 rounded-md hover:bg-blue-50 transition-colors flex items-start gap-3"
title={desc as string}
>
<Icon className="w-4 h-4 text-blue-600 mt-0.5 shrink-0" />
<span>
<span className="block text-[12px] font-black text-slate-900">{label as string}</span>
<span className="block text-[11px] text-slate-400 mt-1 leading-snug">{desc as string}</span>
</span>
</button>
))}
</div>
)}
</div>
<button
onClick={() => setSelectedNodeId('grid-space')}
className="px-3 py-1.5 bg-white hover:bg-slate-50 text-emerald-600 text-[10px] font-black rounded-md border border-slate-200 shadow-sm transition-all uppercase flex items-center gap-2"