mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-14 23:06:15 +08:00
fix: when the variable does not exist, an error should be prompted (#8413)
Co-authored-by: Chen(MAC) <chenchen404@outlook.com>
This commit is contained in:
parent
f01602b570
commit
5b18e851d2
@ -1,9 +1,12 @@
|
|||||||
import { useMemo } from 'react'
|
import { useMemo } from 'react'
|
||||||
import { useNodes } from 'reactflow'
|
import { useNodes } from 'reactflow'
|
||||||
import { capitalize } from 'lodash-es'
|
import { capitalize } from 'lodash-es'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import { RiErrorWarningFill } from '@remixicon/react'
|
||||||
import { VarBlockIcon } from '@/app/components/workflow/block-icon'
|
import { VarBlockIcon } from '@/app/components/workflow/block-icon'
|
||||||
import type {
|
import type {
|
||||||
CommonNodeType,
|
CommonNodeType,
|
||||||
|
Node,
|
||||||
ValueSelector,
|
ValueSelector,
|
||||||
VarType,
|
VarType,
|
||||||
} from '@/app/components/workflow/types'
|
} from '@/app/components/workflow/types'
|
||||||
@ -11,49 +14,59 @@ import { BlockEnum } from '@/app/components/workflow/types'
|
|||||||
import { Line3 } from '@/app/components/base/icons/src/public/common'
|
import { Line3 } from '@/app/components/base/icons/src/public/common'
|
||||||
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
|
import { Variable02 } from '@/app/components/base/icons/src/vender/solid/development'
|
||||||
import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others'
|
import { BubbleX, Env } from '@/app/components/base/icons/src/vender/line/others'
|
||||||
import { 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 cn from '@/utils/classnames'
|
||||||
|
|
||||||
type VariableTagProps = {
|
type VariableTagProps = {
|
||||||
valueSelector: ValueSelector
|
valueSelector: ValueSelector
|
||||||
varType: VarType
|
varType: VarType
|
||||||
|
availableNodes?: Node[]
|
||||||
}
|
}
|
||||||
const VariableTag = ({
|
const VariableTag = ({
|
||||||
valueSelector,
|
valueSelector,
|
||||||
varType,
|
varType,
|
||||||
|
availableNodes,
|
||||||
}: VariableTagProps) => {
|
}: VariableTagProps) => {
|
||||||
const nodes = useNodes<CommonNodeType>()
|
const nodes = useNodes<CommonNodeType>()
|
||||||
const node = useMemo(() => {
|
const node = useMemo(() => {
|
||||||
if (isSystemVar(valueSelector))
|
if (isSystemVar(valueSelector)) {
|
||||||
return nodes.find(node => node.data.type === BlockEnum.Start)
|
const startNode = availableNodes?.find(n => n.data.type === BlockEnum.Start)
|
||||||
|
if (startNode)
|
||||||
|
return startNode
|
||||||
|
}
|
||||||
|
return getNodeInfoById(availableNodes || nodes, valueSelector[0])
|
||||||
|
}, [nodes, valueSelector, availableNodes])
|
||||||
|
|
||||||
return nodes.find(node => node.id === valueSelector[0])
|
|
||||||
}, [nodes, valueSelector])
|
|
||||||
const isEnv = isENV(valueSelector)
|
const isEnv = isENV(valueSelector)
|
||||||
const isChatVar = isConversationVar(valueSelector)
|
const isChatVar = isConversationVar(valueSelector)
|
||||||
|
const isValid = Boolean(node) || isEnv || isChatVar
|
||||||
|
|
||||||
const variableName = isSystemVar(valueSelector) ? valueSelector.slice(0).join('.') : valueSelector.slice(1).join('.')
|
const variableName = isSystemVar(valueSelector) ? valueSelector.slice(0).join('.') : valueSelector.slice(1).join('.')
|
||||||
|
|
||||||
|
const { t } = useTranslation()
|
||||||
return (
|
return (
|
||||||
<div className='inline-flex items-center px-1.5 max-w-full h-6 text-xs rounded-md border-[0.5px] border-[rgba(16, 2440,0.08)] bg-white shadow-xs'>
|
<Tooltip popupContent={!isValid && t('workflow.errorMsg.invalidVariable')}>
|
||||||
{!isEnv && !isChatVar && (
|
<div className={cn('inline-flex items-center px-1.5 max-w-full h-6 text-xs rounded-md border-[0.5px] border-[rgba(16, 2440,0.08)] bg-white shadow-xs',
|
||||||
<>
|
!isValid && 'border-red-400 !bg-[#FEF3F2]',
|
||||||
|
)}>
|
||||||
|
{(!isEnv && !isChatVar && <>
|
||||||
{node && (
|
{node && (
|
||||||
|
<>
|
||||||
<VarBlockIcon
|
<VarBlockIcon
|
||||||
className='shrink-0 mr-0.5 text-text-secondary'
|
type={BlockEnum.Start}
|
||||||
type={node!.data.type}
|
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
<div
|
<div
|
||||||
className='max-w-[60px] truncate text-text-secondary font-medium'
|
className='max-w-[60px] truncate text-text-secondary font-medium'
|
||||||
title={node?.data.title}
|
title={node?.data.title}
|
||||||
>
|
>
|
||||||
{node?.data.title}
|
{node?.data.title}
|
||||||
</div>
|
</div>
|
||||||
<Line3 className='shrink-0 mx-0.5' />
|
|
||||||
<Variable02 className='shrink-0 mr-0.5 w-3.5 h-3.5 text-text-accent' />
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
<Line3 className='shrink-0 mx-0.5' />
|
||||||
|
<Variable02 className='shrink-0 mr-0.5 w-3.5 h-3.5 text-text-accent' />
|
||||||
|
</>)}
|
||||||
{isEnv && <Env className='shrink-0 mr-0.5 w-3.5 h-3.5 text-util-colors-violet-violet-600' />}
|
{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' />}
|
{isChatVar && <BubbleX className='w-3.5 h-3.5 text-util-colors-teal-teal-700' />}
|
||||||
<div
|
<div
|
||||||
@ -67,7 +80,9 @@ const VariableTag = ({
|
|||||||
<div className='shrink-0 ml-0.5 text-text-tertiary'>{capitalize(varType)}</div>
|
<div className='shrink-0 ml-0.5 text-text-tertiary'>{capitalize(varType)}</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
{!isValid && <RiErrorWarningFill className='ml-0.5 w-3 h-3 text-[#D92D20]' />}
|
||||||
</div>
|
</div>
|
||||||
|
</Tooltip>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,9 +5,10 @@ import { useTranslation } from 'react-i18next'
|
|||||||
import {
|
import {
|
||||||
RiArrowDownSLine,
|
RiArrowDownSLine,
|
||||||
RiCloseLine,
|
RiCloseLine,
|
||||||
|
RiErrorWarningFill,
|
||||||
} from '@remixicon/react'
|
} from '@remixicon/react'
|
||||||
import produce from 'immer'
|
import produce from 'immer'
|
||||||
import { useStoreApi } from 'reactflow'
|
import { useEdges, useStoreApi } from 'reactflow'
|
||||||
import useAvailableVarList from '../../hooks/use-available-var-list'
|
import useAvailableVarList from '../../hooks/use-available-var-list'
|
||||||
import VarReferencePopup from './var-reference-popup'
|
import VarReferencePopup from './var-reference-popup'
|
||||||
import { getNodeInfoById, isConversationVar, isENV, isSystemVar } from './utils'
|
import { getNodeInfoById, isConversationVar, isENV, isSystemVar } from './utils'
|
||||||
@ -33,6 +34,8 @@ import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/typ
|
|||||||
import TypeSelector from '@/app/components/workflow/nodes/_base/components/selector'
|
import TypeSelector from '@/app/components/workflow/nodes/_base/components/selector'
|
||||||
import AddButton from '@/app/components/base/button/add-button'
|
import AddButton from '@/app/components/base/button/add-button'
|
||||||
import Badge from '@/app/components/base/badge'
|
import Badge from '@/app/components/base/badge'
|
||||||
|
import Tooltip from '@/app/components/base/tooltip'
|
||||||
|
|
||||||
const TRIGGER_DEFAULT_WIDTH = 227
|
const TRIGGER_DEFAULT_WIDTH = 227
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -77,6 +80,7 @@ const VarReferencePicker: FC<Props> = ({
|
|||||||
const {
|
const {
|
||||||
getNodes,
|
getNodes,
|
||||||
} = store.getState()
|
} = store.getState()
|
||||||
|
const edges = useEdges()
|
||||||
const isChatMode = useIsChatMode()
|
const isChatMode = useIsChatMode()
|
||||||
|
|
||||||
const { getCurrentVariableType } = useWorkflowVariables()
|
const { getCurrentVariableType } = useWorkflowVariables()
|
||||||
@ -206,8 +210,16 @@ const VarReferencePicker: FC<Props> = ({
|
|||||||
isConstant: !!isConstant,
|
isConstant: !!isConstant,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const { isEnv, isChatVar, isValidVar } = useMemo(() => {
|
||||||
const isEnv = isENV(value as ValueSelector)
|
const isEnv = isENV(value as ValueSelector)
|
||||||
const isChatVar = isConversationVar(value as ValueSelector)
|
const isChatVar = isConversationVar(value as ValueSelector)
|
||||||
|
const isValidVar = Boolean(outputVarNode) || isEnv || isChatVar
|
||||||
|
return {
|
||||||
|
isEnv,
|
||||||
|
isChatVar,
|
||||||
|
isValidVar,
|
||||||
|
}
|
||||||
|
}, [value, edges, outputVarNode])
|
||||||
|
|
||||||
// 8(left/right-padding) + 14(icon) + 4 + 14 + 2 = 42 + 17 buff
|
// 8(left/right-padding) + 14(icon) + 4 + 14 + 2 = 42 + 17 buff
|
||||||
const availableWidth = triggerWidth - 56
|
const availableWidth = triggerWidth - 56
|
||||||
@ -285,17 +297,20 @@ const VarReferencePicker: FC<Props> = ({
|
|||||||
className='grow h-full'
|
className='grow h-full'
|
||||||
>
|
>
|
||||||
<div ref={isSupportConstantValue ? triggerRef : null} className={cn('h-full', isSupportConstantValue && 'flex items-center pl-1 py-1 rounded-lg bg-gray-100')}>
|
<div ref={isSupportConstantValue ? triggerRef : null} className={cn('h-full', isSupportConstantValue && 'flex items-center pl-1 py-1 rounded-lg bg-gray-100')}>
|
||||||
<div className={cn('h-full items-center px-1.5 rounded-[5px]', hasValue ? 'bg-white inline-flex' : 'flex')}>
|
<Tooltip popupContent={!isValidVar && hasValue && t('workflow.errorMsg.invalidVariable')}>
|
||||||
|
<div className={cn('h-full items-center px-1.5 rounded-[5px] ', hasValue ? 'bg-white inline-flex' : 'flex',
|
||||||
|
!isValidVar && hasValue && 'border border-red-400 !bg-[#FEF3F2]',
|
||||||
|
)}>
|
||||||
{hasValue
|
{hasValue
|
||||||
? (
|
? (
|
||||||
<>
|
<>
|
||||||
{isShowNodeName && !isEnv && !isChatVar && (
|
{isShowNodeName && !isEnv && !isChatVar && (
|
||||||
<div className='flex items-center'>
|
<div className='flex items-center'>
|
||||||
<div className='p-[1px]'>
|
<div className='px-[1px] h-3'>
|
||||||
<VarBlockIcon
|
{outputVarNode?.type && <VarBlockIcon
|
||||||
className='!text-gray-900'
|
className='!text-gray-900'
|
||||||
type={outputVarNode?.type || BlockEnum.Start}
|
type={outputVarNode.type}
|
||||||
/>
|
/>}
|
||||||
</div>
|
</div>
|
||||||
<div className='mx-0.5 text-xs font-medium text-gray-700 truncate' title={outputVarNode?.title} style={{
|
<div className='mx-0.5 text-xs font-medium text-gray-700 truncate' title={outputVarNode?.title} style={{
|
||||||
maxWidth: maxNodeNameWidth,
|
maxWidth: maxNodeNameWidth,
|
||||||
@ -314,10 +329,12 @@ const VarReferencePicker: FC<Props> = ({
|
|||||||
<div className='ml-0.5 text-xs font-normal text-gray-500 capitalize truncate' title={type} style={{
|
<div className='ml-0.5 text-xs font-normal text-gray-500 capitalize truncate' title={type} style={{
|
||||||
maxWidth: maxTypeWidth,
|
maxWidth: maxTypeWidth,
|
||||||
}}>{type}</div>
|
}}>{type}</div>
|
||||||
|
{!isValidVar && <RiErrorWarningFill className='ml-0.5 w-3 h-3 text-[#D92D20]' /> }
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
: <div className='text-[13px] font-normal text-gray-400'>{t('workflow.common.setVarValuePlaceholder')}</div>}
|
: <div className='text-[13px] font-normal text-gray-400'>{t('workflow.common.setVarValuePlaceholder')}</div>}
|
||||||
</div>
|
</div>
|
||||||
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</VarPickerWrap>
|
</VarPickerWrap>
|
||||||
|
@ -80,6 +80,7 @@ const ConditionItem = ({
|
|||||||
<VariableTag
|
<VariableTag
|
||||||
valueSelector={condition.variable_selector}
|
valueSelector={condition.variable_selector}
|
||||||
varType={condition.varType}
|
varType={condition.varType}
|
||||||
|
availableNodes={availableNodes}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className='mx-1 w-[1px] h-3 bg-divider-regular'></div>
|
<div className='mx-1 w-[1px] h-3 bg-divider-regular'></div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user