mirror of
https://github.com/infiniflow/ragflow.git
synced 2025-12-08 20:42:30 +08:00
### What problem does this PR solve? Feat: Add type card to create agent dialog #9869 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -27,9 +27,11 @@ export default function AgentTemplates() {
|
||||
const [selectMenuItem, setSelectMenuItem] = useState<string>(
|
||||
MenuItemKey.Recommended,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setTemplateList(list);
|
||||
}, [list]);
|
||||
|
||||
const {
|
||||
visible: creatingVisible,
|
||||
hideModal: hideCreatingModal,
|
||||
|
||||
@ -6,16 +6,18 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '@/components/ui/dialog';
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
import { TagRenameId } from '@/pages/add-knowledge/constant';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { CreateAgentForm } from './create-agent-form';
|
||||
import { CreateAgentForm, CreateAgentFormProps } from './create-agent-form';
|
||||
|
||||
type CreateAgentDialogProps = CreateAgentFormProps;
|
||||
|
||||
export function CreateAgentDialog({
|
||||
hideModal,
|
||||
onOk,
|
||||
loading,
|
||||
}: IModalProps<any>) {
|
||||
shouldChooseAgent,
|
||||
}: CreateAgentDialogProps) {
|
||||
const { t } = useTranslation();
|
||||
|
||||
return (
|
||||
@ -24,7 +26,11 @@ export function CreateAgentDialog({
|
||||
<DialogHeader>
|
||||
<DialogTitle>{t('flow.createGraph')}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<CreateAgentForm hideModal={hideModal} onOk={onOk}></CreateAgentForm>
|
||||
<CreateAgentForm
|
||||
hideModal={hideModal}
|
||||
onOk={onOk}
|
||||
shouldChooseAgent={shouldChooseAgent}
|
||||
></CreateAgentForm>
|
||||
<DialogFooter>
|
||||
<ButtonLoading type="submit" form={TagRenameId} loading={loading}>
|
||||
{t('common.save')}
|
||||
|
||||
@ -4,6 +4,8 @@ import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { RAGFlowFormItem } from '@/components/ragflow-form';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
@ -14,10 +16,76 @@ import {
|
||||
} from '@/components/ui/form';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { TagRenameId } from '@/pages/add-knowledge/constant';
|
||||
import { BrainCircuit, Check, Route } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
export function CreateAgentForm({ hideModal, onOk }: IModalProps<any>) {
|
||||
export type CreateAgentFormProps = IModalProps<any> & {
|
||||
shouldChooseAgent?: boolean;
|
||||
};
|
||||
|
||||
enum FlowType {
|
||||
Agent = 'agent',
|
||||
Flow = 'flow',
|
||||
}
|
||||
|
||||
type FlowTypeCardProps = {
|
||||
value?: FlowType;
|
||||
onChange?: (value: FlowType) => void;
|
||||
};
|
||||
function FlowTypeCards({ value, onChange }: FlowTypeCardProps) {
|
||||
const handleChange = useCallback(
|
||||
(value: FlowType) => () => {
|
||||
onChange?.(value);
|
||||
},
|
||||
[onChange],
|
||||
);
|
||||
|
||||
return (
|
||||
<section className="flex gap-10">
|
||||
{Object.values(FlowType).map((val) => {
|
||||
const isActive = value === val;
|
||||
return (
|
||||
<Card
|
||||
key={val}
|
||||
className={cn('flex-1 rounded-lg border bg-transparent', {
|
||||
'border-bg-base': isActive,
|
||||
'border-border-default': !isActive,
|
||||
})}
|
||||
>
|
||||
<CardContent
|
||||
onClick={handleChange(val)}
|
||||
className={cn(
|
||||
'cursor-pointer p-5 text-text-secondary flex justify-between items-center',
|
||||
{
|
||||
'text-text-primary': isActive,
|
||||
},
|
||||
)}
|
||||
>
|
||||
<div className="flex gap-2">
|
||||
{val === FlowType.Agent ? (
|
||||
<BrainCircuit className="size-6" />
|
||||
) : (
|
||||
<Route className="size-6" />
|
||||
)}
|
||||
<p>{val}</p>
|
||||
</div>
|
||||
{isActive && <Check />}
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
})}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
export function CreateAgentForm({
|
||||
hideModal,
|
||||
onOk,
|
||||
shouldChooseAgent = false,
|
||||
}: CreateAgentFormProps) {
|
||||
const { t } = useTranslation();
|
||||
const FormSchema = z.object({
|
||||
name: z
|
||||
@ -28,11 +96,12 @@ export function CreateAgentForm({ hideModal, onOk }: IModalProps<any>) {
|
||||
.trim(),
|
||||
tag: z.string().trim().optional(),
|
||||
description: z.string().trim().optional(),
|
||||
type: z.nativeEnum(FlowType).optional(),
|
||||
});
|
||||
|
||||
const form = useForm<z.infer<typeof FormSchema>>({
|
||||
resolver: zodResolver(FormSchema),
|
||||
defaultValues: { name: '' },
|
||||
defaultValues: { name: '', type: FlowType.Agent },
|
||||
});
|
||||
|
||||
async function onSubmit(data: z.infer<typeof FormSchema>) {
|
||||
@ -49,12 +118,17 @@ export function CreateAgentForm({ hideModal, onOk }: IModalProps<any>) {
|
||||
className="space-y-6"
|
||||
id={TagRenameId}
|
||||
>
|
||||
{shouldChooseAgent && (
|
||||
<RAGFlowFormItem required name="type" label={t('common.type')}>
|
||||
<FlowTypeCards></FlowTypeCards>
|
||||
</RAGFlowFormItem>
|
||||
)}
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="name"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t('common.name')}</FormLabel>
|
||||
<FormLabel required>{t('common.name')}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder={t('common.namePlaceholder')}
|
||||
@ -66,40 +140,6 @@ export function CreateAgentForm({ hideModal, onOk }: IModalProps<any>) {
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
{/* <FormField
|
||||
control={form.control}
|
||||
name="tag"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t('flow.tag')}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder={t('flow.tagPlaceholder')}
|
||||
{...field}
|
||||
autoComplete="off"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="description"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>{t('flow.description')}</FormLabel>
|
||||
<FormControl>
|
||||
<Input
|
||||
placeholder={t('flow.descriptionPlaceholder')}
|
||||
{...field}
|
||||
autoComplete="off"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/> */}
|
||||
</form>
|
||||
</Form>
|
||||
);
|
||||
|
||||
@ -1,14 +1,22 @@
|
||||
import ListFilterBar from '@/components/list-filter-bar';
|
||||
import { RenameDialog } from '@/components/rename-dialog';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuTrigger,
|
||||
} from '@/components/ui/dropdown-menu';
|
||||
import { RAGFlowPagination } from '@/components/ui/ragflow-pagination';
|
||||
import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
||||
import { useFetchAgentListByPage } from '@/hooks/use-agent-request';
|
||||
import { t } from 'i18next';
|
||||
import { pick } from 'lodash';
|
||||
import { Plus } from 'lucide-react';
|
||||
import { Clipboard, ClipboardPlus, FileInput, Plus } from 'lucide-react';
|
||||
import { useCallback } from 'react';
|
||||
import { AgentCard } from './agent-card';
|
||||
import { CreateAgentDialog } from './create-agent-dialog';
|
||||
import { useRenameAgent } from './use-rename-agent';
|
||||
|
||||
export default function Agents() {
|
||||
@ -25,6 +33,12 @@ export default function Agents() {
|
||||
showAgentRenameModal,
|
||||
} = useRenameAgent();
|
||||
|
||||
const {
|
||||
visible: creatingVisible,
|
||||
hideModal: hideCreatingModal,
|
||||
showModal: showCreatingModal,
|
||||
} = useSetModalState();
|
||||
|
||||
const handlePageChange = useCallback(
|
||||
(page: number, pageSize?: number) => {
|
||||
setPagination({ page, pageSize });
|
||||
@ -41,10 +55,34 @@ export default function Agents() {
|
||||
onSearchChange={handleInputChange}
|
||||
icon="agent"
|
||||
>
|
||||
<Button onClick={navigateToAgentTemplates}>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
{t('flow.createGraph')}
|
||||
</Button>
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger>
|
||||
<Button>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
{t('flow.createGraph')}
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent>
|
||||
<DropdownMenuItem
|
||||
justifyBetween={false}
|
||||
onClick={showCreatingModal}
|
||||
>
|
||||
<Clipboard />
|
||||
Create from Blank
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
justifyBetween={false}
|
||||
onClick={navigateToAgentTemplates}
|
||||
>
|
||||
<ClipboardPlus />
|
||||
Create from Template
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem justifyBetween={false}>
|
||||
<FileInput />
|
||||
Import json file
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
</ListFilterBar>
|
||||
</div>
|
||||
<div className="flex-1 overflow-auto">
|
||||
@ -75,6 +113,15 @@ export default function Agents() {
|
||||
loading={agentRenameLoading}
|
||||
></RenameDialog>
|
||||
)}
|
||||
{creatingVisible && (
|
||||
<CreateAgentDialog
|
||||
loading={false}
|
||||
visible={creatingVisible}
|
||||
hideModal={hideCreatingModal}
|
||||
shouldChooseAgent
|
||||
onOk={() => {}}
|
||||
></CreateAgentDialog>
|
||||
)}
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user