mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-08-07 11:23:40 +00:00
feat: upload metadata 、ui size settings 276 320 530 、import flow (#1965)
# Description Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. # How Has This Been Tested? Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration # Snapshots: Include snapshots for easier review. # Checklist: - [ ] My code follows the style guidelines of this project - [ ] I have already rebased the commits and make the commit message conform to the project standard. - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] Any dependent changes have been merged and published in downstream modules
This commit is contained in:
commit
b87b42f8ae
@ -71,3 +71,6 @@ export const getFlowTemplateList = () => {
|
|||||||
export const getFlowTemplateById = (id: string) => {
|
export const getFlowTemplateById = (id: string) => {
|
||||||
return GET<null, any>(`/api/v2/serve/awel/flow/templates/${id}`);
|
return GET<null, any>(`/api/v2/serve/awel/flow/templates/${id}`);
|
||||||
};
|
};
|
||||||
|
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();
|
||||||
|
|
||||||
@ -43,7 +43,17 @@ const Canvas: React.FC = () => {
|
|||||||
const [isSaveFlowModalOpen, setIsSaveFlowModalOpen] = useState(false);
|
const [isSaveFlowModalOpen, setIsSaveFlowModalOpen] = useState(false);
|
||||||
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));
|
||||||
|
@ -122,4 +122,4 @@ table {
|
|||||||
|
|
||||||
.rc-md-editor .editor-container>.section {
|
.rc-md-editor .editor-container>.section {
|
||||||
border-right: none !important;
|
border-right: none !important;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user