Skip to content

Commit c32b75a

Browse files
Improve layout and fix bug with selector length
1 parent c01a015 commit c32b75a

File tree

3 files changed

+130
-98
lines changed

3 files changed

+130
-98
lines changed

hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/capacity/capacity.less

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,24 @@
3535
color: #1b2329;
3636
}
3737

38+
.node-select-container {
39+
display: flex;
40+
flex-direction: column;
41+
gap: 16px;
42+
margin: 16px 0px auto 0px;
43+
height: 15em;
44+
}
45+
3846
.cluster-card-data-container {
3947
display: flex;
4048
justify-content: space-between;
4149
gap: 16px;
4250

51+
&.vertical-layout {
52+
flex-direction: column;
53+
gap: 0px;
54+
}
55+
4356
.cluster-card-statistic {
4457
flex: 2 1 10em;
4558
}
@@ -52,11 +65,14 @@
5265
align-items: stretch;
5366
padding: 16px;
5467
border-radius: 3px;
55-
background-color: #f4f5f6;
5668

5769
.data-detail-breakdown-container {
70+
justify-content: flex-end;
71+
flex-wrap: wrap;
5872
.data-detail-breakdown-statistic {
59-
flex: 1 0 10em;
73+
flex: 0 0 50%;
74+
max-width: 25%;
75+
text-align: right;
6076
}
6177
}
6278
}
@@ -93,6 +109,19 @@
93109
}
94110
}
95111

