mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-09-11 22:09:44 +00:00
feat: add export/import functionality to flow canvas
This commit is contained in:
@@ -110,32 +110,6 @@ const NodeParamHandler: React.FC<NodeParamHandlerProps> = ({ node, data, label,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: refresh flow node
|
|
||||||
async function refreshFlowNode() {
|
|
||||||
// setLoading(true);
|
|
||||||
const params = {
|
|
||||||
id: '',
|
|
||||||
type_name: '',
|
|
||||||
type_cls: '',
|
|
||||||
flow_type: 'operator' as const,
|
|
||||||
refresh: [
|
|
||||||
{
|
|
||||||
name: '',
|
|
||||||
depends: [
|
|
||||||
{
|
|
||||||
name: '',
|
|
||||||
value: '',
|
|
||||||
has_value: true,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
const [_, data] = await apiInterceptors(refreshFlowNodeById(params));
|
|
||||||
// setLoading(false);
|
|
||||||
// setFlowList(data?.items ?? []);
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderComponentByType(type: string, props?: any) {
|
function renderComponentByType(type: string, props?: any) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'select':
|
case 'select':
|
||||||
|
@@ -5,8 +5,8 @@ import ButtonEdge from '@/components/flow/button-edge';
|
|||||||
import CanvasNode from '@/components/flow/canvas-node';
|
import CanvasNode from '@/components/flow/canvas-node';
|
||||||
import { IFlowData, IFlowUpdateParam } from '@/types/flow';
|
import { IFlowData, IFlowUpdateParam } from '@/types/flow';
|
||||||
import { checkFlowDataRequied, getUniqueNodeId, mapHumpToUnderline, mapUnderlineToHump } from '@/utils/flow';
|
import { checkFlowDataRequied, getUniqueNodeId, mapHumpToUnderline, mapUnderlineToHump } from '@/utils/flow';
|
||||||
import { FrownOutlined, SaveOutlined } from '@ant-design/icons';
|
import { ExportOutlined, FrownOutlined, ImportOutlined, SaveOutlined } from '@ant-design/icons';
|
||||||
import { Button, Checkbox, Divider, Form, Input, Modal, Space, message, notification } from 'antd';
|
import { Button, Checkbox, Divider, Form, Input, Modal, Space, Tooltip, message, notification } from 'antd';
|
||||||
import { useSearchParams } from 'next/navigation';
|
import { useSearchParams } from 'next/navigation';
|
||||||
import React, { DragEvent, useCallback, useEffect, useRef, useState } from 'react';
|
import React, { DragEvent, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
@@ -150,7 +150,7 @@ const Canvas: React.FC<Props> = () => {
|
|||||||
form.setFieldsValue({ name: result });
|
form.setFieldsValue({ name: result });
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickSave() {
|
function onSave() {
|
||||||
const flowData = reactFlow.toObject() as IFlowData;
|
const flowData = reactFlow.toObject() as IFlowData;
|
||||||
const [check, node, message] = checkFlowDataRequied(flowData);
|
const [check, node, message] = checkFlowDataRequied(flowData);
|
||||||
if (!check && message) {
|
if (!check && message) {
|
||||||
@@ -175,6 +175,35 @@ const Canvas: React.FC<Props> = () => {
|
|||||||
setIsModalVisible(true);
|
setIsModalVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: EXport flow data
|
||||||
|
function onExport() {
|
||||||
|
const flowData = reactFlow.toObject() as IFlowData;
|
||||||
|
const blob = new Blob([JSON.stringify(flowData)], { type: 'text/plain;charset=utf-8' });
|
||||||
|
const url = URL.createObjectURL(blob);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.download = 'flow.json';
|
||||||
|
a.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Import flow data
|
||||||
|
function onImport() {
|
||||||
|
const input = document.createElement('input');
|
||||||
|
input.type = 'file';
|
||||||
|
input.accept = '.json';
|
||||||
|
input.onchange = async (e: any) => {
|
||||||
|
const file = e.target.files[0];
|
||||||
|
const reader = new FileReader();
|
||||||
|
reader.onload = async (event) => {
|
||||||
|
const flowData = JSON.parse(event.target?.result as string) as IFlowData;
|
||||||
|
setNodes(flowData.nodes);
|
||||||
|
setEdges(flowData.edges);
|
||||||
|
};
|
||||||
|
reader.readAsText(file);
|
||||||
|
};
|
||||||
|
input.click;
|
||||||
|
}
|
||||||
|
|
||||||
async function handleSaveFlow() {
|
async function handleSaveFlow() {
|
||||||
const { name, label, description = '', editable = false, state = 'deployed' } = form.getFieldsValue();
|
const { name, label, description = '', editable = false, state = 'deployed' } = form.getFieldsValue();
|
||||||
console.log(form.getFieldsValue());
|
console.log(form.getFieldsValue());
|
||||||
@@ -202,11 +231,22 @@ const Canvas: React.FC<Props> = () => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<MuiLoading visible={loading} />
|
<MuiLoading visible={loading} />
|
||||||
<div className="my-2 mx-4 flex flex-row justify-end items-center">
|
<Space className="my-2 mx-4 flex flex-row justify-end">
|
||||||
<div className="w-8 h-8 rounded-md bg-stone-300 dark:bg-zinc-700 dark:text-zinc-200 flext justify-center items-center hover:text-blue-500 dark:hover:text-zinc-100">
|
{[
|
||||||
<SaveOutlined className="block text-xl" onClick={clickSave} />
|
{ title: 'import', icon: <ImportOutlined className="block text-xl" onClick={onImport} /> },
|
||||||
</div>
|
{ title: 'export', icon: <ExportOutlined className="block text-xl" onClick={onExport} /> },
|
||||||
</div>
|
{ title: 'save', icon: <SaveOutlined className="block text-xl" onClick={onSave} /> },
|
||||||
|
].map(({ title, icon }) => (
|
||||||
|
<Tooltip
|
||||||
|
key={title}
|
||||||
|
title={title}
|
||||||
|
className="w-8 h-8 rounded-md bg-stone-300 dark:bg-zinc-700 dark:text-zinc-200 hover:text-blue-500 dark:hover:text-zinc-100"
|
||||||
|
>
|
||||||
|
{icon}
|
||||||
|
</Tooltip>
|
||||||
|
))}
|
||||||
|
</Space>
|
||||||
|
|
||||||
<Divider className="mt-0 mb-0" />
|
<Divider className="mt-0 mb-0" />
|
||||||
<div className="h-[calc(100vh-60px)] w-full" ref={reactFlowWrapper}>
|
<div className="h-[calc(100vh-60px)] w-full" ref={reactFlowWrapper}>
|
||||||
<ReactFlow
|
<ReactFlow
|
||||||
|
Reference in New Issue
Block a user