mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-09-11 22:09:44 +00:00
feat: update UI components for better user experience (#1850)
This commit is contained in:
@@ -34,7 +34,7 @@ import {
|
||||
SpaceConfig,
|
||||
} from '@/types/knowledge';
|
||||
import { UpdatePromptParams, IPrompt, PromptParams } from '@/types/prompt';
|
||||
import { IFlow, IFlowNode, IFlowResponse, IFlowUpdateParam } from '@/types/flow';
|
||||
import { IFlow, IFlowNode, IFlowResponse, IFlowUpdateParam, IFlowRefreshParams } from '@/types/flow';
|
||||
import { IAgent, IApp, IAppData, ITeamModal } from '@/types/app';
|
||||
|
||||
/** App */
|
||||
@@ -262,27 +262,31 @@ export const addPrompt = (data: UpdatePromptParams) => {
|
||||
|
||||
/** AWEL Flow */
|
||||
export const addFlow = (data: IFlowUpdateParam) => {
|
||||
return POST<IFlowUpdateParam, IFlow>('/api/v1/serve/awel/flows', data);
|
||||
return POST<IFlowUpdateParam, IFlow>('/api/v2/serve/awel/flows', data);
|
||||
};
|
||||
|
||||
export const getFlows = () => {
|
||||
return GET<null, IFlowResponse>('/api/v1/serve/awel/flows');
|
||||
return GET<null, IFlowResponse>('/api/v2/serve/awel/flows');
|
||||
};
|
||||
|
||||
export const getFlowById = (id: string) => {
|
||||
return GET<null, IFlow>(`/api/v1/serve/awel/flows/${id}`);
|
||||
return GET<null, IFlow>(`/api/v2/serve/awel/flows/${id}`);
|
||||
};
|
||||
|
||||
export const updateFlowById = (id: string, data: IFlowUpdateParam) => {
|
||||
return PUT<IFlowUpdateParam, IFlow>(`/api/v1/serve/awel/flows/${id}`, data);
|
||||
return PUT<IFlowUpdateParam, IFlow>(`/api/v2/serve/awel/flows/${id}`, data);
|
||||
};
|
||||
|
||||
export const deleteFlowById = (id: string) => {
|
||||
return DELETE<null, null>(`/api/v1/serve/awel/flows/${id}`);
|
||||
return DELETE<null, null>(`/api/v2/serve/awel/flows/${id}`);
|
||||
};
|
||||
|
||||
export const getFlowNodes = () => {
|
||||
return GET<null, Array<IFlowNode>>(`/api/v1/serve/awel/nodes`);
|
||||
return GET<null, Array<IFlowNode>>(`/api/v2/serve/awel/nodes`);
|
||||
};
|
||||
|
||||
export const refreshFlowNodeById = (data: IFlowRefreshParams) => {
|
||||
return POST<IFlowRefreshParams, IFlowNode>('/api/v2/serve/awel/nodes/refresh', data);
|
||||
};
|
||||
|
||||
/** app */
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import { IFlowNode, IFlowNodeParameter } from '@/types/flow';
|
||||
import { refreshFlowNodeById, apiInterceptors } from '@/client/api';
|
||||
import { Checkbox, Input, InputNumber, Select, Tooltip } from 'antd';
|
||||
import React from 'react';
|
||||
import RequiredIcon from './required-icon';
|
||||
@@ -51,6 +52,7 @@ const NodeParamHandler: React.FC<NodeParamHandlerProps> = ({ node, data, label,
|
||||
function renderNodeWithoutUiParam(data: IFlowNodeParameter) {
|
||||
let defaultValue = data.value ?? data.default;
|
||||
|
||||
console.log('datacc', data);
|
||||
switch (data.type_name) {
|
||||
case 'int':
|
||||
case 'float':
|
||||
@@ -61,6 +63,8 @@ const NodeParamHandler: React.FC<NodeParamHandlerProps> = ({ node, data, label,
|
||||
className="w-full"
|
||||
defaultValue={defaultValue}
|
||||
onChange={(value: number | null) => {
|
||||
console.log('value', value);
|
||||
|
||||
onChange(value);
|
||||
}}
|
||||
/>
|
||||
@@ -106,6 +110,32 @@ 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) {
|
||||
switch (type) {
|
||||
case 'select':
|
||||
@@ -146,6 +176,8 @@ const NodeParamHandler: React.FC<NodeParamHandlerProps> = ({ node, data, label,
|
||||
let defaultValue = data.value ?? data.default;
|
||||
const props = { data, defaultValue, onChange };
|
||||
|
||||
console.log('xxx', props);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{renderLabelWithTooltip(data)}
|
||||
@@ -161,4 +193,4 @@ const NodeParamHandler: React.FC<NodeParamHandlerProps> = ({ node, data, label,
|
||||
}
|
||||
};
|
||||
|
||||
export default NodeParamHandler;
|
||||
export default NodeParamHandler;
|
||||
|
@@ -22,19 +22,17 @@ export const RenderCodeEditor = (params: Props) => {
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
|
||||
const handleOk = () => {
|
||||
const onOk = () => {
|
||||
setIsModalOpen(false);
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
const onCancel = () => {
|
||||
setIsModalOpen(false);
|
||||
};
|
||||
/**
|
||||
* 设置弹窗宽度
|
||||
*/
|
||||
|
||||
const modalWidth = useMemo(() => {
|
||||
if (data?.ui?.editor?.width) {
|
||||
return data?.ui?.editor?.width + 100
|
||||
return data?.ui?.editor?.width + 100;
|
||||
}
|
||||
return '80%';
|
||||
}, [data?.ui?.editor?.width]);
|
||||
@@ -44,16 +42,16 @@ export const RenderCodeEditor = (params: Props) => {
|
||||
<Button type="primary" onClick={showModal}>
|
||||
{t('openCodeEditor')}
|
||||
</Button>
|
||||
<Modal title={t('openCodeEditor')} width={modalWidth} open={isModalOpen} onOk={handleOk} onCancel={handleCancel}>
|
||||
|
||||
<Modal title={t('openCodeEditor')} width={modalWidth} open={isModalOpen} onOk={onOk} onCancel={onCancel}>
|
||||
<Editor
|
||||
{...data?.ui?.attr}
|
||||
{...attr}
|
||||
width={data?.ui?.editor?.width || '100%'}
|
||||
value={defaultValue}
|
||||
style={{ padding: '10px' }}
|
||||
height={data?.ui?.editor?.height || 200}
|
||||
defaultLanguage={data?.ui?.language}
|
||||
onChange={onChange}
|
||||
theme='vs-dark'
|
||||
theme="vs-dark"
|
||||
options={{
|
||||
minimap: {
|
||||
enabled: false,
|
||||
|
@@ -11,7 +11,6 @@ type Props = {
|
||||
|
||||
export const RenderDatePicker = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
const onChangeDate: DatePickerProps['onChange'] = (date, dateString) => {
|
||||
|
@@ -4,13 +4,13 @@ import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
|
||||
const { Password } = Input;
|
||||
|
||||
type TextAreaProps = {
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
|
||||
export const RenderPassword = (params: TextAreaProps) => {
|
||||
export const RenderPassword = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
|
@@ -4,13 +4,13 @@ import { Col, InputNumber, Row, Slider, Space } from 'antd';
|
||||
import type { InputNumberProps } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
type TextAreaProps = {
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
|
||||
export const RenderSlider = (params: TextAreaProps) => {
|
||||
export const RenderSlider = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
const [inputValue, setInputValue] = useState(defaultValue);
|
||||
@@ -18,7 +18,6 @@ export const RenderSlider = (params: TextAreaProps) => {
|
||||
setInputValue(newValue);
|
||||
onChange(newValue);
|
||||
};
|
||||
console.log(data);
|
||||
|
||||
return (
|
||||
<>
|
||||
|
@@ -5,13 +5,13 @@ import classNames from 'classnames';
|
||||
|
||||
const { TextArea } = Input;
|
||||
|
||||
type TextAreaProps = {
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
|
||||
export const RenderTextArea = (params: TextAreaProps) => {
|
||||
export const RenderTextArea = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
@@ -1,15 +1,16 @@
|
||||
import React, { useState } from 'react';
|
||||
import React from 'react';
|
||||
import type { TimePickerProps } from 'antd';
|
||||
import { TimePicker } from 'antd';
|
||||
import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
|
||||
type TextAreaProps = {
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
export const RenderTimePicker = (params: TextAreaProps) => {
|
||||
|
||||
export const RenderTimePicker = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
|
@@ -3,27 +3,24 @@ import { TreeSelect } from 'antd';
|
||||
import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
|
||||
type TextAreaProps = {
|
||||
type Props = {
|
||||
data: IFlowNodeParameter;
|
||||
defaultValue: any;
|
||||
onChange: (value: any) => void;
|
||||
};
|
||||
export const RenderTreeSelect = (params: TextAreaProps) => {
|
||||
export const RenderTreeSelect = (params: Props) => {
|
||||
const { data, defaultValue, onChange } = params;
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
return (
|
||||
<div className="p-2 text-sm">
|
||||
<TreeSelect
|
||||
className="w-full nodrag"
|
||||
fieldNames={{ label: 'label', value: 'value', children: 'children' }}
|
||||
{...attr}
|
||||
style={{ width: '100%' }}
|
||||
value={defaultValue}
|
||||
treeDefaultExpandAll
|
||||
onChange={onChange}
|
||||
treeData={data.options}
|
||||
/>
|
||||
</div>
|
||||
<TreeSelect
|
||||
{...attr}
|
||||
className="w-full nodrag"
|
||||
fieldNames={{ label: 'label', value: 'value', children: 'children' }}
|
||||
value={defaultValue}
|
||||
treeDefaultExpandAll
|
||||
onChange={onChange}
|
||||
treeData={data.options}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import React from 'react';
|
||||
import { UploadOutlined } from '@ant-design/icons';
|
||||
import type { UploadProps } from 'antd';
|
||||
import { Button, message, Upload } from 'antd';
|
||||
import { Button, Upload } from 'antd';
|
||||
import { convertKeysToCamelCase } from '@/utils/flow';
|
||||
import { IFlowNodeParameter } from '@/types/flow';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -28,7 +28,7 @@ export const RenderUpload = (params: Props) => {
|
||||
const attr = convertKeysToCamelCase(data.ui?.attr || {});
|
||||
|
||||
return (
|
||||
<div style={{ textAlign: 'center' }} className="p-2 text-sm">
|
||||
<div className="p-2 text-sm text-center">
|
||||
<Upload {...attr} {...props}>
|
||||
<Button icon={<UploadOutlined />}>{t('UploadData')}</Button>
|
||||
</Upload>
|
||||
|
@@ -179,6 +179,7 @@ const Canvas: React.FC<Props> = () => {
|
||||
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, state }));
|
||||
setIsModalVisible(false);
|
||||
|
@@ -12,6 +12,21 @@ export type IFlowUpdateParam = {
|
||||
state?: FlowState;
|
||||
};
|
||||
|
||||
export type IFlowRefreshParams = {
|
||||
id: string;
|
||||
type_name: string;
|
||||
type_cls: string;
|
||||
flow_type: 'resource' | 'operator';
|
||||
refresh: {
|
||||
name: string;
|
||||
depends?: Array<{
|
||||
name: string;
|
||||
value: string;
|
||||
has_value: boolean;
|
||||
}>;
|
||||
}[];
|
||||
};
|
||||
|
||||
export type IFlow = {
|
||||
dag_id: string;
|
||||
gmt_created: string;
|
||||
@@ -60,8 +75,8 @@ export type IFlowNodeParameterUI = {
|
||||
[key: string]: any;
|
||||
};
|
||||
editor: {
|
||||
width: Number;
|
||||
height: Number;
|
||||
width: number;
|
||||
height: number;
|
||||
};
|
||||
show_input: boolean;
|
||||
};
|
||||
|
Reference in New Issue
Block a user