mirror of
https://git.mirrors.martin98.com/https://github.com/infiniflow/ragflow.git
synced 2025-08-16 14:05:56 +08:00
### What problem does this PR solve? feat: add CreateFlowModal #918 ### Type of change - [x] New Feature (non-breaking change which adds functionality)
This commit is contained in:
parent
04487d1bce
commit
f9adeb9647
@ -1,11 +1,12 @@
|
|||||||
import { DSL, IFlow } from '@/interfaces/database/flow';
|
import { ResponseType } from '@/interfaces/database/base';
|
||||||
|
import { DSL, IFlow, IFlowTemplate } from '@/interfaces/database/flow';
|
||||||
import i18n from '@/locales/config';
|
import i18n from '@/locales/config';
|
||||||
import flowService from '@/services/flow-service';
|
import flowService from '@/services/flow-service';
|
||||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query';
|
||||||
import { message } from 'antd';
|
import { message } from 'antd';
|
||||||
import { useParams } from 'umi';
|
import { useParams } from 'umi';
|
||||||
|
|
||||||
export const useFetchFlowTemplates = () => {
|
export const useFetchFlowTemplates = (): ResponseType<IFlowTemplate[]> => {
|
||||||
const { data } = useQuery({
|
const { data } = useQuery({
|
||||||
queryKey: ['fetchFlowTemplates'],
|
queryKey: ['fetchFlowTemplates'],
|
||||||
initialData: [],
|
initialData: [],
|
||||||
|
@ -244,3 +244,28 @@ export const useHandleMessageInputChange = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// #endregion
|
// #endregion
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param defaultId
|
||||||
|
* used to switch between different items, similar to radio
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export const useSelectItem = (defaultId?: string) => {
|
||||||
|
const [selectedId, setSelectedId] = useState('');
|
||||||
|
|
||||||
|
const handleItemClick = useCallback(
|
||||||
|
(id: string) => () => {
|
||||||
|
setSelectedId(id);
|
||||||
|
},
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (defaultId) {
|
||||||
|
setSelectedId(defaultId);
|
||||||
|
}
|
||||||
|
}, [defaultId]);
|
||||||
|
|
||||||
|
return { selectedId, handleItemClick };
|
||||||
|
};
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
export interface ResponseType {
|
export interface ResponseType<T = any> {
|
||||||
retcode: number;
|
retcode: number;
|
||||||
data: any;
|
data: T;
|
||||||
retmsg: string;
|
retmsg: string;
|
||||||
status: number;
|
status: number;
|
||||||
}
|
}
|
||||||
|
@ -42,3 +42,16 @@ export interface IFlow {
|
|||||||
update_time: number;
|
update_time: number;
|
||||||
user_id: string;
|
user_id: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IFlowTemplate {
|
||||||
|
avatar: string;
|
||||||
|
canvas_type: string;
|
||||||
|
create_date: string;
|
||||||
|
create_time: number;
|
||||||
|
description: string;
|
||||||
|
dsl: DSL;
|
||||||
|
id: string;
|
||||||
|
title: string;
|
||||||
|
update_date: string;
|
||||||
|
update_time: number;
|
||||||
|
}
|
||||||
|
@ -557,6 +557,7 @@ The above is the content you need to summarize.`,
|
|||||||
messageMsg: 'Please input message or delete this field.',
|
messageMsg: 'Please input message or delete this field.',
|
||||||
addField: 'Add field',
|
addField: 'Add field',
|
||||||
loop: 'Loop',
|
loop: 'Loop',
|
||||||
|
createFlow: 'Create a workflow',
|
||||||
},
|
},
|
||||||
footer: {
|
footer: {
|
||||||
profile: 'All rights reserved @ React',
|
profile: 'All rights reserved @ React',
|
||||||
|
@ -524,6 +524,7 @@ export default {
|
|||||||
fileError: '文件错误',
|
fileError: '文件错误',
|
||||||
},
|
},
|
||||||
flow: {
|
flow: {
|
||||||
|
flow: '工作流',
|
||||||
cite: '引用',
|
cite: '引用',
|
||||||
citeTip: 'citeTip',
|
citeTip: 'citeTip',
|
||||||
name: '名称',
|
name: '名称',
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
import { useSetModalState } from '@/hooks/commonHooks';
|
import { useSetModalState } from '@/hooks/commonHooks';
|
||||||
import {
|
import { useFetchFlow, useSetFlow } from '@/hooks/flow-hooks';
|
||||||
useFetchFlow,
|
|
||||||
useFetchFlowTemplates,
|
|
||||||
useSetFlow,
|
|
||||||
} from '@/hooks/flow-hooks';
|
|
||||||
import { useFetchLlmList } from '@/hooks/llmHooks';
|
import { useFetchLlmList } from '@/hooks/llmHooks';
|
||||||
import { IGraph } from '@/interfaces/database/flow';
|
import { IGraph } from '@/interfaces/database/flow';
|
||||||
import { useIsFetching } from '@tanstack/react-query';
|
import { useIsFetching } from '@tanstack/react-query';
|
||||||
@ -221,7 +217,6 @@ export const useFetchDataOnMount = () => {
|
|||||||
|
|
||||||
useWatchGraphChange();
|
useWatchGraphChange();
|
||||||
|
|
||||||
useFetchFlowTemplates();
|
|
||||||
useFetchLlmList();
|
useFetchLlmList();
|
||||||
|
|
||||||
return { loading, flowDetail: data };
|
return { loading, flowDetail: data };
|
||||||
|
104
web/src/pages/flow/list/create-flow-modal.tsx
Normal file
104
web/src/pages/flow/list/create-flow-modal.tsx
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
||||||
|
import { useTranslate } from '@/hooks/commonHooks';
|
||||||
|
import { useFetchFlowTemplates } from '@/hooks/flow-hooks';
|
||||||
|
import { useSelectItem } from '@/hooks/logicHooks';
|
||||||
|
import { UserOutlined } from '@ant-design/icons';
|
||||||
|
import {
|
||||||
|
Avatar,
|
||||||
|
Card,
|
||||||
|
Flex,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
Modal,
|
||||||
|
Space,
|
||||||
|
Typography,
|
||||||
|
} from 'antd';
|
||||||
|
import classNames from 'classnames';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import styles from './index.less';
|
||||||
|
|
||||||
|
const { Title } = Typography;
|
||||||
|
interface IProps extends Omit<IModalManagerChildrenProps, 'showModal'> {
|
||||||
|
loading: boolean;
|
||||||
|
initialName: string;
|
||||||
|
onOk: (name: string, templateId: string) => void;
|
||||||
|
showModal?(): void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CreateFlowModal = ({
|
||||||
|
visible,
|
||||||
|
hideModal,
|
||||||
|
loading,
|
||||||
|
initialName,
|
||||||
|
onOk,
|
||||||
|
}: IProps) => {
|
||||||
|
const [form] = Form.useForm();
|
||||||
|
const { t } = useTranslate('common');
|
||||||
|
const { data: list } = useFetchFlowTemplates();
|
||||||
|
const { selectedId, handleItemClick } = useSelectItem(list?.at(0)?.id);
|
||||||
|
|
||||||
|
type FieldType = {
|
||||||
|
name?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleOk = async () => {
|
||||||
|
const ret = await form.validateFields();
|
||||||
|
|
||||||
|
return onOk(ret.name, selectedId);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (visible) {
|
||||||
|
form.setFieldValue('name', initialName);
|
||||||
|
}
|
||||||
|
}, [initialName, form, visible]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Modal
|
||||||
|
title={t('createFlow', { keyPrefix: 'flow' })}
|
||||||
|
open={visible}
|
||||||
|
onOk={handleOk}
|
||||||
|
width={600}
|
||||||
|
onCancel={hideModal}
|
||||||
|
okButtonProps={{ loading }}
|
||||||
|
confirmLoading={loading}
|
||||||
|
>
|
||||||
|
<Form
|
||||||
|
name="basic"
|
||||||
|
labelCol={{ span: 4 }}
|
||||||
|
wrapperCol={{ span: 20 }}
|
||||||
|
autoComplete="off"
|
||||||
|
layout={'vertical'}
|
||||||
|
form={form}
|
||||||
|
>
|
||||||
|
<Form.Item<FieldType>
|
||||||
|
label={<b>{t('name')}</b>}
|
||||||
|
name="name"
|
||||||
|
rules={[{ required: true, message: t('namePlaceholder') }]}
|
||||||
|
>
|
||||||
|
<Input />
|
||||||
|
</Form.Item>
|
||||||
|
</Form>
|
||||||
|
<Title level={5}>Choose from templates</Title>
|
||||||
|
<Flex vertical gap={16}>
|
||||||
|
{list?.map((x) => (
|
||||||
|
<Card
|
||||||
|
key={x.id}
|
||||||
|
className={classNames(styles.flowTemplateCard, {
|
||||||
|
[styles.selectedFlowTemplateCard]: selectedId === x.id,
|
||||||
|
})}
|
||||||
|
onClick={handleItemClick(x.id)}
|
||||||
|
>
|
||||||
|
<Space size={'middle'}>
|
||||||
|
<Avatar size={40} icon={<UserOutlined />} src={x.avatar} />
|
||||||
|
<b>{x.title}</b>
|
||||||
|
</Space>
|
||||||
|
<p>{x.description}</p>
|
||||||
|
</Card>
|
||||||
|
))}
|
||||||
|
</Flex>
|
||||||
|
</Modal>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CreateFlowModal;
|
@ -1,10 +1,14 @@
|
|||||||
import { useSetModalState } from '@/hooks/commonHooks';
|
import { useSetModalState } from '@/hooks/commonHooks';
|
||||||
import { useFetchFlowList, useSetFlow } from '@/hooks/flow-hooks';
|
import {
|
||||||
|
useFetchFlowList,
|
||||||
|
useFetchFlowTemplates,
|
||||||
|
useSetFlow,
|
||||||
|
} from '@/hooks/flow-hooks';
|
||||||
import { useCallback, useState } from 'react';
|
import { useCallback, useState } from 'react';
|
||||||
import { useNavigate } from 'umi';
|
import { useNavigate } from 'umi';
|
||||||
// import { dsl } from '../mock';
|
// import { dsl } from '../mock';
|
||||||
import headhunterZhComponents from '../../../../../graph/test/dsl_examples/headhunter_zh.json';
|
// import headhunterZhComponents from '../../../../../graph/test/dsl_examples/headhunter_zh.json';
|
||||||
import headhunter_zh from '../headhunter_zh.json';
|
import dslJson from '../../../../../dls.json';
|
||||||
|
|
||||||
export const useFetchDataOnMount = () => {
|
export const useFetchDataOnMount = () => {
|
||||||
const { data, loading } = useFetchFlowList();
|
const { data, loading } = useFetchFlowList();
|
||||||
@ -21,12 +25,19 @@ export const useSaveFlow = () => {
|
|||||||
} = useSetModalState();
|
} = useSetModalState();
|
||||||
const { loading, setFlow } = useSetFlow();
|
const { loading, setFlow } = useSetFlow();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const { data: list } = useFetchFlowTemplates();
|
||||||
|
|
||||||
const onFlowOk = useCallback(
|
const onFlowOk = useCallback(
|
||||||
async (title: string) => {
|
async (title: string, templateId: string) => {
|
||||||
|
const templateItem = list.find((x) => x.id === templateId);
|
||||||
|
|
||||||
|
let dsl = templateItem?.dsl;
|
||||||
|
// if (dsl) {
|
||||||
|
// dsl.graph = headhunter_zh;
|
||||||
|
// }
|
||||||
const ret = await setFlow({
|
const ret = await setFlow({
|
||||||
title,
|
title,
|
||||||
dsl: { ...headhunterZhComponents, graph: headhunter_zh },
|
dsl: dslJson,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (ret?.retcode === 0) {
|
if (ret?.retcode === 0) {
|
||||||
@ -34,7 +45,7 @@ export const useSaveFlow = () => {
|
|||||||
navigate(`/flow/${ret.data.id}`);
|
navigate(`/flow/${ret.data.id}`);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
[setFlow, hideFlowSettingModal, navigate],
|
[setFlow, hideFlowSettingModal, navigate, list],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleShowFlowSettingModal = useCallback(
|
const handleShowFlowSettingModal = useCallback(
|
||||||
|
@ -46,3 +46,11 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flowTemplateCard {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.selectedFlowTemplateCard {
|
||||||
|
background-color: @selectedBackgroundColor;
|
||||||
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import RenameModal from '@/components/rename-modal';
|
|
||||||
import { PlusOutlined } from '@ant-design/icons';
|
import { PlusOutlined } from '@ant-design/icons';
|
||||||
import { Button, Empty, Flex, Spin } from 'antd';
|
import { Button, Empty, Flex, Spin } from 'antd';
|
||||||
|
import CreateFlowModal from './create-flow-modal';
|
||||||
import FlowCard from './flow-card';
|
import FlowCard from './flow-card';
|
||||||
import { useFetchDataOnMount, useSaveFlow } from './hooks';
|
import { useFetchDataOnMount, useSaveFlow } from './hooks';
|
||||||
|
|
||||||
@ -39,13 +39,15 @@ const FlowList = () => {
|
|||||||
)}
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
</Spin>
|
</Spin>
|
||||||
<RenameModal
|
{flowSettingVisible && (
|
||||||
visible={flowSettingVisible}
|
<CreateFlowModal
|
||||||
onOk={onFlowOk}
|
visible={flowSettingVisible}
|
||||||
loading={flowSettingLoading}
|
onOk={onFlowOk}
|
||||||
hideModal={hideFlowSettingModal}
|
loading={flowSettingLoading}
|
||||||
initialName=""
|
hideModal={hideFlowSettingModal}
|
||||||
></RenameModal>
|
initialName=""
|
||||||
|
></CreateFlowModal>
|
||||||
|
)}
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user