112+
.data-breakdown-section {
113+
display: flex;
114+
gap: 16px;
115+
width: 100%;
116+
justify-content: space-between;
117+
align-items: stretch;
118+
119+
> .ant-card {
120+
flex: 1 1 0;
121+
min-width: 0;
122+
}
123+
}
124+
96125
.unused-space-breakdown {
97126
display: grid;
98127
grid-template-columns: 150px auto;

hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/capacity/capacity.tsx

Lines changed: 68 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -230,75 +230,77 @@ const Capacity: React.FC<object> = () => {
230230
color: '#10073b'
231231
}]}
232232
/>
233-
<CapacityDetail
234-
title='Pending Deletion'
235-
loading={state.loading}
236-
showDropdown={false}
237-
dataDetails={[{
238-
title: 'OZONE MANAGER',
239-
size: usageBreakdown.deletionPendingBytes.byStage.OM.pendingBytes,
240-
breakdown: [{
241-
label: 'KEYS',
242-
value: usageBreakdown.deletionPendingBytes.byStage.OM.pendingKeyBytes,
243-
color: '#658df5'
233+
<div className='data-breakdown-section'>
234+
<CapacityDetail
235+
title='Pending Deletion'
236+
loading={state.loading}
237+
showDropdown={false}
238+
dataDetails={[{
239+
title: 'OZONE MANAGER',
240+
size: usageBreakdown.deletionPendingBytes.byStage.OM.pendingBytes,
241+
breakdown: [{
242+
label: 'KEYS',
243+
value: usageBreakdown.deletionPendingBytes.byStage.OM.pendingKeyBytes,
244+
color: '#f4a233'
245+
}, {
246+
label: 'DIRECTORIES',
247+
value: usageBreakdown.deletionPendingBytes.byStage.OM.pendingDirectoryBytes,
248+
color: '#10073b'
249+
}]
244250
}, {
245-
label: 'DIRECTORIES',
246-
value: usageBreakdown.deletionPendingBytes.byStage.OM.pendingDirectoryBytes,
247-
color: '#4553ef'
248-
}]
249-
}, {
250-
title: 'STORAGE CONTAINER MANAGER',
251-
size: usageBreakdown.deletionPendingBytes.byStage.SCM.pendingBytes,
252-
breakdown: [{
253-
label: 'BLOCKS',
254-
value: usageBreakdown.deletionPendingBytes.byStage.SCM.pendingBytes,
255-
color: '#2c218e'
256-
}]
257-
}, {
258-
title: (
259-
<span>
260-
DATANODES
261-
<WrappedInfoIcon title={datanodesPendingDeletionDesc} />
262-
</span>
263-
),
264-
size: usageBreakdown.deletionPendingBytes.byStage.DN.pendingBytes,
265-
breakdown: [{
266-
label: 'BLOCKS',
267-
value: usageBreakdown.deletionPendingBytes.byStage.DN.pendingBytes,
268-
color: '#f47c2d'
269-
}]
270-
}]} />
271-
<CapacityDetail
272-
title='Datanode'
273-
loading={state.loading}
274-
showDropdown={true}
275-
handleSelect={setSelectedDatanode}
276-
dropdownItems={datanodeUsage.map(datanode => datanode.uuid)}
277-
dataDetails={[{
278-
title: 'USED SPACE',
279-
size: selectedDNDetails.used + selectedDNDetails.pendingDeletion,
280-
breakdown: [{
281-
label: 'PENDING DELETION',
282-
value: selectedDNDetails.pendingDeletion,
283-
color: '#658df5'
251+
title: 'STORAGE CONTAINER MANAGER',
252+
size: usageBreakdown.deletionPendingBytes.byStage.SCM.pendingBytes,
253+
breakdown: [{
254+
label: 'BLOCKS',
255+
value: usageBreakdown.deletionPendingBytes.byStage.SCM.pendingBytes,
256+
color: '#f4a233'
257+
}]
284258
}, {
285-
label: 'OZONE USED',
286-
value: selectedDNDetails.used,
287-
color: '#4553ee'
288-
}]
289-
}, {
290-
title: 'FREE SPACE',
291-
size: selectedDNDetails.remaining + selectedDNDetails.committed,
292-
breakdown: [{
293-
label: unusedSpaceBreakdown,
294-
value: selectedDNDetails.remaining,
295-
color: '#7465f5'
259+
title: (
260+
<span>
261+
DATANODES
262+
<WrappedInfoIcon title={datanodesPendingDeletionDesc} />
263+
</span>
264+
),
265+
size: usageBreakdown.deletionPendingBytes.byStage.DN.pendingBytes,
266+
breakdown: [{
267+
label: 'BLOCKS',
268+
value: usageBreakdown.deletionPendingBytes.byStage.DN.pendingBytes,
269+
color: '#f4a233'
270+
}]
271+
}]} />
272+
<CapacityDetail
273+
title='Datanode'
274+
loading={state.loading}
275+
showDropdown={true}
276+
handleSelect={setSelectedDatanode}
277+
dropdownItems={datanodeUsage.map(datanode => datanode.uuid)}
278+
dataDetails={[{
279+
title: 'USED SPACE',
280+
size: selectedDNDetails.used + selectedDNDetails.pendingDeletion,
281+
breakdown: [{
282+
label: 'PENDING DELETION',
283+
value: selectedDNDetails.pendingDeletion,
284+
color: '#f4a233'
285+
}, {
286+
label: 'OZONE USED',
287+
value: selectedDNDetails.used,
288+
color: '#10073b'
289+
}]
296290
}, {
297-
label: 'OZONE PRE-ALLOCATED',
298-
value: selectedDNDetails.committed,
299-
color: '#592cc6'
300-
}]
301-
}]} />
291+
title: 'FREE SPACE',
292+
size: selectedDNDetails.remaining + selectedDNDetails.committed,
293+
breakdown: [{
294+
label: unusedSpaceBreakdown,
295+
value: selectedDNDetails.remaining,
296+
color: '#f4a233'
297+
}, {
298+
label: 'OZONE PRE-ALLOCATED',
299+
value: selectedDNDetails.committed,
300+
color: '#10073b'
301+
}]
302+
}]} />
303+
</div>
302304
</div>
303305
</>
304306

hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/v2/pages/capacity/components/CapacityDetail.tsx

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
import { EChart } from '@/components/eChart/eChart';
2020
import { GraphLegendIcon } from '@/utils/themeIcons';
21-
import { cardHeadStyle, statisticValueStyle } from '@/v2/pages/capacity/constants/styles.constants';
21+
import { cardBodyStyle, cardHeadStyle, statisticValueStyle } from '@/v2/pages/capacity/constants/styles.constants';
2222
import { Card, Divider, Row, Select, Statistic } from 'antd';
2323
import filesize from 'filesize';
2424
import React from 'react';
@@ -38,7 +38,7 @@ type CapacityDetailProps = {
3838
loading: boolean;
3939
};
4040

