Skip to content

Commit c126d4a

Browse files
committed
UI: volumes view: relative capacities
closes #227
1 parent 3cfb8ce commit c126d4a

3 files changed

Lines changed: 69 additions & 0 deletions

File tree

frontend/main.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ class Handlers implements r.RouteHandlers {
105105
return <VolumesAndMountsPage view="replicationStatuses" />;
106106
}
107107

108+
volumesRelativeCapacities() {
109+
return <VolumesAndMountsPage view="capacities" />;
110+
}
111+
108112
replicationPolicies() {
109113
return <ReplicationPoliciesPage />;
110114
}

frontend/pages/VolumesAndMountsPage.tsx

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import { unrecognizedValue } from 'f61ui/utils';
1818
import {
1919
mountsUrl,
2020
volumesIntegrityUrl,
21+
volumesRelativeCapacitiesUrl,
2122
volumesReplicationUrl,
2223
volumesServiceUrl,
2324
volumesSmartUrl,
@@ -76,6 +77,7 @@ interface VolumesAndMountsPageProps {
7677
| 'service'
7778
| 'smart'
7879
| 'integrity'
80+
| 'capacities'
7981
| 'replicationStatuses';
8082
}
8183

@@ -216,6 +218,12 @@ export default class VolumesAndMountsPage extends React.Component<
216218
{this.renderMounts()}
217219
</Panel>
218220
);
221+
case 'capacities':
222+
return (
223+
<Panel heading={<div>Capacities</div>}>
224+
{this.renderVolumesRelativeCapacity()}
225+
</Panel>
226+
);
219227
default:
220228
throw unrecognizedValue(this.props.view);
221229
}
@@ -253,6 +261,10 @@ export default class VolumesAndMountsPage extends React.Component<
253261
url: volumesReplicationUrl(),
254262
title: 'Replication status',
255263
},
264+
{
265+
url: volumesRelativeCapacitiesUrl(),
266+
title: 'Capacities',
267+
},
256268
]}>
257269
{content}
258270
</TabController>
@@ -747,6 +759,55 @@ export default class VolumesAndMountsPage extends React.Component<
747759
);
748760
}
749761

762+
private renderVolumesRelativeCapacity() {
763+
const [volumes, loadingOrError] = this.state.volumes.unwrap();
764+
765+
if (loadingOrError) {
766+
return loadingOrError;
767+
}
768+
769+
const volumesWithoutCloud = (volumes || []).filter(
770+
(v) => v.Technology !== VolumeTechnology.Cloud,
771+
);
772+
773+
const volumeSortedByQuota = volumesWithoutCloud.sort((a, b) =>
774+
a.Quota > b.Quota ? -1 : 1,
775+
);
776+
777+
const highestQuotaVolume = volumeSortedByQuota[0];
778+
779+
if (!highestQuotaVolume) {
780+
return null;
781+
}
782+
783+
return (
784+
<table className={tableClassStripedHover}>
785+
<thead>
786+
<tr>
787+
<th>Label</th>
788+
<th>Quota</th>
789+
<th>Relative capacity</th>
790+
</tr>
791+
</thead>
792+
<tbody>
793+
{volumeSortedByQuota.map((vol) => {
794+
return (
795+
<tr key={vol.Id}>
796+
<td>{vol.Label}</td>
797+
<td>{bytesToHumanReadable(vol.Quota)}</td>
798+
<td>
799+
<ProgressBar
800+
progress={(vol.Quota / highestQuotaVolume.Quota) * 100}
801+
/>
802+
</td>
803+
</tr>
804+
);
805+
})}
806+
</tbody>
807+
</table>
808+
);
809+
}
810+
750811
private fetchData() {
751812
this.state.volumes.load(() => getVolumes());
752813
this.state.volumesDecommissioned.load(() => getDecommissionedVolumes());

pkg/frontend/ui-routes.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@
8989
"id": "volumesReplication",
9090
"path": "/admin/volumes/replication"
9191
},
92+
{
93+
"id": "volumesRelativeCapacities",
94+
"path": "/admin/volumes/relative_capacities"
95+
},
9296
{
9397
"id": "replicationPolicies",
9498
"path": "/admin/replicationpolicies"

0 commit comments

Comments
 (0)