From a430284aa21e3ae1f0d5654e55b2ad2852519cc2 Mon Sep 17 00:00:00 2001
From: wwf <yearningwang@iqtogether.com>
Date: 星期三, 04 六月 2025 15:17:49 +0800
Subject: [PATCH] 初始化

---
 app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx |  155 +++++++++++++++++++--------------------------------
 1 files changed, 58 insertions(+), 97 deletions(-)

diff --git a/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx b/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx
index 023916e..9ac5e4a 100644
--- a/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx
+++ b/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx
@@ -1,6 +1,6 @@
 'use client'
 import type { FC } from 'react'
-import React, { useEffect, useMemo, useRef, useState } from 'react'
+import React, { useEffect, useRef, useState } from 'react'
 import { useHover } from 'ahooks'
 import { useTranslation } from 'react-i18next'
 import cn from '@/utils/classnames'
@@ -15,14 +15,7 @@
 import Input from '@/app/components/base/input'
 import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others'
 import { checkKeys } from '@/utils/var'
-import type { StructuredOutput } from '../../../llm/types'
-import { Type } from '../../../llm/types'
-import PickerStructurePanel from '@/app/components/workflow/nodes/_base/components/variable/object-child-tree-panel/picker'
-import { varTypeToStructType } from './utils'
-import type { Field } from '@/app/components/workflow/nodes/llm/types'
 import { FILE_STRUCT } from '@/app/components/workflow/constants'
-import { Loop } from '@/app/components/base/icons/src/vender/workflow'
-import { noop } from 'lodash-es'
 
 type ObjectChildrenProps = {
   nodeId: string
@@ -45,10 +38,7 @@
   itemWidth?: number
   isSupportFileVar?: boolean
   isException?: boolean
-  isLoopVar?: boolean
 }