41-
const getEchartOptions = (data: DataDetailItem[]) => {
41+
const getEchartOptions = (title: string | React.ReactNode, data: DataDetailItem) => {
4242
const option = {
4343
grid: {
4444
left: 2,
@@ -62,24 +62,22 @@ const getEchartOptions = (data: DataDetailItem[]) => {
6262
},
6363
};
6464

65-
const series = data.flatMap(item => {
66-
// Determine if this group should be stacked, i.e. if the breakdown has more than one item
67-
const breakdownLen = item.breakdown.length;
65+
const breakdownLen = data.breakdown.length;
66+
const series = data.breakdown.map((breakdown, idx) => ({
67+
type: 'bar',
68+
...(breakdownLen > 1 && { stack: title }),
69+
itemStyle: {
70+
...(idx === breakdownLen - 1 && { borderRadius: [0, 50, 50, 0] }),
71+
...(idx === 0 && { borderRadius: [50, 0, 0, 50] }),
72+
...(breakdownLen === 1 && { borderRadius: [50, 50, 50, 50] }),
73+
color: breakdown.color,
74+
},
75+
data: [breakdown.value],
76+
barWidth: '10px',
77+
barGap: '2px'
78+
}));
6879

69-
return item.breakdown.map((breakdown, idx) => ({
70-
type: 'bar',
71-
...(breakdownLen > 1 && { stack: item.title }),
72-
itemStyle: {
73-
...(idx === breakdownLen - 1 && { borderRadius: [0, 50, 50, 0] }),
74-
...(idx === 0 && { borderRadius: [50, 0, 0, 50] }),
75-
...(breakdownLen === 1 && { borderRadius: [50, 50, 50, 50] }),
76-
color: breakdown.color,
77-
},
78-
data: [breakdown.value],
79-
barWidth: '10px',
80-
barGap: '2px'
81-
}));
82-
});
80+
console.log(series);
8381

8482
return {
8583
...option,
@@ -100,14 +98,17 @@ const CapacityDetail: React.FC<CapacityDetailProps> = (
10098
return (
10199
<Card title={title} size='small' headStyle={cardHeadStyle} loading={loading}>
102100
{ showDropdown && options.length > 0 &&
103-
<Select
104-
defaultValue={options?.[0]?.value}
105-
options={options}
106-
onChange={handleSelect}
107-
style={{ marginBottom: '16px' }}
108-
/>
101+
<div className='node-select-container'>
102+
Node Select:
103+
<Select
104+
defaultValue={options?.[0]?.value}
105+
options={options}
106+
onChange={handleSelect}
107+
style={{ marginBottom: '16px' }}
108+
/>
109+
</div>
109110
}
110-
<div className='cluster-card-data-container'>
111+
<div className='cluster-card-data-container vertical-layout'>
111112
{dataDetails.map((data, idx) => {
112113
const size = filesize(data.size, { round: 1 }).split(' ');
113114
return (
@@ -119,7 +120,6 @@ const CapacityDetail: React.FC<CapacityDetailProps> = (
119120
valueStyle={statisticValueStyle}
120121
className='data-detail-statistic'
121122
/>
122-
<Divider />
123123
<Row className='data-detail-breakdown-container'>
124124
{data.breakdown.map((item, idx) => (
125125
<Statistic
@@ -130,14 +130,15 @@ const CapacityDetail: React.FC<CapacityDetailProps> = (
130130
className='data-detail-breakdown-statistic'
131131
/>
132132
))}
133+
<EChart
134+
option={getEchartOptions(data.title, data)}
135+
style={{ height: '40px', width: '100%', margin: '10px 0px' }} />
136+
{idx < dataDetails.length - 1 && <Divider />}
133137
</Row>
134138
</div>
135139
)
136140
})}
137141
</div>
138-
<EChart
139-
option={getEchartOptions(dataDetails)}
140-
style={{ height: '100px', width: '100%', margin: '16px 0px' }} />
141142
</Card>
142143
);
143144
}

0 commit comments

Comments
 (0)