148 lines
4.4 KiB
TypeScript
148 lines
4.4 KiB
TypeScript
import { forwardRef, useRef, useImperativeHandle, useState } from 'react';
|
|
import clsx from 'clsx';
|
|
|
|
import NodeLibrary from './components/NodeLibrary'
|
|
import Properties from './components/Properties';
|
|
import CanvasToolbar from './components/CanvasToolbar';
|
|
import PortClickHandler from './components/PortClickHandler';
|
|
import { useWorkflowGraph } from './hooks/useWorkflowGraph';
|
|
import type { WorkflowRef, FeaturesConfigForm, FeaturesConfigModalRef } from '@/views/ApplicationConfig/types'
|
|
import Chat from './components/Chat/Chat';
|
|
import type { ChatRef, AddChatVariableRef } from './types'
|
|
import AddChatVariable from './components/AddChatVariable';
|
|
import FeaturesConfigModal from '@/views/ApplicationConfig/components/FeaturesConfig/FeaturesConfigModal'
|
|
|
|
const Workflow = forwardRef<WorkflowRef, { onFeaturesLoad?: (features: FeaturesConfigForm | undefined) => void }>(({ onFeaturesLoad }, ref) => {
|
|
const containerRef = useRef<HTMLDivElement>(null);
|
|
const miniMapRef = useRef<HTMLDivElement>(null);
|
|
const addChatVariableRef = useRef<AddChatVariableRef>(null)
|
|
const chatRef = useRef<ChatRef>(null)
|
|
const [collapsed, setCollapsed] = useState(false)
|
|
// 使用自定义Hook初始化工作流图
|
|
const {
|
|
config,
|
|
graphRef,
|
|
selectedNode,
|
|
zoomLevel,
|
|
isHandMode,
|
|
setIsHandMode,
|
|
onDrop,
|
|
blankClick,
|
|
nodeClick,
|
|
deleteEvent,
|
|
copyEvent,
|
|
parseEvent,
|
|
handleSave,
|
|
chatVariables,
|
|
setChatVariables,
|
|
handleAddNotes,
|
|
handleSaveFeaturesConfig,
|
|
features,
|
|
getStartNodeVariables,
|
|
canUndo,
|
|
canRedo,
|
|
undo,
|
|
redo,
|
|
} = useWorkflowGraph({ containerRef, miniMapRef, onFeaturesLoad });
|
|
|
|
const onDragOver = (event: React.DragEvent) => {
|
|
event.preventDefault();
|
|
};
|
|
const handleRun = () => {
|
|
chatRef.current?.handleOpen()
|
|
}
|
|
const handleToggle = () => {
|
|
setCollapsed(prev => !prev)
|
|
}
|
|
const addVariable = () => {
|
|
addChatVariableRef.current?.handleOpen()
|
|
}
|
|
|
|
// Ref used to imperatively open the config modal
|
|
const funConfigModalRef = useRef<FeaturesConfigModalRef>(null)
|
|
|
|
/** Open the feature config modal pre-populated with the current values */
|
|
const handleFeaturesConfig = () => {
|
|
blankClick()
|
|
funConfigModalRef.current?.handleOpen(features as FeaturesConfigForm)
|
|
}
|
|
|
|
useImperativeHandle(ref, () => ({
|
|
handleSave,
|
|
handleRun,
|
|
graphRef,
|
|
addVariable,
|
|
chatVariables,
|
|
config,
|
|
features: features,
|
|
handleFeaturesConfig,
|
|
handleSaveFeaturesConfig,
|
|
nodeClick
|
|
}))
|
|
return (
|
|
<div className="rb:h-full rb:relative">
|
|
{/* 左侧节点面板 */}
|
|
<NodeLibrary collapsed={collapsed} handleToggle={handleToggle} />
|
|
|
|
{/* 右侧画布区域 */}
|
|
<div
|
|
className={clsx(`rb:fixed rb:top-16 rb:bottom-0 rb:left-0 rb:right-0 rb:transition-all`)}
|
|
onDrop={onDrop}
|
|
onDragOver={onDragOver}
|
|
>
|
|
<div ref={containerRef} className="rb:w-full rb:h-full" />
|
|
{/* 地图工具栏 */}
|
|
<CanvasToolbar
|
|
selectedNode={selectedNode}
|
|
miniMapRef={miniMapRef}
|
|
graphRef={graphRef}
|
|
isHandMode={isHandMode}
|
|
setIsHandMode={setIsHandMode}
|
|
zoomLevel={zoomLevel}
|
|
addNotes={handleAddNotes}
|
|
canUndo={canUndo}
|
|
canRedo={canRedo}
|
|
onUndo={undo}
|
|
onRedo={redo}
|
|
/>
|
|
</div>
|
|
|
|
{/* 右侧属性面板 */}
|
|
{selectedNode &&
|
|
<Properties
|
|
selectedNode={selectedNode}
|
|
graphRef={graphRef}
|
|
blankClick={blankClick}
|
|
deleteEvent={deleteEvent}
|
|
copyEvent={copyEvent}
|
|
parseEvent={parseEvent}
|
|
config={config}
|
|
chatVariables={chatVariables}
|
|
/>
|
|
}
|
|
<Chat
|
|
ref={chatRef}
|
|
data={config}
|
|
features={features}
|
|
graphRef={graphRef}
|
|
appId={config?.app_id as string}
|
|
/>
|
|
<PortClickHandler graph={graphRef.current} />
|
|
|
|
<AddChatVariable
|
|
ref={addChatVariableRef}
|
|
variables={chatVariables}
|
|
onChange={setChatVariables}
|
|
/>
|
|
{/* Modal for editing feature settings; calls refresh on save */}
|
|
<FeaturesConfigModal
|
|
ref={funConfigModalRef}
|
|
refresh={handleSaveFeaturesConfig}
|
|
source="workflow"
|
|
chatVariables={getStartNodeVariables().map(v => ({ name: v.name, key: `start_${v.name}`, label: v.name, type: 'variable', dataType: v.type, value:`{{${v.name}}}` })) as any}
|
|
/>
|
|
</div>
|
|
);
|
|
});
|
|
|
|
export default Workflow; |