-
-const objVarTypes = [VarType.object, VarType.file]
 
 const Item: FC<ItemProps> = ({
   nodeId,
@@ -57,50 +47,24 @@
   itemData,
   onChange,
   onHovering,
+  itemWidth,
   isSupportFileVar,
   isException,
-  isLoopVar,
 }) => {
-  const isStructureOutput = itemData.type === VarType.object && (itemData.children as StructuredOutput)?.schema?.properties
-  const isFile = itemData.type === VarType.file && !isStructureOutput
-  const isObj = ([VarType.object, VarType.file].includes(itemData.type) && itemData.children && (itemData.children as Var[]).length > 0)
+  const isFile = itemData.type === VarType.file
+  const isObj = ([VarType.object, VarType.file].includes(itemData.type) && itemData.children && itemData.children.length > 0)
   const isSys = itemData.variable.startsWith('sys.')
   const isEnv = itemData.variable.startsWith('env.')
   const isChatVar = itemData.variable.startsWith('conversation.')
-
-  const objStructuredOutput: StructuredOutput | null = useMemo(() => {
-    if (!isObj) return null
-    const properties: Record<string, Field> = {};
-    (isFile ? FILE_STRUCT : (itemData.children as Var[])).forEach((c) => {
-      properties[c.variable] = {
-        type: varTypeToStructType(c.type),
-      }
-    })
-    return {
-      schema: {
-        type: Type.object,
-        properties,
-        required: [],
-        additionalProperties: false,
-      },
-    }
-  }, [isFile, isObj, itemData.children])
-
-  const structuredOutput = (() => {
-    if (isStructureOutput)
-      return itemData.children as StructuredOutput
-    return objStructuredOutput
-  })()
-
-  const itemRef = useRef<HTMLDivElement>(null)
+  const itemRef = useRef(null)
   const [isItemHovering, setIsItemHovering] = useState(false)
-  useHover(itemRef, {
+  const _ = useHover(itemRef, {
     onChange: (hovering) => {
       if (hovering) {
         setIsItemHovering(true)
       }
       else {
-        if (isObj || isStructureOutput) {
+        if (isObj) {
           setTimeout(() => {
             setIsItemHovering(false)
           }, 100)
@@ -113,7 +77,7 @@
   })
   const [isChildrenHovering, setIsChildrenHovering] = useState(false)
   const isHovering = isItemHovering || isChildrenHovering
-  const open = (isObj || isStructureOutput) && isHovering
+  const open = isObj && isHovering
   useEffect(() => {
     onHovering && onHovering(isHovering)
     // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -133,58 +97,70 @@
   return (
     <PortalToFollowElem
       open={open}
-      onOpenChange={noop}
+      onOpenChange={() => { }}
       placement='left-start'
     >
       <PortalToFollowElemTrigger className='w-full'>
         <div
           ref={itemRef}
           className={cn(
-            (isObj || isStructureOutput) ? ' pr-1' : 'pr-[18px]',
-            isHovering && ((isObj || isStructureOutput) ? 'bg-primary-50' : 'bg-state-base-hover'),
-            'relative flex h-6 w-full cursor-pointer items-center  rounded-md pl-3')
+            isObj ? ' pr-1' : 'pr-[18px]',
+            isHovering && (isObj ? 'bg-primary-50' : 'bg-state-base-hover'),
+            'relative w-full flex items-center h-6 pl-3  rounded-md cursor-pointer')
           }
           onClick={handleChosen}
-          onMouseDown={e => e.preventDefault()}
         >
-          <div className='flex w-0 grow items-center'>
-            {!isEnv && !isChatVar && !isLoopVar && <Variable02 className={cn('h-3.5 w-3.5 shrink-0 text-text-accent', isException && 'text-text-warning')} />}
-            {isEnv && <Env className='h-3.5 w-3.5 shrink-0 text-util-colors-violet-violet-600' />}
-            {isChatVar && <BubbleX className='h-3.5 w-3.5 shrink-0 text-util-colors-teal-teal-700' />}
-            {isLoopVar && <Loop className='h-3.5 w-3.5 shrink-0 text-util-colors-cyan-cyan-500' />}
+          <div className='flex items-center w-0 grow'>
+            {!isEnv && !isChatVar && <Variable02 className={cn('shrink-0 w-3.5 h-3.5 text-text-accent', isException && 'text-text-warning')} />}
+            {isEnv && <Env className='shrink-0 w-3.5 h-3.5 text-util-colors-violet-violet-600' />}
+            {isChatVar && <BubbleX className='w-3.5 h-3.5 text-util-colors-teal-teal-700' />}
             {!isEnv && !isChatVar && (
-              <div title={itemData.variable} className='system-sm-medium ml-1 w-0 grow truncate text-text-secondary'>{itemData.variable}</div>
+              <div title={itemData.variable} className='ml-1 w-0 grow truncate text-text-secondary system-sm-medium'>{itemData.variable}</div>
             )}
             {isEnv && (
-              <div title={itemData.variable} className='system-sm-medium ml-1 w-0 grow truncate text-text-secondary'>{itemData.variable.replace('env.', '')}</div>
+              <div title={itemData.variable} className='ml-1 w-0 grow truncate text-text-secondary system-sm-medium'>{itemData.variable.replace('env.', '')}</div>
             )}
             {isChatVar && (
-              <div title={itemData.des} className='system-sm-medium ml-1 w-0 grow truncate text-text-secondary'>{itemData.variable.replace('conversation.', '')}</div>
+              <div title={itemData.des} className='ml-1 w-0 grow truncate text-text-secondary system-sm-medium'>{itemData.variable.replace('conversation.', '')}</div>
             )}
           </div>
-          <div className='ml-1 shrink-0 text-xs font-normal capitalize text-text-tertiary'>{itemData.type}</div>
-          {
-            (isObj || isStructureOutput) && (
-              <ChevronRight className={cn('ml-0.5 h-3 w-3 text-text-quaternary', isHovering && 'text-text-tertiary')} />
-            )
-          }
-        </div >
-      </PortalToFollowElemTrigger >
+          <div className='ml-1 shrink-0 text-xs font-normal text-text-tertiary capitalize'>{itemData.type}</div>
+          {isObj && (
+            <ChevronRight className={cn('ml-0.5 w-3 h-3 text-text-quaternary', isHovering && 'text-text-tertiary')} />
+          )}
+        </div>
+      </PortalToFollowElemTrigger>
       <PortalToFollowElemContent style={{
         zIndex: 100,
       }}>
-        {(isStructureOutput || isObj) && (
-          <PickerStructurePanel
-            root={{ nodeId, nodeName: title, attrName: itemData.variable }}
-            payload={structuredOutput!}
+        {(isObj && !isFile) && (
+          // eslint-disable-next-line @typescript-eslint/no-use-before-define
+          <ObjectChildren
+            nodeId={nodeId}
+            title={title}
+            objPath={[...objPath, itemData.variable]}
+            data={itemData.children as Var[]}
+            onChange={onChange}
             onHovering={setIsChildrenHovering}
-            onSelect={(valueSelector) => {
-              onChange(valueSelector, itemData)
-            }}
+            itemWidth={itemWidth}
+            isSupportFileVar={isSupportFileVar}
+          />
+        )}
+        {isFile && (
+          // eslint-disable-next-line @typescript-eslint/no-use-before-define
+          <ObjectChildren
+            nodeId={nodeId}
+            title={title}
+            objPath={[...objPath, itemData.variable]}
+            data={FILE_STRUCT}
+            onChange={onChange}
+            onHovering={setIsChildrenHovering}
+            itemWidth={itemWidth}
+            isSupportFileVar={isSupportFileVar}
           />
         )}
       </PortalToFollowElemContent>
-    </PortalToFollowElem >
+    </PortalToFollowElem>
   )
 }
 
@@ -199,9 +175,9 @@
   isSupportFileVar,
 }) => {
   const currObjPath = objPath
-  const itemRef = useRef<HTMLDivElement>(null)
+  const itemRef = useRef(null)
   const [isItemHovering, setIsItemHovering] = useState(false)
-  useHover(itemRef, {
+  const _ = useHover(itemRef, {
     onChange: (hovering) => {
       if (hovering) {
         setIsItemHovering(true)
@@ -225,11 +201,11 @@
   }, [isItemHovering])
   // absolute top-[-2px]
   return (
-    <div ref={itemRef} className=' space-y-1 rounded-lg border border-gray-200 bg-white shadow-lg' style={{
+    <div ref={itemRef} className=' bg-white rounded-lg border border-gray-200 shadow-lg space-y-1' style={{
       right: itemWidth ? itemWidth - 10 : 215,
       minWidth: 252,
     }}>
-      <div className='flex h-[22px] items-center px-3 text-xs font-normal text-gray-700'><span className='text-gray-500'>{title}.</span>{currObjPath.join('.')}</div>
+      <div className='flex items-center h-[22px] px-3 text-xs font-normal text-gray-700'><span className='text-gray-500'>{title}.</span>{currObjPath.join('.')}</div>
       {
         (data && data.length > 0)
         && data.map((v, i) => (
@@ -258,8 +234,6 @@
   onChange: (value: ValueSelector, item: Var) => void
   itemWidth?: number
   maxHeightClass?: string
-  onClose?: () => void
-  onBlur?: () => void
 }
 const VarReferenceVars: FC<Props> = ({
   hideSearch,
@@ -269,18 +243,9 @@
   onChange,
   itemWidth,
   maxHeightClass,
-  onClose,
-  onBlur,
 }) => {
   const { t } = useTranslation()
   const [searchText, setSearchText] = useState('')
-
-  const handleKeyDown = (e: React.KeyboardEvent) => {
-    if (e.key === 'Escape') {
-      e.preventDefault()
-      onClose?.()
-    }
-  }
 
   const filteredVars = vars.filter((v) => {
     const children = v.vars.filter(v => checkKeys([v.variable], false).isValid || v.variable.startsWith('sys.') || v.variable.startsWith('env.') || v.variable.startsWith('conversation.'))
@@ -312,21 +277,18 @@
       {
         !hideSearch && (
           <>
-            <div className={cn('var-search-input-wrapper mx-2 mb-1 mt-2', searchBoxClassName)} onClick={e => e.stopPropagation()}>
+            <div className={cn('mb-1 mx-2 mt-2', searchBoxClassName)} onClick={e => e.stopPropagation()}>
               <Input
-                className='var-search-input'
                 showLeftIcon
                 showClearIcon
                 value={searchText}
                 placeholder={t('workflow.common.searchVar') || ''}
                 onChange={e => setSearchText(e.target.value)}
-                onKeyDown={handleKeyDown}
                 onClear={() => setSearchText('')}
-                onBlur={onBlur}
                 autoFocus
               />
             </div>
-            <div className='relative left-[-4px] h-[0.5px] bg-black/5' style={{
+            <div className='h-[0.5px] bg-black/5 relative left-[-4px]' style={{
               width: 'calc(100% + 8px)',
             }}></div>
           </>
@@ -340,7 +302,7 @@
             filteredVars.map((item, i) => (
               <div key={i}>
                 <div
-                  className='system-xs-medium-uppercase truncate px-3 leading-[22px] text-text-tertiary'
+                  className='leading-[22px] px-3 text-text-tertiary system-xs-medium-uppercase truncate'
                   title={item.title}
                 >{item.title}</div>
                 {item.vars.map((v, j) => (
@@ -354,14 +316,13 @@
                     itemWidth={itemWidth}
                     isSupportFileVar={isSupportFileVar}
                     isException={v.isException}
-                    isLoopVar={item.isLoop}
                   />
                 ))}
               </div>))
           }
         </div>
-        : <div className='pl-3 text-xs font-medium uppercase leading-[18px] text-gray-500'>{t('workflow.common.noVar')}</div>}
-    </>
+        : <div className='pl-3 leading-[18px] text-xs font-medium text-gray-500 uppercase'>{t('workflow.common.noVar')}</div>}
+    </ >
   )
 }
 export default React.memo(VarReferenceVars)

--
Gitblit v1.8.0