mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-09-18 07:30:40 +00:00
feat(web): copy awel flow (#1200)
Co-authored-by: Fangyin Cheng <staneyffer@gmail.com>
This commit is contained in:
@@ -24,7 +24,7 @@ const edgeTypes = { buttonedge: ButtonEdge };
|
||||
const Canvas: React.FC<Props> = () => {
|
||||
const { t } = useTranslation();
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
const [form] = Form.useForm();
|
||||
const [form] = Form.useForm<IFlowUpdateParam>();
|
||||
const searchParams = useSearchParams();
|
||||
const id = searchParams?.get('id') || '';
|
||||
const reactFlow = useReactFlow();
|
||||
@@ -35,6 +35,7 @@ const Canvas: React.FC<Props> = () => {
|
||||
const reactFlowWrapper = useRef<HTMLDivElement>(null);
|
||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||
const [flowInfo, setFlowInfo] = useState<IFlowUpdateParam>();
|
||||
const [deploy, setDeploy] = useState(true);
|
||||
|
||||
async function getFlowData() {
|
||||
setLoading(true);
|
||||
@@ -175,10 +176,11 @@ const Canvas: React.FC<Props> = () => {
|
||||
}
|
||||
|
||||
async function handleSaveFlow() {
|
||||
const { name, label, description = '', editable = false } = form.getFieldsValue();
|
||||
const { name, label, description = '', editable = false, state = 'deployed' } = form.getFieldsValue();
|
||||
console.log(form.getFieldsValue());
|
||||
const reactFlowObject = mapHumpToUnderline(reactFlow.toObject() as IFlowData);
|
||||
if (id) {
|
||||
const [, , res] = await apiInterceptors(updateFlowById(id, { name, label, description, editable, uid: id, flow_data: reactFlowObject }));
|
||||
const [, , res] = await apiInterceptors(updateFlowById(id, { name, label, description, editable, uid: id, flow_data: reactFlowObject, state }));
|
||||
setIsModalVisible(false);
|
||||
if (res?.success) {
|
||||
messageApi.success(t('save_flow_success'));
|
||||
@@ -186,7 +188,7 @@ const Canvas: React.FC<Props> = () => {
|
||||
messageApi.error(res?.err_msg);
|
||||
}
|
||||
} else {
|
||||
const [_, res] = await apiInterceptors(addFlow({ name, label, description, editable, flow_data: reactFlowObject }));
|
||||
const [_, res] = await apiInterceptors(addFlow({ name, label, description, editable, flow_data: reactFlowObject, state }));
|
||||
if (res?.uid) {
|
||||
messageApi.success(t('save_flow_success'));
|
||||
const history = window.history;
|
||||
@@ -271,7 +273,21 @@ const Canvas: React.FC<Props> = () => {
|
||||
<TextArea rows={3} />
|
||||
</Form.Item>
|
||||
<Form.Item label="Editable" name="editable" initialValue={flowInfo?.editable} valuePropName="checked">
|
||||
<Checkbox></Checkbox>
|
||||
<Checkbox />
|
||||
</Form.Item>
|
||||
<Form.Item hidden name="state">
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item label="Deploy">
|
||||
<Checkbox
|
||||
defaultChecked={flowInfo?.state === 'deployed' || flowInfo?.state === 'running'}
|
||||
value={deploy}
|
||||
onChange={(e) => {
|
||||
const val = e.target.checked;
|
||||
form.setFieldValue('state', val ? 'deployed' : 'developing');
|
||||
setDeploy(val);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item wrapperCol={{ offset: 8, span: 16 }}>
|
||||
<Space>
|
||||
|
@@ -1,16 +1,28 @@
|
||||
import { apiInterceptors, getFlows } from '@/client/api';
|
||||
import { addFlow, apiInterceptors, getFlows } from '@/client/api';
|
||||
import MyEmpty from '@/components/common/MyEmpty';
|
||||
import MuiLoading from '@/components/common/loading';
|
||||
import FlowCard from '@/components/flow/flow-card';
|
||||
import { IFlow } from '@/types/flow';
|
||||
import { IFlow, IFlowUpdateParam } from '@/types/flow';
|
||||
import { PlusOutlined } from '@ant-design/icons';
|
||||
import { Button } from 'antd';
|
||||
import { Button, Checkbox, Form, Input, Modal, message } from 'antd';
|
||||
import Link from 'next/link';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import React, { useEffect, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
type FormFields = Pick<IFlow, 'label' | 'name'>;
|
||||
|
||||
function Flow() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [showModal, setShowModal] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [flowList, setFlowList] = useState<Array<IFlow>>([]);
|
||||
const [deploy, setDeploy] = useState(false);
|
||||
|
||||
const [messageApi, contextHolder] = message.useMessage();
|
||||
const [form] = Form.useForm<Pick<IFlow, 'label' | 'name'>>();
|
||||
|
||||
const copyFlowTemp = useRef<IFlow>();
|
||||
|
||||
async function getFlowList() {
|
||||
setLoading(true);
|
||||
@@ -27,8 +39,34 @@ function Flow() {
|
||||
setFlowList((flows) => flows.filter((flow) => flow.uid !== uid));
|
||||
}
|
||||
|
||||
const handleCopy = (flow: IFlow) => {
|
||||
copyFlowTemp.current = flow;
|
||||
form.setFieldValue('label', `${flow.label} Copy`);
|
||||
form.setFieldValue('name', `${flow.name}_copy`);
|
||||
setDeploy(false);
|
||||
setShowModal(true);
|
||||
};
|
||||
|
||||
const onFinish = async (val: { name: string; label: string }) => {
|
||||
if (!copyFlowTemp.current) return;
|
||||
const { source, uid, dag_id, gmt_created, gmt_modified, state, ...params } = copyFlowTemp.current;
|
||||
const data: IFlowUpdateParam = {
|
||||
...params,
|
||||
editable: true,
|
||||
state: deploy ? 'deployed' : 'developing',
|
||||
...val,
|
||||
};
|
||||
const [err] = await apiInterceptors(addFlow(data));
|
||||
if (!err) {
|
||||
messageApi.success(t('save_flow_success'));
|
||||
setShowModal(false);
|
||||
getFlowList();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="relative p-4 md:p-6 min-h-full overflow-y-auto">
|
||||
{contextHolder}
|
||||
<MuiLoading visible={loading} />
|
||||
<div className="mb-4">
|
||||
<Link href="/flow/canvas">
|
||||
@@ -39,10 +77,41 @@ function Flow() {
|
||||
</div>
|
||||
<div className="flex flex-wrap gap-2 md:gap-4 justify-start items-stretch">
|
||||
{flowList.map((flow) => (
|
||||
<FlowCard key={flow.uid} flow={flow} deleteCallback={updateFlowList} />
|
||||
<FlowCard key={flow.uid} flow={flow} deleteCallback={updateFlowList} onCopy={handleCopy} />
|
||||
))}
|
||||
{flowList.length === 0 && <MyEmpty description="No flow found" />}
|
||||
</div>
|
||||
<Modal
|
||||
open={showModal}
|
||||
title="Copy AWEL Flow"
|
||||
onCancel={() => {
|
||||
setShowModal(false);
|
||||
}}
|
||||
footer={false}
|
||||
>
|
||||
<Form form={form} onFinish={onFinish} className="mt-6">
|
||||
<Form.Item name="name" label="Name" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item name="label" label="Label" rules={[{ required: true }]}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
<Form.Item label="Deploy">
|
||||
<Checkbox
|
||||
value={deploy}
|
||||
onChange={(e) => {
|
||||
const val = e.target.checked;
|
||||
setDeploy(val);
|
||||
}}
|
||||
/>
|
||||
</Form.Item>
|
||||
<div className="flex justify-end">
|
||||
<Button type="primary" htmlType="submit">
|
||||
{t('Submit')}
|
||||
</Button>
|
||||
</div>
|
||||
</Form>
|
||||
</Modal>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
Reference in New Issue
Block a user