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 RunSheet component #3221 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
@ -5,7 +5,7 @@ import {
|
||||
ReactFlow,
|
||||
} from '@xyflow/react';
|
||||
import '@xyflow/react/dist/style.css';
|
||||
// import ChatDrawer from '../chat/drawer';
|
||||
import { ChatSheet } from '../chat/chat-sheet';
|
||||
import FormSheet from '../form-sheet/next';
|
||||
import {
|
||||
useHandleDrop,
|
||||
@ -15,7 +15,7 @@ import {
|
||||
} from '../hooks';
|
||||
import { useBeforeDelete } from '../hooks/use-before-delete';
|
||||
import { useShowDrawer } from '../hooks/use-show-drawer';
|
||||
// import RunDrawer from '../run-drawer';
|
||||
import RunSheet from '../run-sheet';
|
||||
import { ButtonEdge } from './edge';
|
||||
import styles from './index.less';
|
||||
import { RagNode } from './node';
|
||||
@ -66,7 +66,7 @@ interface IProps {
|
||||
hideDrawer(): void;
|
||||
}
|
||||
|
||||
function FlowCanvas({ drawerVisible, hideDrawer }: IProps) {
|
||||
function AgentCanvas({ drawerVisible, hideDrawer }: IProps) {
|
||||
const {
|
||||
nodes,
|
||||
edges,
|
||||
@ -165,21 +165,21 @@ function FlowCanvas({ drawerVisible, hideDrawer }: IProps) {
|
||||
showSingleDebugDrawer={showSingleDebugDrawer}
|
||||
></FormSheet>
|
||||
)}
|
||||
{/* {chatVisible && (
|
||||
<ChatDrawer
|
||||
{chatVisible && (
|
||||
<ChatSheet
|
||||
visible={chatVisible}
|
||||
hideModal={hideRunOrChatDrawer}
|
||||
></ChatDrawer>
|
||||
></ChatSheet>
|
||||
)}
|
||||
|
||||
{runVisible && (
|
||||
<RunDrawer
|
||||
<RunSheet
|
||||
hideModal={hideRunOrChatDrawer}
|
||||
showModal={showChatModal}
|
||||
></RunDrawer>
|
||||
)} */}
|
||||
></RunSheet>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default FlowCanvas;
|
||||
export default AgentCanvas;
|
||||
|
||||
26
web/src/pages/agent/chat/chat-sheet.tsx
Normal file
26
web/src/pages/agent/chat/chat-sheet.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
import {
|
||||
Sheet,
|
||||
SheetContent,
|
||||
SheetDescription,
|
||||
SheetHeader,
|
||||
SheetTitle,
|
||||
SheetTrigger,
|
||||
} from '@/components/ui/sheet';
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
|
||||
export function ChatSheet({ visible }: IModalProps<any>) {
|
||||
return (
|
||||
<Sheet open={visible} modal={false}>
|
||||
<SheetTrigger>Open</SheetTrigger>
|
||||
<SheetContent>
|
||||
<SheetHeader>
|
||||
<SheetTitle>Are you absolutely sure?</SheetTitle>
|
||||
<SheetDescription>
|
||||
This action cannot be undone. This will permanently delete your
|
||||
account and remove your data from our servers.
|
||||
</SheetDescription>
|
||||
</SheetHeader>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
);
|
||||
}
|
||||
@ -1,30 +1,27 @@
|
||||
import { Authorization } from '@/constants/authorization';
|
||||
import { FileUploader } from '@/components/file-uploader';
|
||||
import { ButtonLoading } from '@/components/ui/button';
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormLabel,
|
||||
FormMessage,
|
||||
} from '@/components/ui/form';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { RAGFlowSelect } from '@/components/ui/select';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { Textarea } from '@/components/ui/textarea';
|
||||
import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import { useSetSelectedRecord } from '@/hooks/logic-hooks';
|
||||
import { useHandleSubmittable } from '@/hooks/login-hooks';
|
||||
import api from '@/utils/api';
|
||||
import { getAuthorization } from '@/utils/authorization-util';
|
||||
import { UploadOutlined } from '@ant-design/icons';
|
||||
import {
|
||||
Button,
|
||||
Form,
|
||||
FormItemProps,
|
||||
Input,
|
||||
InputNumber,
|
||||
Select,
|
||||
Switch,
|
||||
Upload,
|
||||
} from 'antd';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { UploadChangeParam, UploadFile } from 'antd/es/upload';
|
||||
import { pick } from 'lodash';
|
||||
import { Link } from 'lucide-react';
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { z } from 'zod';
|
||||
import { BeginQueryType } from '../constant';
|
||||
import { BeginQuery } from '../interface';
|
||||
import { PopoverForm } from './popover-form';
|
||||
|
||||
import styles from './index.less';
|
||||
|
||||
interface IProps {
|
||||
parameters: BeginQuery[];
|
||||
@ -34,6 +31,8 @@ interface IProps {
|
||||
submitButtonDisabled?: boolean;
|
||||
}
|
||||
|
||||
const values = {};
|
||||
|
||||
const DebugContent = ({
|
||||
parameters,
|
||||
ok,
|
||||
@ -42,7 +41,20 @@ const DebugContent = ({
|
||||
submitButtonDisabled = false,
|
||||
}: IProps) => {
|
||||
const { t } = useTranslation();
|
||||
const [form] = Form.useForm();
|
||||
|
||||
const FormSchema = useMemo(() => {
|
||||
const obj = parameters.reduce((pre, cur, idx) => {
|
||||
pre[idx] = z.string().optional();
|
||||
return pre;
|
||||
}, {});
|
||||
return z.object(obj);
|
||||
}, [parameters]);
|
||||
|
||||
const form = useForm({
|
||||
defaultValues: values,
|
||||
resolver: zodResolver(FormSchema),
|
||||
});
|
||||
|
||||
const {
|
||||
visible,
|
||||
hideModal: hidePopover,
|
||||
@ -50,7 +62,8 @@ const DebugContent = ({
|
||||
showModal: showPopover,
|
||||
} = useSetModalState();
|
||||
const { setRecord, currentRecord } = useSetSelectedRecord<number>();
|
||||
const { submittable } = useHandleSubmittable(form);
|
||||
// const { submittable } = useHandleSubmittable(form);
|
||||
const submittable = true;
|
||||
const [isUploading, setIsUploading] = useState(false);
|
||||
|
||||
const handleShowPopover = useCallback(
|
||||
@ -79,8 +92,8 @@ const DebugContent = ({
|
||||
);
|
||||
|
||||
const renderWidget = useCallback(
|
||||
(q: BeginQuery, idx: number) => {
|
||||
const props: FormItemProps & { key: number } = {
|
||||
(q: BeginQuery, idx: string) => {
|
||||
const props = {
|
||||
key: idx,
|
||||
label: q.name ?? q.key,
|
||||
name: idx,
|
||||
@ -89,80 +102,119 @@ const DebugContent = ({
|
||||
props.rules = [{ required: true }];
|
||||
}
|
||||
|
||||
const urlList: { url: string; result: string }[] =
|
||||
form.getFieldValue(idx) || [];
|
||||
// const urlList: { url: string; result: string }[] =
|
||||
// form.getFieldValue(idx) || [];
|
||||
|
||||
const urlList: { url: string; result: string }[] = [];
|
||||
|
||||
const BeginQueryTypeMap = {
|
||||
[BeginQueryType.Line]: (
|
||||
<Form.Item {...props}>
|
||||
<Input></Input>
|
||||
</Form.Item>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={props.name}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1">
|
||||
<FormLabel>{props.label}</FormLabel>
|
||||
<FormControl>
|
||||
<Input {...field}></Input>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
),
|
||||
[BeginQueryType.Paragraph]: (
|
||||
<Form.Item {...props}>
|
||||
<Input.TextArea rows={1}></Input.TextArea>
|
||||
</Form.Item>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={props.name}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1">
|
||||
<FormLabel>{props.label}</FormLabel>
|
||||
<FormControl>
|
||||
<Textarea rows={1} {...field}></Textarea>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
),
|
||||
[BeginQueryType.Options]: (
|
||||
<Form.Item {...props}>
|
||||
<Select
|
||||
allowClear
|
||||
options={q.options?.map((x) => ({ label: x, value: x })) ?? []}
|
||||
></Select>
|
||||
</Form.Item>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={props.name}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1">
|
||||
<FormLabel>{props.label}</FormLabel>
|
||||
<FormControl>
|
||||
<RAGFlowSelect
|
||||
allowClear
|
||||
options={
|
||||
q.options?.map((x) => ({ label: x, value: x })) ?? []
|
||||
}
|
||||
{...field}
|
||||
></RAGFlowSelect>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
),
|
||||
[BeginQueryType.File]: (
|
||||
<React.Fragment key={idx}>
|
||||
<Form.Item label={q.name ?? q.key} required={!q.optional}>
|
||||
<div className="relative">
|
||||
<Form.Item
|
||||
{...props}
|
||||
valuePropName="fileList"
|
||||
getValueFromEvent={normFile}
|
||||
noStyle
|
||||
>
|
||||
<Upload
|
||||
name="file"
|
||||
action={api.parse}
|
||||
multiple
|
||||
headers={{ [Authorization]: getAuthorization() }}
|
||||
onChange={onChange(q.optional)}
|
||||
>
|
||||
<Button icon={<UploadOutlined />}>
|
||||
{t('common.upload')}
|
||||
</Button>
|
||||
</Upload>
|
||||
</Form.Item>
|
||||
<Form.Item
|
||||
{...pick(props, ['key', 'label', 'rules'])}
|
||||
required={!q.optional}
|
||||
className={urlList.length > 0 ? 'mb-1' : ''}
|
||||
noStyle
|
||||
>
|
||||
<PopoverForm visible={visible} switchVisible={switchVisible}>
|
||||
<Button
|
||||
onClick={handleShowPopover(idx)}
|
||||
className="absolute left-1/2 top-0"
|
||||
icon={<Link className="size-3" />}
|
||||
>
|
||||
{t('flow.pasteFileLink')}
|
||||
</Button>
|
||||
</PopoverForm>
|
||||
</Form.Item>
|
||||
</div>
|
||||
</Form.Item>
|
||||
<Form.Item name={idx} noStyle {...pick(props, ['rules'])} />
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={'file'}
|
||||
render={({ field }) => (
|
||||
<div className="space-y-6">
|
||||
<FormItem className="w-full">
|
||||
<FormLabel>{t('assistantAvatar')}</FormLabel>
|
||||
<FormControl>
|
||||
<FileUploader
|
||||
value={field.value}
|
||||
onValueChange={field.onChange}
|
||||
maxFileCount={1}
|
||||
maxSize={4 * 1024 * 1024}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
</React.Fragment>
|
||||
),
|
||||
[BeginQueryType.Integer]: (
|
||||
<Form.Item {...props}>
|
||||
<InputNumber></InputNumber>
|
||||
</Form.Item>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={props.name}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1">
|
||||
<FormLabel>{props.label}</FormLabel>
|
||||
<FormControl>
|
||||
<Input type="number" {...field}></Input>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
),
|
||||
[BeginQueryType.Boolean]: (
|
||||
<Form.Item valuePropName={'checked'} {...props}>
|
||||
<Switch></Switch>
|
||||
</Form.Item>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={props.name}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1">
|
||||
<FormLabel>{props.label}</FormLabel>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
></Switch>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
),
|
||||
};
|
||||
|
||||
@ -171,11 +223,11 @@ const DebugContent = ({
|
||||
BeginQueryTypeMap[BeginQueryType.Paragraph]
|
||||
);
|
||||
},
|
||||
[form, handleShowPopover, onChange, switchVisible, t, visible],
|
||||
[form, t],
|
||||
);
|
||||
|
||||
const onOk = useCallback(async () => {
|
||||
const values = await form.validateFields();
|
||||
// const values = await form.validateFields();
|
||||
const nextValues = Object.entries(values).map(([key, value]) => {
|
||||
const item = parameters[Number(key)];
|
||||
let nextValue = value;
|
||||
@ -193,44 +245,49 @@ const DebugContent = ({
|
||||
});
|
||||
|
||||
ok(nextValues);
|
||||
}, [form, ok, parameters]);
|
||||
}, [ok, parameters]);
|
||||
|
||||
const onSubmit = useCallback(
|
||||
(values: z.infer<typeof FormSchema>) => {
|
||||
const nextValues = Object.entries(values).map(([key, value]) => {
|
||||
const item = parameters[Number(key)];
|
||||
let nextValue = value;
|
||||
if (Array.isArray(value)) {
|
||||
nextValue = ``;
|
||||
|
||||
value.forEach((x) => {
|
||||
nextValue +=
|
||||
x?.originFileObj instanceof File
|
||||
? `${x.name}\n${x.response?.data}\n----\n`
|
||||
: `${x.url}\n${x.result}\n----\n`;
|
||||
});
|
||||
}
|
||||
return { ...item, value: nextValue };
|
||||
});
|
||||
|
||||
ok(nextValues);
|
||||
},
|
||||
[ok, parameters],
|
||||
);
|
||||
|
||||
return (
|
||||
<>
|
||||
<section className={styles.formWrapper}>
|
||||
<Form.Provider
|
||||
onFormFinish={(name, { values, forms }) => {
|
||||
if (name === 'urlForm') {
|
||||
const { basicForm } = forms;
|
||||
const urlInfo = basicForm.getFieldValue(currentRecord) || [];
|
||||
basicForm.setFieldsValue({
|
||||
[currentRecord]: [...urlInfo, { ...values, name: values.url }],
|
||||
});
|
||||
hidePopover();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Form
|
||||
name="basicForm"
|
||||
autoComplete="off"
|
||||
layout={'vertical'}
|
||||
form={form}
|
||||
>
|
||||
<section>
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
{parameters.map((x, idx) => {
|
||||
return renderWidget(x, idx);
|
||||
return <div key={idx}>{renderWidget(x, idx.toString())}</div>;
|
||||
})}
|
||||
</Form>
|
||||
</Form.Provider>
|
||||
</form>
|
||||
</Form>
|
||||
</section>
|
||||
<Button
|
||||
type={'primary'}
|
||||
block
|
||||
<ButtonLoading
|
||||
onClick={onOk}
|
||||
loading={loading}
|
||||
disabled={!submittable || isUploading || submitButtonDisabled}
|
||||
>
|
||||
{t(isNext ? 'common.next' : 'flow.run')}
|
||||
</Button>
|
||||
</ButtonLoading>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,74 +1,103 @@
|
||||
import {
|
||||
Form,
|
||||
FormControl,
|
||||
FormField,
|
||||
FormItem,
|
||||
FormMessage,
|
||||
} from '@/components/ui/form';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Popover, PopoverContent } from '@/components/ui/popover';
|
||||
import { useParseDocument } from '@/hooks/document-hooks';
|
||||
import { useResetFormOnCloseModal } from '@/hooks/logic-hooks';
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
import { Button, Form, Input, Popover } from 'antd';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { PropsWithChildren } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { z } from 'zod';
|
||||
|
||||
const reg =
|
||||
/^(((ht|f)tps?):\/\/)?([^!@#$%^&*?.\s-]([^!@#$%^&*?.\s]{0,63}[^!@#$%^&*?.\s])?\.)+[a-z]{2,6}\/?/;
|
||||
|
||||
const FormSchema = z.object({
|
||||
url: z.string(),
|
||||
result: z.any(),
|
||||
});
|
||||
|
||||
const values = {
|
||||
url: '',
|
||||
result: null,
|
||||
};
|
||||
|
||||
export const PopoverForm = ({
|
||||
children,
|
||||
visible,
|
||||
switchVisible,
|
||||
}: PropsWithChildren<IModalProps<any>>) => {
|
||||
const [form] = Form.useForm();
|
||||
const form = useForm({
|
||||
defaultValues: values,
|
||||
resolver: zodResolver(FormSchema),
|
||||
});
|
||||
const { parseDocument, loading } = useParseDocument();
|
||||
const { t } = useTranslation();
|
||||
|
||||
useResetFormOnCloseModal({
|
||||
form,
|
||||
visible,
|
||||
});
|
||||
// useResetFormOnCloseModal({
|
||||
// form,
|
||||
// visible,
|
||||
// });
|
||||
|
||||
const onOk = async () => {
|
||||
const values = await form.validateFields();
|
||||
async function onSubmit(values: z.infer<typeof FormSchema>) {
|
||||
const val = values.url;
|
||||
|
||||
if (reg.test(val)) {
|
||||
const ret = await parseDocument(val);
|
||||
if (ret?.data?.code === 0) {
|
||||
form.setFieldValue('result', ret?.data?.data);
|
||||
form.submit();
|
||||
form.setValue('result', ret?.data?.data);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const content = (
|
||||
<Form form={form} name="urlForm">
|
||||
<Form.Item
|
||||
name="url"
|
||||
rules={[{ required: true, type: 'url' }]}
|
||||
className="m-0"
|
||||
>
|
||||
<Input
|
||||
onPressEnter={(e) => e.preventDefault()}
|
||||
placeholder={t('flow.pasteFileLink')}
|
||||
suffix={
|
||||
<Button
|
||||
type="primary"
|
||||
onClick={onOk}
|
||||
size={'small'}
|
||||
loading={loading}
|
||||
>
|
||||
{t('common.submit')}
|
||||
</Button>
|
||||
}
|
||||
<Form {...form}>
|
||||
<form onSubmit={form.handleSubmit(onSubmit)}>
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`url`}
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex-1">
|
||||
<FormControl>
|
||||
<Input
|
||||
{...field}
|
||||
// onPressEnter={(e) => e.preventDefault()}
|
||||
placeholder={t('flow.pasteFileLink')}
|
||||
// suffix={
|
||||
// <Button
|
||||
// type="primary"
|
||||
// onClick={onOk}
|
||||
// size={'small'}
|
||||
// loading={loading}
|
||||
// >
|
||||
// {t('common.submit')}
|
||||
// </Button>
|
||||
// }
|
||||
/>
|
||||
</FormControl>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item name={'result'} noStyle />
|
||||
<FormField
|
||||
control={form.control}
|
||||
name={`result`}
|
||||
render={() => <></>}
|
||||
/>
|
||||
</form>
|
||||
</Form>
|
||||
);
|
||||
|
||||
return (
|
||||
<Popover
|
||||
content={content}
|
||||
open={visible}
|
||||
trigger={'click'}
|
||||
onOpenChange={switchVisible}
|
||||
>
|
||||
<Popover open={visible} onOpenChange={switchVisible}>
|
||||
{children}
|
||||
<PopoverContent>{content}</PopoverContent>
|
||||
</Popover>
|
||||
);
|
||||
};
|
||||
|
||||
@ -12,14 +12,19 @@ import { useSetModalState } from '@/hooks/common-hooks';
|
||||
import { useNavigatePage } from '@/hooks/logic-hooks/navigate-hooks';
|
||||
import { ReactFlowProvider } from '@xyflow/react';
|
||||
import { CodeXml, EllipsisVertical, Forward, Import, Key } from 'lucide-react';
|
||||
import { ComponentPropsWithoutRef } from 'react';
|
||||
import { ComponentPropsWithoutRef, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { AgentSidebar } from './agent-sidebar';
|
||||
import FlowCanvas from './canvas';
|
||||
import AgentCanvas from './canvas';
|
||||
import { useHandleExportOrImportJsonFile } from './hooks/use-export-json';
|
||||
import { useFetchDataOnMount } from './hooks/use-fetch-data';
|
||||
import { useGetBeginNodeDataQuery } from './hooks/use-get-begin-query';
|
||||
import { useOpenDocument } from './hooks/use-open-document';
|
||||
import { useSaveGraph } from './hooks/use-save-graph';
|
||||
import {
|
||||
useSaveGraph,
|
||||
useSaveGraphBeforeOpeningDebugDrawer,
|
||||
} from './hooks/use-save-graph';
|
||||
import { BeginQuery } from './interface';
|
||||
import { UploadAgentDialog } from './upload-agent-dialog';
|
||||
|
||||
function AgentDropdownMenuItem({
|
||||
@ -52,6 +57,18 @@ export default function Agent() {
|
||||
const { saveGraph, loading } = useSaveGraph();
|
||||
|
||||
const { flowDetail } = useFetchDataOnMount();
|
||||
const getBeginNodeDataQuery = useGetBeginNodeDataQuery();
|
||||
|
||||
const { handleRun } = useSaveGraphBeforeOpeningDebugDrawer(showChatDrawer);
|
||||
|
||||
const handleRunAgent = useCallback(() => {
|
||||
const query: BeginQuery[] = getBeginNodeDataQuery();
|
||||
if (query.length > 0) {
|
||||
showChatDrawer();
|
||||
} else {
|
||||
handleRun();
|
||||
}
|
||||
}, [getBeginNodeDataQuery, handleRun, showChatDrawer]);
|
||||
|
||||
return (
|
||||
<section>
|
||||
@ -64,7 +81,9 @@ export default function Agent() {
|
||||
>
|
||||
Save
|
||||
</ButtonLoading>
|
||||
<Button variant={'outline'}>Run app</Button>
|
||||
<Button variant={'outline'} onClick={handleRunAgent}>
|
||||
Run app
|
||||
</Button>
|
||||
<Button variant={'outline'}>Publish</Button>
|
||||
|
||||
<DropdownMenu>
|
||||
@ -104,10 +123,10 @@ export default function Agent() {
|
||||
<div className="w-full">
|
||||
<SidebarTrigger />
|
||||
<div className="w-full h-full">
|
||||
<FlowCanvas
|
||||
<AgentCanvas
|
||||
drawerVisible={chatDrawerVisible}
|
||||
hideDrawer={hideChatDrawer}
|
||||
></FlowCanvas>
|
||||
></AgentCanvas>
|
||||
</div>
|
||||
</div>
|
||||
</SidebarProvider>
|
||||
|
||||
62
web/src/pages/agent/run-sheet/index.tsx
Normal file
62
web/src/pages/agent/run-sheet/index.tsx
Normal file
@ -0,0 +1,62 @@
|
||||
import { IModalProps } from '@/interfaces/common';
|
||||
import { Drawer } from 'antd';
|
||||
import { useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { BeginId } from '../constant';
|
||||
import DebugContent from '../debug-content';
|
||||
import { useGetBeginNodeDataQuery } from '../hooks/use-get-begin-query';
|
||||
import { useSaveGraphBeforeOpeningDebugDrawer } from '../hooks/use-save-graph';
|
||||
import { BeginQuery } from '../interface';
|
||||
import useGraphStore from '../store';
|
||||
import { getDrawerWidth } from '../utils';
|
||||
|
||||
const RunSheet = ({
|
||||
hideModal,
|
||||
showModal: showChatModal,
|
||||
}: IModalProps<any>) => {
|
||||
const { t } = useTranslation();
|
||||
const updateNodeForm = useGraphStore((state) => state.updateNodeForm);
|
||||
|
||||
const getBeginNodeDataQuery = useGetBeginNodeDataQuery();
|
||||
const query: BeginQuery[] = getBeginNodeDataQuery();
|
||||
|
||||
const { handleRun, loading } = useSaveGraphBeforeOpeningDebugDrawer(
|
||||
showChatModal!,
|
||||
);
|
||||
|
||||
const handleRunAgent = useCallback(
|
||||
(nextValues: Record<string, any>) => {
|
||||
const currentNodes = updateNodeForm(BeginId, nextValues, ['query']);
|
||||
handleRun(currentNodes);
|
||||
hideModal?.();
|
||||
},
|
||||
[handleRun, hideModal, updateNodeForm],
|
||||
);
|
||||
|
||||
const onOk = useCallback(
|
||||
async (nextValues: any[]) => {
|
||||
handleRunAgent(nextValues);
|
||||
},
|
||||
[handleRunAgent],
|
||||
);
|
||||
|
||||
return (
|
||||
<Drawer
|
||||
title={t('flow.testRun')}
|
||||
placement="right"
|
||||
onClose={hideModal}
|
||||
open
|
||||
getContainer={false}
|
||||
width={getDrawerWidth()}
|
||||
mask={false}
|
||||
>
|
||||
<DebugContent
|
||||
ok={onOk}
|
||||
parameters={query}
|
||||
loading={loading}
|
||||
></DebugContent>
|
||||
</Drawer>
|
||||
);
|
||||
};
|
||||
|
||||
export default RunSheet;
|
||||
Reference in New Issue
Block a user