feat(web): iteration add output_type ;
docs(web): add comments
This commit is contained in:
@@ -1,18 +1,36 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 15:40:13
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 15:40:13
|
||||
*/
|
||||
import { type FC } from 'react'
|
||||
import clsx from 'clsx';
|
||||
import { Select, type SelectProps } from 'antd'
|
||||
import type { Suggestion } from '../Editor/plugin/AutocompletePlugin'
|
||||
type LabelRender = SelectProps['labelRender'];
|
||||
|
||||
/**
|
||||
* Props for VariableSelect component
|
||||
*/
|
||||
interface VariableSelectProps extends SelectProps {
|
||||
/** Available variable options */
|
||||
options: Suggestion[];
|
||||
/** Current selected value */
|
||||
value?: string;
|
||||
onChange?: (value: string) => void;
|
||||
/** Whether to show clear button */
|
||||
allowClear?: boolean;
|
||||
/** Filter out boolean type variables */
|
||||
filterBooleanType?: boolean;
|
||||
/** Size of the select component */
|
||||
size?: 'small' | 'middle' | 'large'
|
||||
}
|
||||
|
||||
/**
|
||||
* VariableSelect component
|
||||
* Custom select component for workflow variables with grouped options and custom rendering
|
||||
* @param props - Component props
|
||||
*/
|
||||
const VariableSelect: FC<VariableSelectProps> = ({
|
||||
placeholder,
|
||||
options,
|
||||
@@ -24,9 +42,19 @@ const VariableSelect: FC<VariableSelectProps> = ({
|
||||
...resetPorps
|
||||
}) => {
|
||||
|
||||
const handleChange = (value: string) => {
|
||||
onChange?.(value);
|
||||
/**
|
||||
* Handle value change and pass selected option to parent
|
||||
* @param value - Selected value
|
||||
*/
|
||||
const handleChange: SelectProps['onChange'] = (value: string) => {
|
||||
const filterItem = options.find(option => `{{${option.value}}}` === value)
|
||||
onChange?.(value, filterItem);
|
||||
}
|
||||
/**
|
||||
* Custom label renderer for selected value
|
||||
* Displays node icon, name and variable label
|
||||
* @param props - Label render props
|
||||
*/
|
||||
const labelRender: LabelRender = (props) => {
|
||||
const { value } = props
|
||||
const filterOption = filteredOptions.find(vo => `{{${vo.value}}}` === value)
|
||||
@@ -57,10 +85,14 @@ const VariableSelect: FC<VariableSelectProps> = ({
|
||||
}
|
||||
return null
|
||||
}
|
||||
// Filter options based on boolean type if needed
|
||||
const filteredOptions = filterBooleanType
|
||||
? options.filter(option => option.dataType !== 'boolean')
|
||||
: options;
|
||||
|
||||
/**
|
||||
* Group suggestions by node ID
|
||||
*/
|
||||
const groupedSuggestions = filteredOptions.reduce((groups: Record<string, any[]>, suggestion) => {
|
||||
const { nodeData } = suggestion
|
||||
const nodeId = nodeData.id as string;
|
||||
@@ -71,6 +103,9 @@ const VariableSelect: FC<VariableSelectProps> = ({
|
||||
return groups;
|
||||
}, {});
|
||||
|
||||
/**
|
||||
* Format grouped options for Select component
|
||||
*/
|
||||
const groupedOptions = Object.entries(groupedSuggestions).map(([_nodeId, suggestions]) => ({
|
||||
label: suggestions[0].nodeData.name,
|
||||
options: suggestions.map(s => ({
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 15:39:59
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 15:39:59
|
||||
*/
|
||||
import { type FC, useEffect, useState, useMemo } from "react";
|
||||
import clsx from 'clsx'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@@ -31,17 +37,35 @@ import RbSlider from './RbSlider'
|
||||
import JinjaRender from './JinjaRender'
|
||||
import CodeExecution from './CodeExecution'
|
||||
|
||||
/**
|
||||
* Props for Properties component
|
||||
*/
|
||||
interface PropertiesProps {
|
||||
/** Currently selected node */
|
||||
selectedNode?: Node | null;
|
||||
/** Function to update selected node */
|
||||
setSelectedNode: (node: Node | null) => void;
|
||||
/** Reference to graph instance */
|
||||
graphRef: React.MutableRefObject<Graph | undefined>;
|
||||
/** Handler for blank canvas click */
|
||||
blankClick: () => void;
|
||||
/** Handler for delete event */
|
||||
deleteEvent: () => void;
|
||||
/** Handler for copy event */
|
||||
copyEvent: () => void;
|
||||
/** Handler for paste event */
|
||||
parseEvent: () => void;
|
||||
/** Workflow configuration */
|
||||
config?: any;
|
||||
/** Chat variables */
|
||||
chatVariables: ChatVariable[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Properties panel component
|
||||
* Displays and manages configuration for selected workflow node
|
||||
* @param props - Component props
|
||||
*/
|
||||
const Properties: FC<PropertiesProps> = ({
|
||||
selectedNode,
|
||||
graphRef,
|
||||
@@ -83,6 +107,10 @@ const Properties: FC<PropertiesProps> = ({
|
||||
}
|
||||
}, [selectedNode, form])
|
||||
|
||||
/**
|
||||
* Update node label in graph
|
||||
* @param newLabel - New label text
|
||||
*/
|
||||
const updateNodeLabel = (newLabel: string) => {
|
||||
if (selectedNode && form) {
|
||||
const nodeData = selectedNode.data as NodeProperties;
|
||||
@@ -107,8 +135,6 @@ const Properties: FC<PropertiesProps> = ({
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
|
||||
Object.keys(values).forEach(key => {
|
||||
if (selectedNode.data?.config?.[key]) {
|
||||
// Create a deep copy to avoid reference sharing between nodes
|
||||
@@ -131,7 +157,12 @@ const Properties: FC<PropertiesProps> = ({
|
||||
|
||||
|
||||
|
||||
// Filter out boolean type variables for loop and llm nodes
|
||||
/**
|
||||
* Get filtered variable list based on node type and config key
|
||||
* @param nodeType - Type of the node
|
||||
* @param key - Configuration key
|
||||
* @returns Filtered variable list
|
||||
*/
|
||||
const getFilteredVariableList = (nodeType?: string, key?: string) => {
|
||||
// Check if current node is a child of iteration node
|
||||
const parentIterationNode = selectedNode ? (() => {
|
||||
@@ -321,15 +352,33 @@ const Properties: FC<PropertiesProps> = ({
|
||||
|
||||
console.log('values', values)
|
||||
|
||||
/**
|
||||
* Get current node output variables
|
||||
*/
|
||||
const currentNodeVariables = useMemo(() => {
|
||||
if (!selectedNode) return []
|
||||
return getCurrentNodeVariables(selectedNode?.getData(), values)
|
||||
}, [selectedNode?.getData(), values])
|
||||
|
||||
const [outputCollapsed, setOutputCollapsed] = useState(true)
|
||||
/**
|
||||
* Toggle output section collapsed state
|
||||
*/
|
||||
const handleToggle = () => {
|
||||
setOutputCollapsed((prev: boolean) => !prev)
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle variable list change and update output type for iteration nodes
|
||||
* @param _value - Selected value
|
||||
* @param option - Selected option
|
||||
* @param key - Configuration key
|
||||
*/
|
||||
const handleChangeVariableList = (_value: string, option: any, key: string) => {
|
||||
if (selectedNode?.data?.type === 'iteration' && key === 'output') {
|
||||
form.setFieldValue('output_type', option?.dataType)
|
||||
}
|
||||
}
|
||||
console.log('variableList', variableList, currentNodeVariables)
|
||||
|
||||
return (
|
||||
@@ -422,6 +471,9 @@ const Properties: FC<PropertiesProps> = ({
|
||||
</Form.Item>
|
||||
)
|
||||
}
|
||||
if (selectedNode?.data?.type === 'iteration' && key === 'output_type') {
|
||||
return (<Form.Item key={key} name={key} hidden />)
|
||||
}
|
||||
if (config.type === 'define') {
|
||||
return null
|
||||
}
|
||||
@@ -628,8 +680,8 @@ const Properties: FC<PropertiesProps> = ({
|
||||
);
|
||||
}
|
||||
return baseVariableList;
|
||||
})()
|
||||
}
|
||||
})()}
|
||||
onChange={(value, option) => handleChangeVariableList(value, option, key)}
|
||||
size="small"
|
||||
/>
|
||||
: config.type === 'switch'
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 15:06:18
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 15:10:19
|
||||
* @Last Modified time: 2026-02-03 15:25:25
|
||||
*/
|
||||
import LoopNode from './components/Nodes/LoopNode';
|
||||
import NormalNode from './components/Nodes/NormalNode';
|
||||
@@ -317,6 +317,9 @@ export const nodeLibrary: NodeLibrary[] = [
|
||||
output: {
|
||||
type: 'variableList',
|
||||
filterChildNodes: true
|
||||
},
|
||||
output_type: {
|
||||
type: 'define',
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user