Feat: If a query variable in a data manipulation operator is deleted, a warning message should be displayed to the user. #10427
This commit is contained in:
parent
db5ec89dc5
commit
652e650663
8 changed files with 37 additions and 9 deletions
|
|
@ -48,7 +48,7 @@ const JsonSchemaVisualizer: FC<JsonSchemaVisualizerProps> = ({
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const parsedJson = JSON.parse(value);
|
const parsedJson = JSON.parse(value);
|
||||||
if (onChange) {
|
if (onChange && typeof parsedJson !== 'number') {
|
||||||
onChange(parsedJson);
|
onChange(parsedJson);
|
||||||
}
|
}
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
|
|
|
||||||
|
|
@ -1646,6 +1646,7 @@ The variable aggregation node (originally the variable assignment node) is a cru
|
||||||
beginInputTip:
|
beginInputTip:
|
||||||
'By defining input parameters, this content can be accessed by other components in subsequent processes.',
|
'By defining input parameters, this content can be accessed by other components in subsequent processes.',
|
||||||
query: 'Query variables',
|
query: 'Query variables',
|
||||||
|
queryRequired: 'Query is required',
|
||||||
queryTip: 'Select the variable you want to use',
|
queryTip: 'Select the variable you want to use',
|
||||||
agent: 'Agent',
|
agent: 'Agent',
|
||||||
addAgent: 'Add Agent',
|
addAgent: 'Add Agent',
|
||||||
|
|
|
||||||
|
|
@ -1549,6 +1549,7 @@ General:实体和关系提取提示来自 GitHub - microsoft/graphrag:基于
|
||||||
task: '任务',
|
task: '任务',
|
||||||
beginInputTip: '通过定义输入参数,此内容可以被后续流程中的其他组件访问。',
|
beginInputTip: '通过定义输入参数,此内容可以被后续流程中的其他组件访问。',
|
||||||
query: '查询变量',
|
query: '查询变量',
|
||||||
|
queryRequired: '查询变量是必填项',
|
||||||
queryTip: '选择您想要使用的变量',
|
queryTip: '选择您想要使用的变量',
|
||||||
agent: '智能体',
|
agent: '智能体',
|
||||||
addAgent: '添加智能体',
|
addAgent: '添加智能体',
|
||||||
|
|
|
||||||
|
|
@ -11,11 +11,12 @@ export function DataOperationsNode({
|
||||||
}: NodeProps<BaseNode<DataOperationsFormSchemaType>>) {
|
}: NodeProps<BaseNode<DataOperationsFormSchemaType>>) {
|
||||||
const { data } = props;
|
const { data } = props;
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
const operations = data.form?.operations;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RagNode {...props}>
|
<RagNode {...props}>
|
||||||
<LabelCard>
|
<LabelCard>
|
||||||
{t(`flow.operationsOptions.${camelCase(data.form?.operations)}`)}
|
{operations && t(`flow.operationsOptions.${camelCase(operations)}`)}
|
||||||
</LabelCard>
|
</LabelCard>
|
||||||
</RagNode>
|
</RagNode>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -7,17 +7,24 @@ export type FormListHeaderProps = {
|
||||||
label: ReactNode;
|
label: ReactNode;
|
||||||
tooltip?: string;
|
tooltip?: string;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function DynamicFormHeader({
|
export function DynamicFormHeader({
|
||||||
label,
|
label,
|
||||||
tooltip,
|
tooltip,
|
||||||
onClick,
|
onClick,
|
||||||
|
disabled = false,
|
||||||
}: FormListHeaderProps) {
|
}: FormListHeaderProps) {
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<FormLabel tooltip={tooltip}>{label}</FormLabel>
|
<FormLabel tooltip={tooltip}>{label}</FormLabel>
|
||||||
<Button variant={'ghost'} type="button" onClick={onClick}>
|
<Button
|
||||||
|
variant={'ghost'}
|
||||||
|
type="button"
|
||||||
|
onClick={onClick}
|
||||||
|
disabled={disabled}
|
||||||
|
>
|
||||||
<Plus />
|
<Plus />
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,10 @@ import { Button } from '@/components/ui/button';
|
||||||
import { X } from 'lucide-react';
|
import { X } from 'lucide-react';
|
||||||
import { useFieldArray, useFormContext } from 'react-hook-form';
|
import { useFieldArray, useFormContext } from 'react-hook-form';
|
||||||
import { JsonSchemaDataType } from '../../constant';
|
import { JsonSchemaDataType } from '../../constant';
|
||||||
|
import {
|
||||||
|
flatOptions,
|
||||||
|
useFilterQueryVariableOptionsByTypes,
|
||||||
|
} from '../../hooks/use-get-begin-query';
|
||||||
import { DynamicFormHeader, FormListHeaderProps } from './dynamic-fom-header';
|
import { DynamicFormHeader, FormListHeaderProps } from './dynamic-fom-header';
|
||||||
import { QueryVariable } from './query-variable';
|
import { QueryVariable } from './query-variable';
|
||||||
|
|
||||||
|
|
@ -16,6 +20,10 @@ export function QueryVariableList({
|
||||||
const form = useFormContext();
|
const form = useFormContext();
|
||||||
const name = 'query';
|
const name = 'query';
|
||||||
|
|
||||||
|
let options = useFilterQueryVariableOptionsByTypes(types);
|
||||||
|
|
||||||
|
const secondOptions = flatOptions(options);
|
||||||
|
|
||||||
const { fields, remove, append } = useFieldArray({
|
const { fields, remove, append } = useFieldArray({
|
||||||
name: name,
|
name: name,
|
||||||
control: form.control,
|
control: form.control,
|
||||||
|
|
@ -26,14 +34,15 @@ export function QueryVariableList({
|
||||||
<DynamicFormHeader
|
<DynamicFormHeader
|
||||||
label={label}
|
label={label}
|
||||||
tooltip={tooltip}
|
tooltip={tooltip}
|
||||||
onClick={() => append({ input: '' })}
|
onClick={() => append({ input: secondOptions.at(0)?.value })}
|
||||||
|
disabled={!secondOptions.length}
|
||||||
></DynamicFormHeader>
|
></DynamicFormHeader>
|
||||||
<div className="space-y-5">
|
<div className="space-y-5">
|
||||||
{fields.map((field, index) => {
|
{fields.map((field, index) => {
|
||||||
const nameField = `${name}.${index}.input`;
|
const nameField = `${name}.${index}.input`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={field.id} className="flex items-center gap-2">
|
<div key={field.id} className="flex gap-2">
|
||||||
<QueryVariable
|
<QueryVariable
|
||||||
name={nameField}
|
name={nameField}
|
||||||
hideLabel
|
hideLabel
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import { Form } from '@/components/ui/form';
|
||||||
import { Separator } from '@/components/ui/separator';
|
import { Separator } from '@/components/ui/separator';
|
||||||
import { buildOptions } from '@/utils/form';
|
import { buildOptions } from '@/utils/form';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
|
import { t } from 'i18next';
|
||||||
import { memo } from 'react';
|
import { memo } from 'react';
|
||||||
import { useForm, useWatch } from 'react-hook-form';
|
import { useForm, useWatch } from 'react-hook-form';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
@ -25,7 +26,11 @@ import { SelectKeys } from './select-keys';
|
||||||
import { Updates } from './updates';
|
import { Updates } from './updates';
|
||||||
|
|
||||||
export const RetrievalPartialSchema = {
|
export const RetrievalPartialSchema = {
|
||||||
query: z.array(z.object({ input: z.string().optional() })),
|
query: z.array(
|
||||||
|
z.object({
|
||||||
|
input: z.string().min(1, { message: t('flow.queryRequired') }),
|
||||||
|
}),
|
||||||
|
),
|
||||||
operations: z.string(),
|
operations: z.string(),
|
||||||
select_keys: z.array(z.object({ name: z.string().optional() })).optional(),
|
select_keys: z.array(z.object({ name: z.string().optional() })).optional(),
|
||||||
remove_keys: z.array(z.object({ name: z.string().optional() })).optional(),
|
remove_keys: z.array(z.object({ name: z.string().optional() })).optional(),
|
||||||
|
|
|
||||||
|
|
@ -317,14 +317,18 @@ export const useGetComponentLabelByValue = (nodeId: string) => {
|
||||||
return getLabel;
|
return getLabel;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function flatOptions(options: DefaultOptionType[]) {
|
||||||
|
return options.reduce<DefaultOptionType[]>((pre, cur) => {
|
||||||
|
return [...pre, ...cur.options];
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
export function useFlattenQueryVariableOptions(nodeId?: string) {
|
export function useFlattenQueryVariableOptions(nodeId?: string) {
|
||||||
const { getNode } = useGraphStore((state) => state);
|
const { getNode } = useGraphStore((state) => state);
|
||||||
const nextOptions = useBuildQueryVariableOptions(getNode(nodeId));
|
const nextOptions = useBuildQueryVariableOptions(getNode(nodeId));
|
||||||
|
|
||||||
const flattenOptions = useMemo(() => {
|
const flattenOptions = useMemo(() => {
|
||||||
return nextOptions.reduce<DefaultOptionType[]>((pre, cur) => {
|
return flatOptions(nextOptions);
|
||||||
return [...pre, ...cur.options];
|
|
||||||
}, []);
|
|
||||||
}, [nextOptions]);
|
}, [nextOptions]);
|
||||||
|
|
||||||
return flattenOptions;
|
return flattenOptions;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue