import type { EnvironmentVariable } from '@/app/components/workflow/types' import { Button } from '@langgenius/dify-ui/button' import { cn } from '@langgenius/dify-ui/cn' import { toast } from '@langgenius/dify-ui/toast' import { RiCloseLine } from '@remixicon/react' import * as React from 'react' import { useEffect } from 'react' import { useTranslation } from 'react-i18next' import { v4 as uuid4 } from 'uuid' import { Infotip } from '@/app/components/base/infotip' import Input from '@/app/components/base/input' import { useWorkflowStore } from '@/app/components/workflow/store' import { checkKeys, replaceSpaceWithUnderscoreInVarNameInput } from '@/utils/var' type ModalPropsType = { env?: EnvironmentVariable onClose: () => void onSave: (env: EnvironmentVariable) => void } const VariableModal = ({ env, onClose, onSave }: ModalPropsType) => { const { t } = useTranslation() const workflowStore = useWorkflowStore() const [type, setType] = React.useState<'string' | 'number' | 'secret'>('string') const [name, setName] = React.useState('') const [value, setValue] = React.useState() const [description, setDescription] = React.useState('') const checkVariableName = (value: string) => { const { isValid, errorMessageKey } = checkKeys([value], false) if (!isValid) { toast.error( t(($) => $[`varKeyError.${errorMessageKey}`], { ns: 'appDebug', key: t(($) => $['env.modal.name'], { ns: 'workflow' }), }), ) return false } return true } const handleVarNameChange = (e: React.ChangeEvent) => { replaceSpaceWithUnderscoreInVarNameInput(e.target) if (!!e.target.value && !checkVariableName(e.target.value)) return setName(e.target.value || '') } const handleSave = () => { if (!checkVariableName(name)) return if (!value) return toast.error(t(($) => $['env.modal.valueRequired'], { ns: 'workflow' })) // Add check for duplicate name when editing const envList = workflowStore.getState().environmentVariables if (env && env.name !== name && envList.some((e) => e.name === name)) return toast.error( t(($) => $['varKeyError.keyAlreadyExists'], { ns: 'appDebug', key: t(($) => $['env.modal.name'], { ns: 'workflow' }), }), ) // Original check for create new variable if (!env && envList.some((e) => e.name === name)) return toast.error( t(($) => $['varKeyError.keyAlreadyExists'], { ns: 'appDebug', key: t(($) => $['env.modal.name'], { ns: 'workflow' }), }), ) onSave({ id: env ? env.id : uuid4(), value_type: type, name, value: type === 'number' ? Number(value) : value, description, }) onClose() } useEffect(() => { if (env) { setType(env.value_type) setName(env.name) const envSecrets = workflowStore.getState().envSecrets setValue(env.value_type === 'secret' ? envSecrets[env.id] : env.value) setDescription(env.description) } }, [env, workflowStore]) return (
{!env ? t(($) => $['env.modal.title'], { ns: 'workflow' }) : t(($) => $['env.modal.editTitle'], { ns: 'workflow' })}
{/* type */}
{t(($) => $['env.modal.type'], { ns: 'workflow' })}
setType('string')} > String
{ setType('number') if (!/^\d$/.test(value)) setValue('') }} > Number
setType('secret')} > Secret $['env.modal.secretTip'], { ns: 'workflow' })} className="ml-0.5 size-3.5" popupClassName="w-[240px]" > {t(($) => $['env.modal.secretTip'], { ns: 'workflow' })}
{/* name */}
{t(($) => $['env.modal.name'], { ns: 'workflow' })}
$['env.modal.namePlaceholder'], { ns: 'workflow' }) || ''} value={name} onChange={handleVarNameChange} onBlur={(e) => checkVariableName(e.target.value)} type="text" />
{/* value */}
{t(($) => $['env.modal.value'], { ns: 'workflow' })}
{type !== 'number' ? (