fix(web): list-operator output variable type

This commit is contained in:
zhaoying
2026-04-07 20:34:10 +08:00
parent 08b4d5c1cf
commit b8825a83dd
5 changed files with 36 additions and 25 deletions

View File

@@ -2,7 +2,7 @@
* @Author: ZhaoYing
* @Date: 2026-03-13 17:27:52
* @Last Modified by: ZhaoYing
* @Last Modified time: 2026-04-07 18:08:18
* @Last Modified time: 2026-04-07 20:25:45
*/
import { type FC, useState, useRef, useEffect } from 'react'
import { useTranslation } from 'react-i18next'
@@ -109,7 +109,7 @@ const TestChat: FC<TestChatProps> = ({
setFeatures(config?.features || {} as FeaturesConfigForm)
if (config?.features?.opening_statement.enabled && config?.features?.opening_statement?.statement && config?.features?.opening_statement?.statement.trim() !== '') {
if (config?.features?.opening_statement?.enabled && config?.features?.opening_statement?.statement && config?.features?.opening_statement?.statement.trim() !== '') {
setChatList(prev => [...prev, {
role: 'assistant',
created_at: Date.now(),

View File

@@ -2,7 +2,7 @@
* @Author: ZhaoYing
* @Date: 2026-02-03 15:40:13
* @Last Modified by: ZhaoYing
* @Last Modified time: 2026-04-03 20:19:34
* @Last Modified time: 2026-04-07 19:40:27
*/
import { useState, useRef, useEffect, useLayoutEffect, type FC } from 'react'
import { createPortal } from 'react-dom'
@@ -232,15 +232,16 @@ const VariableSelect: FC<VariableSelectProps> = ({
<span className="rb:text-[#bfbfbf] rb:flex-1 rb:text-[12px]">{placeholder}</span>
)
) : selectedSuggestion ? (
<span className="rb:flex rb:flex-1 rb:min-w-0">
<span className="rb:inline-flex rb:items-center rb:gap-0.5 rb:bg-[#f0f8ff] rb:rounded rb:px-1 rb:py-0.5 rb:text-[11px] rb:max-w-full">
<div className="rb:flex rb:flex-1 rb:min-w-0 rb:max-w-full">
<span className="rb:inline-flex rb:items-center rb:gap-0.5 rb:bg-[#f0f8ff] rb:rounded rb:px-1 rb:py-0.5 rb:text-[11px] rb:max-w-full rb:overflow-hidden">
{!isConversation && nodeData?.icon && <div className={`rb:size-3 rb:shrink-0 rb:bg-cover ${nodeData.icon}`} />}
{!isConversation && nodeData?.name && <span className="rb:text-[#5B6167]">{nodeData.name}{sep}</span>}
<span className="rb:text-[#171719]">
{!isConversation && nodeData?.name && <span className="rb:text-[#5B6167] rb:shrink rb:min-w-0 rb:truncate rb:max-w-[40%]">{nodeData.name}</span>}
{!isConversation && nodeData?.name && <span className="rb:text-[#5B6167]">{sep}</span>}
<span className="rb:text-[#171719] rb:shrink rb:min-w-0 rb:truncate">
{parentOfSelected ? <>{parentOfSelected.label}{sep}{selectedSuggestion.label}</> : selectedSuggestion.label}
</span>
</span>
</span>
</div>
) : (
<span className="rb:text-[#bfbfbf] rb:flex-1">{placeholder}</span>
)}
@@ -264,7 +265,7 @@ const VariableSelect: FC<VariableSelectProps> = ({
{open && createPortal(
<div
ref={dropdownRef}
className="rb:fixed rb:z-9999 rb:bg-white rb:text-[14px] rb:rounded-xl rb:shadow-[0px_2px_12px_0px_rgba(23,23,25,0.12)]"
className="rb:fixed rb:z-9999 rb:bg-white rb:text-[14px] rb:rounded-lg rb:shadow-[0px_2px_12px_0px_rgba(23,23,25,0.12)] rb:p-1"
style={{ top: dropdownPos.top, left: dropdownPos.left, minWidth: dropdownPos.width }}
>
<div className="rb:min-w-70 rb:max-h-60 rb:overflow-y-auto rb:py-1">
@@ -272,8 +273,8 @@ const VariableSelect: FC<VariableSelectProps> = ({
const nd = suggestions[0].nodeData;
return (
<div key={nodeId}>
<Flex align="center" gap={4} className="rb:px-3! rb:py-1.25! rb:text-[12px] rb:font-medium rb:text-[#5B6167]">
{nd.icon && <div className={`rb:size-3 rb:bg-cover ${nd.icon}`} />}
<Flex align="center" gap={4} className="rb:px-3! rb:py-1.25! rb:text-[12px] rb:text-[#5B6167]">
{nd.icon && <div className={`rb:size-4 rb:bg-cover ${nd.icon}`} />}
{nd.name}
</Flex>
{suggestions.map(s => {
@@ -286,14 +287,15 @@ const VariableSelect: FC<VariableSelectProps> = ({
<Flex
key={s.key}
ref={(el) => { if (el) itemRefs.current.set(s.key, el); }}
className="rb:mx-3! rb:pl-3! rb:pr-3! rb:py-1.5! rb:rounded-lg!"
className={clsx("rb:pl-6! rb:pr-3! rb:py-1.25! rb:rounded-lg!", {
'rb:bg-[#e6f4ff]': isSelected || isExpanded,
'rb:bg-white rb:hover:bg-[#F6F6F6]!': !(isSelected || isExpanded),
'rb:opacity-60': s.disabled,
'rb:cursor-not-allowed': s.disabled,
'rb:cursor-pointer': !s.disabled,
})}
align="center"
justify="space-between"
style={{
cursor: s.disabled ? 'not-allowed' : 'pointer',
background: isSelected || isExpanded ? '#f0f8ff' : 'white',
opacity: s.disabled ? 0.5 : 1,
}}
onClick={() => {
if (s.disabled) return;
if (hasChildren) {

View File

@@ -2,7 +2,7 @@
* @Author: ZhaoYing
* @Date: 2026-01-19 17:00:26
* @Last Modified by: ZhaoYing
* @Last Modified time: 2026-04-02 16:58:40
* @Last Modified time: 2026-04-07 20:33:26
*/
/**
* useVariableList Hook
@@ -125,7 +125,7 @@ const processNodeVariables = (
if (type in NODE_VARIABLES) {
if (type === 'list-operator') {
// Determine output type from the first variable in config
const variableValue = config?.variable;
const variableValue = config?.input_list?.defaultValue;
let itemType = 'string';
if (variableValue) {
const refVar = variableList.find(v => `{{${v.value}}}` === variableValue);
@@ -321,7 +321,6 @@ export const getChildNodeVariables = (
if (p?.name) addVariable(list, keys, `${nodeId}_${p.name}`, p.name, p.type || 'string', `${nodeId}.${p.name}`, nodeData);
});
}
// Add code node variables
if (type === 'code') {
(nodeData.config?.output_variables?.defaultValue || []).forEach((p: any) => {
@@ -393,8 +392,18 @@ export const useVariableList = (
// Add chat variables
chatVariables?.forEach(v => addVariable(list, keys, `CONVERSATION_${v.name}`, v.name, v.type, `conv.${v.name}`, { type: 'CONVERSATION', name: 'CONVERSATION', icon: '' }, { group: 'CONVERSATION' }));
// Process each relevant node
// Process each relevant node: non-list-operator first, then list-operator
const listOperatorIds: string[] = [];
relevantIds.forEach(id => {
const node = nodes.find(n => n.id === id);
if (!node) return;
if (node.getData()?.type === 'list-operator') {
listOperatorIds.push(id);
} else {
processNodeVariables(node.getData(), node.getData().id, list, keys);
}
});
listOperatorIds.forEach(id => {
const node = nodes.find(n => n.id === id);
if (node) processNodeVariables(node.getData(), node.getData().id, list, keys);
});

View File

@@ -2,7 +2,7 @@
* @Author: ZhaoYing
* @Date: 2026-02-03 15:06:18
* @Last Modified by: ZhaoYing
* @Last Modified time: 2026-04-03 20:28:08
* @Last Modified time: 2026-04-07 19:56:56
*/
import LoopNode from './components/Nodes/LoopNode';
import NormalNode from './components/Nodes/NormalNode';
@@ -579,7 +579,7 @@ export const noteNode = {
export const nodeWidth = 240;
export const conditionNodePortItemArgsY = 60;
export const conditionNodePortItemArgsY = 56.5;
export const conditionNodeItemHeight = 26;
export const conditionNodeHeight = 110;
/**
@@ -703,7 +703,7 @@ export const portTextAttrs = { fontSize: 12, fill: '#5B6167' }
/**
* Port position arguments
*/
export const portItemArgsY = 26;
export const portItemArgsY = 26.5;
export const portArgs = { x: nodeWidth, y: portItemArgsY }
const defaultPortGroup = {

View File

@@ -108,7 +108,7 @@ export interface ChatVariable {
required: boolean;
description: string;
default?: string;
defaultValue: string;
defaultValue: string | any[];
}
export interface AddChatVariableRef {
handleOpen: (value?: ChatVariable) => void;