Skip to content

Commit

Permalink
feat: Add support for retrieving keys and variables by key in Flow API
Browse files Browse the repository at this point in the history
  • Loading branch information
谨欣 committed Sep 4, 2024
1 parent ed12ee0 commit 9a4e6b6
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 86 deletions.
13 changes: 8 additions & 5 deletions web/client/api/flow/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ import {
IFlowRefreshParams,
IFlowResponse,
IFlowUpdateParam,
IFlowVariablesParams,
IGetKeysRequestParams,
IGetKeysResponseData,
IGetVariablesByKeyRequestParams,
IGetVariablesByKeyResponseData,
IUploadFileRequestParams,
IUploadFileResponse,
} from '@/types/flow';
Expand Down Expand Up @@ -72,12 +75,12 @@ export const getFlowTemplateById = (id: string) => {
return GET<null, any>(`/api/v2/serve/awel/flow/templates/${id}`);
};

export const getKeys = () => {
return GET<null, Array<any>>('/api/v2/serve/awel/variables/keys');
export const getKeys = (data?: IGetKeysRequestParams) => {
return GET<IGetKeysRequestParams, Array<IGetKeysResponseData>>('/api/v2/serve/awel/variables/keys', data);
};

export const getVariablesByKey = ({ key, scope }: { key: string; scope: string }) => {
return GET<IFlowVariablesParams, any>('/api/v2/serve/awel/variables', { key, scope });
export const getVariablesByKey = (data: IGetVariablesByKeyRequestParams) => {
return GET<IGetVariablesByKeyRequestParams, IGetVariablesByKeyResponseData>('/api/v2/serve/awel/variables', data);
};

export const metadataBatch = (data: IUploadFileRequestParams) => {
Expand Down
119 changes: 43 additions & 76 deletions web/components/flow/canvas-modal/add-flow-variable-modal.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
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 { Button, Cascader, Form, Input, Modal, Select, Space } from 'antd';
import { uniqBy } from 'lodash';
Expand All @@ -16,26 +16,14 @@ interface Option {
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 {
if (!enableEscape) {
return value;
}
return value.replace(/@/g, '\\@').replace(/#/g, '\\#').replace(/%/g, '\\%').replace(/:/g, '\\:');
}

function buildVariableString(variableDict) {
function buildVariableString(variableDict: IVariableItem): string {
const scopeSig = '@';
const sysCodeSig = '#';
const userSig = '%';
Expand All @@ -44,8 +32,7 @@ function buildVariableString(variableDict) {

const specialChars = new Set([scopeSig, sysCodeSig, userSig, kvSig]);

// Replace undefined or null with ""
const newVariableDict: VariableDict = {
const newVariableDict: Partial<IVariableItem> = {
key: variableDict.key || '',
name: variableDict.name || '',
scope: variableDict.scope || '',
Expand All @@ -56,9 +43,9 @@ function buildVariableString(variableDict) {

// Check for special characters in values
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) {
newVariableDict[key as keyof VariableDict] = escapeVariable(value, enableEscape);
newVariableDict[key] = escapeVariable(value as string, enableEscape);
} else {
throw new Error(
`${key} contains special characters, error value: ${value}, special characters: ${[...specialChars].join(', ')}`,
Expand All @@ -71,25 +58,15 @@ function buildVariableString(variableDict) {

let variableStr = `${key}`;

if (name) {
variableStr += `${kvSig}${name}`;
}

if (scope) {
if (name) variableStr += `${kvSig}${name}`;
if (scope || scope_key) {
variableStr += `${scopeSig}${scope}`;
if (scope_key) {
variableStr += `${kvSig}${scope_key}`;
}
}

if (sys_code) {
variableStr += `${sysCodeSig}${sys_code}`;
}

if (user_name) {
variableStr += `${userSig}${user_name}`;
}

if (sys_code) variableStr += `${sysCodeSig}${sys_code}`;
if (user_name) variableStr += `${userSig}${user_name}`;
return `\${${variableStr}}`;
}

Expand All @@ -109,7 +86,7 @@ export const AddFlowVariableModal: React.FC = () => {

if (err) return;

const keyOptions = res?.map(({ key, label, scope }: IVariableInfo) => ({
const keyOptions = res?.map(({ key, label, scope }: IGetKeysResponseData) => ({
value: key,
label,
scope,
Expand All @@ -125,7 +102,7 @@ export const AddFlowVariableModal: React.FC = () => {
setIsModalOpen(false);
};

function onNameChange(e: React.ChangeEvent<HTMLInputElement>, index: number) {
const onNameChange = (e: React.ChangeEvent<HTMLInputElement>, index: number) => {
const name = e.target.value;

const result = name
Expand All @@ -139,32 +116,15 @@ export const AddFlowVariableModal: React.FC = () => {
value: result,
},
]);
};

// change value to ref
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 onValueTypeChange = (type: ValueType, index: number) => {
const newControlTypes = [...controlTypes];
newControlTypes[index] = type;
setControlTypes(newControlTypes);
}
};

function loadData(selectedOptions: Option[]) {
const loadData = (selectedOptions: Option[]) => {
const targetOption = selectedOptions[selectedOptions.length - 1];
const { value, scope } = targetOption as Option & { scope: string };

Expand All @@ -181,32 +141,39 @@ export const AddFlowVariableModal: React.FC = () => {
targetOption.children = uniqueItems?.map(item => ({
value: item?.name,
label: item.label,
data: item,
item: item,
}));
setRefVariableOptions([...refVariableOptions]);
}, 1000);
}
};

function onRefTypeValueChange(value: string[], selectedOptions: Option[], index: number) {
// 选择两个select后,获取到的value,才能设置引用变量的值
if (value?.length === 2) {
const [selectRefKey, selectedRefVariable] = selectedOptions;
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 onRefTypeValueChange = (value: (string | number | null)[], selectedOptions: Option[], index: number) => {
// when select ref variable, must be select two options(key and variable)
if (value?.length !== 2) {
return;
}
}

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 (
<>
Expand Down
2 changes: 1 addition & 1 deletion web/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"compilerOptions": {
"target": "es5",
"target": "es6",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
Expand Down
39 changes: 35 additions & 4 deletions web/types/flow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export type IFlowUpdateParam = {
uid?: string;
flow_data?: IFlowData;
state?: FlowState;
variables?: IVariableInfo[];
variables?: IGetKeysResponseData[];
};

export type IFlowRefreshParams = {
Expand Down Expand Up @@ -202,7 +202,23 @@ export type IUploadFileResponse = {
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;
scope: string;
scope_key?: string;
Expand All @@ -212,12 +228,27 @@ export type IFlowVariablesParams = {
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;
label: string;
description: string;
description: string | null;
value_type: string;
category: string;
scope: string;
scope_key: string | null;
name: string;
value: string;
enabled: boolean;
user_name: string | null;
sys_code: string | null;
id: number;
[key: string]: any;
};

0 comments on commit 9a4e6b6

Please sign in to comment.