Skip to content

Commit b3ccd82

Browse files
authored
[INLONG-4550][Dashboard] Support DataProxy Cluster and Node management (#4555)
1 parent a0657a0 commit b3ccd82

File tree

9 files changed

+365
-12
lines changed

9 files changed

+365
-12
lines changed

inlong-dashboard/src/configs/routes/index.tsx

+7
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@ const routes: RouteProps[] = [
9696
path: '/clusters',
9797
component: () => import('@/pages/Clusters'),
9898
exact: true,
99+
childRoutes: [
100+
{
101+
path: '/node',
102+
component: () => import('@/pages/Clusters/NodeManage'),
103+
exact: true,
104+
},
105+
],
99106
},
100107
{
101108
component: () => import('@/pages/Error/404'),

inlong-dashboard/src/locales/cn.json

+5
Original file line numberDiff line numberDiff line change
@@ -343,11 +343,16 @@
343343
"pages.ConsumeDetail.ConsumptionDetails": "消费详情",
344344
"pages.Clusters.Type": "类型",
345345
"pages.Clusters.Create": "新建集群",
346+
"pages.Clusters.Edit": "编辑集群",
346347
"pages.Clusters.LastModifier": "最后操作",
347348
"pages.Clusters.Name": "集群名称",
348349
"pages.Clusters.Tag": "集群标签",
349350
"pages.Clusters.InCharges": "责任人",
350351
"pages.Clusters.Description": "集群描述",
352+
"pages.Clusters.Node.Name": "节点",
353+
"pages.Clusters.Node.Port": "端口",
354+
"pages.Clusters.Node.LastModifier": "最后操作",
355+
"pages.Clusters.Node.Create": "新建节点",
351356
"pages.Clusters.Pulsar.Tenant": "默认租户",
352357
"pages.Datasources.status.Success": "正常",
353358
"pages.Datasources.status.Error": "失败",

inlong-dashboard/src/locales/en.json

+5
Original file line numberDiff line numberDiff line change
@@ -343,11 +343,16 @@
343343
"pages.ConsumeDetail.ConsumptionDetails": "Consumption Detail",
344344
"pages.Clusters.Type": "Type",
345345
"pages.Clusters.Create": "Create",
346+
"pages.Clusters.Edit": "Edit",
346347
"pages.Clusters.LastModifier": "LastModifier",
347348
"pages.Clusters.Name": "Cluster Name",
348349
"pages.Clusters.Tag": "Cluster Tag",
349350
"pages.Clusters.InCharges": "InCharges",
350351
"pages.Clusters.Description": "Description",
352+
"pages.Clusters.Node.Name": "Node",
353+
"pages.Clusters.Node.Port": "端口",
354+
"pages.Clusters.Node.LastModifier": "LastModifier",
355+
"pages.Clusters.Node.Create": "Create",
351356
"pages.Clusters.Pulsar.Tenant": "Default Tenant",
352357
"pages.Datasources.status.Success": "Success",
353358
"pages.Datasources.status.Error": "Error",

inlong-dashboard/src/pages/Clusters/CreateModal.tsx

+10-11
Original file line numberDiff line numberDiff line change
@@ -20,24 +20,21 @@
2020
import React, { useMemo } from 'react';
2121
import { Modal, message } from 'antd';
2222
import { ModalProps } from 'antd/es/modal';
23-
import { State } from '@/models';
2423
import FormGenerator, { useForm } from '@/components/FormGenerator';
25-
import { useRequest, useUpdateEffect, useSelector } from '@/hooks';
24+
import { useRequest, useUpdateEffect } from '@/hooks';
2625
import request from '@/utils/request';
2726
import { Clusters } from './config';
27+
import i18n from '@/i18n';
2828

2929
export interface Props extends ModalProps {
30-
// 类型
3130
type: string;
32-
// 编辑时需传
31+
// Require when edit
3332
id?: string;
3433
}
3534

3635
const Comp: React.FC<Props> = ({ type, id, ...modalProps }) => {
3736
const [form] = useForm();
3837

39-
const { userName } = useSelector<State, State>(state => state);
40-
4138
const { run: getData } = useRequest(
4239
id => ({
4340
url: `/cluster/get/${id}`,
@@ -72,17 +69,15 @@ const Comp: React.FC<Props> = ({ type, id, ...modalProps }) => {
7269
data: submitData,
7370
});
7471
await modalProps?.onOk(submitData);
75-
message.success('保存成功');
72+
message.success(i18n.t('basic.OperatingSuccess'));
7673
};
7774

7875
useUpdateEffect(() => {
7976
if (modalProps.visible) {
8077
// open
81-
form.resetFields(); // 注意会导致表单重新mount发起select的请求
78+
form.resetFields();
8279
if (id) {
8380
getData(id);
84-
} else {
85-
userName && type === 'dbsync' && form.setFieldsValue({ inCharges: [userName] });
8681
}
8782
}
8883
}, [modalProps.visible]);
@@ -93,7 +88,11 @@ const Comp: React.FC<Props> = ({ type, id, ...modalProps }) => {
9388
}, [type]);
9489

9590
return (
96-
<Modal {...modalProps} title={`${id ? '编辑' : '新建'}集群`} onOk={onOk}>
91+
<Modal
92+
{...modalProps}
93+
title={id ? i18n.t('pages.Clusters.Edit') : i18n.t('pages.Clusters.Create')}
94+
onOk={onOk}
95+
>
9796
<FormGenerator content={content} form={form} useMaxWidth />
9897
</Modal>
9998
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
*/
19+
20+
import React, { useMemo } from 'react';
21+
import i18n from '@/i18n';
22+
import { Modal, message } from 'antd';
23+
import { ModalProps } from 'antd/es/modal';
24+
import FormGenerator, { useForm } from '@/components/FormGenerator';
25+
import { useRequest, useUpdateEffect } from '@/hooks';
26+
import request from '@/utils/request';
27+
28+
export interface NodeEditModalProps extends ModalProps {
29+
id?: number;
30+
type: string;
31+
clusterId: number;
32+
}
33+
34+
const NodeEditModal: React.FC<NodeEditModalProps> = ({ id, type, clusterId, ...modalProps }) => {
35+
const [form] = useForm();
36+
37+
const { data: savedData, run: getData } = useRequest(
38+
id => ({
39+
url: `/cluster/node/get/${id}`,
40+
}),
41+
{
42+
manual: true,
43+
formatResult: result => ({
44+
...result,
45+
// inCharges: result.inCharges.split(','),
46+
}),
47+
onSuccess: result => {
48+
form.setFieldsValue(result);
49+
},
50+
},
51+
);
52+
53+
const onOk = async () => {
54+
const values = await form.validateFields();
55+
const isUpdate = id;
56+
const submitData = {
57+
...values,
58+
type,
59+
parentId: savedData.parentId || clusterId,
60+
// inCharges: values.inCharges?.join(','),
61+
};
62+
if (isUpdate) {
63+
submitData.id = id;
64+
}
65+
await request({
66+
url: `/cluster/node/${isUpdate ? 'update' : 'save'}`,
67+
method: 'POST',
68+
data: submitData,
69+
});
70+
await modalProps?.onOk(submitData);
71+
message.success(i18n.t('basic.OperatingSuccess'));
72+
};
73+
74+
useUpdateEffect(() => {
75+
if (modalProps.visible) {
76+
// open
77+
form.resetFields();
78+
if (id) {
79+
getData(id);
80+
}
81+
}
82+
}, [modalProps.visible]);
83+
84+
const content = useMemo(() => {
85+
return [
86+
{
87+
type: 'input',
88+
label: 'IP',
89+
name: 'ip',
90+
},
91+
{
92+
type: 'input',
93+
label: i18n.t('pages.Clusters.Node.Port'),
94+
name: 'port',
95+
},
96+
];
97+
}, []);
98+
99+
return (
100+
<Modal {...modalProps} title={i18n.t('pages.Clusters.Node.Name')} onOk={onOk}>
101+
<FormGenerator content={content} form={form} useMaxWidth />
102+
</Modal>
103+
);
104+
};
105+
106+
export default NodeEditModal;

0 commit comments

Comments
 (0)