diff --git a/web/app/components/workflow/nodes/start/components/var-item.tsx b/web/app/components/workflow/nodes/start/components/var-item.tsx index 029547542e..e51cd79734 100644 --- a/web/app/components/workflow/nodes/start/components/var-item.tsx +++ b/web/app/components/workflow/nodes/start/components/var-item.tsx @@ -19,7 +19,7 @@ type Props = { className?: string readonly: boolean payload: InputVar - onChange?: (item: InputVar, moreInfo?: MoreInfo) => void + onChange?: (item: InputVar, moreInfo?: MoreInfo) => boolean onRemove?: () => void rightContent?: React.JSX.Element varKeys?: string[] @@ -31,7 +31,7 @@ const VarItem: FC = ({ className, readonly, payload, - onChange = noop, + onChange = () => true, onRemove = noop, rightContent, varKeys = [], @@ -48,7 +48,9 @@ const VarItem: FC = ({ }] = useBoolean(false) const handlePayloadChange = useCallback((payload: InputVar, moreInfo?: MoreInfo) => { - onChange(payload, moreInfo) + const isValid = onChange(payload, moreInfo) + if(!isValid) + return hideEditVarModal() }, [onChange, hideEditVarModal]) return ( diff --git a/web/app/components/workflow/nodes/start/components/var-list.tsx b/web/app/components/workflow/nodes/start/components/var-list.tsx index 024b50a759..a3c307bbd4 100644 --- a/web/app/components/workflow/nodes/start/components/var-list.tsx +++ b/web/app/components/workflow/nodes/start/components/var-list.tsx @@ -9,6 +9,8 @@ import { v4 as uuid4 } from 'uuid' import { ReactSortable } from 'react-sortablejs' import { RiDraggable } from '@remixicon/react' import cn from '@/utils/classnames' +import { hasDuplicateStr } from '@/utils/var' +import Toast from '@/app/components/base/toast' type Props = { readonly: boolean @@ -28,7 +30,27 @@ const VarList: FC = ({ const newList = produce(list, (draft) => { draft[index] = payload }) + let errorMsgKey = '' + let typeName = '' + if(hasDuplicateStr(newList.map(item => item.variable))) { + errorMsgKey = 'appDebug.varKeyError.keyAlreadyExists' + typeName = 'appDebug.variableConfig.varName' + } + + if(hasDuplicateStr(newList.map(item => item.label as string))) { + errorMsgKey = 'appDebug.varKeyError.keyAlreadyExists' + typeName = 'appDebug.variableConfig.labelName' + } + + if (errorMsgKey) { + Toast.notify({ + type: 'error', + message: t(errorMsgKey, { key: t(typeName) }), + }) + return false + } onChange(newList, moreInfo ? { index, payload: moreInfo } : undefined) + return true } }, [list, onChange]) diff --git a/web/utils/var.ts b/web/utils/var.ts index bdc2fbdd42..4bbb7ca631 100644 --- a/web/utils/var.ts +++ b/web/utils/var.ts @@ -45,7 +45,7 @@ export const getNewVarInWorkflow = (key: string, type = InputVarType.textInput) } } -export const checkKey = (key: string, canBeEmpty?: boolean) => { +export const checkKey = (key: string, canBeEmpty?: boolean, keys?: string[]) => { if (key.length === 0 && !canBeEmpty) return 'canNoBeEmpty' @@ -82,6 +82,17 @@ export const checkKeys = (keys: string[], canBeEmpty?: boolean) => { return { isValid, errorKey, errorMessageKey } } +export const hasDuplicateStr = (strArr: string[]) => { + const strObj: Record = {} + strArr.forEach((str) => { + if (strObj[str]) + strObj[str] += 1 + else + strObj[str] = 1 + }) + return !!Object.keys(strObj).find(key => strObj[key] > 1) +} + const varRegex = /\{\{([a-zA-Z_]\w*)\}\}/g export const getVars = (value: string) => { if (!value)