feat(variables): auto replace spaces with underscores in variable name inputs (#21843)

This commit is contained in:
Minamiyama
2025-07-03 10:36:38 +08:00
committed by GitHub
parent cb0d4a1e15
commit a45aa1e505
6 changed files with 36 additions and 7 deletions

View File

@@ -8,7 +8,7 @@ import RemoveButton from '../remove-button'
import VarTypePicker from './var-type-picker' import VarTypePicker from './var-type-picker'
import Input from '@/app/components/base/input' import Input from '@/app/components/base/input'
import type { VarType } from '@/app/components/workflow/types' 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' import Toast from '@/app/components/base/toast'
type Props = { type Props = {
@@ -37,6 +37,8 @@ const OutputVarList: FC<Props> = ({
const handleVarNameChange = useCallback((index: number) => { const handleVarNameChange = useCallback((index: number) => {
return (e: React.ChangeEvent<HTMLInputElement>) => { return (e: React.ChangeEvent<HTMLInputElement>) => {
const oldKey = list[index].variable const oldKey = list[index].variable
replaceSpaceWithUnderscreInVarNameInput(e.target)
const newKey = e.target.value const newKey = e.target.value
const { isValid, errorKey, errorMessageKey } = checkKeys([newKey], true) const { isValid, errorKey, errorMessageKey } = checkKeys([newKey], true)

View File

@@ -8,7 +8,7 @@ import VarReferencePicker from './var-reference-picker'
import Input from '@/app/components/base/input' import Input from '@/app/components/base/input'
import type { ValueSelector, Var, Variable } from '@/app/components/workflow/types' import type { ValueSelector, Var, Variable } from '@/app/components/workflow/types'
import { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/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' import Toast from '@/app/components/base/toast'
type Props = { type Props = {
@@ -38,6 +38,8 @@ const VarList: FC<Props> = ({
const handleVarNameChange = useCallback((index: number) => { const handleVarNameChange = useCallback((index: number) => {
return (e: React.ChangeEvent<HTMLInputElement>) => { return (e: React.ChangeEvent<HTMLInputElement>) => {
replaceSpaceWithUnderscreInVarNameInput(e.target)
const newKey = e.target.value const newKey = e.target.value
const { isValid, errorKey, errorMessageKey } = checkKeys([newKey], true) const { isValid, errorKey, errorMessageKey } = checkKeys([newKey], true)
if (!isValid) { if (!isValid) {

View File

@@ -15,7 +15,7 @@ import { VarType } from '@/app/components/workflow/types'
import type { NodeOutPutVar, ValueSelector, Var } 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 { VarType as VarKindType } from '@/app/components/workflow/nodes/tool/types'
import { Folder } from '@/app/components/base/icons/src/vender/line/files' 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' import Toast from '@/app/components/base/toast'
const i18nPrefix = 'workflow.nodes.variableAssigner' const i18nPrefix = 'workflow.nodes.variableAssigner'
@@ -89,6 +89,7 @@ const VarGroupItem: FC<Props> = ({
}] = useBoolean(false) }] = useBoolean(false)
const handleGroupNameChange = useCallback((e: ChangeEvent<any>) => { const handleGroupNameChange = useCallback((e: ChangeEvent<any>) => {
replaceSpaceWithUnderscreInVarNameInput(e.target)
const value = e.target.value const value = e.target.value
const { isValid, errorKey, errorMessageKey } = checkKeys([value], false) const { isValid, errorKey, errorMessageKey } = checkKeys([value], false)
if (!isValid) { if (!isValid) {

View File

@@ -16,7 +16,7 @@ import type { ConversationVariable } from '@/app/components/workflow/types'
import { CodeLanguage } from '@/app/components/workflow/nodes/code/types' import { CodeLanguage } from '@/app/components/workflow/nodes/code/types'
import { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type' import { ChatVarType } from '@/app/components/workflow/panel/chat-variable-panel/type'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { checkKeys } from '@/utils/var' import { checkKeys, replaceSpaceWithUnderscreInVarNameInput } from '@/utils/var'
export type ModalPropsType = { export type ModalPropsType = {
chatVar?: ConversationVariable chatVar?: ConversationVariable
@@ -143,6 +143,13 @@ const ChatVariableModal = ({
return true return true
} }
const handleVarNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
replaceSpaceWithUnderscreInVarNameInput(e.target)
if (!!e.target.value && !checkVariableName(e.target.value))
return
setName(e.target.value || '')
}
const handleTypeChange = (v: ChatVarType) => { const handleTypeChange = (v: ChatVarType) => {
setValue(undefined) setValue(undefined)
setEditorContent(undefined) setEditorContent(undefined)
@@ -275,7 +282,7 @@ const ChatVariableModal = ({
<Input <Input
placeholder={t('workflow.chatVariable.modal.namePlaceholder') || ''} placeholder={t('workflow.chatVariable.modal.namePlaceholder') || ''}
value={name} value={name}
onChange={e => setName(e.target.value || '')} onChange={handleVarNameChange}
onBlur={e => checkVariableName(e.target.value)} onBlur={e => checkVariableName(e.target.value)}
type='text' type='text'
/> />

View File

@@ -10,7 +10,7 @@ import { ToastContext } from '@/app/components/base/toast'
import { useStore } from '@/app/components/workflow/store' import { useStore } from '@/app/components/workflow/store'
import type { EnvironmentVariable } from '@/app/components/workflow/types' import type { EnvironmentVariable } from '@/app/components/workflow/types'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
import { checkKeys } from '@/utils/var' import { checkKeys, replaceSpaceWithUnderscreInVarNameInput } from '@/utils/var'
export type ModalPropsType = { export type ModalPropsType = {
env?: EnvironmentVariable env?: EnvironmentVariable
@@ -42,6 +42,13 @@ const VariableModal = ({
return true return true
} }
const handleVarNameChange = (e: React.ChangeEvent<HTMLInputElement>) => {
replaceSpaceWithUnderscreInVarNameInput(e.target)
if (!!e.target.value && !checkVariableName(e.target.value))
return
setName(e.target.value || '')
}
const handleSave = () => { const handleSave = () => {
if (!checkVariableName(name)) if (!checkVariableName(name))
return return
@@ -127,7 +134,7 @@ const VariableModal = ({
<Input <Input
placeholder={t('workflow.env.modal.namePlaceholder') || ''} placeholder={t('workflow.env.modal.namePlaceholder') || ''}
value={name} value={name}
onChange={e => setName(e.target.value || '')} onChange={handleVarNameChange}
onBlur={e => checkVariableName(e.target.value)} onBlur={e => checkVariableName(e.target.value)}
type='text' type='text'
/> />

View File

@@ -120,3 +120,13 @@ export function getMarketplaceUrl(path: string, params?: Record<string, string |
} }
return `${MARKETPLACE_URL_PREFIX}${path}?${searchParams.toString()}` return `${MARKETPLACE_URL_PREFIX}${path}?${searchParams.toString()}`
} }
export const replaceSpaceWithUnderscreInVarNameInput = (input: HTMLInputElement) => {
const start = input.selectionStart
const end = input.selectionEnd
input.value = input.value.replaceAll(' ', '_')
if (start !== null && end !== null)
input.setSelectionRange(start, end)
}