From 3390b57878d6d250723eec0b2b1d947cc68740b3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=AE=B4=E6=99=96?= <2689991790@qq.com>
Date: Thu, 13 Jun 2024 17:54:02 +0800
Subject: [PATCH 1/4] feat:obproxy
---
ui/src/components/CustomFormItem/index.tsx | 27 ++++
ui/src/components/InputLabelComp/index.tsx | 10 +-
ui/src/components/TooltipPretty/index.less | 5 +
ui/src/components/TooltipPretty/index.tsx | 22 ++++
ui/src/constants/doc.ts | 3 +-
ui/src/constants/index.ts | 20 +++
ui/src/pages/Cluster/New/BasicInfo.tsx | 12 +-
ui/src/pages/Cluster/New/Observer.tsx | 64 +++-------
ui/src/pages/OBProxy/ClusterList.tsx | 2 +-
.../OBProxy/Detail/Overview/ConfigDrawer.tsx | 115 ++++++++++++++++++
.../OBProxy/Detail/Overview/DetailConfig.tsx | 25 ++--
ui/src/pages/OBProxy/New/BasicConfig.tsx | 50 +++++---
ui/src/pages/OBProxy/New/DetailConfig.tsx | 86 +++++++++++++
ui/src/pages/OBProxy/New/index.less | 4 +
ui/src/pages/OBProxy/New/index.tsx | 33 ++++-
15 files changed, 395 insertions(+), 83 deletions(-)
create mode 100644 ui/src/components/CustomFormItem/index.tsx
create mode 100644 ui/src/components/TooltipPretty/index.less
create mode 100644 ui/src/components/TooltipPretty/index.tsx
create mode 100644 ui/src/pages/OBProxy/Detail/Overview/ConfigDrawer.tsx
create mode 100644 ui/src/pages/OBProxy/New/DetailConfig.tsx
create mode 100644 ui/src/pages/OBProxy/New/index.less
diff --git a/ui/src/components/CustomFormItem/index.tsx b/ui/src/components/CustomFormItem/index.tsx
new file mode 100644
index 000000000..ddf1a4811
--- /dev/null
+++ b/ui/src/components/CustomFormItem/index.tsx
@@ -0,0 +1,27 @@
+import { intl } from '@/utils/intl';
+import { Form } from 'antd';
+
+export const CustomFormItem = (prop: any) => {
+ const { label, message } = prop;
+ return (
+
+ {prop.children}
+
+ );
+};
diff --git a/ui/src/components/InputLabelComp/index.tsx b/ui/src/components/InputLabelComp/index.tsx
index c922a5737..3823c9939 100644
--- a/ui/src/components/InputLabelComp/index.tsx
+++ b/ui/src/components/InputLabelComp/index.tsx
@@ -12,6 +12,7 @@ interface InputLabelCompPorps {
maxLength?: number;
defaulLabelName?: string;
regex?: boolean;
+ disable?: boolean;
}
export default function InputLabelComp(props: InputLabelCompPorps) {
@@ -22,6 +23,7 @@ export default function InputLabelComp(props: InputLabelCompPorps) {
onBlur,
defaulLabelName = 'key',
regex,
+ disable = false,
} = props;
const labelNameInput = (value: string, index: number) => {
@@ -53,16 +55,18 @@ export default function InputLabelComp(props: InputLabelCompPorps) {
{labels?.map((label, index) => (
-
+
labelNameInput(e.target.value, index)}
placeholder="请输入标签名"
/>
-
+
labelValueInput(e.target.value, index)}
@@ -99,7 +103,7 @@ export default function InputLabelComp(props: InputLabelCompPorps) {
))}
- {!maxLength || labels.length < maxLength ? (
+ {(!maxLength || labels.length < maxLength) && !disable ? (
diff --git a/ui/src/pages/OBProxy/ClusterList.tsx b/ui/src/pages/OBProxy/ClusterList.tsx
index f7c5dab35..0e08ffcc4 100644
--- a/ui/src/pages/OBProxy/ClusterList.tsx
+++ b/ui/src/pages/OBProxy/ClusterList.tsx
@@ -40,7 +40,7 @@ const columns: ColumnsType = [
},
{
title: '副本数',
- dataIndex: 'Replicas',
+ dataIndex: 'replicas',
key: 'Replicas',
},
{
diff --git a/ui/src/pages/OBProxy/Detail/Overview/ConfigDrawer.tsx b/ui/src/pages/OBProxy/Detail/Overview/ConfigDrawer.tsx
new file mode 100644
index 000000000..74117fea8
--- /dev/null
+++ b/ui/src/pages/OBProxy/Detail/Overview/ConfigDrawer.tsx
@@ -0,0 +1,115 @@
+import { obproxy } from '@/api';
+import type { CommonKVPair, CommonResourceSpec } from '@/api/generated';
+import { ObproxyPatchOBProxyParam } from '@/api/generated';
+import AlertDrawer from '@/components/AlertDrawer';
+import { CustomFormItem } from '@/components/CustomFormItem';
+import InputLabelComp from '@/components/InputLabelComp';
+import { SERVICE_TYPE, SUFFIX_UNIT } from '@/constants';
+import { MIRROR_OBPROXY } from '@/constants/doc';
+import { intl } from '@/utils/intl';
+import type { DrawerProps } from 'antd';
+import { Button, Form, Input, InputNumber, Select, Space } from 'antd';
+
+interface ConfigDrawerProps extends DrawerProps {
+ onClose: () => void;
+ name?: string;
+ namespace?: string;
+ image?: string;
+ parameters?: CommonKVPair[];
+ resource?: CommonResourceSpec;
+ serviceType?: string;
+ replicas?: number;
+}
+
+type FormValue = {
+ parameters: { key: string; value: string }[];
+} & ObproxyPatchOBProxyParam;
+
+export default function ConfigDrawer({
+ onClose,
+ name,
+ namespace,
+ ...props
+}: ConfigDrawerProps) {
+ const [form] = Form.useForm();
+ const submit = (values: FormValue) => {
+ if (namespace && name) obproxy.patchOBProxy(namespace, name, values);
+ };
+ const Footer = () => {
+ return (
+
+
+
+
+
+
+ );
+ };
+ const titleStyle = { fontSize: 14, fontWeight: 600 };
+ return (
+ }
+ onSubmit={() => form.submit()}
+ destroyOnClose={true}
+ onClose={() => onClose()}
+ {...props}
+ >
+
+
+ );
+}
diff --git a/ui/src/pages/OBProxy/Detail/Overview/DetailConfig.tsx b/ui/src/pages/OBProxy/Detail/Overview/DetailConfig.tsx
index 1e009d724..8b6029252 100644
--- a/ui/src/pages/OBProxy/Detail/Overview/DetailConfig.tsx
+++ b/ui/src/pages/OBProxy/Detail/Overview/DetailConfig.tsx
@@ -1,5 +1,8 @@
import type { CommonKVPair, CommonResourceSpec } from '@/api/generated';
+import InputLabelComp from '@/components/InputLabelComp';
import { Button, Card, Col, Row } from 'antd';
+import { useState } from 'react';
+import ConfigDrawer from './ConfigDrawer';
interface DetailConfigProps {
name?: string;
@@ -13,17 +16,19 @@ interface DetailConfigProps {
}
export default function DetailConfig({
- image,
- parameters,
- resource,
- serviceType,
- replicas,
style,
+ ...props
}: DetailConfigProps) {
+ const {image,serviceType,replicas,resource,parameters} = props;
+ const [drawerOpen, setDrawerOpen] = useState(false);
return (
详细配置}
- extra={}
+ extra={
+
+ }
style={style}
>
@@ -38,8 +43,14 @@ export default function DetailConfig({
参数设置
-
{JSON.stringify(parameters)}
+
+ setDrawerOpen(false)}
+ width={580}
+ {...props}
+ />
);
}
diff --git a/ui/src/pages/OBProxy/New/BasicConfig.tsx b/ui/src/pages/OBProxy/New/BasicConfig.tsx
index 8cb25029c..6cda75264 100644
--- a/ui/src/pages/OBProxy/New/BasicConfig.tsx
+++ b/ui/src/pages/OBProxy/New/BasicConfig.tsx
@@ -1,9 +1,12 @@
import IconTip from '@/components/IconTip';
import SelectNSFromItem from '@/components/SelectNSFromItem';
+import TooltipPretty from '@/components/TooltipPretty';
+import { resourceNameRule } from '@/constants/rules';
import { getSimpleClusterList } from '@/services';
import { useRequest } from 'ahooks';
import { Card, Col, Form, Input, Row, Select } from 'antd';
import type { FormInstance } from 'antd/lib/form';
+import { useEffect } from 'react';
interface BasicConfigProps {
form: FormInstance;
@@ -11,33 +14,49 @@ interface BasicConfigProps {
export default function BasicConfig({ form }: BasicConfigProps) {
const { data: clusterListRes } = useRequest(getSimpleClusterList);
+ const selectCluster = Form.useWatch('obCluster');
const clisterList = clusterListRes?.data.map((cluster) => ({
label: cluster.name,
- value: `${cluster.name}+${cluster.namespace}`,
+ value: JSON.stringify({ name: cluster.name, namespace: cluster.namespace }),
}));
+
+ useEffect(() => {
+ if (selectCluster && !form.getFieldValue('namespace')) {
+ form.setFieldValue('namespace', selectCluster.split('+')?.[1]);
+ }
+ }, [selectCluster]);
return (
-
-
-
+
+
+
+
+
@@ -51,7 +70,7 @@ export default function BasicConfig({ form }: BasicConfigProps) {
rules={[
{
required: true,
- message: '请选择',
+ message: '请选择 OB 集群',
},
]}
>
@@ -60,13 +79,14 @@ export default function BasicConfig({ form }: BasicConfigProps) {
}
rules={[
{
required: true,
- message: '请输入',
+ message: '请输入 OBProxy root 密码',
},
]}
>
diff --git a/ui/src/pages/OBProxy/New/DetailConfig.tsx b/ui/src/pages/OBProxy/New/DetailConfig.tsx
new file mode 100644
index 000000000..5630b07c7
--- /dev/null
+++ b/ui/src/pages/OBProxy/New/DetailConfig.tsx
@@ -0,0 +1,86 @@
+import { CustomFormItem } from '@/components/CustomFormItem';
+import InputLabelComp from '@/components/InputLabelComp';
+import { SERVICE_TYPE, SUFFIX_UNIT } from '@/constants';
+import { MIRROR_OBPROXY } from '@/constants/doc';
+import { intl } from '@/utils/intl';
+import { Card, Col, Input, InputNumber, Row, Select } from 'antd';
+import styles from './index.less';
+
+const commonStyle = { width: 280 };
+
+export default function DetailConfig() {
+ return (
+
+
+ 资源设置
+
+
+ {intl.formatMessage({
+ id: 'Dashboard.Cluster.New.Observer.Image',
+ defaultMessage: '镜像',
+ })}{' '}
+
+ {intl.formatMessage({
+ id: 'Dashboard.Cluster.New.Observer.ImageList',
+ defaultMessage: '(镜像列表)',
+ })}
+
+ >
+ }
+ name="image"
+ message={intl.formatMessage({
+ id: 'Dashboard.Cluster.New.Observer.EnterAnImage',
+ defaultMessage: '请输入镜像',
+ })}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 参数设置
+
+
+
+
+
+
+
+ );
+}
diff --git a/ui/src/pages/OBProxy/New/index.less b/ui/src/pages/OBProxy/New/index.less
new file mode 100644
index 000000000..95a2e940f
--- /dev/null
+++ b/ui/src/pages/OBProxy/New/index.less
@@ -0,0 +1,4 @@
+.titleText {
+ font-size: 14px;
+ font-weight: 600;
+ }
\ No newline at end of file
diff --git a/ui/src/pages/OBProxy/New/index.tsx b/ui/src/pages/OBProxy/New/index.tsx
index cb7af1896..309b4609a 100644
--- a/ui/src/pages/OBProxy/New/index.tsx
+++ b/ui/src/pages/OBProxy/New/index.tsx
@@ -1,11 +1,33 @@
+import { obproxy } from '@/api';
+import { ObproxyCreateOBProxyParam } from '@/api/generated';
import { PageContainer } from '@ant-design/pro-components';
import { useNavigate } from '@umijs/max';
-import { Button, Col, Form, Row } from 'antd';
+import { Button, Col, Form, Row, message } from 'antd';
import BasicConfig from './BasicConfig';
+import DetailConfig from './DetailConfig';
+
+type FormValues = {
+ obCluster: string;
+} & ObproxyCreateOBProxyParam;
export default function New() {
const navigate = useNavigate();
const [form] = Form.useForm();
+ const submit = async (values: FormValues) => {
+ try {
+ const res = await obproxy.createOBPROXY({
+ ...values,
+ obCluster: JSON.parse(values.obCluster),
+ });
+ if (res.successful) {
+ message.success('创建成功!', 3);
+ form.resetFields();
+ history.back();
+ }
+ } catch (err) {
+ console.error('err:', err);
+ }
+ };
return (
navigate('/obproxy')}>取消,
- ,
+ ,
]}
>
-
From c7d0d9bed9711a9f8b80bdd67ff8fd9e0babfcbb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=AE=B4=E6=99=96?= <2689991790@qq.com>
Date: Fri, 14 Jun 2024 16:56:31 +0800
Subject: [PATCH 2/4] Support editing parameters
---
ui/src/api/generated/api.ts | 199 +++++++++++++++---
ui/src/components/CustomFormItem/index.tsx | 20 +-
ui/src/components/InputLabelComp/index.tsx | 4 +-
.../OBProxy/Detail/Overview/ConfigDrawer.tsx | 135 ++++++++++--
.../OBProxy/Detail/Overview/DetailConfig.tsx | 20 +-
ui/src/pages/OBProxy/helper.ts | 17 ++
6 files changed, 321 insertions(+), 74 deletions(-)
create mode 100644 ui/src/pages/OBProxy/helper.ts
diff --git a/ui/src/api/generated/api.ts b/ui/src/api/generated/api.ts
index b2830f146..e6329dba5 100644
--- a/ui/src/api/generated/api.ts
+++ b/ui/src/api/generated/api.ts
@@ -990,6 +990,31 @@ export interface ListOBProxies200Response {
*/
'successful': boolean;
}
+/**
+ *
+ * @export
+ * @interface ListOBProxyParameters200Response
+ */
+export interface ListOBProxyParameters200Response {
+ /**
+ *
+ * @type {Array}
+ * @memberof ListOBProxyParameters200Response
+ */
+ 'data': Array;
+ /**
+ *
+ * @type {string}
+ * @memberof ListOBProxyParameters200Response
+ */
+ 'message': string;
+ /**
+ *
+ * @type {boolean}
+ * @memberof ListOBProxyParameters200Response
+ */
+ 'successful': boolean;
+}
/**
*
* @export
@@ -1796,6 +1821,43 @@ export interface ModelsStorageSpec {
*/
'storageSize'?: number;
}
+/**
+ *
+ * @export
+ * @interface ObproxyConfigItem
+ */
+export interface ObproxyConfigItem {
+ /**
+ *
+ * @type {string}
+ * @memberof ObproxyConfigItem
+ */
+ 'info'?: string;
+ /**
+ *
+ * @type {string}
+ * @memberof ObproxyConfigItem
+ */
+ 'name'?: string;
+ /**
+ *
+ * @type {boolean}
+ * @memberof ObproxyConfigItem
+ */
+ 'needReboot'?: boolean;
+ /**
+ *
+ * @type {string}
+ * @memberof ObproxyConfigItem
+ */
+ 'value'?: string;
+ /**
+ *
+ * @type {string}
+ * @memberof ObproxyConfigItem
+ */
+ 'visibleLevel'?: string;
+}
/**
*
* @export
@@ -2052,22 +2114,16 @@ export interface ObproxyOBProxyOverview {
export interface ObproxyPatchOBProxyParam {
/**
*
- * @type {Array}
- * @memberof ObproxyPatchOBProxyParam
- */
- 'addedParameters'?: Array;
- /**
- *
- * @type {Array}
+ * @type {string}
* @memberof ObproxyPatchOBProxyParam
*/
- 'deletedParameters'?: Array;
+ 'image'?: string;
/**
*
- * @type {string}
+ * @type {Array}
* @memberof ObproxyPatchOBProxyParam
*/
- 'image'?: string;
+ 'parameters'?: Array;
/**
*
* @type {number}
@@ -5043,51 +5099,51 @@ export interface ResponseStorageSpec {
/**
*
* @export
- * @interface RouteRoute
+ * @interface RouteRouteParam
*/
-export interface RouteRoute {
+export interface RouteRouteParam {
/**
*
* @type {Array}
- * @memberof RouteRoute
+ * @memberof RouteRouteParam
*/
'aggregateLabels': Array;
/**
*
* @type {number}
- * @memberof RouteRoute
+ * @memberof RouteRouteParam
*/
'groupInterval': number;
/**
*
* @type {number}
- * @memberof RouteRoute
+ * @memberof RouteRouteParam
*/
'groupWait': number;
+ /**
+ *
+ * @type {string}
+ * @memberof RouteRouteParam
+ */
+ 'id'?: string;
/**
*
* @type {Array}
- * @memberof RouteRoute
+ * @memberof RouteRouteParam
*/
'matchers': Array;
/**
*
* @type {string}
- * @memberof RouteRoute
+ * @memberof RouteRouteParam
*/
'receiver': string;
/**
*
* @type {number}
- * @memberof RouteRoute
+ * @memberof RouteRouteParam
*/
'repeatInterval': number;
- /**
- *
- * @type {string}
- * @memberof RouteRoute
- */
- 'id'?: string;
}
/**
*
@@ -5592,11 +5648,11 @@ export const AlarmApiAxiosParamCreator = function (configuration?: Configuration
/**
* Create or update alarm route.
* @summary Create or update alarm route
- * @param {RouteRoute} body route
+ * @param {RouteRouteParam} body route
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
- createOrUpdateRoute: async (body: RouteRoute, options: RawAxiosRequestConfig = {}): Promise => {
+ createOrUpdateRoute: async (body: RouteRouteParam, options: RawAxiosRequestConfig = {}): Promise => {
// verify required parameter 'body' is not null or undefined
assertParamExists('createOrUpdateRoute', 'body', body)
const localVarPath = `/api/v1/alarm/route/routes`;
@@ -6275,11 +6331,11 @@ export const AlarmApiFp = function(configuration?: Configuration) {
/**
* Create or update alarm route.
* @summary Create or update alarm route
- * @param {RouteRoute} body route
+ * @param {RouteRouteParam} body route
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
- async createOrUpdateRoute(body: RouteRoute, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> {
+ async createOrUpdateRoute(body: RouteRouteParam, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> {
const localVarAxiosArgs = await localVarAxiosParamCreator.createOrUpdateRoute(body, options);
const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
const localVarOperationServerBasePath = operationServerMap['AlarmApi.createOrUpdateRoute']?.[localVarOperationServerIndex]?.url;
@@ -6526,11 +6582,11 @@ export const AlarmApiFactory = function (configuration?: Configuration, basePath
/**
* Create or update alarm route.
* @summary Create or update alarm route
- * @param {RouteRoute} body route
+ * @param {RouteRouteParam} body route
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
- createOrUpdateRoute(body: RouteRoute, options?: any): AxiosPromise {
+ createOrUpdateRoute(body: RouteRouteParam, options?: any): AxiosPromise {
return localVarFp.createOrUpdateRoute(body, options).then((request) => request(axios, basePath));
},
/**
@@ -6725,12 +6781,12 @@ export class AlarmApi extends BaseAPI {
/**
* Create or update alarm route.
* @summary Create or update alarm route
- * @param {RouteRoute} body route
+ * @param {RouteRouteParam} body route
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof AlarmApi
*/
- public createOrUpdateRoute(body: RouteRoute, options?: RawAxiosRequestConfig) {
+ public createOrUpdateRoute(body: RouteRouteParam, options?: RawAxiosRequestConfig) {
return AlarmApiFp(this.configuration).createOrUpdateRoute(body, options).then((request) => request(this.axios, this.basePath));
}
@@ -7347,7 +7403,8 @@ export class ClusterApi extends BaseAPI {
export const ListK8sEventsObjectTypeEnum = {
OBCLUSTER: 'OBCLUSTER',
OBTENANT: 'OBTENANT',
- OBBACKUPPOLICY: 'OBBACKUPPOLICY'
+ OBBACKUPPOLICY: 'OBBACKUPPOLICY',
+ OBPROXY: 'OBPROXY'
} as const;
export type ListK8sEventsObjectTypeEnum = typeof ListK8sEventsObjectTypeEnum[keyof typeof ListK8sEventsObjectTypeEnum];
/**
@@ -8791,6 +8848,44 @@ export const OBProxyApiAxiosParamCreator = function (configuration?: Configurati
+ setSearchParams(localVarUrlObj, localVarQueryParameter);
+ let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
+ localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
+
+ return {
+ url: toPathString(localVarUrlObj),
+ options: localVarRequestOptions,
+ };
+ },
+ /**
+ * List OBProxy Parameters by namespace and name
+ * @summary List OBProxy Parameters
+ * @param {string} namespace namespace of obproxy deployment
+ * @param {string} name name of obproxy deployment
+ * @param {*} [options] Override http request option.
+ * @throws {RequiredError}
+ */
+ listOBProxyParameters: async (namespace: string, name: string, options: RawAxiosRequestConfig = {}): Promise => {
+ // verify required parameter 'namespace' is not null or undefined
+ assertParamExists('listOBProxyParameters', 'namespace', namespace)
+ // verify required parameter 'name' is not null or undefined
+ assertParamExists('listOBProxyParameters', 'name', name)
+ const localVarPath = `/api/v1/obproxies/{namespace}/{name}/parameters`
+ .replace(`{${"namespace"}}`, encodeURIComponent(String(namespace)))
+ .replace(`{${"name"}}`, encodeURIComponent(String(name)));
+ // use dummy base URL string because the URL constructor only accepts absolute URLs.
+ const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
+ let baseOptions;
+ if (configuration) {
+ baseOptions = configuration.baseOptions;
+ }
+
+ const localVarRequestOptions = { method: 'GET', ...baseOptions, ...options};
+ const localVarHeaderParameter = {} as any;
+ const localVarQueryParameter = {} as any;
+
+
+
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
@@ -8911,6 +9006,20 @@ export const OBProxyApiFp = function(configuration?: Configuration) {
const localVarOperationServerBasePath = operationServerMap['OBProxyApi.listOBProxies']?.[localVarOperationServerIndex]?.url;
return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
},
+ /**
+ * List OBProxy Parameters by namespace and name
+ * @summary List OBProxy Parameters
+ * @param {string} namespace namespace of obproxy deployment
+ * @param {string} name name of obproxy deployment
+ * @param {*} [options] Override http request option.
+ * @throws {RequiredError}
+ */
+ async listOBProxyParameters(namespace: string, name: string, options?: RawAxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise> {
+ const localVarAxiosArgs = await localVarAxiosParamCreator.listOBProxyParameters(namespace, name, options);
+ const localVarOperationServerIndex = configuration?.serverIndex ?? 0;
+ const localVarOperationServerBasePath = operationServerMap['OBProxyApi.listOBProxyParameters']?.[localVarOperationServerIndex]?.url;
+ return (axios, basePath) => createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration)(axios, localVarOperationServerBasePath || basePath);
+ },
/**
* Patch OBProxy with the specified parameters
* @summary Patch OBProxy
@@ -8978,6 +9087,17 @@ export const OBProxyApiFactory = function (configuration?: Configuration, basePa
listOBProxies(ns?: string, options?: any): AxiosPromise {
return localVarFp.listOBProxies(ns, options).then((request) => request(axios, basePath));
},
+ /**
+ * List OBProxy Parameters by namespace and name
+ * @summary List OBProxy Parameters
+ * @param {string} namespace namespace of obproxy deployment
+ * @param {string} name name of obproxy deployment
+ * @param {*} [options] Override http request option.
+ * @throws {RequiredError}
+ */
+ listOBProxyParameters(namespace: string, name: string, options?: any): AxiosPromise {
+ return localVarFp.listOBProxyParameters(namespace, name, options).then((request) => request(axios, basePath));
+ },
/**
* Patch OBProxy with the specified parameters
* @summary Patch OBProxy
@@ -9050,6 +9170,19 @@ export class OBProxyApi extends BaseAPI {
return OBProxyApiFp(this.configuration).listOBProxies(ns, options).then((request) => request(this.axios, this.basePath));
}
+ /**
+ * List OBProxy Parameters by namespace and name
+ * @summary List OBProxy Parameters
+ * @param {string} namespace namespace of obproxy deployment
+ * @param {string} name name of obproxy deployment
+ * @param {*} [options] Override http request option.
+ * @throws {RequiredError}
+ * @memberof OBProxyApi
+ */
+ public listOBProxyParameters(namespace: string, name: string, options?: RawAxiosRequestConfig) {
+ return OBProxyApiFp(this.configuration).listOBProxyParameters(namespace, name, options).then((request) => request(this.axios, this.basePath));
+ }
+
/**
* Patch OBProxy with the specified parameters
* @summary Patch OBProxy
diff --git a/ui/src/components/CustomFormItem/index.tsx b/ui/src/components/CustomFormItem/index.tsx
index ddf1a4811..e3799fd23 100644
--- a/ui/src/components/CustomFormItem/index.tsx
+++ b/ui/src/components/CustomFormItem/index.tsx
@@ -1,7 +1,8 @@
import { intl } from '@/utils/intl';
+import type { FormItemProps } from 'antd';
import { Form } from 'antd';
-export const CustomFormItem = (prop: any) => {
+export const CustomFormItem = (prop: FormItemProps & { message: string }) => {
const { label, message } = prop;
return (
{
{
required: true,
message:
- message ||
- intl.formatMessage(
- {
- id: 'Dashboard.Cluster.New.Observer.EnterLabel',
- defaultMessage: '请输入{{label}}',
- },
- { label: label },
- ),
+ message || typeof label === 'string'
+ ? intl.formatMessage(
+ {
+ id: 'Dashboard.Cluster.New.Observer.EnterLabel',
+ defaultMessage: '请输入{{label}}',
+ },
+ { label: label as string },
+ )
+ : '请输入',
},
]}
>
diff --git a/ui/src/components/InputLabelComp/index.tsx b/ui/src/components/InputLabelComp/index.tsx
index e6b7eff06..9177e6516 100644
--- a/ui/src/components/InputLabelComp/index.tsx
+++ b/ui/src/components/InputLabelComp/index.tsx
@@ -14,6 +14,7 @@ interface InputLabelCompPorps {
defaulLabelName?: string;
regex?: boolean;
disable?: boolean;
+ allowDelete?: boolean;
}
export default function InputLabelComp(props: InputLabelCompPorps) {
@@ -25,6 +26,7 @@ export default function InputLabelComp(props: InputLabelCompPorps) {
defaulLabelName = 'key',
regex,
disable = false,
+ allowDelete = true,
} = props;
const labelNameInput = (value: string, index: number) => {
@@ -96,7 +98,7 @@ export default function InputLabelComp(props: InputLabelCompPorps) {
)}
- {labels.length > 1 && (
+ {labels.length > 1 && allowDelete && (
void;
- name?: string;
- namespace?: string;
+ name: string;
+ namespace: string;
image?: string;
parameters?: CommonKVPair[];
resource?: CommonResourceSpec;
@@ -22,9 +34,11 @@ interface ConfigDrawerProps extends DrawerProps {
}
type FormValue = {
- parameters: { key: string; value: string }[];
+ parameters?: { key: string; value: string }[];
} & ObproxyPatchOBProxyParam;
+const { Text } = Typography;
+
export default function ConfigDrawer({
onClose,
name,
@@ -32,26 +46,40 @@ export default function ConfigDrawer({
...props
}: ConfigDrawerProps) {
const [form] = Form.useForm();
+ const preParameters = useRef();
+ const { data: listParametersRes } = useRequest(
+ obproxy.listOBProxyParameters,
+ {
+ defaultParams: [namespace, name],
+ },
+ );
+ const listParametersOptions = listParametersRes?.data.map((item) => ({
+ label: item.name,
+ value: item.name,
+ info: item.info,
+ }));
+
const submit = (values: FormValue) => {
- if (namespace && name) obproxy.patchOBProxy(namespace, name, values);
- };
- const Footer = () => {
- return (
-
-
-
-
-
-
- );
+ if (
+ !isDifferentParams(values.parameters || [], preParameters.current || [])
+ ) {
+ delete values.parameters;
+ }
};
const titleStyle = { fontSize: 14, fontWeight: 600 };
+
+ const labelChange = (label: string, name: number) => {
+ const value = listParametersRes?.data?.find(
+ (parameter) => parameter.name === label,
+ )?.value;
+ value && form.setFieldValue(['parameters', name, 'value'], value);
+ };
+ useEffect(() => {
+ preParameters.current = props.parameters;
+ }, [props.parameters]);
return (
}
onSubmit={() => form.submit()}
destroyOnClose={true}
onClose={() => onClose()}
@@ -106,9 +134,72 @@ export default function ConfigDrawer({
参数设置
-
-
-
+
+ {(fields, { add, remove }) => (
+ <>
+ {fields.map(({ name }) => (
+
+
+
+
+
+
+
+
+
+
+
+ remove(name)} />
+
+
+ ))}
+
+
+
+ >
+ )}
+
);
diff --git a/ui/src/pages/OBProxy/Detail/Overview/DetailConfig.tsx b/ui/src/pages/OBProxy/Detail/Overview/DetailConfig.tsx
index a0691b31f..a29bf7042 100644
--- a/ui/src/pages/OBProxy/Detail/Overview/DetailConfig.tsx
+++ b/ui/src/pages/OBProxy/Detail/Overview/DetailConfig.tsx
@@ -30,7 +30,7 @@ export default function DetailConfig({ style, ...props }: DetailConfigProps) {
}
extra={
-
@@ -91,14 +91,16 @@ export default function DetailConfig({ style, ...props }: DetailConfigProps) {
defaultMessage: '参数设置',
})}
-
+
- setDrawerOpen(false)}
- width={580}
- {...props}
- />
+ {props.name && props.namespace ? (
+ setDrawerOpen(false)}
+ width={880}
+ {...props}
+ />
+ ) : null}
);
}
diff --git a/ui/src/pages/OBProxy/helper.ts b/ui/src/pages/OBProxy/helper.ts
new file mode 100644
index 000000000..297893d79
--- /dev/null
+++ b/ui/src/pages/OBProxy/helper.ts
@@ -0,0 +1,17 @@
+import type { CommonKVPair } from '@/api/generated';
+
+/**
+ *
+ * @description Determines whether two parameter lists are different
+ */
+export const isDifferentParams = (
+ newParams: CommonKVPair[],
+ oldParams: CommonKVPair[],
+) => {
+ if (newParams.length !== oldParams.length) return true;
+ for (const newParam of newParams) {
+ const oldParam = oldParams.find((item) => item.key === newParam.key);
+ if (!oldParam || oldParam.value !== newParam.value) return true;
+ }
+ return false;
+};
From 4ec13228bbc0a17e84696de30ad297f6d266d039 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=AE=B4=E6=99=96?= <2689991790@qq.com>
Date: Sat, 15 Jun 2024 23:52:17 +0800
Subject: [PATCH 3/4] fix
---
ui/src/components/CustomFormItem/index.tsx | 10 +-
ui/src/i18n/strings/zh-CN.json | 38 +++++-
ui/src/pages/Layouts/DetailLayout/index.tsx | 2 +-
.../OBProxy/Detail/Overview/ConfigDrawer.tsx | 108 ++++++++++++++----
.../OBProxy/Detail/Overview/DetailConfig.tsx | 19 ++-
ui/src/pages/OBProxy/New/BasicConfig.tsx | 50 ++++++--
ui/src/pages/OBProxy/New/DetailConfig.tsx | 85 ++++++++++++--
ui/src/pages/OBProxy/New/index.tsx | 23 ++--
ui/src/type/obproxy.d.ts | 13 +++
ui/src/type/typings.d.ts | 1 +
10 files changed, 278 insertions(+), 71 deletions(-)
create mode 100644 ui/src/type/obproxy.d.ts
diff --git a/ui/src/components/CustomFormItem/index.tsx b/ui/src/components/CustomFormItem/index.tsx
index e3799fd23..f70223428 100644
--- a/ui/src/components/CustomFormItem/index.tsx
+++ b/ui/src/components/CustomFormItem/index.tsx
@@ -2,7 +2,7 @@ import { intl } from '@/utils/intl';
import type { FormItemProps } from 'antd';
import { Form } from 'antd';
-export const CustomFormItem = (prop: FormItemProps & { message: string }) => {
+export const CustomFormItem = (prop: FormItemProps & { message?: string }) => {
const { label, message } = prop;
return (
{
{
required: true,
message:
- message || typeof label === 'string'
+ message ||
+ (typeof label === 'string'
? intl.formatMessage(
{
id: 'Dashboard.Cluster.New.Observer.EnterLabel',
@@ -19,7 +20,10 @@ export const CustomFormItem = (prop: FormItemProps & { message: string }) => {
},
{ label: label as string },
)
- : '请输入',
+ : intl.formatMessage({
+ id: 'src.components.CustomFormItem.2C6315A1',
+ defaultMessage: '请输入',
+ })),
},
]}
>
diff --git a/ui/src/i18n/strings/zh-CN.json b/ui/src/i18n/strings/zh-CN.json
index bb2ebaaeb..8715d4bfd 100644
--- a/ui/src/i18n/strings/zh-CN.json
+++ b/ui/src/i18n/strings/zh-CN.json
@@ -985,5 +985,41 @@
"src.components.InputLabelComp.6C88A39D": "添加",
"src.components.AlertDrawer.95C6A631": "提交",
"src.components.AlertDrawer.9B7CD984": "取消",
- "src.api.2CA64FC6": "登陆已过期"
+ "src.api.2CA64FC6": "登陆已过期",
+ "src.pages.OBProxy.New.49694AC5": "创建成功!",
+ "src.pages.OBProxy.New.7CAF48E9": "详细配置",
+ "src.pages.OBProxy.New.0C4EFBB0": "资源设置",
+ "src.pages.OBProxy.New.CCD9785D": "请选择服务类型",
+ "src.pages.OBProxy.New.88D0BC94": "服务类型",
+ "src.pages.OBProxy.New.2F497A97": "请选择",
+ "src.pages.OBProxy.New.A3E900B4": "副本数",
+ "src.pages.OBProxy.New.D4645164": "请输入",
+ "src.pages.OBProxy.New.6A1E93D2": "CPU 核数",
+ "src.pages.OBProxy.New.AEDDBA86": "请输入",
+ "src.pages.OBProxy.New.CE387455": "内存大小",
+ "src.pages.OBProxy.New.7C04AD55": "请输入",
+ "src.pages.OBProxy.New.134CD1CE": "参数设置",
+ "src.pages.OBProxy.New.D6D90ACC": "k8s中资源的名称",
+ "src.pages.OBProxy.New.803427AF": "资源名称",
+ "src.pages.OBProxy.New.F602E292": "请输入k8s资源名称",
+ "src.pages.OBProxy.New.37FA27BA": "资源名不能使用纯数字",
+ "src.pages.OBProxy.New.9B4BA02B": "请输入",
+ "src.pages.OBProxy.New.BB6BC872": "OBProxy 集群名",
+ "src.pages.OBProxy.New.CA42FD5D": "请输入集群名",
+ "src.pages.OBProxy.New.94339826": "请选择 OB 集群",
+ "src.pages.OBProxy.New.67DC144A": "请输入 OBProxy root 密码",
+ "src.pages.OBProxy.Detail.Overview.680A1826": "详细配置",
+ "src.pages.OBProxy.Detail.Overview.F9D66FC0": "资源设置",
+ "src.pages.OBProxy.Detail.Overview.DBE1B6C0": "服务类型",
+ "src.pages.OBProxy.Detail.Overview.E7B1B575": "请选择",
+ "src.pages.OBProxy.Detail.Overview.2DA6A0A7": "副本数",
+ "src.pages.OBProxy.Detail.Overview.52C1F09A": "请输入",
+ "src.pages.OBProxy.Detail.Overview.A4448DF2": "CPU 核数",
+ "src.pages.OBProxy.Detail.Overview.2FA13720": "请输入",
+ "src.pages.OBProxy.Detail.Overview.0075C2B3": "内存大小",
+ "src.pages.OBProxy.Detail.Overview.3F3066D5": "请输入",
+ "src.pages.OBProxy.Detail.Overview.D537DD35": "参数设置",
+ "src.pages.OBProxy.Detail.Overview.8A75D872": "请选择",
+ "src.pages.OBProxy.Detail.Overview.8E87D135": "添加",
+ "src.components.CustomFormItem.2C6315A1": "请输入"
}
\ No newline at end of file
diff --git a/ui/src/pages/Layouts/DetailLayout/index.tsx b/ui/src/pages/Layouts/DetailLayout/index.tsx
index 4c62484fa..8a2ea478b 100644
--- a/ui/src/pages/Layouts/DetailLayout/index.tsx
+++ b/ui/src/pages/Layouts/DetailLayout/index.tsx
@@ -95,7 +95,7 @@ const DetailLayout: React.FC = ({
useEffect(() => {
getAppInfoFromStorage().then((appInfo) => {
- setVersion(appInfo.version);
+ setVersion(appInfo?.version);
});
}, []);
diff --git a/ui/src/pages/OBProxy/Detail/Overview/ConfigDrawer.tsx b/ui/src/pages/OBProxy/Detail/Overview/ConfigDrawer.tsx
index 68a4a5966..7af01190b 100644
--- a/ui/src/pages/OBProxy/Detail/Overview/ConfigDrawer.tsx
+++ b/ui/src/pages/OBProxy/Detail/Overview/ConfigDrawer.tsx
@@ -1,10 +1,11 @@
import { obproxy } from '@/api';
-import type { CommonKVPair, CommonResourceSpec } from '@/api/generated';
+import type { CommonKVPair } from '@/api/generated';
import { ObproxyPatchOBProxyParam } from '@/api/generated';
import AlertDrawer from '@/components/AlertDrawer';
import { CustomFormItem } from '@/components/CustomFormItem';
import { SERVICE_TYPE, SUFFIX_UNIT } from '@/constants';
import { MIRROR_OBPROXY } from '@/constants/doc';
+import { OBProxy } from '@/type/obproxy';
import { intl } from '@/utils/intl';
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
import { useRequest } from 'ahooks';
@@ -22,16 +23,10 @@ import {
import { useEffect, useRef } from 'react';
import { isDifferentParams } from '../../helper';
-interface ConfigDrawerProps extends DrawerProps {
+type ConfigDrawerProps = {
onClose: () => void;
- name: string;
- namespace: string;
- image?: string;
- parameters?: CommonKVPair[];
- resource?: CommonResourceSpec;
- serviceType?: string;
- replicas?: number;
-}
+} & OBProxy.CommonProxyDetail &
+ DrawerProps;
type FormValue = {
parameters?: { key: string; value: string }[];
@@ -79,7 +74,10 @@ export default function ConfigDrawer({
}, [props.parameters]);
return (
form.submit()}
destroyOnClose={true}
onClose={() => onClose()}
@@ -92,7 +90,12 @@ export default function ConfigDrawer({
preserve={false}
layout="vertical"
>
- 资源设置
+
+ {intl.formatMessage({
+ id: 'src.pages.OBProxy.Detail.Overview.F9D66FC0',
+ defaultMessage: '资源设置',
+ })}
+
@@ -121,19 +124,73 @@ export default function ConfigDrawer({
})}
/>
-
-
+
+
-
-
+
+
-
-
+
+
-
-
+
+
- 参数设置
+
+ {intl.formatMessage({
+ id: 'src.pages.OBProxy.Detail.Overview.D537DD35',
+ defaultMessage: '参数设置',
+ })}
+
{(fields, { add, remove }) => (
<>
@@ -142,7 +199,10 @@ export default function ConfigDrawer({
diff --git a/ui/src/pages/OBProxy/Detail/Overview/DetailConfig.tsx b/ui/src/pages/OBProxy/Detail/Overview/DetailConfig.tsx
index a29bf7042..7c83c0d38 100644
--- a/ui/src/pages/OBProxy/Detail/Overview/DetailConfig.tsx
+++ b/ui/src/pages/OBProxy/Detail/Overview/DetailConfig.tsx
@@ -1,23 +1,16 @@
-import type { CommonKVPair, CommonResourceSpec } from '@/api/generated';
import InputLabelComp from '@/components/InputLabelComp';
+import { OBProxy } from '@/type/obproxy';
import { intl } from '@/utils/intl';
import { Button, Card, Col, Row } from 'antd';
import { useState } from 'react';
import ConfigDrawer from './ConfigDrawer';
-
-interface DetailConfigProps {
- name?: string;
- namespace?: string;
- image?: string;
- parameters?: CommonKVPair[];
- resource?: CommonResourceSpec;
- serviceType?: string;
- replicas?: number;
+interface DetailConfigProps extends OBProxy.CommonProxyDetail {
style?: React.CSSProperties;
}
export default function DetailConfig({ style, ...props }: DetailConfigProps) {
const { image, serviceType, replicas, resource, parameters } = props;
+
const [drawerOpen, setDrawerOpen] = useState(false);
return (
-
+
{props.name && props.namespace ? (
-
+
-
+
@@ -84,7 +110,10 @@ export default function BasicConfig({ form }: BasicConfigProps) {
rules={[
{
required: true,
- message: '请选择 OB 集群',
+ message: intl.formatMessage({
+ id: 'src.pages.OBProxy.New.94339826',
+ defaultMessage: '请选择 OB 集群',
+ }),
},
]}
>
@@ -109,7 +138,10 @@ export default function BasicConfig({ form }: BasicConfigProps) {
rules={[
{
required: true,
- message: '请输入 OBProxy root 密码',
+ message: intl.formatMessage({
+ id: 'src.pages.OBProxy.New.67DC144A',
+ defaultMessage: '请输入 OBProxy root 密码',
+ }),
},
]}
>
diff --git a/ui/src/pages/OBProxy/New/DetailConfig.tsx b/ui/src/pages/OBProxy/New/DetailConfig.tsx
index 5630b07c7..36a58b593 100644
--- a/ui/src/pages/OBProxy/New/DetailConfig.tsx
+++ b/ui/src/pages/OBProxy/New/DetailConfig.tsx
@@ -10,9 +10,19 @@ const commonStyle = { width: 280 };
export default function DetailConfig() {
return (
-
+
- 资源设置
+
+ {intl.formatMessage({
+ id: 'src.pages.OBProxy.New.0C4EFBB0',
+ defaultMessage: '资源设置',
+ })}
+
-
+
-
-
+
+
-
-
+
+
-
+
@@ -74,9 +130,14 @@ export default function DetailConfig() {
- 参数设置
+
+ {intl.formatMessage({
+ id: 'src.pages.OBProxy.New.134CD1CE',
+ defaultMessage: '参数设置',
+ })}
+
-
+
diff --git a/ui/src/pages/OBProxy/New/index.tsx b/ui/src/pages/OBProxy/New/index.tsx
index 0e8ee4ac7..7fc1f6c99 100644
--- a/ui/src/pages/OBProxy/New/index.tsx
+++ b/ui/src/pages/OBProxy/New/index.tsx
@@ -3,7 +3,7 @@ import { ObproxyCreateOBProxyParam } from '@/api/generated';
import { intl } from '@/utils/intl';
import { PageContainer } from '@ant-design/pro-components';
import { useNavigate } from '@umijs/max';
-import { Button, Col, Form, Row, message } from 'antd';
+import { Button, Form, Space, message } from 'antd';
import BasicConfig from './BasicConfig';
import DetailConfig from './DetailConfig';
@@ -21,7 +21,13 @@ export default function New() {
obCluster: JSON.parse(values.obCluster),
});
if (res.successful) {
- message.success('创建成功!', 3);
+ message.success(
+ intl.formatMessage({
+ id: 'src.pages.OBProxy.New.49694AC5',
+ defaultMessage: '创建成功!',
+ }),
+ 3,
+ );
form.resetFields();
history.back();
}
@@ -54,16 +60,13 @@ export default function New() {
})}
,
]}
+ style={{ paddingBottom: 50 }}
>
);
diff --git a/ui/src/type/obproxy.d.ts b/ui/src/type/obproxy.d.ts
new file mode 100644
index 000000000..ec8355e1c
--- /dev/null
+++ b/ui/src/type/obproxy.d.ts
@@ -0,0 +1,13 @@
+declare namespace OBProxy {
+ interface CommonProxyDetail {
+ name: string;
+ namespace: string;
+ image?: string;
+ parameters?: CommonKVPair[];
+ resource?: CommonResourceSpec;
+ serviceType?: string;
+ replicas?: number;
+ }
+}
+
+export { OBProxy };
diff --git a/ui/src/type/typings.d.ts b/ui/src/type/typings.d.ts
index c1079c0c8..9f39b0d3c 100644
--- a/ui/src/type/typings.d.ts
+++ b/ui/src/type/typings.d.ts
@@ -849,4 +849,5 @@ declare namespace API {
setVisible: (prop: boolean) => void;
successCallback?: (val?: any) => void;
};
+
}
From f0f1de5a043f3d3d759eca5cd680092d1994565d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=AE=B4=E6=99=96?= <2689991790@qq.com>
Date: Sun, 16 Jun 2024 00:15:37 +0800
Subject: [PATCH 4/4] isDifferentParams
---
ui/src/pages/OBProxy/helper.ts | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/ui/src/pages/OBProxy/helper.ts b/ui/src/pages/OBProxy/helper.ts
index 297893d79..29f4e6ec7 100644
--- a/ui/src/pages/OBProxy/helper.ts
+++ b/ui/src/pages/OBProxy/helper.ts
@@ -1,17 +1,26 @@
import type { CommonKVPair } from '@/api/generated';
+const buildLabelsMap = (labels: CommonKVPair[]) => {
+ const labelsMap = new Map();
+ for (const label of labels) {
+ labelsMap.set(label.key, label.value);
+ }
+ return labelsMap;
+};
+
/**
- *
+ *
* @description Determines whether two parameter lists are different
*/
export const isDifferentParams = (
newParams: CommonKVPair[],
oldParams: CommonKVPair[],
) => {
- if (newParams.length !== oldParams.length) return true;
- for (const newParam of newParams) {
- const oldParam = oldParams.find((item) => item.key === newParam.key);
- if (!oldParam || oldParam.value !== newParam.value) return true;
+ const newParamsMap = buildLabelsMap(newParams),
+ oldParamsMap = buildLabelsMap(oldParams);
+ if (newParamsMap.size !== oldParamsMap.size) return true;
+ for (const key of newParamsMap.keys()) {
+ if (newParamsMap.get(key) !== oldParamsMap.get(key)) return true;
}
return false;
};