diff --git a/web/app/components/workflow/nodes/_base/components/selector.tsx b/web/app/components/workflow/nodes/_base/components/selector.tsx index 05e5be406e..dd00c69794 100644 --- a/web/app/components/workflow/nodes/_base/components/selector.tsx +++ b/web/app/components/workflow/nodes/_base/components/selector.tsx @@ -15,6 +15,7 @@ type Props = { noLeft?: boolean options: Item[] value: string + placeholder?: string onChange: (value: any) => void uppercase?: boolean popupClassName?: string @@ -30,6 +31,7 @@ const TypeSelector: FC = ({ noLeft, options: list, value, + placeholder = '', onChange, uppercase, triggerClassName, @@ -38,6 +40,7 @@ const TypeSelector: FC = ({ readonly, showChecked, }) => { + const noValue = value === '' || value === undefined || value === null const item = list.find(item => item.value === value) const [showOption, { setFalse: setHide, toggle: toggleShow }] = useBoolean(false) const ref = React.useRef(null) @@ -58,7 +61,7 @@ const TypeSelector: FC = ({
-
{item?.label}
+
{!noValue ? item?.label : placeholder}
)} diff --git a/web/app/components/workflow/nodes/if-else/components/condition-item.tsx b/web/app/components/workflow/nodes/if-else/components/condition-item.tsx index e47163920e..34130be553 100644 --- a/web/app/components/workflow/nodes/if-else/components/condition-item.tsx +++ b/web/app/components/workflow/nodes/if-else/components/condition-item.tsx @@ -91,7 +91,7 @@ const Item: FC = ({ filterVar, }) => { const { t } = useTranslation() - const isValueReadOnly = [ComparisonOperator.empty, ComparisonOperator.notEmpty, ComparisonOperator.isNull, ComparisonOperator.isNotNull].includes(payload.comparison_operator) + const isValueReadOnly = payload.comparison_operator ? [ComparisonOperator.empty, ComparisonOperator.notEmpty, ComparisonOperator.isNull, ComparisonOperator.isNotNull].includes(payload.comparison_operator) : false const handleVarReferenceChange = useCallback((value: ValueSelector | string) => { onChange({ @@ -156,18 +156,23 @@ const Item: FC = ({ if (!varType) { e.stopPropagation() Toast.notify({ - message: 'please selector var first', // t(`${i18nPrefix}.selectVarType`) + message: t(`${i18nPrefix}.notSetVariable`), type: 'error', }) } }} className='shrink-0 w-[100px] whitespace-nowrap flex items-center h-8 justify-between px-2.5 rounded-lg bg-gray-100 capitalize cursor-pointer' > -
{isComparisonOperatorNeedTranslate(payload.comparison_operator) ? t(`${i18nPrefix}.comparisonOperator.${payload.comparison_operator}`) : payload.comparison_operator}
+ { + !payload.comparison_operator + ?
{t(`${i18nPrefix}.operator`)}
+ :
{isComparisonOperatorNeedTranslate(payload.comparison_operator) ? t(`${i18nPrefix}.comparisonOperator.${payload.comparison_operator}`) : payload.comparison_operator}
+ } + } readonly={readonly} - value={payload.comparison_operator} + value={payload.comparison_operator || ''} options={getOperators(varType).map((o) => { return { label: isComparisonOperatorNeedTranslate(o) ? t(`${i18nPrefix}.comparisonOperator.${o}`) : o, @@ -178,10 +183,18 @@ const Item: FC = ({ /> { + if (!varType) { + Toast.notify({ + message: t(`${i18nPrefix}.notSetVariable`), + type: 'error', + }) + } + }} value={!isValueReadOnly ? payload.value : ''} onChange={handleValueChange} - placeholder={!isValueReadOnly ? t(`${i18nPrefix}.enterValue`)! : ''} + placeholder={(!readonly && !isValueReadOnly) ? t(`${i18nPrefix}.enterValue`)! : ''} className='w-[80px] h-8 leading-8 px-2.5 rounded-lg border-0 bg-gray-100 text-gray-900 text-[13px] placeholder:text-gray-400 focus:outline-none focus:ring-1 focus:ring-inset focus:ring-gray-200' type='text' /> diff --git a/web/app/components/workflow/nodes/if-else/default.ts b/web/app/components/workflow/nodes/if-else/default.ts index c0e44cb499..65f850c76c 100644 --- a/web/app/components/workflow/nodes/if-else/default.ts +++ b/web/app/components/workflow/nodes/if-else/default.ts @@ -1,7 +1,7 @@ import { BlockEnum, type NodeDefault } from '../../types' import { type IfElseNodeType, LogicalOperator } from './types' +import { isEmptyRelatedOperator } from './utils' import { ALL_CHAT_AVAILABLE_BLOCKS, ALL_COMPLETION_AVAILABLE_BLOCKS } from '@/app/components/workflow/constants' - const i18nPrefix = 'workflow.errorMsg' const nodeDefault: NodeDefault = { @@ -38,7 +38,9 @@ const nodeDefault: NodeDefault = { conditions.forEach((condition) => { if (!errorMessages && (!condition.variable_selector || condition.variable_selector.length === 0)) errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t(`${i18nPrefix}.fields.variable`) }) - if (!errorMessages && !condition.value) + if (!errorMessages && !condition.comparison_operator) + errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t('workflow.nodes.ifElse.operator') }) + if (!errorMessages && !isEmptyRelatedOperator(condition.comparison_operator!) && !condition.value) errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t(`${i18nPrefix}.fields.variableValue`) }) }) return { diff --git a/web/app/components/workflow/nodes/if-else/node.tsx b/web/app/components/workflow/nodes/if-else/node.tsx index 11677f352f..ce2413d640 100644 --- a/web/app/components/workflow/nodes/if-else/node.tsx +++ b/web/app/components/workflow/nodes/if-else/node.tsx @@ -25,13 +25,13 @@ const IfElseNode: FC> = (props) => {
{t(`${i18nPrefix}.conditions`)}
- {conditions.map((condition, i) => ( + {conditions.filter(item => (item.variable_selector && item.variable_selector.length > 0 && item.comparison_operator && (isEmptyRelatedOperator(item.comparison_operator!) ? true : !!item.value))).map((condition, i) => (
{condition.variable_selector.slice(-1)[0]} {isComparisonOperatorNeedTranslate(condition.comparison_operator) ? t(`${i18nPrefix}.comparisonOperator.${condition.comparison_operator}`) : condition.comparison_operator} - {!isEmptyRelatedOperator(condition.comparison_operator) && {condition.value}} + {!isEmptyRelatedOperator(condition.comparison_operator!) && {condition.value}}
{i !== conditions.length - 1 && (
{t(`${i18nPrefix}.${logical_operator}`)}
diff --git a/web/app/components/workflow/nodes/if-else/types.ts b/web/app/components/workflow/nodes/if-else/types.ts index a952f39184..45adf375e5 100644 --- a/web/app/components/workflow/nodes/if-else/types.ts +++ b/web/app/components/workflow/nodes/if-else/types.ts @@ -27,7 +27,7 @@ export enum ComparisonOperator { export type Condition = { id: string variable_selector: ValueSelector - comparison_operator: ComparisonOperator + comparison_operator?: ComparisonOperator value: string } diff --git a/web/app/components/workflow/nodes/if-else/use-config.ts b/web/app/components/workflow/nodes/if-else/use-config.ts index f5bc36a0ee..993641ba89 100644 --- a/web/app/components/workflow/nodes/if-else/use-config.ts +++ b/web/app/components/workflow/nodes/if-else/use-config.ts @@ -3,7 +3,7 @@ import produce from 'immer' import type { Var } from '../../types' import { VarType } from '../../types' import { getVarType } from '../_base/components/variable/utils' -import { ComparisonOperator, LogicalOperator } from './types' +import { LogicalOperator } from './types' import type { Condition, IfElseNodeType } from './types' import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud' import { @@ -30,7 +30,7 @@ const useConfig = (id: string, payload: IfElseNodeType) => { draft.conditions.push({ id: `${Date.now()}`, variable_selector: [], - comparison_operator: ComparisonOperator.equal, + comparison_operator: undefined, value: '', }) }) diff --git a/web/app/components/workflow/nodes/if-else/utils.ts b/web/app/components/workflow/nodes/if-else/utils.ts index 55b1f656f6..51858c64aa 100644 --- a/web/app/components/workflow/nodes/if-else/utils.ts +++ b/web/app/components/workflow/nodes/if-else/utils.ts @@ -1,20 +1,17 @@ -import type { IfElseNodeType } from './types' import { ComparisonOperator } from './types' export const isEmptyRelatedOperator = (operator: ComparisonOperator) => { return [ComparisonOperator.empty, ComparisonOperator.notEmpty, ComparisonOperator.isNull, ComparisonOperator.isNotNull].includes(operator) } -export const checkNodeValid = (payload: IfElseNodeType) => { - return true -} - const notTranslateKey = [ ComparisonOperator.equal, ComparisonOperator.notEqual, ComparisonOperator.largerThan, ComparisonOperator.largerThanOrEqual, ComparisonOperator.lessThan, ComparisonOperator.lessThanOrEqual, ] -export const isComparisonOperatorNeedTranslate = (operator: ComparisonOperator) => { +export const isComparisonOperatorNeedTranslate = (operator?: ComparisonOperator) => { + if (!operator) + return false return !notTranslateKey.includes(operator) } diff --git a/web/i18n/en-US/workflow.ts b/web/i18n/en-US/workflow.ts index a1f717ade3..85677eb416 100644 --- a/web/i18n/en-US/workflow.ts +++ b/web/i18n/en-US/workflow.ts @@ -231,6 +231,8 @@ const translation = { elseDescription: 'Used to define the logic that should be executed when the if condition is not met.', and: 'and', or: 'or', + operator: 'Operator', + notSetVariable: 'Please set variable first', comparisonOperator: { 'contains': 'contains', 'not contains': 'not contains', diff --git a/web/i18n/zh-Hans/workflow.ts b/web/i18n/zh-Hans/workflow.ts index dc868fd992..13e0615072 100644 --- a/web/i18n/zh-Hans/workflow.ts +++ b/web/i18n/zh-Hans/workflow.ts @@ -231,6 +231,8 @@ const translation = { elseDescription: '用于定义当 if 条件不满足时应执行的逻辑。', and: 'and', or: 'or', + operator: '操作符', + notSetVariable: '请先设置变量', comparisonOperator: { 'contains': '包含', 'not contains': '不包含',