Browse Source

feat: ifelse condition variable editable after selection (#11431)

Yi Xiao 4 months ago
parent
commit
32f8a98cf8

+ 1 - 1
web/app/components/workflow/nodes/_base/components/variable-tag.tsx

@@ -72,7 +72,7 @@ const VariableTag = ({
         {isEnv && <Env className='shrink-0 mr-0.5 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' />}
         <div
-          className={cn('truncate text-text-accent font-medium', (isEnv || isChatVar) && 'text-text-secondary')}
+          className={cn('truncate ml-0.5 text-text-accent font-medium', (isEnv || isChatVar) && 'text-text-secondary')}
           title={variableName}
         >
           {variableName}

+ 1 - 1
web/app/components/workflow/nodes/_base/components/variable/var-reference-vars.tsx

@@ -274,7 +274,7 @@ const VarReferenceVars: FC<Props> = ({
       {
         !hideSearch && (
           <>
-            <div className={cn('mb-2 mx-1', searchBoxClassName)} onClick={e => e.stopPropagation()}>
+            <div className={cn('mb-1 mx-2 mt-2', searchBoxClassName)} onClick={e => e.stopPropagation()}>
               <Input
                 showLeftIcon
                 showClearIcon

+ 20 - 3
web/app/components/workflow/nodes/if-else/components/condition-list/condition-item.tsx

@@ -25,10 +25,12 @@ import { FILE_TYPE_OPTIONS, SUB_VARIABLES, TRANSFER_METHOD } from '../../default
 import ConditionWrap from '../condition-wrap'
 import ConditionOperator from './condition-operator'
 import ConditionInput from './condition-input'
-import VariableTag from '@/app/components/workflow/nodes/_base/components/variable-tag'
+
+import ConditionVarSelector from './condition-var-selector'
 import type {
   Node,
   NodeOutPutVar,
+  ValueSelector,
   Var,
 } from '@/app/components/workflow/types'
 import { VarType } from '@/app/components/workflow/types'
@@ -82,6 +84,7 @@ const ConditionItem = ({
   const { t } = useTranslation()
 
   const [isHovered, setIsHovered] = useState(false)
+  const [open, setOpen] = useState(false)
 
   const doUpdateCondition = useCallback((newCondition: Condition) => {
     if (isSubVariableKey)
@@ -190,6 +193,17 @@ const ConditionItem = ({
       onRemoveCondition?.(caseId, condition.id)
   }, [caseId, condition, conditionId, isSubVariableKey, onRemoveCondition, onRemoveSubVariableCondition])
 
+  const handleVarChange = useCallback((valueSelector: ValueSelector, varItem: Var) => {
+    const newCondition = produce(condition, (draft) => {
+      draft.variable_selector = valueSelector
+      draft.varType = varItem.type
+      draft.value = ''
+      draft.comparison_operator = getOperators(varItem.type)[0]
+    })
+    doUpdateCondition(newCondition)
+    setOpen(false)
+  }, [condition, doUpdateCondition])
+
   return (
     <div className={cn('flex mb-1 last-of-type:mb-0', className)}>
       <div className={cn(
@@ -221,11 +235,14 @@ const ConditionItem = ({
                 />
               )
               : (
-                <VariableTag
+                <ConditionVarSelector
+                  open={open}
+                  onOpenChange={setOpen}
                   valueSelector={condition.variable_selector || []}
                   varType={condition.varType}
                   availableNodes={availableNodes}
-                  isShort
+                  nodesOutputVars={nodesOutputVars}
+                  onChange={handleVarChange}
                 />
               )}
 

+ 58 - 0
web/app/components/workflow/nodes/if-else/components/condition-list/condition-var-selector.tsx

@@ -0,0 +1,58 @@
+import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem'
+import VariableTag from '@/app/components/workflow/nodes/_base/components/variable-tag'
+import VarReferenceVars from '@/app/components/workflow/nodes/_base/components/variable/var-reference-vars'
+import type { Node, NodeOutPutVar, ValueSelector, Var, VarType } from '@/app/components/workflow/types'
+
+type ConditionVarSelectorProps = {
+  open: boolean
+  onOpenChange: (open: boolean) => void
+  valueSelector: ValueSelector
+  varType: VarType
+  availableNodes: Node[]
+  nodesOutputVars: NodeOutPutVar[]
+  onChange: (valueSelector: ValueSelector, varItem: Var) => void
+}
+
+const ConditionVarSelector = ({
+  open,
+  onOpenChange,
+  valueSelector,
+  varType,
+  availableNodes,
+  nodesOutputVars,
+  onChange,
+}: ConditionVarSelectorProps) => {
+  return (
+    <PortalToFollowElem
+      open={open}
+      onOpenChange={onOpenChange}
+      placement='bottom-start'
+      offset={{
+        mainAxis: 4,
+        crossAxis: 0,
+      }}
+    >
+      <PortalToFollowElemTrigger onClick={() => onOpenChange(!open)}>
+        <div className="cursor-pointer">
+          <VariableTag
+            valueSelector={valueSelector}
+            varType={varType}
+            availableNodes={availableNodes}
+            isShort
+          />
+        </div>
+      </PortalToFollowElemTrigger>
+      <PortalToFollowElemContent className='z-[1000]'>
+        <div className='w-[296px] bg-components-panel-bg-blur rounded-lg border-[0.5px] border-components-panel-border shadow-lg'>
+          <VarReferenceVars
+            vars={nodesOutputVars}
+            isSupportFileVar
+            onChange={onChange}
+          />
+        </div>
+      </PortalToFollowElemContent>
+    </PortalToFollowElem>
+  )
+}
+
+export default ConditionVarSelector

+ 1 - 1
web/app/components/workflow/nodes/if-else/components/condition-value.tsx

@@ -73,7 +73,7 @@ const ConditionValue = ({
 
       <div
         className={cn(
-          'shrink-0  truncate text-xs font-medium text-text-accent',
+          'shrink-0 ml-0.5 truncate text-xs font-medium text-text-accent',
           !notHasValue && 'max-w-[70px]',
         )}
         title={variableName}