From a45aa1e505b0f29a408d3b4d65165993c1248108 Mon Sep 17 00:00:00 2001 From: Minamiyama Date: Thu, 3 Jul 2025 10:36:38 +0800 Subject: [PATCH] feat(variables): auto replace spaces with underscores in variable name inputs (#21843) --- .../_base/components/variable/output-var-list.tsx | 4 +++- .../nodes/_base/components/variable/var-list.tsx | 4 +++- .../variable-assigner/components/var-group-item.tsx | 3 ++- .../chat-variable-panel/components/variable-modal.tsx | 11 +++++++++-- .../workflow/panel/env-panel/variable-modal.tsx | 11 +++++++++-- web/utils/var.ts | 10 ++++++++++ 6 files changed, 36 insertions(+), 7 deletions(-) diff --git a/web/app/components/workflow/nodes/_base/components/variable/output-var-list.tsx b/web/app/components/workflow/nodes/_base/components/variable/output-var-list.tsx index dba93aaf97..a7c9a9d172 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/output-var-list.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/output-var-list.tsx @@ -8,7 +8,7 @@ import RemoveButton from '../remove-button' import VarTypePicker from './var-type-picker' import Input from '@/app/components/base/input' import type { VarType } from '@/app/components/workflow/types' -import { checkKeys } from '@/utils/var' +import { checkKeys, replaceSpaceWithUnderscreInVarNameInput } from '@/utils/var' import Toast from '@/app/components/base/toast' type Props = { @@ -37,6 +37,8 @@ const OutputVarList: FC = ({ const handleVarNameChange = useCallback((index: number) => { return (e: React.ChangeEvent) => { const oldKey = list[index].variable + + replaceSpaceWithUnderscreInVarNameInput(e.target) const newKey = e.target.value const { isValid, errorKey, errorMessageKey } = checkKeys([newKey], true) diff --git a/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx b/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx index fe489a5b80..73ee8262a0 100644 --- a/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx +++ b/web/app/components/workflow/nodes/_base/components/variable/var-list.tsx @@ -8,7 +8,7 @@ import VarReferencePicker from './var-reference-picker' import Input from '@/app/components/base/input' import type { ValueSelector, Var, Variable } from '@/app/components/workflow/types' import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types' -import { checkKeys } from '@/utils/var' +import { checkKeys, replaceSpaceWithUnderscreInVarNameInput } from '@/utils/var' import Toast from '@/app/components/base/toast' type Props = { @@ -38,6 +38,8 @@ const VarList: FC = ({ const handleVarNameChange = useCallback((index: number) => { return (e: React.ChangeEvent) => { + replaceSpaceWithUnderscreInVarNameInput(e.target) + const newKey = e.target.value const { isValid, errorKey, errorMessageKey } = checkKeys([newKey], true) if (!isValid) { diff --git a/web/app/components/workflow/nodes/variable-assigner/components/var-group-item.tsx b/web/app/components/workflow/nodes/variable-assigner/components/var-group-item.tsx index cf9d4152a4..60be8a0842 100644 --- a/web/app/components/workflow/nodes/variable-assigner/components/var-group-item.tsx +++ b/web/app/components/workflow/nodes/variable-assigner/components/var-group-item.tsx @@ -15,7 +15,7 @@ import { VarType } from '@/app/components/workflow/types' import type { NodeOutPutVar, ValueSelector, Var } from '@/app/components/workflow/types' import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types' import { Folder } from '@/app/components/base/icons/src/vender/line/files' -import { checkKeys } from '@/utils/var' +import { checkKeys, replaceSpaceWithUnderscreInVarNameInput } from '@/utils/var' import Toast from '@/app/components/base/toast' const i18nPrefix = 'workflow.nodes.variableAssigner' @@ -89,6 +89,7 @@ const VarGroupItem: FC = ({ }] = useBoolean(false) const handleGroupNameChange = useCallback((e: ChangeEvent) => { + replaceSpaceWithUnderscreInVarNameInput(e.target) const value = e.target.value const { isValid, errorKey, errorMessageKey } = checkKeys([value], false) if (!isValid) { diff --git a/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal.tsx b/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal.tsx index 3240496b62..347c83c155 100644 --- a/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal.tsx +++ b/web/app/components/workflow/panel/chat-variable-panel/components/variable-modal.tsx @@ -16,7 +16,7 @@ import type { ConversationVariable } from '@/app/components/workflow/types' import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' import { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type' import cn from '@/utils/classnames' -import { checkKeys } from '@/utils/var' +import { checkKeys, replaceSpaceWithUnderscreInVarNameInput } from '@/utils/var' export type ModalPropsType = { chatVar?: ConversationVariable @@ -143,6 +143,13 @@ const ChatVariableModal = ({ return true } + const handleVarNameChange = (e: React.ChangeEvent) => { + replaceSpaceWithUnderscreInVarNameInput(e.target) + if (!!e.target.value && !checkVariableName(e.target.value)) + return + setName(e.target.value || '') + } + const handleTypeChange = (v: ChatVarType) => { setValue(undefined) setEditorContent(undefined) @@ -275,7 +282,7 @@ const ChatVariableModal = ({ setName(e.target.value || '')} + onChange={handleVarNameChange} onBlur={e => checkVariableName(e.target.value)} type='text' /> diff --git a/web/app/components/workflow/panel/env-panel/variable-modal.tsx b/web/app/components/workflow/panel/env-panel/variable-modal.tsx index c842554948..c35c01042e 100644 --- a/web/app/components/workflow/panel/env-panel/variable-modal.tsx +++ b/web/app/components/workflow/panel/env-panel/variable-modal.tsx @@ -10,7 +10,7 @@ import { ToastContext } from '@/app/components/base/toast' import { useStore } from '@/app/components/workflow/store' import type { EnvironmentVariable } from '@/app/components/workflow/types' import cn from '@/utils/classnames' -import { checkKeys } from '@/utils/var' +import { checkKeys, replaceSpaceWithUnderscreInVarNameInput } from '@/utils/var' export type ModalPropsType = { env?: EnvironmentVariable @@ -42,6 +42,13 @@ const VariableModal = ({ return true } + const handleVarNameChange = (e: React.ChangeEvent) => { + replaceSpaceWithUnderscreInVarNameInput(e.target) + if (!!e.target.value && !checkVariableName(e.target.value)) + return + setName(e.target.value || '') + } + const handleSave = () => { if (!checkVariableName(name)) return @@ -127,7 +134,7 @@ const VariableModal = ({ setName(e.target.value || '')} + onChange={handleVarNameChange} onBlur={e => checkVariableName(e.target.value)} type='text' /> diff --git a/web/utils/var.ts b/web/utils/var.ts index 8ce7bdb858..ce0ca030e1 100644 --- a/web/utils/var.ts +++ b/web/utils/var.ts @@ -120,3 +120,13 @@ export function getMarketplaceUrl(path: string, params?: Record { + const start = input.selectionStart + const end = input.selectionEnd + + input.value = input.value.replaceAll(' ', '_') + + if (start !== null && end !== null) + input.setSelectionRange(start, end) +}