Fix: Add prompts when merging or deleting metadata. (#12138)

### What problem does this PR solve?

Fix: Add prompts when merging or deleting metadata.

### Type of change

- [x] Bug Fix (non-breaking change which fixes an issue)

---------

Co-authored-by: Kevin Hu <kevinhu.sh@gmail.com>
This commit is contained in:
chanx
2025-12-24 09:32:41 +08:00
committed by GitHub
parent c33134ea2c
commit d72debf0db
11 changed files with 322 additions and 100 deletions

View File

@ -35,6 +35,7 @@ import { cn } from '@/lib/utils';
import { t } from 'i18next';
import { Loader } from 'lucide-react';
import { MultiSelect, MultiSelectOptionType } from './ui/multi-select';
import { Switch } from './ui/switch';
// Field type enumeration
export enum FormFieldType {
@ -46,6 +47,7 @@ export enum FormFieldType {
Select = 'select',
MultiSelect = 'multi-select',
Checkbox = 'checkbox',
Switch = 'switch',
Tag = 'tag',
Custom = 'custom',
}
@ -154,6 +156,7 @@ export const generateSchema = (fields: FormFieldConfig[]): ZodSchema<any> => {
}
break;
case FormFieldType.Checkbox:
case FormFieldType.Switch:
fieldSchema = z.boolean();
break;
case FormFieldType.Tag:
@ -193,6 +196,8 @@ export const generateSchema = (fields: FormFieldConfig[]): ZodSchema<any> => {
if (
field.type !== FormFieldType.Number &&
field.type !== FormFieldType.Checkbox &&
field.type !== FormFieldType.Switch &&
field.type !== FormFieldType.Custom &&
field.type !== FormFieldType.Tag &&
field.required
) {
@ -289,7 +294,10 @@ const generateDefaultValues = <T extends FieldValues>(
const lastKey = keys[keys.length - 1];
if (field.defaultValue !== undefined) {
current[lastKey] = field.defaultValue;
} else if (field.type === FormFieldType.Checkbox) {
} else if (
field.type === FormFieldType.Checkbox ||
field.type === FormFieldType.Switch
) {
current[lastKey] = false;
} else if (field.type === FormFieldType.Tag) {
current[lastKey] = [];
@ -299,7 +307,10 @@ const generateDefaultValues = <T extends FieldValues>(
} else {
if (field.defaultValue !== undefined) {
defaultValues[field.name] = field.defaultValue;
} else if (field.type === FormFieldType.Checkbox) {
} else if (
field.type === FormFieldType.Checkbox ||
field.type === FormFieldType.Switch
) {
defaultValues[field.name] = false;
} else if (
field.type === FormFieldType.Tag ||
@ -502,6 +513,32 @@ export const RenderField = ({
)}
/>
);
case FormFieldType.Switch:
return (
<RAGFlowFormItem
{...field}
labelClassName={labelClassName || field.labelClassName}
>
{(fieldProps) => {
const finalFieldProps = field.onChange
? {
...fieldProps,
onChange: (checked: boolean) => {
fieldProps.onChange(checked);
field.onChange?.(checked);
},
}
: fieldProps;
return (
<Switch
checked={finalFieldProps.value as boolean}
onCheckedChange={(checked) => finalFieldProps.onChange(checked)}
disabled={field.disabled}
/>
);
}}
</RAGFlowFormItem>
);
case FormFieldType.Tag:
return (

View File

@ -31,14 +31,16 @@ const handleCheckChange = ({
(value: string) => value !== item.id.toString(),
);
const newValue = {
...currentValue,
[parentId]: newParentValues,
};
const newValue = newParentValues?.length
? {
...currentValue,
[parentId]: newParentValues,
}
: { ...currentValue };
if (newValue[parentId].length === 0) {
delete newValue[parentId];
}
// if (newValue[parentId].length === 0) {
// delete newValue[parentId];
// }
return field.onChange(newValue);
} else {
@ -66,20 +68,31 @@ const FilterItem = memo(
}) => {
return (
<div
className={`flex items-center justify-between text-text-primary text-xs ${level > 0 ? 'ml-4' : ''}`}
className={`flex items-center justify-between text-text-primary text-xs ${level > 0 ? 'ml-1' : ''}`}
>
<FormItem className="flex flex-row space-x-3 space-y-0 items-center">
<FormItem className="flex flex-row space-x-3 space-y-0 items-center ">
<FormControl>
<Checkbox
checked={field.value?.includes(item.id.toString())}
onCheckedChange={(checked: boolean) =>
handleCheckChange({ checked, field, item })
}
/>
<div className="flex space-x-3">
<Checkbox
checked={field.value?.includes(item.id.toString())}
onCheckedChange={(checked: boolean) =>
handleCheckChange({ checked, field, item })
}
// className="hidden group-hover:block"
/>
<FormLabel
onClick={() =>
handleCheckChange({
checked: !field.value?.includes(item.id.toString()),
field,
item,
})
}
>
{item.label}
</FormLabel>
</div>
</FormControl>
<FormLabel onClick={(e) => e.stopPropagation()}>
{item.label}
</FormLabel>
</FormItem>
{item.count !== undefined && (
<span className="text-sm">{item.count}</span>
@ -107,11 +120,11 @@ export const FilterField = memo(
<FormField
key={item.id}
control={form.control}
name={parent.field as string}
name={parent.field?.toString() as string}
render={({ field }) => {
if (hasNestedList) {
return (
<div className={`flex flex-col gap-2 ${level > 0 ? 'ml-4' : ''}`}>
<div className={`flex flex-col gap-2 ${level > 0 ? 'ml-1' : ''}`}>
<div
className="flex items-center justify-between cursor-pointer"
onClick={() => {
@ -138,23 +151,6 @@ export const FilterField = memo(
}}
level={level + 1}
/>
// <FilterItem key={child.id} item={child} field={child.field} level={level+1} />
// <div
// className="flex flex-row space-x-3 space-y-0 items-center"
// key={child.id}
// >
// <FormControl>
// <Checkbox
// checked={field.value?.includes(child.id.toString())}
// onCheckedChange={(checked) =>
// handleCheckChange({ checked, field, item: child })
// }
// />
// </FormControl>
// <FormLabel onClick={(e) => e.stopPropagation()}>
// {child.label}
// </FormLabel>
// </div>
))}
</div>
);

View File

@ -11,7 +11,7 @@ import {
useMemo,
useState,
} from 'react';
import { useForm } from 'react-hook-form';
import { FieldPath, useForm } from 'react-hook-form';
import { ZodArray, ZodString, z } from 'zod';
import { Button } from '@/components/ui/button';
@ -178,7 +178,9 @@ function CheckboxFormMultiple({
<FormField
key={x.field}
control={form.control}
name={x.field}
name={
x.field.toString() as FieldPath<z.infer<typeof FormSchema>>
}
render={() => (
<FormItem className="space-y-4">
<div>
@ -186,19 +188,20 @@ function CheckboxFormMultiple({
{x.label}
</FormLabel>
</div>
{x.list.map((item) => {
return (
<FilterField
key={item.id}
item={{ ...item }}
parent={{
...x,
id: x.field,
// field: `${x.field}${item.field ? '.' + item.field : ''}`,
}}
/>
);
})}
{x.list?.length &&
x.list.map((item) => {
return (
<FilterField
key={item.id}
item={{ ...item }}
parent={{
...x,
id: x.field,
// field: `${x.field}${item.field ? '.' + item.field : ''}`,
}}
/>
);
})}
<FormMessage />
</FormItem>
)}