mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-09-05 11:01:09 +00:00
Merge branch 'feat/sprint-flow-remaining-requirements' into feat/dag
This commit is contained in:
@@ -79,3 +79,7 @@ export const getKeys = () => {
|
|||||||
export const getVariablesByKey = ({ key, scope }: { key: string; scope: string }) => {
|
export const getVariablesByKey = ({ key, scope }: { key: string; scope: string }) => {
|
||||||
return GET<IFlowVariablesParams, any>('/api/v2/serve/awel/variables', { key, scope });
|
return GET<IFlowVariablesParams, any>('/api/v2/serve/awel/variables', { key, scope });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const metadataBatch = (data: IUploadFileRequestParams) => {
|
||||||
|
return POST<IUploadFileRequestParams, Array<IUploadFileResponse>>('/api/v2/serve/file/files/metadata/batch', data);
|
||||||
|
};
|
||||||
|
@@ -4,7 +4,7 @@ import { Button, Form, GetProp, Modal, Radio, Space, Upload, UploadFile, UploadP
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
import { Edge, Node } from 'reactflow';
|
import { Edge, Node } from 'reactflow';
|
||||||
|
import CanvasWrapper from '@/pages/construct/flow/canvas/index';
|
||||||
type Props = {
|
type Props = {
|
||||||
isImportModalOpen: boolean;
|
isImportModalOpen: boolean;
|
||||||
setNodes: React.Dispatch<React.SetStateAction<Node<any, string | undefined>[]>>;
|
setNodes: React.Dispatch<React.SetStateAction<Node<any, string | undefined>[]>>;
|
||||||
@@ -37,9 +37,12 @@ export const ImportFlowModal: React.FC<Props> = ({ isImportModalOpen, setIsImpor
|
|||||||
const [, , res] = await apiInterceptors(importFlow(formData));
|
const [, , res] = await apiInterceptors(importFlow(formData));
|
||||||
|
|
||||||
if (res?.success) {
|
if (res?.success) {
|
||||||
messageApi.success(t('Export_Flow_Success'));
|
messageApi.success(t('Import_Flow_Success'));
|
||||||
|
localStorage.setItem('importFlowData', JSON.stringify(res?.data));
|
||||||
|
CanvasWrapper(res?.data)
|
||||||
} else if (res?.err_msg) {
|
} else if (res?.err_msg) {
|
||||||
messageApi.error(res?.err_msg);
|
messageApi.error(res?.err_msg);
|
||||||
|
|
||||||
}
|
}
|
||||||
setIsImportFlowModalOpen(false);
|
setIsImportFlowModalOpen(false);
|
||||||
};
|
};
|
||||||
|
@@ -19,7 +19,6 @@ type CanvasNodeProps = {
|
|||||||
function TypeLabel({ label }: { label: string }) {
|
function TypeLabel({ label }: { label: string }) {
|
||||||
return <div className='w-full h-8 align-middle font-semibold'>{label}</div>;
|
return <div className='w-full h-8 align-middle font-semibold'>{label}</div>;
|
||||||
}
|
}
|
||||||
const forceTypeList = ['file', 'multiple_files', 'time'];
|
|
||||||
|
|
||||||
const CanvasNode: React.FC<CanvasNodeProps> = ({ data }) => {
|
const CanvasNode: React.FC<CanvasNodeProps> = ({ data }) => {
|
||||||
const node = data;
|
const node = data;
|
||||||
@@ -128,9 +127,6 @@ const CanvasNode: React.FC<CanvasNodeProps> = ({ data }) => {
|
|||||||
function onParameterValuesChange(changedValues: any, allValues: any) {
|
function onParameterValuesChange(changedValues: any, allValues: any) {
|
||||||
const [changedKey, changedVal] = Object.entries(changedValues)[0];
|
const [changedKey, changedVal] = Object.entries(changedValues)[0];
|
||||||
|
|
||||||
if (!allValues?.force && forceTypeList.includes(changedKey)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
updateCurrentNodeValue(changedKey, changedVal);
|
updateCurrentNodeValue(changedKey, changedVal);
|
||||||
if (changedVal) {
|
if (changedVal) {
|
||||||
updateDependsNodeValue(changedKey, changedVal);
|
updateDependsNodeValue(changedKey, changedVal);
|
||||||
@@ -197,8 +193,11 @@ const CanvasNode: React.FC<CanvasNodeProps> = ({ data }) => {
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
'w-80 h-auto rounded-xl shadow-md px-2 py-4 border bg-white dark:bg-zinc-800 cursor-grab flex flex-col space-y-2 text-sm',
|
'h-auto rounded-xl shadow-md px-2 py-4 border bg-white dark:bg-zinc-800 cursor-grab flex flex-col space-y-2 text-sm',
|
||||||
{
|
{
|
||||||
|
'w-80':node?.tags?.ui_size === 'middle' || !node?.tags?.ui_size,
|
||||||
|
'w-[256px]':node?.tags?.ui_size === 'small',
|
||||||
|
'w-[530px]':node?.tags?.ui_size === 'large',
|
||||||
'border-blue-500': node.selected || isHovered,
|
'border-blue-500': node.selected || isHovered,
|
||||||
'border-stone-400 dark:border-white': !node.selected && !isHovered,
|
'border-stone-400 dark:border-white': !node.selected && !isHovered,
|
||||||
'border-dashed': flowType !== 'operator',
|
'border-dashed': flowType !== 'operator',
|
||||||
|
@@ -131,6 +131,7 @@ const NodeParamHandler: React.FC<NodeParamHandlerProps> = ({ formValuesChange, n
|
|||||||
if (ui_type === 'slider' && data.is_list) {
|
if (ui_type === 'slider' && data.is_list) {
|
||||||
defaultValue = [0, 1];
|
defaultValue = [0, 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Form.Item
|
<Form.Item
|
||||||
className='mb-2'
|
className='mb-2'
|
||||||
|
@@ -2,10 +2,11 @@
|
|||||||
import { IFlowNodeParameter } from '@/types/flow';
|
import { IFlowNodeParameter } from '@/types/flow';
|
||||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||||
import { UploadOutlined } from '@ant-design/icons';
|
import { UploadOutlined } from '@ant-design/icons';
|
||||||
import type { UploadProps } from 'antd';
|
import type { UploadProps,UploadFile } from 'antd';
|
||||||
import { Button, Upload, message } from 'antd';
|
import { Button, Upload, message } from 'antd';
|
||||||
import { useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { metadataBatch } from '@/client/api';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
formValuesChange: any;
|
formValuesChange: any;
|
||||||
@@ -16,6 +17,33 @@ export const renderUpload = (params: Props) => {
|
|||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const urlList = useRef<string[]>([]);
|
const urlList = useRef<string[]>([]);
|
||||||
const { data, formValuesChange } = params;
|
const { data, formValuesChange } = params;
|
||||||
|
const [fileList, setFileList] = useState<UploadFile[]>([])
|
||||||
|
|
||||||
|
// 获取上传文件元数据
|
||||||
|
useEffect(() => {
|
||||||
|
if (data.value) {
|
||||||
|
let uris:string[] = []
|
||||||
|
typeof(data.value) === 'string'? uris.push(data.value):uris = data.value
|
||||||
|
let parameter:any = {
|
||||||
|
uris
|
||||||
|
}
|
||||||
|
metadataBatch(parameter).then((res)=>{
|
||||||
|
let urlList:UploadFile[] = []
|
||||||
|
for (let index = 0; index < res.data.data.length; index++) {
|
||||||
|
const element = res.data.data[index];
|
||||||
|
urlList.push({
|
||||||
|
uid: element.file_id,
|
||||||
|
name:element.file_name,
|
||||||
|
status: 'done',
|
||||||
|
url: element.uri,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
setFileList(urlList)
|
||||||
|
}).catch((error)=>{
|
||||||
|
console.log(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||||
const [uploading, setUploading] = useState(false);
|
const [uploading, setUploading] = useState(false);
|
||||||
@@ -51,6 +79,7 @@ export const renderUpload = (params: Props) => {
|
|||||||
headers: {
|
headers: {
|
||||||
authorization: 'authorization-text',
|
authorization: 'authorization-text',
|
||||||
},
|
},
|
||||||
|
defaultFileList: fileList,
|
||||||
onChange(info) {
|
onChange(info) {
|
||||||
setUploading(true);
|
setUploading(true);
|
||||||
if (info.file.status !== 'uploading') {
|
if (info.file.status !== 'uploading') {
|
||||||
@@ -73,19 +102,11 @@ export const renderUpload = (params: Props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='p-2 text-sm text-center'>
|
<div className='p-2 text-sm text-center'>
|
||||||
{data.is_list ? (
|
<Upload onRemove={handleFileRemove} {...props} {...attr} multiple={data.is_list?true:false} accept={uploadType}>
|
||||||
<Upload onRemove={handleFileRemove} {...props} {...attr} multiple={true} accept={uploadType}>
|
|
||||||
<Button loading={uploading} icon={<UploadOutlined />}>
|
<Button loading={uploading} icon={<UploadOutlined />}>
|
||||||
{t('Upload_Data')}
|
{t('Upload_Data')}
|
||||||
</Button>
|
</Button>
|
||||||
</Upload>
|
</Upload>
|
||||||
) : (
|
|
||||||
<Upload onRemove={handleFileRemove} {...props} {...attr} multiple={false} accept={uploadType}>
|
|
||||||
<Button loading={uploading} icon={<UploadOutlined />}>
|
|
||||||
{t('Upload_Data')}
|
|
||||||
</Button>
|
|
||||||
</Upload>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@@ -26,8 +26,8 @@ import 'reactflow/dist/style.css';
|
|||||||
|
|
||||||
const nodeTypes = { customNode: CanvasNode };
|
const nodeTypes = { customNode: CanvasNode };
|
||||||
const edgeTypes = { buttonedge: ButtonEdge };
|
const edgeTypes = { buttonedge: ButtonEdge };
|
||||||
|
|
||||||
const Canvas: React.FC = () => {
|
const Canvas: React.FC = () => {
|
||||||
|
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const [messageApi, contextHolder] = message.useMessage();
|
const [messageApi, contextHolder] = message.useMessage();
|
||||||
|
|
||||||
@@ -44,6 +44,16 @@ const Canvas: React.FC = () => {
|
|||||||
const [isExportFlowModalOpen, setIsExportFlowModalOpen] = useState(false);
|
const [isExportFlowModalOpen, setIsExportFlowModalOpen] = useState(false);
|
||||||
const [isImportModalOpen, setIsImportFlowModalOpen] = useState(false);
|
const [isImportModalOpen, setIsImportFlowModalOpen] = useState(false);
|
||||||
|
|
||||||
|
if (localStorage.getItem('importFlowData') ) {
|
||||||
|
const importFlowData = JSON.parse(localStorage.getItem('importFlowData') );
|
||||||
|
localStorage.removeItem('importFlowData')
|
||||||
|
setLoading(true);
|
||||||
|
const flowData = mapUnderlineToHump(importFlowData.flow_data);
|
||||||
|
setFlowInfo(importFlowData);
|
||||||
|
setNodes(flowData.nodes);
|
||||||
|
setEdges(flowData.edges);
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
async function getFlowData() {
|
async function getFlowData() {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
const [_, data] = await apiInterceptors(getFlowById(id));
|
const [_, data] = await apiInterceptors(getFlowById(id));
|
||||||
|
Reference in New Issue
Block a user