Feat: Render agent setting dialog #3221 (#9312)

### What problem does this PR solve?

Feat: Render agent setting dialog #3221
### Type of change


- [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
balibabu
2025-08-08 11:00:55 +08:00
committed by GitHub
parent 1bd64dafcb
commit 58a64000ea
10 changed files with 339 additions and 25 deletions

View File

@ -0,0 +1,53 @@
import { ButtonLoading } from '@/components/ui/button';
import {
Dialog,
DialogContent,
DialogFooter,
DialogHeader,
DialogTitle,
} from '@/components/ui/dialog';
import { useSetAgentSetting } from '@/hooks/use-agent-request';
import { IModalProps } from '@/interfaces/common';
import { transformFile2Base64 } from '@/utils/file-util';
import { useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import {
AgentSettingId,
SettingForm,
SettingFormSchemaType,
} from './setting-form';
export function SettingDialog({ hideModal }: IModalProps<any>) {
const { t } = useTranslation();
const { setAgentSetting } = useSetAgentSetting();
const submit = useCallback(
async (values: SettingFormSchemaType) => {
const avatar = values.avatar;
const code = await setAgentSetting({
...values,
avatar: avatar.length > 0 ? await transformFile2Base64(avatar[0]) : '',
});
if (code === 0) {
hideModal?.();
}
},
[hideModal, setAgentSetting],
);
return (
<Dialog open onOpenChange={hideModal}>
<DialogContent>
<DialogHeader>
<DialogTitle>Are you absolutely sure?</DialogTitle>
</DialogHeader>
<SettingForm submit={submit}></SettingForm>
<DialogFooter>
<ButtonLoading type="submit" form={AgentSettingId} loading={false}>
{t('common.save')}
</ButtonLoading>
</DialogFooter>
</DialogContent>
</Dialog>
);
}

View File

@ -0,0 +1,158 @@
import { z } from 'zod';
import {
FileUpload,
FileUploadDropzone,
FileUploadItem,
FileUploadItemDelete,
FileUploadItemMetadata,
FileUploadItemPreview,
FileUploadList,
FileUploadTrigger,
} from '@/components/file-upload';
import { RAGFlowFormItem } from '@/components/ragflow-form';
import { Button } from '@/components/ui/button';
import { Form, FormControl, FormItem, FormLabel } from '@/components/ui/form';
import { Input } from '@/components/ui/input';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { Textarea } from '@/components/ui/textarea';
import { useTranslate } from '@/hooks/common-hooks';
import { useFetchAgent } from '@/hooks/use-agent-request';
import { transformBase64ToFile } from '@/utils/file-util';
import { zodResolver } from '@hookform/resolvers/zod';
import { CloudUpload, X } from 'lucide-react';
import { useEffect } from 'react';
import { useForm } from 'react-hook-form';
const formSchema = z.object({
title: z.string().min(1, {}),
avatar: z.array(z.custom<File>()),
description: z.string(),
permission: z.string(),
});
export type SettingFormSchemaType = z.infer<typeof formSchema>;
export const AgentSettingId = 'agentSettingId';
type SettingFormProps = {
submit: (values: SettingFormSchemaType) => void;
};
export function SettingForm({ submit }: SettingFormProps) {
const { t } = useTranslate('flow.settings');
const { data } = useFetchAgent();
const form = useForm<SettingFormSchemaType>({
resolver: zodResolver(formSchema),
defaultValues: {
title: '',
permission: 'me',
},
});
useEffect(() => {
form.reset({
title: data?.title,
description: data?.description,
avatar: data.avatar ? [transformBase64ToFile(data.avatar)] : [],
permission: data?.permission,
});
}, [data, form]);
return (
<Form {...form}>
<form
onSubmit={form.handleSubmit(submit)}
className="space-y-8"
id={AgentSettingId}
>
<RAGFlowFormItem name="title" label={t('title')}>
<Input />
</RAGFlowFormItem>
<RAGFlowFormItem name="avatar" label={t('photo')}>
{(field) => (
<FileUpload
value={field.value}
onValueChange={field.onChange}
accept="image/*"
maxFiles={1}
onFileReject={(_, message) => {
form.setError('avatar', {
message,
});
}}
multiple
>
<FileUploadDropzone className="flex-row flex-wrap border-dotted text-center">
<CloudUpload className="size-4" />
Drag and drop or
<FileUploadTrigger asChild>
<Button variant="link" size="sm" className="p-0">
choose files
</Button>
</FileUploadTrigger>
to upload
</FileUploadDropzone>
<FileUploadList>
{field.value?.map((file: File, index: number) => (
<FileUploadItem key={index} value={file}>
<FileUploadItemPreview />
<FileUploadItemMetadata />
<FileUploadItemDelete asChild>
<Button variant="ghost" size="icon" className="size-7">
<X />
<span className="sr-only">Delete</span>
</Button>
</FileUploadItemDelete>
</FileUploadItem>
))}
</FileUploadList>
</FileUpload>
)}
</RAGFlowFormItem>
<RAGFlowFormItem name="description" label={t('description')}>
<Textarea rows={4} />
</RAGFlowFormItem>
<RAGFlowFormItem
name="permission"
label={t('permissions')}
tooltip={t('permissionsTip')}
>
{(field) => (
<RadioGroup
onValueChange={field.onChange}
value={field.value}
className="flex"
>
<FormItem className="flex items-center gap-3">
<FormControl>
<RadioGroupItem value="me" id="me" />
</FormControl>
<FormLabel
className="font-normal !m-0 cursor-pointer"
htmlFor="me"
>
{t('me')}
</FormLabel>
</FormItem>
<FormItem className="flex items-center gap-3">
<FormControl>
<RadioGroupItem value="team" id="team" />
</FormControl>
<FormLabel
className="font-normal !m-0 cursor-pointer"
htmlFor="team"
>
{t('team')}
</FormLabel>
</FormItem>
</RadioGroup>
)}
</RAGFlowFormItem>
</form>
</Form>
);
}