Skip to content

Commit fed6c3a

Browse files
authored
add nfs info and resource drawer in cluster detail (#658)
* chore: update openapi info * fix CR * feat: add nfsInfo resourceDrawer in cluster detail * improve: update ResourceDrawer UI * update ParametersModal and Parameters table * fix CR
1 parent fe6e39f commit fed6c3a

File tree

7 files changed

+1040
-445
lines changed

7 files changed

+1040
-445
lines changed

ui/src/pages/Cluster/Detail/Overview/BasicInfo.tsx

Lines changed: 74 additions & 152 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
1+
import { obcluster } from '@/api';
12
import { MODE_MAP, STATUS_LIST } from '@/constants';
2-
import { floorToTwoDecimalPlaces } from '@/utils/helper';
33
import { intl } from '@/utils/intl';
44
import { findByValue } from '@oceanbase/util';
5-
import { Card, Descriptions, Switch, Tag, Typography } from 'antd';
6-
import { useState } from 'react';
7-
import styles from './index.less';
5+
import { useRequest } from 'ahooks';
6+
import { Card, Checkbox, Descriptions, Tag, Typography, message } from 'antd';
87

98
const { Text } = Typography;
109
export default function BasicInfo({
@@ -15,79 +14,27 @@ export default function BasicInfo({
1514
image,
1615
mode,
1716
rootPasswordSecret,
18-
resource,
19-
storage,
2017
backupVolume,
2118
monitor,
2219
clusterName,
23-
extra = true,
2420
style,
21+
addDeletionProtection,
2522
}: API.ClusterInfo & { style?: React.CSSProperties; extra?: boolean }) {
26-
const [checked, setChecked] = useState<boolean>(false);
27-
const OBServerConfig = extra
28-
? [
29-
{
30-
label: 'CPU',
31-
value: resource.cpu,
32-
},
33-
{
34-
label: 'Memory',
35-
value: floorToTwoDecimalPlaces(resource.memory / (1 << 30)) + 'Gi',
36-
},
37-
{
38-
label: intl.formatMessage({
39-
id: 'Dashboard.Detail.Overview.BasicInfo.DatafileStorageClass',
40-
defaultMessage: 'Datafile 存储类',
41-
}),
42-
value: storage.dataStorage.storageClass,
43-
},
44-
{
45-
label: intl.formatMessage({
46-
id: 'Dashboard.Detail.Overview.BasicInfo.DatafileStorageSize',
47-
defaultMessage: 'Datafile 存储大小',
48-
}),
49-
value:
50-
floorToTwoDecimalPlaces(storage.dataStorage.size / (1 << 30)) +
51-
'Gi',
52-
},
53-
{
54-
label: intl.formatMessage({
55-
id: 'Dashboard.Detail.Overview.BasicInfo.RedologStorageClass',
56-
defaultMessage: 'RedoLog 存储类',
57-
}),
58-
value: storage.redoLogStorage.storageClass,
59-
},
60-
{
61-
label: intl.formatMessage({
62-
id: 'Dashboard.Detail.Overview.BasicInfo.RedologSize',
63-
defaultMessage: 'RedoLog 大小',
64-
}),
65-
value:
66-
floorToTwoDecimalPlaces(storage.redoLogStorage.size / (1 << 30)) +
67-
'Gi',
68-
},
69-
{
70-
label: intl.formatMessage({
71-
id: 'Dashboard.Detail.Overview.BasicInfo.SystemLogStorageClass',
72-
defaultMessage: '系统日志存储类',
73-
}),
74-
value: storage.sysLogStorage.storageClass,
75-
},
76-
{
77-
label: intl.formatMessage({
78-
id: 'Dashboard.Detail.Overview.BasicInfo.SystemLogStorageSize',
79-
defaultMessage: '系统日志存储大小',
80-
}),
81-
value:
82-
floorToTwoDecimalPlaces(storage.sysLogStorage.size / (1 << 30)) +
83-
'Gi',
84-
},
85-
]
86-
: [];
87-
8823
const statusItem = findByValue(STATUS_LIST, status);
8924
const statusDetailItem = findByValue(STATUS_LIST, statusDetail);
9025

26+
const { runAsync: patchOBCluster, loading } = useRequest(
27+
obcluster.patchOBCluster,
28+
{
29+
manual: true,
30+
onSuccess: (res) => {
31+
if (res.successful) {
32+
message.success('修改删除保护已成功');
33+
}
34+
},
35+
},
36+
);
37+
9138
return (
9239
<Card
9340
style={style}
@@ -158,6 +105,20 @@ export default function BasicInfo({
158105
)}
159106
</Tag>
160107
</Descriptions.Item>
108+
109+
<Descriptions.Item label={'删除保护'}>
110+
<Checkbox
111+
// loading 态禁止操作,防止重复操作
112+
disabled={loading}
113+
defaultChecked={addDeletionProtection}
114+
onChange={(e) => {
115+
const body = {
116+
addDeletionProtection: e.target.checked,
117+
};
118+
patchOBCluster(name, namespace, body);
119+
}}
120+
/>
121+
</Descriptions.Item>
161122
<Descriptions.Item
162123
span={2}
163124
label={intl.formatMessage({
@@ -178,94 +139,55 @@ export default function BasicInfo({
178139
{rootPasswordSecret || '-'}
179140
</Descriptions.Item>
180141
</Descriptions>
181-
{extra && (
182-
<div style={{ marginBottom: 12 }}>
183-
<span
184-
style={{
185-
color: '#132039',
186-
fontSize: 16,
187-
fontWeight: 600,
188-
marginRight: 8,
189-
}}
190-
>
191-
{intl.formatMessage({
192-
id: 'Dashboard.Detail.Overview.BasicInfo.DetailedClusterConfiguration',
193-
defaultMessage: '集群详细配置',
142+
143+
{monitor && (
144+
<Descriptions
145+
title={intl.formatMessage({
146+
id: 'Dashboard.Detail.Overview.BasicInfo.MonitoringConfiguration',
147+
defaultMessage: '监控配置',
148+
})}
149+
>
150+
<Descriptions.Item label="CPU">
151+
{monitor.resource.cpu}
152+
</Descriptions.Item>
153+
<Descriptions.Item label="Memory">
154+
{monitor.resource.memory}
155+
</Descriptions.Item>
156+
<Descriptions.Item
157+
label={intl.formatMessage({
158+
id: 'Dashboard.Detail.Overview.BasicInfo.Image',
159+
defaultMessage: '镜像',
194160
})}
195-
</span>
196-
<Switch
197-
checked={checked}
198-
onChange={(checked) => setChecked(checked)}
199-
/>
200-
</div>
161+
>
162+
{monitor.image}
163+
</Descriptions.Item>
164+
</Descriptions>
201165
)}
202166

203-
{checked && extra && (
204-
<div className={styles.detailConfig}>
205-
<Descriptions
206-
style={{ width: '50%' }}
207-
title={intl.formatMessage({
208-
id: 'Dashboard.Detail.Overview.BasicInfo.ObserverResourceConfiguration',
209-
defaultMessage: 'OBServer 资源配置',
167+
{backupVolume && (
168+
<Descriptions
169+
title={intl.formatMessage({
170+
id: 'Dashboard.Detail.Overview.BasicInfo.BackupVolumeConfiguration',
171+
defaultMessage: '备份卷配置',
172+
})}
173+
>
174+
<Descriptions.Item
175+
label={intl.formatMessage({
176+
id: 'Dashboard.Detail.Overview.BasicInfo.Address',
177+
defaultMessage: '地址',
210178
})}
211179
>
212-
{OBServerConfig.map((item, index) => (
213-
<Descriptions.Item span={2} key={index} label={item.label}>
214-
{item.value}
215-
</Descriptions.Item>
216-
))}
217-
</Descriptions>
218-
219-
{monitor && (
220-
<Descriptions
221-
title={intl.formatMessage({
222-
id: 'Dashboard.Detail.Overview.BasicInfo.MonitoringConfiguration',
223-
defaultMessage: '监控配置',
224-
})}
225-
>
226-
<Descriptions.Item label="CPU">
227-
{monitor.resource.cpu}
228-
</Descriptions.Item>
229-
<Descriptions.Item label="Memory">
230-
{monitor.resource.memory}
231-
</Descriptions.Item>
232-
<Descriptions.Item
233-
label={intl.formatMessage({
234-
id: 'Dashboard.Detail.Overview.BasicInfo.Image',
235-
defaultMessage: '镜像',
236-
})}
237-
>
238-
{monitor.image}
239-
</Descriptions.Item>
240-
</Descriptions>
241-
)}
242-
243-
{backupVolume && (
244-
<Descriptions
245-
title={intl.formatMessage({
246-
id: 'Dashboard.Detail.Overview.BasicInfo.BackupVolumeConfiguration',
247-
defaultMessage: '备份卷配置',
248-
})}
249-
>
250-
<Descriptions.Item
251-
label={intl.formatMessage({
252-
id: 'Dashboard.Detail.Overview.BasicInfo.Address',
253-
defaultMessage: '地址',
254-
})}
255-
>
256-
{backupVolume.address}
257-
</Descriptions.Item>
258-
<Descriptions.Item
259-
label={intl.formatMessage({
260-
id: 'Dashboard.Detail.Overview.BasicInfo.Path',
261-
defaultMessage: '路径',
262-
})}
263-
>
264-
{backupVolume.path}
265-
</Descriptions.Item>
266-
</Descriptions>
267-
)}
268-
</div>
180+
{backupVolume.address}
181+
</Descriptions.Item>
182+
<Descriptions.Item
183+
label={intl.formatMessage({
184+
id: 'Dashboard.Detail.Overview.BasicInfo.Path',
185+
defaultMessage: '路径',
186+
})}
187+
>
188+
{backupVolume.path}
189+
</Descriptions.Item>
190+
</Descriptions>
269191
)}
270192
</Card>
271193
);
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { obcluster } from '@/api';
2+
import { useRequest } from 'ahooks';
3+
import { Form, Input, message, Modal } from 'antd';
4+
import React from 'react';
5+
6+
export interface NFSInfoModalProps {
7+
visible: boolean;
8+
onCancel: () => void;
9+
onSuccess: () => void;
10+
removeNFS: boolean;
11+
title: string;
12+
name: string;
13+
namespace: string;
14+
}
15+
16+
const NFSInfoModal: React.FC<NFSInfoModalProps> = ({
17+
visible,
18+
onCancel,
19+
removeNFS,
20+
onSuccess,
21+
title,
22+
name,
23+
namespace,
24+
}) => {
25+
const [form] = Form.useForm<FormData>();
26+
27+
const { runAsync: patchOBCluster, loading } = useRequest(
28+
obcluster.patchOBCluster,
29+
{
30+
manual: true,
31+
onSuccess: (res) => {
32+
if (res.successful) {
33+
message.success(`修改${title}成功`);
34+
onSuccess();
35+
}
36+
},
37+
},
38+
);
39+
40+
return (
41+
<Modal
42+
title={title}
43+
open={visible}
44+
destroyOnClose
45+
onCancel={() => onCancel()}
46+
confirmLoading={loading}
47+
onOk={() => {
48+
if (removeNFS) {
49+
const body = {
50+
removeBackupVolume: true,
51+
};
52+
patchOBCluster(name, namespace, body);
53+
} else {
54+
form.validateFields().then((values) => {
55+
const { address, path } = values;
56+
const body = {
57+
backupVolume: {
58+
address,
59+
path,
60+
},
61+
};
62+
patchOBCluster(name, namespace, body);
63+
});
64+
}
65+
}}
66+
>
67+
{removeNFS ? (
68+
' 注意,移除挂载的 NFS 备份卷会滚动重启所有节点,确认移除吗?'
69+
) : (
70+
<Form form={form}>
71+
<Form.Item
72+
label="地址"
73+
name="address"
74+
rules={[
75+
{
76+
required: true,
77+
message: '请输入地址',
78+
},
79+
]}
80+
>
81+
<Input placeholder={'请输入'} />
82+
</Form.Item>
83+
<Form.Item
84+
label="路径"
85+
name="path"
86+
rules={[
87+
{
88+
required: true,
89+
message: '请输入路径',
90+
},
91+
]}
92+
>
93+
<Input placeholder={'请输入'} />
94+
</Form.Item>
95+
<Form.Item noStyle>注意,挂载备份卷会滚动重启所有节点</Form.Item>
96+
</Form>
97+
)}
98+
</Modal>
99+
);
100+
};
101+
102+
export default NFSInfoModal;

0 commit comments

Comments
 (0)