| } from 'lexical' | } from 'lexical' | ||||
| import { mergeRegister } from '@lexical/utils' | import { mergeRegister } from '@lexical/utils' | ||||
| import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' | import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext' | ||||
| import { | |||||
| RiErrorWarningFill, | |||||
| RiMoreLine, | |||||
| } from '@remixicon/react' | |||||
| import { useReactFlow, useStoreApi } from 'reactflow' | import { useReactFlow, useStoreApi } from 'reactflow' | ||||
| import { useSelectOrDelete } from '../../hooks' | import { useSelectOrDelete } from '../../hooks' | ||||
| import type { WorkflowNodesMap } from './node' | import type { WorkflowNodesMap } from './node' | ||||
| DELETE_WORKFLOW_VARIABLE_BLOCK_COMMAND, | DELETE_WORKFLOW_VARIABLE_BLOCK_COMMAND, | ||||
| UPDATE_WORKFLOW_NODES_MAP, | UPDATE_WORKFLOW_NODES_MAP, | ||||
| } from './index' | } from './index' | ||||
| import cn from '@/utils/classnames' | |||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | |||||
| import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others' | |||||
| import { VarBlockIcon } from '@/app/components/workflow/block-icon' | |||||
| import { Line3 } from '@/app/components/base/icons/src/public/common' | |||||
| import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | ||||
| import Tooltip from '@/app/components/base/tooltip' | import Tooltip from '@/app/components/base/tooltip' | ||||
| import { isExceptionVariable } from '@/app/components/workflow/utils' | import { isExceptionVariable } from '@/app/components/workflow/utils' | ||||
| import VarFullPathPanel from '@/app/components/workflow/nodes/_base/components/variable/var-full-path-panel' | import VarFullPathPanel from '@/app/components/workflow/nodes/_base/components/variable/var-full-path-panel' | ||||
| import { Type } from '@/app/components/workflow/nodes/llm/types' | import { Type } from '@/app/components/workflow/nodes/llm/types' | ||||
| import type { ValueSelector, Var } from '@/app/components/workflow/types' | import type { ValueSelector, Var } from '@/app/components/workflow/types' | ||||
| import { | |||||
| VariableLabelInEditor, | |||||
| } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| type WorkflowVariableBlockComponentProps = { | type WorkflowVariableBlockComponentProps = { | ||||
| nodeKey: string | nodeKey: string | ||||
| }, [node, reactflow, store]) | }, [node, reactflow, store]) | ||||
| const Item = ( | const Item = ( | ||||
| <div | |||||
| className={cn( | |||||
| 'group/wrap relative mx-0.5 flex h-[18px] select-none items-center rounded-[5px] border pl-0.5 pr-[3px] hover:border-state-accent-solid hover:bg-state-accent-hover', | |||||
| isSelected ? ' border-state-accent-solid bg-state-accent-hover' : ' border-components-panel-border-subtle bg-components-badge-white-to-dark', | |||||
| !variableValid && '!border-state-destructive-solid !bg-state-destructive-hover', | |||||
| )} | |||||
| <VariableLabelInEditor | |||||
| nodeType={node?.type} | |||||
| nodeTitle={node?.title} | |||||
| variables={variables} | |||||
| onClick={(e) => { | onClick={(e) => { | ||||
| e.stopPropagation() | e.stopPropagation() | ||||
| handleVariableJump() | handleVariableJump() | ||||
| }} | }} | ||||
| isExceptionVariable={isException} | |||||
| errorMsg={!variableValid ? t('workflow.errorMsg.invalidVariable') : undefined} | |||||
| isSelected={isSelected} | |||||
| ref={ref} | ref={ref} | ||||
| > | |||||
| {!isEnv && !isChatVar && ( | |||||
| <div className='flex items-center'> | |||||
| { | |||||
| node?.type && ( | |||||
| <div className='p-[1px]'> | |||||
| <VarBlockIcon | |||||
| className='!text-text-secondary' | |||||
| type={node?.type} | |||||
| /> | |||||
| </div> | |||||
| ) | |||||
| } | |||||
| <div className='mx-0.5 max-w-[60px] shrink-0 truncate text-xs font-medium text-text-secondary' title={node?.title} style={{ | |||||
| }}>{node?.title}</div> | |||||
| <Line3 className='mr-0.5 text-divider-deep'></Line3> | |||||
| </div> | |||||
| )} | |||||
| {isShowAPart && ( | |||||
| <div className='flex items-center'> | |||||
| <RiMoreLine className='h-3 w-3 text-text-secondary' /> | |||||
| <Line3 className='mr-0.5 text-divider-deep'></Line3> | |||||
| </div> | |||||
| )} | |||||
| <div className='flex items-center text-text-accent'> | |||||
| {!isEnv && !isChatVar && <Variable02 className={cn('h-3.5 w-3.5 shrink-0', 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 text-util-colors-teal-teal-700' />} | |||||
| <div className={cn( | |||||
| 'ml-0.5 shrink-0 truncate text-xs font-medium', | |||||
| isEnv && 'text-util-colors-violet-violet-600', | |||||
| isChatVar && 'text-util-colors-teal-teal-700', | |||||
| isException && 'text-text-warning', | |||||
| )} title={varName}>{varName}</div> | |||||
| { | |||||
| !variableValid && ( | |||||
| <RiErrorWarningFill className='ml-0.5 h-3 w-3 text-text-destructive' /> | |||||
| ) | |||||
| } | |||||
| </div> | |||||
| </div> | |||||
| notShowFullPath={isShowAPart} | |||||
| /> | |||||
| ) | ) | ||||
| if (!variableValid) { | |||||
| return ( | |||||
| <Tooltip popupContent={t('workflow.errorMsg.invalidVariable')}> | |||||
| {Item} | |||||
| </Tooltip> | |||||
| ) | |||||
| } | |||||
| if (!node) | if (!node) | ||||
| return Item | return Item | ||||
| import cn from 'classnames' | import cn from 'classnames' | ||||
| import { useWorkflow } from '../../../hooks' | import { useWorkflow } from '../../../hooks' | ||||
| import { BlockEnum } from '../../../types' | import { BlockEnum } from '../../../types' | ||||
| import { VarBlockIcon } from '../../../block-icon' | |||||
| import { getNodeInfoById, isConversationVar, isENV, isSystemVar } from './variable/utils' | |||||
| import { Line3 } from '@/app/components/base/icons/src/public/common' | |||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | |||||
| import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others' | |||||
| import { RiMoreLine } from '@remixicon/react' | |||||
| import { getNodeInfoById, isSystemVar } from './variable/utils' | |||||
| import { | |||||
| VariableLabelInText, | |||||
| } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| type Props = { | type Props = { | ||||
| nodeId: string | nodeId: string | ||||
| value: string | value: string | ||||
| const value = vars[index].split('.') | const value = vars[index].split('.') | ||||
| const isSystem = isSystemVar(value) | const isSystem = isSystemVar(value) | ||||
| const isEnv = isENV(value) | |||||
| const isChatVar = isConversationVar(value) | |||||
| const node = (isSystem ? startNode : getNodeInfoById(availableNodes, value[0]))?.data | const node = (isSystem ? startNode : getNodeInfoById(availableNodes, value[0]))?.data | ||||
| const varName = `${isSystem ? 'sys.' : ''}${value[value.length - 1]}` | |||||
| const isShowAPart = value.length > 2 | const isShowAPart = value.length > 2 | ||||
| return (<span key={index}> | return (<span key={index}> | ||||
| <span className='relative top-[-3px] leading-[16px]'>{str}</span> | <span className='relative top-[-3px] leading-[16px]'>{str}</span> | ||||
| <div className=' inline-flex h-[16px] items-center rounded-[5px] bg-components-badge-white-to-dark px-1.5'> | |||||
| {!isEnv && !isChatVar && ( | |||||
| <div className='flex items-center'> | |||||
| <div className='p-[1px]'> | |||||
| <VarBlockIcon | |||||
| className='!text-text-primary' | |||||
| type={node?.type || BlockEnum.Start} | |||||
| /> | |||||
| </div> | |||||
| <div className='mx-0.5 max-w-[60px] truncate text-xs font-medium text-text-secondary' title={node?.title}>{node?.title}</div> | |||||
| <Line3 className='mr-0.5'></Line3> | |||||
| </div> | |||||
| )} | |||||
| {isShowAPart && ( | |||||
| <div className='flex items-center'> | |||||
| <RiMoreLine className='h-3 w-3 text-text-secondary' /> | |||||
| <Line3 className='mr-0.5 text-divider-deep'></Line3> | |||||
| </div> | |||||
| )} | |||||
| <div className='flex items-center text-text-accent'> | |||||
| {!isEnv && !isChatVar && <Variable02 className='h-3.5 w-3.5 shrink-0' />} | |||||
| {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 text-util-colors-teal-teal-700' />} | |||||
| <div className={cn('ml-0.5 max-w-[50px] truncate text-xs font-medium', (isEnv || isChatVar) && 'text-text-primary')} title={varName}>{varName}</div> | |||||
| </div> | |||||
| </div> | |||||
| <VariableLabelInText | |||||
| nodeTitle={node?.title} | |||||
| nodeType={node?.type} | |||||
| notShowFullPath={isShowAPart} | |||||
| variables={value} | |||||
| /> | |||||
| </span>) | </span>) | ||||
| }) | }) | ||||
| return html | return html |
| import { useCallback, useMemo } from 'react' | import { useCallback, useMemo } from 'react' | ||||
| import { useNodes, useReactFlow, useStoreApi } from 'reactflow' | import { useNodes, useReactFlow, useStoreApi } from 'reactflow' | ||||
| import { capitalize } from 'lodash-es' | |||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import { RiErrorWarningFill } from '@remixicon/react' | |||||
| import { VarBlockIcon } from '@/app/components/workflow/block-icon' | |||||
| import type { | import type { | ||||
| CommonNodeType, | CommonNodeType, | ||||
| Node, | Node, | ||||
| VarType, | VarType, | ||||
| } from '@/app/components/workflow/types' | } from '@/app/components/workflow/types' | ||||
| import { BlockEnum } from '@/app/components/workflow/types' | import { BlockEnum } from '@/app/components/workflow/types' | ||||
| import { Line3 } from '@/app/components/base/icons/src/public/common' | |||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | |||||
| import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others' | |||||
| import { getNodeInfoById, isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | import { getNodeInfoById, isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | ||||
| import Tooltip from '@/app/components/base/tooltip' | |||||
| import cn from '@/utils/classnames' | |||||
| import { isExceptionVariable } from '@/app/components/workflow/utils' | import { isExceptionVariable } from '@/app/components/workflow/utils' | ||||
| import { | |||||
| VariableLabelInSelect, | |||||
| } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| type VariableTagProps = { | type VariableTagProps = { | ||||
| valueSelector: ValueSelector | valueSelector: ValueSelector | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| return ( | return ( | ||||
| <Tooltip popupContent={!isValid && t('workflow.errorMsg.invalidVariable')}> | |||||
| <div className={cn('border-[rgba(16, 2440,0.08)] inline-flex h-6 max-w-full items-center rounded-md border-[0.5px] border-divider-subtle bg-components-badge-white-to-dark px-1.5 text-xs shadow-xs', | |||||
| !isValid && 'border-red-400 !bg-[#FEF3F2]', | |||||
| )} | |||||
| onClick={(e) => { | |||||
| if (e.metaKey || e.ctrlKey) { | |||||
| e.stopPropagation() | |||||
| handleVariableJump() | |||||
| } | |||||
| }} | |||||
| > | |||||
| {(!isEnv && !isChatVar && <> | |||||
| {node && ( | |||||
| <> | |||||
| <VarBlockIcon | |||||
| type={node.data.type || BlockEnum.Start} | |||||
| className='mr-0.5 !text-text-primary' | |||||
| /> | |||||
| <div | |||||
| className='max-w-[60px] truncate font-medium text-text-secondary' | |||||
| title={node?.data.title} | |||||
| > | |||||
| {node?.data.title} | |||||
| </div> | |||||
| </> | |||||
| )} | |||||
| <Line3 className='mx-0.5 shrink-0' /> | |||||
| <Variable02 className={cn('mr-0.5 h-3.5 w-3.5 shrink-0 text-text-accent', isException && 'text-text-warning')} /> | |||||
| </>)} | |||||
| {isEnv && <Env className='mr-0.5 h-3.5 w-3.5 shrink-0 text-util-colors-violet-violet-600' />} | |||||
| {isChatVar && <BubbleX className='h-3.5 w-3.5 text-util-colors-teal-teal-700' />} | |||||
| <div | |||||
| className={cn('ml-0.5 truncate font-medium text-text-accent', (isEnv || isChatVar) && 'text-text-secondary', isException && 'text-text-warning')} | |||||
| title={variableName} | |||||
| > | |||||
| {variableName} | |||||
| </div> | |||||
| { | |||||
| !isShort && varType && ( | |||||
| <div className='ml-0.5 shrink-0 text-text-tertiary'>{capitalize(varType)}</div> | |||||
| ) | |||||
| <VariableLabelInSelect | |||||
| variables={valueSelector} | |||||
| nodeType={node?.data.type} | |||||
| nodeTitle={node?.data.title} | |||||
| variableType={!isShort ? varType : undefined} | |||||
| onClick={(e) => { | |||||
| if (e.metaKey || e.ctrlKey) { | |||||
| e.stopPropagation() | |||||
| handleVariableJump() | |||||
| } | } | ||||
| {!isValid && <RiErrorWarningFill className='ml-0.5 h-3 w-3 text-[#D92D20]' />} | |||||
| </div> | |||||
| </Tooltip> | |||||
| }} | |||||
| errorMsg={!isValid ? t('workflow.errorMsg.invalidVariable') : undefined} | |||||
| isExceptionVariable={isException} | |||||
| /> | |||||
| ) | ) | ||||
| } | } | ||||
| import { BlockEnum } from '@/app/components/workflow/types' | import { BlockEnum } from '@/app/components/workflow/types' | ||||
| import { VarBlockIcon } from '@/app/components/workflow/block-icon' | import { VarBlockIcon } from '@/app/components/workflow/block-icon' | ||||
| import { Line3 } from '@/app/components/base/icons/src/public/common' | import { Line3 } from '@/app/components/base/icons/src/public/common' | ||||
| import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others' | |||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | ||||
| import { | import { | ||||
| PortalToFollowElem, | PortalToFollowElem, | ||||
| import { noop } from 'lodash-es' | import { noop } from 'lodash-es' | ||||
| import { useFetchDynamicOptions } from '@/service/use-plugins' | import { useFetchDynamicOptions } from '@/service/use-plugins' | ||||
| import type { Tool } from '@/app/components/tools/types' | import type { Tool } from '@/app/components/tools/types' | ||||
| import { VariableIconWithColor } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| const TRIGGER_DEFAULT_WIDTH = 227 | const TRIGGER_DEFAULT_WIDTH = 227 | ||||
| useEffect(() => { | useEffect(() => { | ||||
| if (triggerRef.current) | if (triggerRef.current) | ||||
| setTriggerWidth(triggerRef.current.clientWidth) | setTriggerWidth(triggerRef.current.clientWidth) | ||||
| // eslint-disable-next-line react-hooks/exhaustive-deps | |||||
| }, [triggerRef.current]) | }, [triggerRef.current]) | ||||
| const [varKindType, setVarKindType] = useState<VarKindType>(defaultVarKindType) | const [varKindType, setVarKindType] = useState<VarKindType>(defaultVarKindType) | ||||
| const [open, setOpen] = useState(false) | const [open, setOpen] = useState(false) | ||||
| useEffect(() => { | useEffect(() => { | ||||
| onOpen() | onOpen() | ||||
| // eslint-disable-next-line react-hooks/exhaustive-deps | |||||
| }, [open]) | }, [open]) | ||||
| const hasValue = !isConstant && value.length > 0 | const hasValue = !isConstant && value.length > 0 | ||||
| return schema | return schema | ||||
| }, [dynamicOptions]) | }, [dynamicOptions]) | ||||
| const variableCategory = useMemo(() => { | |||||
| if (isEnv) return 'environment' | |||||
| if (isChatVar) return 'conversation' | |||||
| if (isLoopVar) return 'loop' | |||||
| return 'system' | |||||
| }, [isEnv, isChatVar, isLoopVar]) | |||||
| return ( | return ( | ||||
| <div className={cn(className, !readonly && 'cursor-pointer')}> | <div className={cn(className, !readonly && 'cursor-pointer')}> | ||||
| <PortalToFollowElem | <PortalToFollowElem | ||||
| </div> | </div> | ||||
| )} | )} | ||||
| <div className='flex items-center text-text-accent'> | <div className='flex items-center text-text-accent'> | ||||
| {!hasValue && <Variable02 className='h-3.5 w-3.5' />} | |||||
| {isLoading && <RiLoader4Line className='h-3.5 w-3.5 animate-spin text-text-secondary' />} | {isLoading && <RiLoader4Line className='h-3.5 w-3.5 animate-spin text-text-secondary' />} | ||||
| {isEnv && <Env className='h-3.5 w-3.5 text-util-colors-violet-violet-600' />} | |||||
| {isChatVar && <BubbleX className='h-3.5 w-3.5 text-util-colors-teal-teal-700' />} | |||||
| <VariableIconWithColor | |||||
| variableCategory={variableCategory} | |||||
| isExceptionVariable={isException} | |||||
| /> | |||||
| <div className={cn('ml-0.5 truncate text-xs font-medium', isEnv && '!text-text-secondary', isChatVar && 'text-util-colors-teal-teal-700', isException && 'text-text-warning')} title={varName} style={{ | <div className={cn('ml-0.5 truncate text-xs font-medium', isEnv && '!text-text-secondary', isChatVar && 'text-util-colors-teal-teal-700', isException && 'text-text-warning')} title={varName} style={{ | ||||
| maxWidth: maxVarNameWidth, | maxWidth: maxVarNameWidth, | ||||
| }}>{varName}</div> | }}>{varName}</div> |
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import { type NodeOutPutVar, type ValueSelector, type Var, VarType } from '@/app/components/workflow/types' | import { type NodeOutPutVar, type ValueSelector, type Var, VarType } from '@/app/components/workflow/types' | ||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | |||||
| import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows' | import { ChevronRight } from '@/app/components/base/icons/src/vender/line/arrows' | ||||
| import { | import { | ||||
| PortalToFollowElem, | PortalToFollowElem, | ||||
| PortalToFollowElemTrigger, | PortalToFollowElemTrigger, | ||||
| } from '@/app/components/base/portal-to-follow-elem' | } from '@/app/components/base/portal-to-follow-elem' | ||||
| import Input from '@/app/components/base/input' | 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 { checkKeys } from '@/utils/var' | ||||
| import type { StructuredOutput } from '../../../llm/types' | import type { StructuredOutput } from '../../../llm/types' | ||||
| import { Type } from '../../../llm/types' | import { Type } from '../../../llm/types' | ||||
| import { varTypeToStructType } from './utils' | import { varTypeToStructType } from './utils' | ||||
| import type { Field } from '@/app/components/workflow/nodes/llm/types' | import type { Field } from '@/app/components/workflow/nodes/llm/types' | ||||
| import { FILE_STRUCT } from '@/app/components/workflow/constants' | import { FILE_STRUCT } from '@/app/components/workflow/constants' | ||||
| import { Loop } from '@/app/components/base/icons/src/vender/workflow' | |||||
| import { noop } from 'lodash-es' | import { noop } from 'lodash-es' | ||||
| import { VariableIconWithColor } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| type ObjectChildrenProps = { | type ObjectChildrenProps = { | ||||
| nodeId: string | nodeId: string | ||||
| const open = (isObj || isStructureOutput) && isHovering | const open = (isObj || isStructureOutput) && isHovering | ||||
| useEffect(() => { | useEffect(() => { | ||||
| onHovering && onHovering(isHovering) | onHovering && onHovering(isHovering) | ||||
| // eslint-disable-next-line react-hooks/exhaustive-deps | |||||
| }, [isHovering]) | }, [isHovering]) | ||||
| const handleChosen = (e: React.MouseEvent) => { | const handleChosen = (e: React.MouseEvent) => { | ||||
| e.stopPropagation() | e.stopPropagation() | ||||
| onChange([nodeId, ...objPath, itemData.variable], itemData) | onChange([nodeId, ...objPath, itemData.variable], itemData) | ||||
| } | } | ||||
| } | } | ||||
| const variableCategory = useMemo(() => { | |||||
| if (isEnv) return 'environment' | |||||
| if (isChatVar) return 'conversation' | |||||
| if (isLoopVar) return 'loop' | |||||
| return 'system' | |||||
| }, [isEnv, isChatVar, isSys, isLoopVar]) | |||||
| return ( | return ( | ||||
| <PortalToFollowElem | <PortalToFollowElem | ||||
| open={open} | open={open} | ||||
| onMouseDown={e => e.preventDefault()} | onMouseDown={e => e.preventDefault()} | ||||
| > | > | ||||
| <div className='flex w-0 grow items-center'> | <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' />} | |||||
| <VariableIconWithColor | |||||
| variableCategory={variableCategory} | |||||
| isExceptionVariable={isException} | |||||
| /> | |||||
| {!isEnv && !isChatVar && ( | {!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='system-sm-medium ml-1 w-0 grow truncate text-text-secondary'>{itemData.variable}</div> | ||||
| )} | )} | ||||
| const isHovering = isItemHovering || isChildrenHovering | const isHovering = isItemHovering || isChildrenHovering | ||||
| useEffect(() => { | useEffect(() => { | ||||
| onHovering && onHovering(isHovering) | onHovering && onHovering(isHovering) | ||||
| // eslint-disable-next-line react-hooks/exhaustive-deps | |||||
| }, [isHovering]) | }, [isHovering]) | ||||
| useEffect(() => { | useEffect(() => { | ||||
| onHovering && onHovering(isItemHovering) | onHovering && onHovering(isItemHovering) | ||||
| // eslint-disable-next-line react-hooks/exhaustive-deps | |||||
| }, [isItemHovering]) | }, [isItemHovering]) | ||||
| // absolute top-[-2px] | // absolute top-[-2px] | ||||
| return ( | return ( |
| import { memo } from 'react' | |||||
| import cn from '@/utils/classnames' | |||||
| import { useVarIcon } from '../hooks' | |||||
| import type { VarInInspectType } from '@/types/workflow' | |||||
| export type VariableIconProps = { | |||||
| className?: string | |||||
| variables?: string[] | |||||
| variableCategory?: VarInInspectType | string | |||||
| } | |||||
| const VariableIcon = ({ | |||||
| className, | |||||
| variables = [], | |||||
| variableCategory, | |||||
| }: VariableIconProps) => { | |||||
| const VarIcon = useVarIcon(variables, variableCategory) | |||||
| return VarIcon && ( | |||||
| <VarIcon | |||||
| className={cn( | |||||
| 'size-3.5 shrink-0', | |||||
| className, | |||||
| )} | |||||
| /> | |||||
| ) | |||||
| } | |||||
| export default memo(VariableIcon) |
| import { memo } from 'react' | |||||
| import { capitalize } from 'lodash-es' | |||||
| import { | |||||
| RiErrorWarningFill, | |||||
| RiMoreLine, | |||||
| } from '@remixicon/react' | |||||
| import type { VariablePayload } from '../types' | |||||
| import { useVarColor } from '../hooks' | |||||
| import VariableNodeLabel from './variable-node-label' | |||||
| import VariableIcon from './variable-icon' | |||||
| import VariableName from './variable-name' | |||||
| import cn from '@/utils/classnames' | |||||
| import Tooltip from '@/app/components/base/tooltip' | |||||
| const VariableLabel = ({ | |||||
| nodeType, | |||||
| nodeTitle, | |||||
| variables, | |||||
| variableType, | |||||
| className, | |||||
| errorMsg, | |||||
| onClick, | |||||
| isExceptionVariable, | |||||
| ref, | |||||
| notShowFullPath, | |||||
| rightSlot, | |||||
| }: VariablePayload) => { | |||||
| const varColorClassName = useVarColor(variables, isExceptionVariable) | |||||
| return ( | |||||
| <div | |||||
| className={cn( | |||||
| 'inline-flex h-6 max-w-full items-center space-x-0.5 rounded-md border-[0.5px] border-components-panel-border-subtle bg-components-badge-white-to-dark px-1.5 shadow-xs', | |||||
| className, | |||||
| )} | |||||
| onClick={onClick} | |||||
| ref={ref} | |||||
| > | |||||
| <VariableNodeLabel | |||||
| nodeType={nodeType} | |||||
| nodeTitle={nodeTitle} | |||||
| /> | |||||
| { | |||||
| notShowFullPath && ( | |||||
| <> | |||||
| <RiMoreLine className='h-3 w-3 shrink-0 text-text-secondary' /> | |||||
| <div className='system-xs-regular shrink-0 text-divider-deep'>/</div> | |||||
| </> | |||||
| ) | |||||
| } | |||||
| <VariableIcon | |||||
| variables={variables} | |||||
| className={varColorClassName} | |||||
| /> | |||||
| <VariableName | |||||
| variables={variables} | |||||
| className={cn(varColorClassName)} | |||||
| notShowFullPath={notShowFullPath} | |||||
| /> | |||||
| { | |||||
| variableType && ( | |||||
| <div className='system-xs-regular shrink-0 text-text-tertiary'> | |||||
| {capitalize(variableType)} | |||||
| </div> | |||||
| ) | |||||
| } | |||||
| { | |||||
| !!errorMsg && ( | |||||
| <Tooltip | |||||
| popupContent={errorMsg} | |||||
| asChild | |||||
| > | |||||
| <RiErrorWarningFill className='h-3 w-3 shrink-0 text-text-destructive' /> | |||||
| </Tooltip> | |||||
| ) | |||||
| } | |||||
| { | |||||
| rightSlot | |||||
| } | |||||
| </div> | |||||
| ) | |||||
| } | |||||
| export default memo(VariableLabel) |
| import { memo } from 'react' | |||||
| import { useVarName } from '../hooks' | |||||
| import cn from '@/utils/classnames' | |||||
| type VariableNameProps = { | |||||
| variables: string[] | |||||
| className?: string | |||||
| notShowFullPath?: boolean | |||||
| } | |||||
| const VariableName = ({ | |||||
| variables, | |||||
| className, | |||||
| notShowFullPath, | |||||
| }: VariableNameProps) => { | |||||
| const varName = useVarName(variables, notShowFullPath) | |||||
| return ( | |||||
| <div | |||||
| className={cn( | |||||
| 'system-xs-medium truncate', | |||||
| className, | |||||
| )} | |||||
| title={varName} | |||||
| > | |||||
| {varName} | |||||
| </div> | |||||
| ) | |||||
| } | |||||
| export default memo(VariableName) |
| import { memo } from 'react' | |||||
| import { VarBlockIcon } from '@/app/components/workflow/block-icon' | |||||
| import type { BlockEnum } from '@/app/components/workflow/types' | |||||
| type VariableNodeLabelProps = { | |||||
| nodeType?: BlockEnum | |||||
| nodeTitle?: string | |||||
| } | |||||
| const VariableNodeLabel = ({ | |||||
| nodeType, | |||||
| nodeTitle, | |||||
| }: VariableNodeLabelProps) => { | |||||
| if (!nodeType) | |||||
| return null | |||||
| return ( | |||||
| <> | |||||
| <VarBlockIcon | |||||
| type={nodeType} | |||||
| className='shrink-0 text-text-secondary' | |||||
| /> | |||||
| { | |||||
| nodeTitle && ( | |||||
| <div | |||||
| className='system-xs-medium max-[60px] truncate text-text-secondary' | |||||
| title={nodeTitle} | |||||
| > | |||||
| {nodeTitle} | |||||
| </div> | |||||
| ) | |||||
| } | |||||
| <div className='system-xs-regular shrink-0 text-divider-deep'>/</div> | |||||
| </> | |||||
| ) | |||||
| } | |||||
| export default memo(VariableNodeLabel) |
| import { useMemo } from 'react' | |||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | |||||
| import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others' | |||||
| import { Loop } from '@/app/components/base/icons/src/vender/workflow' | |||||
| import { | |||||
| isConversationVar, | |||||
| isENV, | |||||
| isSystemVar, | |||||
| } from '../utils' | |||||
| import { VarInInspectType } from '@/types/workflow' | |||||
| export const useVarIcon = (variables: string[], variableCategory?: VarInInspectType | string) => { | |||||
| if (variableCategory === 'loop') | |||||
| return Loop | |||||
| if (isENV(variables) || variableCategory === VarInInspectType.environment || variableCategory === 'environment') | |||||
| return Env | |||||
| if (isConversationVar(variables) || variableCategory === VarInInspectType.conversation || variableCategory === 'conversation') | |||||
| return BubbleX | |||||
| return Variable02 | |||||
| } | |||||
| export const useVarColor = (variables: string[], isExceptionVariable?: boolean, variableCategory?: VarInInspectType | string) => { | |||||
| return useMemo(() => { | |||||
| if (isExceptionVariable) | |||||
| return 'text-text-warning' | |||||
| if (variableCategory === 'loop') | |||||
| return 'text-util-colors-cyan-cyan-500' | |||||
| if (isENV(variables) || variableCategory === VarInInspectType.environment || variableCategory === 'environment') | |||||
| return 'text-util-colors-violet-violet-600' | |||||
| if (isConversationVar(variables) || variableCategory === VarInInspectType.conversation || variableCategory === 'conversation') | |||||
| return 'text-util-colors-teal-teal-700' | |||||
| return 'text-text-accent' | |||||
| }, [variables, isExceptionVariable]) | |||||
| } | |||||
| export const useVarName = (variables: string[], notShowFullPath?: boolean) => { | |||||
| const variableFullPathName = variables.slice(1).join('.') | |||||
| const variablesLength = variables.length | |||||
| const varName = useMemo(() => { | |||||
| const isSystem = isSystemVar(variables) | |||||
| const varName = notShowFullPath ? variables[variablesLength - 1] : variableFullPathName | |||||
| return `${isSystem ? 'sys.' : ''}${varName}` | |||||
| }, [variables, notShowFullPath]) | |||||
| return varName | |||||
| } | |||||
| export const useVarBgColorInEditor = (variables: string[], hasError?: boolean) => { | |||||
| if (hasError) { | |||||
| return { | |||||
| hoverBorderColor: 'hover:border-state-destructive-active', | |||||
| hoverBgColor: 'hover:bg-state-destructive-hover', | |||||
| selectedBorderColor: '!border-state-destructive-solid', | |||||
| selectedBgColor: '!bg-state-destructive-hover', | |||||
| } | |||||
| } | |||||
| if (isENV(variables)) { | |||||
| return { | |||||
| hoverBorderColor: 'hover:border-util-colors-violet-violet-100', | |||||
| hoverBgColor: 'hover:bg-util-colors-violet-violet-50', | |||||
| selectedBorderColor: 'border-util-colors-violet-violet-600', | |||||
| selectedBgColor: 'bg-util-colors-violet-violet-50', | |||||
| } | |||||
| } | |||||
| if (isConversationVar(variables)) { | |||||
| return { | |||||
| hoverBorderColor: 'hover:border-util-colors-teal-teal-100', | |||||
| hoverBgColor: 'hover:bg-util-colors-teal-teal-50', | |||||
| selectedBorderColor: 'border-util-colors-teal-teal-600', | |||||
| selectedBgColor: 'bg-util-colors-teal-teal-50', | |||||
| } | |||||
| } | |||||
| return { | |||||
| hoverBorderColor: 'hover:border-state-accent-alt', | |||||
| hoverBgColor: 'hover:bg-state-accent-hover', | |||||
| selectedBorderColor: 'border-state-accent-solid', | |||||
| selectedBgColor: 'bg-state-accent-hover', | |||||
| } | |||||
| } |
| export { default as VariableLabelInSelect } from './variable-label-in-select' | |||||
| export { default as VariableLabelInEditor } from './variable-label-in-editor' | |||||
| export { default as VariableLabelInNode } from './variable-label-in-node' | |||||
| export { default as VariableLabelInText } from './variable-label-in-text' | |||||
| export { default as VariableIconWithColor } from './variable-icon-with-color' |
| import type { ReactNode } from 'react' | |||||
| import type { | |||||
| BlockEnum, | |||||
| VarType, | |||||
| } from '@/app/components/workflow/types' | |||||
| export type VariablePayload = { | |||||
| className?: string | |||||
| nodeType?: BlockEnum | |||||
| nodeTitle?: string | |||||
| variables: string[] | |||||
| variableType?: VarType | |||||
| onClick?: (e: React.MouseEvent<HTMLDivElement>) => void | |||||
| errorMsg?: string | |||||
| isExceptionVariable?: boolean | |||||
| ref?: React.Ref<HTMLDivElement> | |||||
| notShowFullPath?: boolean | |||||
| rightSlot?: ReactNode | |||||
| } |
| import { memo } from 'react' | |||||
| import VariableIcon from './base/variable-icon' | |||||
| import type { VariableIconProps } from './base/variable-icon' | |||||
| import { useVarColor } from './hooks' | |||||
| import cn from '@/utils/classnames' | |||||
| type VariableIconWithColorProps = { | |||||
| isExceptionVariable?: boolean | |||||
| } & VariableIconProps | |||||
| const VariableIconWithColor = ({ | |||||
| isExceptionVariable, | |||||
| variableCategory, | |||||
| variables = [], | |||||
| className, | |||||
| }: VariableIconWithColorProps) => { | |||||
| const varColorClassName = useVarColor(variables, isExceptionVariable, variableCategory) | |||||
| return ( | |||||
| <VariableIcon | |||||
| variables={variables} | |||||
| variableCategory={variableCategory} | |||||
| className={cn( | |||||
| varColorClassName, | |||||
| className, | |||||
| )} | |||||
| /> | |||||
| ) | |||||
| } | |||||
| export default memo(VariableIconWithColor) |
| import { memo } from 'react' | |||||
| import type { VariablePayload } from './types' | |||||
| import VariableLabel from './base/variable-label' | |||||
| import { useVarBgColorInEditor } from './hooks' | |||||
| import cn from '@/utils/classnames' | |||||
| type VariableLabelInEditorProps = { | |||||
| isSelected?: boolean | |||||
| } & VariablePayload | |||||
| const VariableLabelInEditor = ({ | |||||
| isSelected, | |||||
| variables, | |||||
| errorMsg, | |||||
| ...rest | |||||
| }: VariableLabelInEditorProps) => { | |||||
| const { | |||||
| hoverBorderColor, | |||||
| hoverBgColor, | |||||
| selectedBorderColor, | |||||
| selectedBgColor, | |||||
| } = useVarBgColorInEditor(variables, !!errorMsg) | |||||
| return ( | |||||
| <VariableLabel | |||||
| className={cn( | |||||
| 'h-[18px] space-x-[1px] rounded-[5px] px-1 shadow-xs', | |||||
| !isSelected && hoverBgColor, | |||||
| !isSelected && hoverBorderColor, | |||||
| isSelected && 'border', | |||||
| isSelected && selectedBorderColor, | |||||
| isSelected && selectedBgColor, | |||||
| )} | |||||
| variables={variables} | |||||
| errorMsg={errorMsg} | |||||
| {...rest} | |||||
| /> | |||||
| ) | |||||
| } | |||||
| export default memo(VariableLabelInEditor) |
| import { memo } from 'react' | |||||
| import type { VariablePayload } from './types' | |||||
| import VariableLabel from './base/variable-label' | |||||
| import cn from '@/utils/classnames' | |||||
| const VariableLabelInNode = (variablePayload: VariablePayload) => { | |||||
| return ( | |||||
| <VariableLabel | |||||
| className={cn( | |||||
| 'w-full space-x-[1px] bg-workflow-block-parma-bg px-1 shadow-none', | |||||
| )} | |||||
| {...variablePayload} | |||||
| /> | |||||
| ) | |||||
| } | |||||
| export default memo(VariableLabelInNode) |
| import { memo } from 'react' | |||||
| import type { VariablePayload } from './types' | |||||
| import VariableLabel from './base/variable-label' | |||||
| const VariableLabelInSelect = (variablePayload: VariablePayload) => { | |||||
| return ( | |||||
| <VariableLabel | |||||
| {...variablePayload} | |||||
| /> | |||||
| ) | |||||
| } | |||||
| export default memo(VariableLabelInSelect) |
| import { memo } from 'react' | |||||
| import type { VariablePayload } from './types' | |||||
| import VariableLabel from './base/variable-label' | |||||
| import cn from '@/utils/classnames' | |||||
| const VariableLabelInText = (variablePayload: VariablePayload) => { | |||||
| return ( | |||||
| <VariableLabel | |||||
| className={cn( | |||||
| 'h-[18px] space-x-[1px] rounded-[5px] px-1 shadow-xs', | |||||
| )} | |||||
| {...variablePayload} | |||||
| /> | |||||
| ) | |||||
| } | |||||
| export default memo(VariableLabelInText) |
| import React from 'react' | import React from 'react' | ||||
| import { useNodes } from 'reactflow' | import { useNodes } from 'reactflow' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import NodeVariableItem from '../variable-assigner/components/node-variable-item' | |||||
| import type { AssignerNodeType } from './types' | import type { AssignerNodeType } from './types' | ||||
| import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { BlockEnum, type Node, type NodeProps } from '@/app/components/workflow/types' | import { BlockEnum, type Node, type NodeProps } from '@/app/components/workflow/types' | ||||
| import { | |||||
| VariableLabelInNode, | |||||
| } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| import Badge from '@/app/components/base/badge' | |||||
| const i18nPrefix = 'workflow.nodes.assigner' | const i18nPrefix = 'workflow.nodes.assigner' | ||||
| if (!variable || variable.length === 0) | if (!variable || variable.length === 0) | ||||
| return null | return null | ||||
| const isSystem = isSystemVar(variable) | const isSystem = isSystemVar(variable) | ||||
| const isEnv = isENV(variable) | |||||
| const isChatVar = isConversationVar(variable) | |||||
| const node = isSystem ? nodes.find(node => node.data.type === BlockEnum.Start) : nodes.find(node => node.id === variable[0]) | const node = isSystem ? nodes.find(node => node.data.type === BlockEnum.Start) : nodes.find(node => node.id === variable[0]) | ||||
| const varName = isSystem ? `sys.${variable[variable.length - 1]}` : variable.slice(1).join('.') | |||||
| return ( | return ( | ||||
| <NodeVariableItem | |||||
| <VariableLabelInNode | |||||
| key={index} | key={index} | ||||
| node={node as Node} | |||||
| isEnv={isEnv} | |||||
| isChatVar={isChatVar} | |||||
| writeMode={value.operation} | |||||
| varName={varName} | |||||
| className='bg-workflow-block-parma-bg' | |||||
| variables={variable} | |||||
| nodeType={node?.data.type} | |||||
| nodeTitle={node?.data.title} | |||||
| rightSlot={ | |||||
| value.operation && <Badge className='!ml-auto shrink-0' text={t(`${i18nPrefix}.operations.${value.operation}`)} /> | |||||
| } | |||||
| /> | /> | ||||
| ) | ) | ||||
| })} | })} | ||||
| if (!variable || variable.length === 0) | if (!variable || variable.length === 0) | ||||
| return null | return null | ||||
| const isSystem = isSystemVar(variable) | const isSystem = isSystemVar(variable) | ||||
| const isEnv = isENV(variable) | |||||
| const isChatVar = isConversationVar(variable) | |||||
| const node = isSystem ? nodes.find(node => node.data.type === BlockEnum.Start) : nodes.find(node => node.id === variable[0]) | const node = isSystem ? nodes.find(node => node.data.type === BlockEnum.Start) : nodes.find(node => node.id === variable[0]) | ||||
| const varName = isSystem ? `sys.${variable[variable.length - 1]}` : variable.slice(1).join('.') | |||||
| return ( | return ( | ||||
| <div className='relative flex flex-col items-start gap-0.5 self-stretch px-3 py-1'> | <div className='relative flex flex-col items-start gap-0.5 self-stretch px-3 py-1'> | ||||
| <NodeVariableItem | |||||
| node={node as Node} | |||||
| isEnv={isEnv} | |||||
| isChatVar={isChatVar} | |||||
| varName={varName} | |||||
| writeMode={writeMode} | |||||
| className='bg-workflow-block-parma-bg' | |||||
| <VariableLabelInNode | |||||
| variables={variable} | |||||
| nodeType={node?.data.type} | |||||
| nodeTitle={node?.data.title} | |||||
| rightSlot={ | |||||
| writeMode && <Badge className='!ml-auto shrink-0' text={t(`${i18nPrefix}.operations.${writeMode}`)} /> | |||||
| } | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| ) | ) |
| import React from 'react' | import React from 'react' | ||||
| import { useNodes } from 'reactflow' | import { useNodes } from 'reactflow' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import NodeVariableItem from '../variable-assigner/components/node-variable-item' | |||||
| import type { DocExtractorNodeType } from './types' | import type { DocExtractorNodeType } from './types' | ||||
| import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { BlockEnum, type Node, type NodeProps } from '@/app/components/workflow/types' | import { BlockEnum, type Node, type NodeProps } from '@/app/components/workflow/types' | ||||
| import { | |||||
| VariableLabelInNode, | |||||
| } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| const i18nPrefix = 'workflow.nodes.docExtractor' | const i18nPrefix = 'workflow.nodes.docExtractor' | ||||
| return null | return null | ||||
| const isSystem = isSystemVar(variable) | const isSystem = isSystemVar(variable) | ||||
| const isEnv = isENV(variable) | |||||
| const isChatVar = isConversationVar(variable) | |||||
| const node = isSystem ? nodes.find(node => node.data.type === BlockEnum.Start) : nodes.find(node => node.id === variable[0]) | const node = isSystem ? nodes.find(node => node.data.type === BlockEnum.Start) : nodes.find(node => node.id === variable[0]) | ||||
| const varName = isSystem ? `sys.${variable[variable.length - 1]}` : variable.slice(1).join('.') | |||||
| return ( | return ( | ||||
| <div className='relative px-3'> | <div className='relative px-3'> | ||||
| <div className='system-2xs-medium-uppercase mb-1 text-text-tertiary'>{t(`${i18nPrefix}.inputVar`)}</div> | <div className='system-2xs-medium-uppercase mb-1 text-text-tertiary'>{t(`${i18nPrefix}.inputVar`)}</div> | ||||
| <NodeVariableItem | |||||
| node={node as Node} | |||||
| isEnv={isEnv} | |||||
| isChatVar={isChatVar} | |||||
| varName={varName} | |||||
| className='bg-workflow-block-parma-bg' | |||||
| <VariableLabelInNode | |||||
| variables={variable} | |||||
| nodeType={node?.data.type} | |||||
| nodeTitle={node?.data.title} | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| ) | ) |
| import type { FC } from 'react' | import type { FC } from 'react' | ||||
| import React from 'react' | import React from 'react' | ||||
| import cn from 'classnames' | |||||
| import type { EndNodeType } from './types' | import type { EndNodeType } from './types' | ||||
| import type { NodeProps, Variable } from '@/app/components/workflow/types' | import type { NodeProps, Variable } from '@/app/components/workflow/types' | ||||
| import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { | import { | ||||
| useIsChatMode, | useIsChatMode, | ||||
| useWorkflow, | useWorkflow, | ||||
| useWorkflowVariables, | useWorkflowVariables, | ||||
| } from '@/app/components/workflow/hooks' | } from '@/app/components/workflow/hooks' | ||||
| import { VarBlockIcon } from '@/app/components/workflow/block-icon' | |||||
| import { Line3 } from '@/app/components/base/icons/src/public/common' | |||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | |||||
| import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others' | |||||
| import { BlockEnum } from '@/app/components/workflow/types' | import { BlockEnum } from '@/app/components/workflow/types' | ||||
| import { | |||||
| VariableLabelInNode, | |||||
| } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| const Node: FC<NodeProps<EndNodeType>> = ({ | const Node: FC<NodeProps<EndNodeType>> = ({ | ||||
| id, | id, | ||||
| <div className='mb-1 space-y-0.5 px-3 py-1'> | <div className='mb-1 space-y-0.5 px-3 py-1'> | ||||
| {filteredOutputs.map(({ value_selector }, index) => { | {filteredOutputs.map(({ value_selector }, index) => { | ||||
| const node = getNode(value_selector[0]) | const node = getNode(value_selector[0]) | ||||
| const isSystem = isSystemVar(value_selector) | |||||
| const isEnv = isENV(value_selector) | |||||
| const isChatVar = isConversationVar(value_selector) | |||||
| const varName = isSystem ? `sys.${value_selector[value_selector.length - 1]}` : value_selector[value_selector.length - 1] | |||||
| const varType = getCurrentVariableType({ | const varType = getCurrentVariableType({ | ||||
| valueSelector: value_selector, | valueSelector: value_selector, | ||||
| availableNodes, | availableNodes, | ||||
| isChatMode, | isChatMode, | ||||
| }) | }) | ||||
| return ( | |||||
| <div key={index} className='flex h-6 items-center justify-between space-x-1 rounded-md bg-workflow-block-parma-bg px-1 text-xs font-normal text-text-secondary'> | |||||
| <div className='flex items-center text-xs font-medium text-text-tertiary'> | |||||
| {!isEnv && !isChatVar && ( | |||||
| <> | |||||
| <div className='p-[1px]'> | |||||
| <VarBlockIcon | |||||
| className='!text-text-primary' | |||||
| type={node?.data.type || BlockEnum.Start} | |||||
| /> | |||||
| </div> | |||||
| <div className='max-w-[75px] truncate'>{node?.data.title}</div> | |||||
| <Line3 className='mr-0.5'></Line3> | |||||
| </> | |||||
| )} | |||||
| <div className='flex items-center text-text-accent'> | |||||
| {!isEnv && !isChatVar && <Variable02 className='h-3.5 w-3.5 shrink-0 text-text-accent' />} | |||||
| {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 text-util-colors-teal-teal-700' />} | |||||
| <div className={cn('ml-0.5 max-w-[50px] truncate text-xs font-medium', (isEnv || isChatVar) && '!max-w-[70px] text-text-primary')}>{varName}</div> | |||||
| </div> | |||||
| </div> | |||||
| <div className='text-xs font-normal text-text-secondary'> | |||||
| <div className='ml-0.5 max-w-[42px] truncate text-xs font-normal capitalize text-text-tertiary' title={varType}>{varType}</div> | |||||
| </div> | |||||
| </div> | |||||
| return ( | |||||
| <VariableLabelInNode | |||||
| key={index} | |||||
| variables={value_selector} | |||||
| nodeType={node?.data.type} | |||||
| nodeTitle={node?.data.title} | |||||
| variableType={varType} | |||||
| /> | |||||
| ) | ) | ||||
| })} | })} | ||||
| <div className='mb-1 px-3 py-1'> | <div className='mb-1 px-3 py-1'> | ||||
| <div className='flex items-center justify-start rounded-md bg-workflow-block-parma-bg p-1'> | <div className='flex items-center justify-start rounded-md bg-workflow-block-parma-bg p-1'> | ||||
| <div className='flex h-4 shrink-0 items-center rounded bg-components-badge-white-to-dark px-1 text-xs font-semibold uppercase text-text-secondary'>{method}</div> | <div className='flex h-4 shrink-0 items-center rounded bg-components-badge-white-to-dark px-1 text-xs font-semibold uppercase text-text-secondary'>{method}</div> | ||||
| <div className='pl-1 pt-1'> | |||||
| <div className='w-0 grow pl-1 pt-1'> | |||||
| <ReadonlyInputWithSelectVar | <ReadonlyInputWithSelectVar | ||||
| className='text-text-secondary' | className='text-text-secondary' | ||||
| value={url} | value={url} |
| } from '../utils' | } from '../utils' | ||||
| import { FILE_TYPE_OPTIONS, TRANSFER_METHOD } from '../../constants' | import { FILE_TYPE_OPTIONS, TRANSFER_METHOD } from '../../constants' | ||||
| import type { ValueSelector } from '../../../types' | import type { ValueSelector } from '../../../types' | ||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | |||||
| import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others' | |||||
| import cn from '@/utils/classnames' | |||||
| import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { | |||||
| VariableLabelInNode, | |||||
| } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| const i18nPrefix = 'workflow.nodes.ifElse' | const i18nPrefix = 'workflow.nodes.ifElse' | ||||
| type ConditionValueProps = { | type ConditionValueProps = { | ||||
| const variableSelector = variable_selector as ValueSelector | const variableSelector = variable_selector as ValueSelector | ||||
| const variableName = (isSystemVar(variableSelector) ? variableSelector.slice(0).join('.') : variableSelector.slice(1).join('.')) | |||||
| const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`workflow.nodes.ifElse.comparisonOperator.${operator}`) : operator | const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`workflow.nodes.ifElse.comparisonOperator.${operator}`) : operator | ||||
| const notHasValue = comparisonOperatorNotRequireValue(operator) | |||||
| const isEnvVar = isENV(variableSelector) | |||||
| const isChatVar = isConversationVar(variableSelector) | |||||
| const formatValue = useCallback((c: Condition) => { | const formatValue = useCallback((c: Condition) => { | ||||
| const notHasValue = comparisonOperatorNotRequireValue(c.comparison_operator) | const notHasValue = comparisonOperatorNotRequireValue(c.comparison_operator) | ||||
| if (notHasValue) | if (notHasValue) | ||||
| return ( | return ( | ||||
| <div className='rounded-md bg-workflow-block-parma-bg'> | <div className='rounded-md bg-workflow-block-parma-bg'> | ||||
| <div className='flex h-6 items-center px-1 '> | <div className='flex h-6 items-center px-1 '> | ||||
| {!isEnvVar && !isChatVar && <Variable02 className='mr-1 h-3.5 w-3.5 shrink-0 text-text-accent' />} | |||||
| {isEnvVar && <Env className='mr-1 h-3.5 w-3.5 shrink-0 text-util-colors-violet-violet-600' />} | |||||
| {isChatVar && <BubbleX className='h-3.5 w-3.5 text-util-colors-teal-teal-700' />} | |||||
| <div | |||||
| className={cn( | |||||
| 'shrink-0 truncate text-xs font-medium text-text-accent', | |||||
| !notHasValue && 'max-w-[70px]', | |||||
| )} | |||||
| title={variableName} | |||||
| > | |||||
| {variableName} | |||||
| </div> | |||||
| <VariableLabelInNode | |||||
| className='w-0 grow' | |||||
| variables={variableSelector} | |||||
| notShowFullPath | |||||
| /> | |||||
| <div | <div | ||||
| className='mx-1 shrink-0 text-xs font-medium text-text-primary' | className='mx-1 shrink-0 text-xs font-medium text-text-primary' | ||||
| title={operatorName} | title={operatorName} |
| isComparisonOperatorNeedTranslate, | isComparisonOperatorNeedTranslate, | ||||
| } from '../utils' | } from '../utils' | ||||
| import { FILE_TYPE_OPTIONS, TRANSFER_METHOD } from '../../constants' | import { FILE_TYPE_OPTIONS, TRANSFER_METHOD } from '../../constants' | ||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | |||||
| import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others' | |||||
| import cn from '@/utils/classnames' | |||||
| import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { isExceptionVariable } from '@/app/components/workflow/utils' | import { isExceptionVariable } from '@/app/components/workflow/utils' | ||||
| import type { | import type { | ||||
| CommonNodeType, | CommonNodeType, | ||||
| Node, | Node, | ||||
| } from '@/app/components/workflow/types' | } from '@/app/components/workflow/types' | ||||
| import { | |||||
| VariableLabelInText, | |||||
| } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| type ConditionValueProps = { | type ConditionValueProps = { | ||||
| variableSelector: string[] | variableSelector: string[] | ||||
| const variableName = labelName || (isSystemVar(variableSelector) ? variableSelector.slice(0).join('.') : variableSelector.slice(1).join('.')) | const variableName = labelName || (isSystemVar(variableSelector) ? variableSelector.slice(0).join('.') : variableSelector.slice(1).join('.')) | ||||
| const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`workflow.nodes.ifElse.comparisonOperator.${operator}`) : operator | const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`workflow.nodes.ifElse.comparisonOperator.${operator}`) : operator | ||||
| const notHasValue = comparisonOperatorNotRequireValue(operator) | const notHasValue = comparisonOperatorNotRequireValue(operator) | ||||
| const isEnvVar = isENV(variableSelector) | |||||
| const isChatVar = isConversationVar(variableSelector) | |||||
| const node: Node<CommonNodeType> | undefined = nodes.find(n => n.id === variableSelector[0]) as Node<CommonNodeType> | const node: Node<CommonNodeType> | undefined = nodes.find(n => n.id === variableSelector[0]) as Node<CommonNodeType> | ||||
| const isException = isExceptionVariable(variableName, node?.data.type) | const isException = isExceptionVariable(variableName, node?.data.type) | ||||
| const formatValue = useMemo(() => { | const formatValue = useMemo(() => { | ||||
| return ( | return ( | ||||
| <div className='flex h-6 items-center rounded-md bg-workflow-block-parma-bg px-1'> | <div className='flex h-6 items-center rounded-md bg-workflow-block-parma-bg px-1'> | ||||
| {!isEnvVar && !isChatVar && <Variable02 className={cn('mr-1 h-3.5 w-3.5 shrink-0 text-text-accent', isException && 'text-text-warning')} />} | |||||
| {isEnvVar && <Env className='mr-1 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' />} | |||||
| <div | |||||
| className={cn( | |||||
| 'ml-0.5 shrink-[2] truncate text-xs font-medium text-text-accent', | |||||
| !notHasValue && 'max-w-[70px]', | |||||
| isException && 'text-text-warning', | |||||
| )} | |||||
| title={variableName} | |||||
| > | |||||
| {variableName} | |||||
| </div> | |||||
| <VariableLabelInText | |||||
| className='w-0 grow' | |||||
| variables={variableSelector} | |||||
| nodeTitle={node?.data.title} | |||||
| nodeType={node?.data.type} | |||||
| isExceptionVariable={isException} | |||||
| notShowFullPath | |||||
| /> | |||||
| <div | <div | ||||
| className='mx-1 shrink-0 text-xs font-medium text-text-primary' | className='mx-1 shrink-0 text-xs font-medium text-text-primary' | ||||
| title={operatorName} | title={operatorName} |
| import React from 'react' | import React from 'react' | ||||
| import { useNodes } from 'reactflow' | import { useNodes } from 'reactflow' | ||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||
| import NodeVariableItem from '../variable-assigner/components/node-variable-item' | |||||
| import type { ListFilterNodeType } from './types' | import type { ListFilterNodeType } from './types' | ||||
| import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { BlockEnum, type Node, type NodeProps } from '@/app/components/workflow/types' | import { BlockEnum, type Node, type NodeProps } from '@/app/components/workflow/types' | ||||
| import { | |||||
| VariableLabelInNode, | |||||
| } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| const i18nPrefix = 'workflow.nodes.listFilter' | const i18nPrefix = 'workflow.nodes.listFilter' | ||||
| return null | return null | ||||
| const isSystem = isSystemVar(variable) | const isSystem = isSystemVar(variable) | ||||
| const isEnv = isENV(variable) | |||||
| const isChatVar = isConversationVar(variable) | |||||
| const node = isSystem ? nodes.find(node => node.data.type === BlockEnum.Start) : nodes.find(node => node.id === variable[0]) | const node = isSystem ? nodes.find(node => node.data.type === BlockEnum.Start) : nodes.find(node => node.id === variable[0]) | ||||
| const varName = isSystem ? `sys.${variable[variable.length - 1]}` : variable.slice(1).join('.') | |||||
| return ( | return ( | ||||
| <div className='relative px-3'> | <div className='relative px-3'> | ||||
| <div className='system-2xs-medium-uppercase mb-1 text-text-tertiary'>{t(`${i18nPrefix}.inputVar`)}</div> | <div className='system-2xs-medium-uppercase mb-1 text-text-tertiary'>{t(`${i18nPrefix}.inputVar`)}</div> | ||||
| <NodeVariableItem | |||||
| node={node as Node} | |||||
| isEnv={isEnv} | |||||
| isChatVar={isChatVar} | |||||
| varName={varName} | |||||
| className='bg-workflow-block-parma-bg' | |||||
| <VariableLabelInNode | |||||
| variables={variable} | |||||
| nodeType={node?.data.type} | |||||
| nodeTitle={node?.data.title} | |||||
| /> | /> | ||||
| </div> | </div> | ||||
| ) | ) |
| } from '../utils' | } from '../utils' | ||||
| import type { ValueSelector } from '../../../types' | import type { ValueSelector } from '../../../types' | ||||
| import { FILE_TYPE_OPTIONS, TRANSFER_METHOD } from './../default' | import { FILE_TYPE_OPTIONS, TRANSFER_METHOD } from './../default' | ||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | |||||
| import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others' | |||||
| import cn from '@/utils/classnames' | |||||
| import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { | |||||
| VariableLabelInNode, | |||||
| } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| const i18nPrefix = 'workflow.nodes.ifElse' | const i18nPrefix = 'workflow.nodes.ifElse' | ||||
| type ConditionValueProps = { | type ConditionValueProps = { | ||||
| const variableSelector = variable_selector as ValueSelector | const variableSelector = variable_selector as ValueSelector | ||||
| const variableName = (isSystemVar(variableSelector) ? variableSelector.slice(0).join('.') : variableSelector.slice(1).join('.')) | |||||
| const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`workflow.nodes.ifElse.comparisonOperator.${operator}`) : operator | const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`workflow.nodes.ifElse.comparisonOperator.${operator}`) : operator | ||||
| const notHasValue = comparisonOperatorNotRequireValue(operator) | |||||
| const isEnvVar = isENV(variableSelector) | |||||
| const isChatVar = isConversationVar(variableSelector) | |||||
| const formatValue = useCallback((c: Condition) => { | const formatValue = useCallback((c: Condition) => { | ||||
| const notHasValue = comparisonOperatorNotRequireValue(c.comparison_operator) | const notHasValue = comparisonOperatorNotRequireValue(c.comparison_operator) | ||||
| if (notHasValue) | if (notHasValue) | ||||
| return ( | return ( | ||||
| <div className='rounded-md bg-workflow-block-parma-bg'> | <div className='rounded-md bg-workflow-block-parma-bg'> | ||||
| <div className='flex h-6 items-center px-1 '> | <div className='flex h-6 items-center px-1 '> | ||||
| {!isEnvVar && !isChatVar && <Variable02 className='mr-1 h-3.5 w-3.5 shrink-0 text-text-accent' />} | |||||
| {isEnvVar && <Env className='mr-1 h-3.5 w-3.5 shrink-0 text-util-colors-violet-violet-600' />} | |||||
| {isChatVar && <BubbleX className='h-3.5 w-3.5 text-util-colors-teal-teal-700' />} | |||||
| <div | |||||
| className={cn( | |||||
| 'shrink-0 truncate text-xs font-medium text-text-accent', | |||||
| !notHasValue && 'max-w-[70px]', | |||||
| )} | |||||
| title={variableName} | |||||
| > | |||||
| {variableName} | |||||
| </div> | |||||
| <VariableLabelInNode | |||||
| className='w-0 grow' | |||||
| variables={variableSelector} | |||||
| notShowFullPath | |||||
| /> | |||||
| <div | <div | ||||
| className='mx-1 shrink-0 text-xs font-medium text-text-primary' | className='mx-1 shrink-0 text-xs font-medium text-text-primary' | ||||
| title={operatorName} | title={operatorName} |
| isComparisonOperatorNeedTranslate, | isComparisonOperatorNeedTranslate, | ||||
| } from '../utils' | } from '../utils' | ||||
| import { FILE_TYPE_OPTIONS, TRANSFER_METHOD } from './../default' | import { FILE_TYPE_OPTIONS, TRANSFER_METHOD } from './../default' | ||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | |||||
| import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others' | |||||
| import cn from '@/utils/classnames' | |||||
| import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { | |||||
| VariableLabelInNode, | |||||
| } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| type ConditionValueProps = { | type ConditionValueProps = { | ||||
| variableSelector: string[] | variableSelector: string[] | ||||
| value, | value, | ||||
| }: ConditionValueProps) => { | }: ConditionValueProps) => { | ||||
| const { t } = useTranslation() | const { t } = useTranslation() | ||||
| const variableName = labelName || (isSystemVar(variableSelector) ? variableSelector.slice(0).join('.') : variableSelector.slice(1).join('.')) | |||||
| const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`workflow.nodes.ifElse.comparisonOperator.${operator}`) : operator | const operatorName = isComparisonOperatorNeedTranslate(operator) ? t(`workflow.nodes.ifElse.comparisonOperator.${operator}`) : operator | ||||
| const notHasValue = comparisonOperatorNotRequireValue(operator) | const notHasValue = comparisonOperatorNotRequireValue(operator) | ||||
| const isEnvVar = isENV(variableSelector) | |||||
| const isChatVar = isConversationVar(variableSelector) | |||||
| const formatValue = useMemo(() => { | const formatValue = useMemo(() => { | ||||
| if (notHasValue) | if (notHasValue) | ||||
| return '' | return '' | ||||
| return ( | return ( | ||||
| <div className='flex h-6 items-center rounded-md bg-workflow-block-parma-bg px-1'> | <div className='flex h-6 items-center rounded-md bg-workflow-block-parma-bg px-1'> | ||||
| {!isEnvVar && !isChatVar && <Variable02 className='mr-1 h-3.5 w-3.5 shrink-0 text-text-accent' />} | |||||
| {isEnvVar && <Env className='mr-1 h-3.5 w-3.5 shrink-0 text-util-colors-violet-violet-600' />} | |||||
| {isChatVar && <BubbleX className='h-3.5 w-3.5 text-util-colors-teal-teal-700' />} | |||||
| <div | |||||
| className={cn( | |||||
| 'shrink-0 truncate text-xs font-medium text-text-accent', | |||||
| !notHasValue && 'max-w-[70px]', | |||||
| )} | |||||
| title={variableName} | |||||
| > | |||||
| {variableName} | |||||
| </div> | |||||
| <VariableLabelInNode | |||||
| className='w-0 grow' | |||||
| variables={variableSelector} | |||||
| notShowFullPath | |||||
| /> | |||||
| <div | <div | ||||
| className='mx-1 shrink-0 text-xs font-medium text-text-primary' | className='mx-1 shrink-0 text-xs font-medium text-text-primary' | ||||
| title={operatorName} | title={operatorName} |
| } from '../hooks' | } from '../hooks' | ||||
| import { filterVar } from '../utils' | import { filterVar } from '../utils' | ||||
| import AddVariable from './add-variable' | import AddVariable from './add-variable' | ||||
| import NodeVariableItem from './node-variable-item' | |||||
| import { isConversationVar, isENV, isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import { isSystemVar } from '@/app/components/workflow/nodes/_base/components/variable/utils' | |||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import { isExceptionVariable } from '@/app/components/workflow/utils' | import { isExceptionVariable } from '@/app/components/workflow/utils' | ||||
| import { | |||||
| VariableLabelInNode, | |||||
| } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| const i18nPrefix = 'workflow.nodes.variableAssigner' | const i18nPrefix = 'workflow.nodes.variableAssigner' | ||||
| type GroupItem = { | type GroupItem = { | ||||
| ) | ) | ||||
| } | } | ||||
| { | { | ||||
| !!item.variables.length && item.variables.map((variable = [], index) => { | |||||
| const isSystem = isSystemVar(variable) | |||||
| const isEnv = isENV(variable) | |||||
| const isChatVar = isConversationVar(variable) | |||||
| !!item.variables.length && ( | |||||
| <div className='space-y-0.5'> | |||||
| { | |||||
| item.variables.map((variable = [], index) => { | |||||
| const isSystem = isSystemVar(variable) | |||||
| const node = isSystem ? nodes.find(node => node.data.type === BlockEnum.Start) : nodes.find(node => node.id === variable[0]) | |||||
| const varName = isSystem ? `sys.${variable[variable.length - 1]}` : variable.slice(1).join('.') | |||||
| const isException = isExceptionVariable(varName, node?.data.type) | |||||
| const node = isSystem ? nodes.find(node => node.data.type === BlockEnum.Start) : nodes.find(node => node.id === variable[0]) | |||||
| const varName = isSystem ? `sys.${variable[variable.length - 1]}` : variable.slice(1).join('.') | |||||
| const isException = isExceptionVariable(varName, node?.data.type) | |||||
| return ( | |||||
| <NodeVariableItem | |||||
| key={index} | |||||
| isEnv={isEnv} | |||||
| isChatVar={isChatVar} | |||||
| isException={isException} | |||||
| node={node as Node} | |||||
| varName={varName} | |||||
| showBorder={showSelectedBorder || showSelectionBorder} | |||||
| /> | |||||
| ) | |||||
| }) | |||||
| return ( | |||||
| <VariableLabelInNode | |||||
| key={index} | |||||
| variables={variable} | |||||
| nodeType={node?.data.type} | |||||
| nodeTitle={node?.data.title} | |||||
| isExceptionVariable={isException} | |||||
| /> | |||||
| ) | |||||
| }) | |||||
| } | |||||
| </div> | |||||
| ) | |||||
| } | } | ||||
| </div> | </div> | ||||
| ) | ) |
| import { | |||||
| memo, | |||||
| useMemo, | |||||
| } from 'react' | |||||
| import { useTranslation } from 'react-i18next' | |||||
| import cn from '@/utils/classnames' | |||||
| import { VarBlockIcon } from '@/app/components/workflow/block-icon' | |||||
| import { Line3 } from '@/app/components/base/icons/src/public/common' | |||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | |||||
| import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others' | |||||
| import Badge from '@/app/components/base/badge' | |||||
| import type { Node } from '@/app/components/workflow/types' | |||||
| type NodeVariableItemProps = { | |||||
| isEnv: boolean | |||||
| isChatVar: boolean | |||||
| node: Node | |||||
| varName: string | |||||
| writeMode?: string | |||||
| showBorder?: boolean | |||||
| className?: string | |||||
| isException?: boolean | |||||
| } | |||||
| const i18nPrefix = 'workflow.nodes.assigner' | |||||
| const NodeVariableItem = ({ | |||||
| isEnv, | |||||
| isChatVar, | |||||
| node, | |||||
| varName, | |||||
| writeMode, | |||||
| showBorder, | |||||
| className, | |||||
| isException, | |||||
| }: NodeVariableItemProps) => { | |||||
| const { t } = useTranslation() | |||||
| const VariableIcon = useMemo(() => { | |||||
| if (isEnv) { | |||||
| return ( | |||||
| <Env className='h-3.5 w-3.5 shrink-0 text-util-colors-violet-violet-600' /> | |||||
| ) | |||||
| } | |||||
| if (isChatVar) { | |||||
| return ( | |||||
| <BubbleX className='h-3.5 w-3.5 shrink-0 text-util-colors-teal-teal-700' /> | |||||
| ) | |||||
| } | |||||
| return ( | |||||
| <Variable02 | |||||
| className={cn( | |||||
| 'h-3.5 w-3.5 shrink-0 text-text-accent', | |||||
| isException && 'text-text-warning', | |||||
| )} | |||||
| /> | |||||
| ) | |||||
| }, [isEnv, isChatVar, isException]) | |||||
| const VariableName = useMemo(() => { | |||||
| return ( | |||||
| <div | |||||
| className={cn( | |||||
| 'system-xs-medium ml-0.5 shrink truncate text-text-accent', | |||||
| isEnv && 'text-text-primary', | |||||
| isException && 'text-text-warning', | |||||
| isChatVar && 'text-util-colors-teal-teal-700', | |||||
| )} | |||||
| title={varName} | |||||
| > | |||||
| {varName} | |||||
| </div> | |||||
| ) | |||||
| }, [isEnv, isChatVar, varName, isException]) | |||||
| return ( | |||||
| <div className={cn( | |||||
| 'relative flex items-center gap-1 self-stretch rounded-md bg-workflow-block-parma-bg p-[3px] pl-[5px]', | |||||
| showBorder && '!bg-state-base-hover', | |||||
| className, | |||||
| )}> | |||||
| <div className='flex w-0 grow items-center'> | |||||
| { | |||||
| node && ( | |||||
| <> | |||||
| <div className='shrink-0 p-[1px]'> | |||||
| <VarBlockIcon | |||||
| className='!text-text-primary' | |||||
| type={node.data.type} | |||||
| /> | |||||
| </div> | |||||
| <div | |||||
| className='mx-0.5 shrink-[1000] truncate text-xs font-medium text-text-secondary' | |||||
| title={node?.data.title} | |||||
| > | |||||
| {node?.data.title} | |||||
| </div> | |||||
| <Line3 className='mr-0.5 shrink-0'></Line3> | |||||
| </> | |||||
| ) | |||||
| } | |||||
| {VariableIcon} | |||||
| {VariableName} | |||||
| </div> | |||||
| {writeMode && <Badge className='shrink-0' text={t(`${i18nPrefix}.operations.${writeMode}`)} />} | |||||
| </div> | |||||
| ) | |||||
| } | |||||
| export default memo(NodeVariableItem) |
| import ActionButton from '@/app/components/base/action-button' | import ActionButton from '@/app/components/base/action-button' | ||||
| import Tooltip from '@/app/components/base/tooltip' | import Tooltip from '@/app/components/base/tooltip' | ||||
| import BlockIcon from '@/app/components/workflow/block-icon' | import BlockIcon from '@/app/components/workflow/block-icon' | ||||
| import { | |||||
| BubbleX, | |||||
| Env, | |||||
| } from '@/app/components/base/icons/src/vender/line/others' | |||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | |||||
| import type { currentVarType } from './panel' | import type { currentVarType } from './panel' | ||||
| import { VarInInspectType } from '@/types/workflow' | import { VarInInspectType } from '@/types/workflow' | ||||
| import type { NodeWithVar, VarInInspect } from '@/types/workflow' | import type { NodeWithVar, VarInInspect } from '@/types/workflow' | ||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import { useToolIcon } from '../hooks' | import { useToolIcon } from '../hooks' | ||||
| import { VariableIconWithColor } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| type Props = { | type Props = { | ||||
| nodeData?: NodeWithVar | nodeData?: NodeWithVar | ||||
| )} | )} | ||||
| onClick={() => handleSelectVar(varItem, varType)} | onClick={() => handleSelectVar(varItem, varType)} | ||||
| > | > | ||||
| {isEnv && <Env className='h-4 w-4 shrink-0 text-util-colors-violet-violet-600' />} | |||||
| {isChatVar && <BubbleX className='h-4 w-4 shrink-0 text-util-colors-teal-teal-700' />} | |||||
| {(isSystem || nodeData) && <Variable02 className={cn('h-4 w-4 shrink-0 text-text-accent', ['error_type', 'error_message'].includes(varItem.name) && 'text-text-warning')} />} | |||||
| <VariableIconWithColor | |||||
| variableCategory={varType} | |||||
| isExceptionVariable={['error_type', 'error_message'].includes(varItem.name)} | |||||
| className='size-4' | |||||
| /> | |||||
| <div className='system-sm-medium grow truncate text-text-secondary'>{varItem.name}</div> | <div className='system-sm-medium grow truncate text-text-secondary'>{varItem.name}</div> | ||||
| <div className='system-xs-regular shrink-0 text-text-tertiary'>{varItem.value_type}</div> | <div className='system-xs-regular shrink-0 text-text-tertiary'>{varItem.value_type}</div> | ||||
| </div> | </div> |
| import CopyFeedback from '@/app/components/base/copy-feedback' | import CopyFeedback from '@/app/components/base/copy-feedback' | ||||
| import Tooltip from '@/app/components/base/tooltip' | import Tooltip from '@/app/components/base/tooltip' | ||||
| import BlockIcon from '@/app/components/workflow/block-icon' | import BlockIcon from '@/app/components/workflow/block-icon' | ||||
| import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others' | |||||
| import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development' | |||||
| import Loading from '@/app/components/base/loading' | import Loading from '@/app/components/base/loading' | ||||
| import type { currentVarType } from './panel' | import type { currentVarType } from './panel' | ||||
| import { VarInInspectType } from '@/types/workflow' | import { VarInInspectType } from '@/types/workflow' | ||||
| import cn from '@/utils/classnames' | import cn from '@/utils/classnames' | ||||
| import { VariableIconWithColor } from '@/app/components/workflow/nodes/_base/components/variable/variable-label' | |||||
| type Props = { | type Props = { | ||||
| currentNodeVar?: currentVarType | currentNodeVar?: currentVarType | ||||
| <div className='flex w-0 grow items-center gap-1'> | <div className='flex w-0 grow items-center gap-1'> | ||||
| {currentNodeVar && ( | {currentNodeVar && ( | ||||
| <> | <> | ||||
| {currentNodeVar.nodeType === VarInInspectType.environment && ( | |||||
| <Env className='h-4 w-4 shrink-0 text-util-colors-violet-violet-600' /> | |||||
| )} | |||||
| {currentNodeVar.nodeType === VarInInspectType.conversation && ( | |||||
| <BubbleX className='h-4 w-4 shrink-0 text-util-colors-teal-teal-700' /> | |||||
| )} | |||||
| {currentNodeVar.nodeType === VarInInspectType.system && ( | |||||
| <Variable02 className='h-4 w-4 shrink-0 text-text-accent' /> | |||||
| )} | |||||
| { | |||||
| [VarInInspectType.environment, VarInInspectType.conversation, VarInInspectType.system].includes(currentNodeVar.nodeType as VarInInspectType) && ( | |||||
| <VariableIconWithColor | |||||
| variableCategory={currentNodeVar.nodeType as VarInInspectType} | |||||
| className='size-4' | |||||
| /> | |||||
| ) | |||||
| } | |||||
| {currentNodeVar.nodeType !== VarInInspectType.environment && currentNodeVar.nodeType !== VarInInspectType.conversation && currentNodeVar.nodeType !== VarInInspectType.system && ( | {currentNodeVar.nodeType !== VarInInspectType.environment && currentNodeVar.nodeType !== VarInInspectType.conversation && currentNodeVar.nodeType !== VarInInspectType.system && ( | ||||
| <> | <> | ||||
| <BlockIcon | <BlockIcon |