mirror of
https://github.com/csunny/DB-GPT.git
synced 2025-08-01 08:11:45 +00:00
feat: Add support for retrieving keys and variables by key in Flow API
This commit is contained in:
parent
ed12ee0555
commit
9a4e6b623e
@ -6,7 +6,10 @@ import {
|
|||||||
IFlowRefreshParams,
|
IFlowRefreshParams,
|
||||||
IFlowResponse,
|
IFlowResponse,
|
||||||
IFlowUpdateParam,
|
IFlowUpdateParam,
|
||||||
IFlowVariablesParams,
|
IGetKeysRequestParams,
|
||||||
|
IGetKeysResponseData,
|
||||||
|
IGetVariablesByKeyRequestParams,
|
||||||
|
IGetVariablesByKeyResponseData,
|
||||||
IUploadFileRequestParams,
|
IUploadFileRequestParams,
|
||||||
IUploadFileResponse,
|
IUploadFileResponse,
|
||||||
} from '@/types/flow';
|
} from '@/types/flow';
|
||||||
@ -72,12 +75,12 @@ 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 getKeys = () => {
|
export const getKeys = (data?: IGetKeysRequestParams) => {
|
||||||
return GET<null, Array<any>>('/api/v2/serve/awel/variables/keys');
|
return GET<IGetKeysRequestParams, Array<IGetKeysResponseData>>('/api/v2/serve/awel/variables/keys', data);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getVariablesByKey = ({ key, scope }: { key: string; scope: string }) => {
|
export const getVariablesByKey = (data: IGetVariablesByKeyRequestParams) => {
|
||||||
return GET<IFlowVariablesParams, any>('/api/v2/serve/awel/variables', { key, scope });
|
return GET<IGetVariablesByKeyRequestParams, IGetVariablesByKeyResponseData>('/api/v2/serve/awel/variables', data);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const metadataBatch = (data: IUploadFileRequestParams) => {
|
export const metadataBatch = (data: IUploadFileRequestParams) => {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { apiInterceptors, getKeys, getVariablesByKey } from '@/client/api';
|
import { apiInterceptors, getKeys, getVariablesByKey } from '@/client/api';
|
||||||
import { IVariableInfo } from '@/types/flow';
|
import { IGetKeysResponseData, IVariableItem } from '@/types/flow';
|
||||||
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
|
||||||
import { Button, Cascader, Form, Input, Modal, Select, Space } from 'antd';
|
import { Button, Cascader, Form, Input, Modal, Select, Space } from 'antd';
|
||||||
import { uniqBy } from 'lodash';
|
import { uniqBy } from 'lodash';
|
||||||
@ -16,18 +16,6 @@ interface Option {
|
|||||||
isLeaf?: boolean;
|
isLeaf?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface VariableDict {
|
|
||||||
key: string;
|
|
||||||
name?: string;
|
|
||||||
scope?: string;
|
|
||||||
scope_key?: string;
|
|
||||||
sys_code?: string;
|
|
||||||
user_name?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const DAG_PARAM_KEY = 'dbgpt.core.flow.params';
|
|
||||||
const DAG_PARAM_SCOPE = 'flow_priv';
|
|
||||||
|
|
||||||
function escapeVariable(value: string, enableEscape: boolean): string {
|
function escapeVariable(value: string, enableEscape: boolean): string {
|
||||||
if (!enableEscape) {
|
if (!enableEscape) {
|
||||||
return value;
|
return value;
|
||||||
@ -35,7 +23,7 @@ function escapeVariable(value: string, enableEscape: boolean): string {
|
|||||||
return value.replace(/@/g, '\\@').replace(/#/g, '\\#').replace(/%/g, '\\%').replace(/:/g, '\\:');
|
return value.replace(/@/g, '\\@').replace(/#/g, '\\#').replace(/%/g, '\\%').replace(/:/g, '\\:');
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildVariableString(variableDict) {
|
function buildVariableString(variableDict: IVariableItem): string {
|
||||||
const scopeSig = '@';
|
const scopeSig = '@';
|
||||||
const sysCodeSig = '#';
|
const sysCodeSig = '#';
|
||||||
const userSig = '%';
|
const userSig = '%';
|
||||||
@ -44,8 +32,7 @@ function buildVariableString(variableDict) {
|
|||||||
|
|
||||||
const specialChars = new Set([scopeSig, sysCodeSig, userSig, kvSig]);
|
const specialChars = new Set([scopeSig, sysCodeSig, userSig, kvSig]);
|
||||||
|
|
||||||
// Replace undefined or null with ""
|
const newVariableDict: Partial<IVariableItem> = {
|
||||||
const newVariableDict: VariableDict = {
|
|
||||||
key: variableDict.key || '',
|
key: variableDict.key || '',
|
||||||
name: variableDict.name || '',
|
name: variableDict.name || '',
|
||||||
scope: variableDict.scope || '',
|
scope: variableDict.scope || '',
|
||||||
@ -56,9 +43,9 @@ function buildVariableString(variableDict) {
|
|||||||
|
|
||||||
// Check for special characters in values
|
// Check for special characters in values
|
||||||
for (const [key, value] of Object.entries(newVariableDict)) {
|
for (const [key, value] of Object.entries(newVariableDict)) {
|
||||||
if (value && [...specialChars].some(char => value.includes(char))) {
|
if (value && [...specialChars].some(char => (value as string).includes(char))) {
|
||||||
if (enableEscape) {
|
if (enableEscape) {
|
||||||
newVariableDict[key as keyof VariableDict] = escapeVariable(value, enableEscape);
|
newVariableDict[key] = escapeVariable(value as string, enableEscape);
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`${key} contains special characters, error value: ${value}, special characters: ${[...specialChars].join(', ')}`,
|
`${key} contains special characters, error value: ${value}, special characters: ${[...specialChars].join(', ')}`,
|
||||||
@ -71,25 +58,15 @@ function buildVariableString(variableDict) {
|
|||||||
|
|
||||||
let variableStr = `${key}`;
|
let variableStr = `${key}`;
|
||||||
|
|
||||||
if (name) {
|
if (name) variableStr += `${kvSig}${name}`;
|
||||||
variableStr += `${kvSig}${name}`;
|
if (scope || scope_key) {
|
||||||
}
|
|
||||||
|
|
||||||
if (scope) {
|
|
||||||
variableStr += `${scopeSig}${scope}`;
|
variableStr += `${scopeSig}${scope}`;
|
||||||
if (scope_key) {
|
if (scope_key) {
|
||||||
variableStr += `${kvSig}${scope_key}`;
|
variableStr += `${kvSig}${scope_key}`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (sys_code) variableStr += `${sysCodeSig}${sys_code}`;
|
||||||
if (sys_code) {
|
if (user_name) variableStr += `${userSig}${user_name}`;
|
||||||
variableStr += `${sysCodeSig}${sys_code}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (user_name) {
|
|
||||||
variableStr += `${userSig}${user_name}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return `\${${variableStr}}`;
|
return `\${${variableStr}}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,7 +86,7 @@ export const AddFlowVariableModal: React.FC = () => {
|
|||||||
|
|
||||||
if (err) return;
|
if (err) return;
|
||||||
|
|
||||||
const keyOptions = res?.map(({ key, label, scope }: IVariableInfo) => ({
|
const keyOptions = res?.map(({ key, label, scope }: IGetKeysResponseData) => ({
|
||||||
value: key,
|
value: key,
|
||||||
label,
|
label,
|
||||||
scope,
|
scope,
|
||||||
@ -125,7 +102,7 @@ export const AddFlowVariableModal: React.FC = () => {
|
|||||||
setIsModalOpen(false);
|
setIsModalOpen(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
function onNameChange(e: React.ChangeEvent<HTMLInputElement>, index: number) {
|
const onNameChange = (e: React.ChangeEvent<HTMLInputElement>, index: number) => {
|
||||||
const name = e.target.value;
|
const name = e.target.value;
|
||||||
|
|
||||||
const result = name
|
const result = name
|
||||||
@ -139,32 +116,15 @@ export const AddFlowVariableModal: React.FC = () => {
|
|||||||
value: result,
|
value: result,
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
// change value to ref
|
const onValueTypeChange = (type: ValueType, index: number) => {
|
||||||
const type = form.getFieldValue(['parameters', index, 'value_type']);
|
|
||||||
|
|
||||||
if (type === 'ref') {
|
|
||||||
const parameters = form.getFieldValue('parameters');
|
|
||||||
const param = parameters?.[index];
|
|
||||||
|
|
||||||
if (param) {
|
|
||||||
const { name = '' } = param;
|
|
||||||
param.value = `${DAG_PARAM_KEY}:${name}@scope:${DAG_PARAM_SCOPE}`;
|
|
||||||
|
|
||||||
form.setFieldsValue({
|
|
||||||
parameters: [...parameters],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function onValueTypeChange(type: ValueType, index: number) {
|
|
||||||
const newControlTypes = [...controlTypes];
|
const newControlTypes = [...controlTypes];
|
||||||
newControlTypes[index] = type;
|
newControlTypes[index] = type;
|
||||||
setControlTypes(newControlTypes);
|
setControlTypes(newControlTypes);
|
||||||
}
|
};
|
||||||
|
|
||||||
function loadData(selectedOptions: Option[]) {
|
const loadData = (selectedOptions: Option[]) => {
|
||||||
const targetOption = selectedOptions[selectedOptions.length - 1];
|
const targetOption = selectedOptions[selectedOptions.length - 1];
|
||||||
const { value, scope } = targetOption as Option & { scope: string };
|
const { value, scope } = targetOption as Option & { scope: string };
|
||||||
|
|
||||||
@ -181,32 +141,39 @@ export const AddFlowVariableModal: React.FC = () => {
|
|||||||
targetOption.children = uniqueItems?.map(item => ({
|
targetOption.children = uniqueItems?.map(item => ({
|
||||||
value: item?.name,
|
value: item?.name,
|
||||||
label: item.label,
|
label: item.label,
|
||||||
data: item,
|
item: item,
|
||||||
}));
|
}));
|
||||||
setRefVariableOptions([...refVariableOptions]);
|
setRefVariableOptions([...refVariableOptions]);
|
||||||
}, 1000);
|
}, 1000);
|
||||||
}
|
};
|
||||||
|
|
||||||
function onRefTypeValueChange(value: string[], selectedOptions: Option[], index: number) {
|
const onRefTypeValueChange = (value: (string | number | null)[], selectedOptions: Option[], index: number) => {
|
||||||
// 选择两个select后,获取到的value,才能设置引用变量的值
|
// when select ref variable, must be select two options(key and variable)
|
||||||
if (value?.length === 2) {
|
if (value?.length !== 2) {
|
||||||
const [selectRefKey, selectedRefVariable] = selectedOptions;
|
return;
|
||||||
const selectedVariableData = selectRefKey?.children?.find(({ value }) => value === selectedRefVariable?.value);
|
|
||||||
const variableStr = buildVariableString(selectedVariableData?.data);
|
|
||||||
|
|
||||||
const parameters = form.getFieldValue('parameters');
|
|
||||||
const param = parameters?.[index];
|
|
||||||
if (param) {
|
|
||||||
param.value = variableStr;
|
|
||||||
param.category = selectedVariableData?.data?.category;
|
|
||||||
param.value_type = selectedVariableData?.data?.value_type;
|
|
||||||
|
|
||||||
form.setFieldsValue({
|
|
||||||
parameters: [...parameters],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
const [selectRefKey, selectedRefVariable] = selectedOptions as Option[];
|
||||||
|
|
||||||
|
const selectedVariable = selectRefKey?.children?.find(
|
||||||
|
({ value }) => value === selectedRefVariable?.value,
|
||||||
|
) as Option & { item: IVariableItem };
|
||||||
|
|
||||||
|
// build variable string by rule
|
||||||
|
const variableStr = buildVariableString(selectedVariable?.item);
|
||||||
|
|
||||||
|
const parameters = form.getFieldValue('parameters');
|
||||||
|
const param = parameters?.[index];
|
||||||
|
if (param) {
|
||||||
|
param.value = variableStr;
|
||||||
|
param.category = selectedVariable?.item?.category;
|
||||||
|
param.value_type = selectedVariable?.item?.value_type;
|
||||||
|
|
||||||
|
form.setFieldsValue({
|
||||||
|
parameters: [...parameters],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"target": "es5",
|
"target": "es6",
|
||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
|
@ -12,7 +12,7 @@ export type IFlowUpdateParam = {
|
|||||||
uid?: string;
|
uid?: string;
|
||||||
flow_data?: IFlowData;
|
flow_data?: IFlowData;
|
||||||
state?: FlowState;
|
state?: FlowState;
|
||||||
variables?: IVariableInfo[];
|
variables?: IGetKeysResponseData[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IFlowRefreshParams = {
|
export type IFlowRefreshParams = {
|
||||||
@ -202,7 +202,23 @@ export type IUploadFileResponse = {
|
|||||||
uri?: string;
|
uri?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IFlowVariablesParams = {
|
export type IGetKeysRequestParams = {
|
||||||
|
user_name?: string;
|
||||||
|
sys_code?: string;
|
||||||
|
category?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type IGetKeysResponseData = {
|
||||||
|
key: string;
|
||||||
|
label: string;
|
||||||
|
description: string;
|
||||||
|
value_type: string;
|
||||||
|
category: string;
|
||||||
|
scope: string;
|
||||||
|
scope_key: string | null;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type IGetVariablesByKeyRequestParams = {
|
||||||
key: string;
|
key: string;
|
||||||
scope: string;
|
scope: string;
|
||||||
scope_key?: string;
|
scope_key?: string;
|
||||||
@ -212,12 +228,27 @@ export type IFlowVariablesParams = {
|
|||||||
page_size?: number;
|
page_size?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type IVariableInfo = {
|
export type IGetVariablesByKeyResponseData = {
|
||||||
|
items: IVariableItem[];
|
||||||
|
total_count: number;
|
||||||
|
total_pages: number;
|
||||||
|
page: number;
|
||||||
|
page_size: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type IVariableItem = {
|
||||||
key: string;
|
key: string;
|
||||||
label: string;
|
label: string;
|
||||||
description: string;
|
description: string | null;
|
||||||
value_type: string;
|
value_type: string;
|
||||||
category: string;
|
category: string;
|
||||||
scope: string;
|
scope: string;
|
||||||
scope_key: string | null;
|
scope_key: string | null;
|
||||||
|
name: string;
|
||||||
|
value: string;
|
||||||
|
enabled: boolean;
|
||||||
|
user_name: string | null;
|
||||||
|
sys_code: string | null;
|
||||||
|
id: number;
|
||||||
|
[key: string]: any;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user