Feat: The keys for data manipulation operators can only be numbers, letters, and underscores. #10427 (#11130)

### What problem does this PR solve?

Feat: The keys for data manipulation operators can only be numbers,
letters, and underscores. #10427

### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-11-10 13:27:09 +08:00
committed by GitHub
parent d016a06fd5
commit 86af330f06
8 changed files with 40 additions and 13 deletions

View File

@ -79,7 +79,7 @@ export function AccordionOperators({
Operator.Code,
Operator.StringTransform,
Operator.DataOperations,
Operator.VariableAssigner,
// Operator.VariableAssigner,
Operator.VariableAggregator,
]}
isCustomDropdown={isCustomDropdown}

View File

@ -22,7 +22,7 @@ export function VariableAggregatorNode({
<span className="text-text-secondary">{x.type}</span>
</div>
<div className="space-y-1">
{x.variables.map((y, index) => (
{x.variables?.map((y, index) => (
<LabelCard key={index} className="truncate">
{getLabel(y.value)}
</LabelCard>

View File

@ -0,0 +1,25 @@
import { Input } from '@/components/ui/input';
import { ChangeEvent, useCallback } from 'react';
type KeyInputProps = {
value?: string;
onChange?: (value: string) => void;
searchValue?: string | RegExp;
};
export function KeyInput({
value,
onChange,
searchValue = /[^a-zA-Z0-9_]/g,
}: KeyInputProps) {
const handleChange = useCallback(
(e: ChangeEvent<HTMLInputElement>) => {
const value = e.target.value ?? '';
const filteredValue = value.replace(searchValue, '');
onChange?.(filteredValue);
},
[onChange, searchValue],
);
return <Input value={value} onChange={handleChange} />;
}

View File

@ -1,7 +1,6 @@
import { SelectWithSearch } from '@/components/originui/select-with-search';
import { RAGFlowFormItem } from '@/components/ragflow-form';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Separator } from '@/components/ui/separator';
import { useBuildSwitchOperatorOptions } from '@/hooks/logic-hooks/use-build-operator-options';
import { X } from 'lucide-react';
@ -9,6 +8,7 @@ import { ReactNode } from 'react';
import { useFieldArray, useFormContext } from 'react-hook-form';
import { DataOperationsOperatorOptions } from '../../constant';
import { DynamicFormHeader } from '../components/dynamic-fom-header';
import { KeyInput } from '../components/key-input';
import { PromptEditor } from '../components/prompt-editor';
type SelectKeysProps = {
@ -55,7 +55,7 @@ export function FilterValues({
return (
<div key={field.id} className="flex items-center gap-2">
<RAGFlowFormItem name={keyFieldAlias} className="flex-1">
<Input></Input>
<KeyInput></KeyInput>
</RAGFlowFormItem>
<Separator className="w-2" />

View File

@ -1,11 +1,11 @@
import { RAGFlowFormItem } from '@/components/ragflow-form';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Separator } from '@/components/ui/separator';
import { X } from 'lucide-react';
import { ReactNode } from 'react';
import { useFieldArray, useFormContext } from 'react-hook-form';
import { DynamicFormHeader } from '../components/dynamic-fom-header';
import { KeyInput } from '../components/key-input';
import { PromptEditor } from '../components/prompt-editor';
type SelectKeysProps = {
@ -44,7 +44,7 @@ export function Updates({
return (
<div key={field.id} className="flex items-center gap-2">
<RAGFlowFormItem name={keyFieldAlias} className="flex-1">
<Input></Input>
<KeyInput></KeyInput>
</RAGFlowFormItem>
<Separator className="w-2" />
<RAGFlowFormItem name={valueFieldAlias} className="flex-1">

View File

@ -35,7 +35,7 @@ function VariableAggregatorForm({ node }: INextOperatorForm) {
});
const appendItem = useCallback(() => {
append({ group_name: `Group ${fields.length}`, variables: [] });
append({ group_name: `Group${fields.length}`, variables: [] });
}, [append, fields.length]);
const outputList = buildOutputList(

View File

@ -21,8 +21,10 @@ export const useHandleNameChange = (previousName: string) => {
return name;
}, [form, name, previousName]);
const handleNameChange = useCallback((e: ChangeEvent<any>) => {
setName(e.target.value);
const handleNameChange = useCallback((e: ChangeEvent<HTMLInputElement>) => {
const value = e.target.value;
const filteredValue = value.replace(/[^a-zA-Z0-9_]/g, '');
setName(filteredValue);
}, []);
useEffect(() => {

View File

@ -80,13 +80,13 @@ export default function McpServer() {
)}
{t(`mcp.${isSelectionMode ? 'exitBulkManage' : 'bulkManage'}`)}
</Button>
<Button variant={'secondary'} onClick={showEditModal('')}>
<Plus className="size-3.5" /> {t('mcp.addMCP')}
</Button>
<Button onClick={showImportModal}>
<Button variant={'secondary'} onClick={showImportModal}>
<Download className="size-3.5" />
{t('mcp.import')}
</Button>
<Button onClick={showEditModal('')}>
<Plus className="size-3.5" /> {t('mcp.addMCP')}
</Button>
</div>
</section>
</>