Skip to content

Commit f4d08a7

Browse files
authored
Tenant Details (#162)
1 parent fb59e8c commit f4d08a7

File tree

7 files changed

+179
-194
lines changed

7 files changed

+179
-194
lines changed

portal-ui/bindata_assetfs.go

Lines changed: 91 additions & 91 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

portal-ui/src/screens/Console/Console.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ const Console = ({
307307
},
308308
{
309309
component: TenantDetails,
310-
path: "/clusters/:clusterName",
310+
path: "/tenants/:tenantName",
311311
},
312312
];
313313
const allowedRoutes = routes.filter((route: any) => allowedPages[route.path]);

portal-ui/src/screens/Console/Tenants/ListTenants/AddTenant.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,11 @@ const styles = (theme: Theme) =>
5454
...modalBasic,
5555
});
5656

57+
interface Opts {
58+
label: string;
59+
value: string;
60+
}
61+
5762
const AddTenant = ({
5863
open,
5964
closeModalAndRefresh,
@@ -75,7 +80,7 @@ const AddTenant = ({
7580
const [enableMCS, setEnableMCS] = useState<boolean>(false);
7681
const [enableSSL, setEnableSSL] = useState<boolean>(false);
7782
const [sizeFactor, setSizeFactor] = useState<string>("Gi");
78-
const [storageClasses, setStorageClassesList] = useState<string[]>([]);
83+
const [storageClasses, setStorageClassesList] = useState<Opts[]>([]);
7984

8085
useEffect(() => {
8186
fetchStorageClassList();
@@ -136,18 +141,18 @@ const AddTenant = ({
136141
if (res !== null) {
137142
classes = res;
138143
}
139-
setStorageClassesList(classes);
144+
setStorageClassesList(
145+
classes.map((s: string) => ({
146+
label: s,
147+
value: s,
148+
}))
149+
);
140150
})
141151
.catch((err: any) => {
142152
console.log(err);
143153
});
144154
};
145155

146-
const storageClassesList = storageClasses.map((s: string) => ({
147-
label: s,
148-
value: s,
149-
}));
150-
151156
return (
152157
<ModalWrapper
153158
title="Create Tenant"
@@ -279,7 +284,7 @@ const AddTenant = ({
279284
}}
280285
label="Storage Class"
281286
value={volumeConfiguration.storage_class}
282-
options={storageClassesList}
287+
options={storageClasses}
283288
/>
284289
</Grid>
285290
<Grid item xs={12}>

portal-ui/src/screens/Console/Tenants/ListTenants/ZonesMultiSelector.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ const ZonesMultiSelector = ({
7676
onChange,
7777
classes,
7878
}: IZonesMultiSelector) => {
79-
const defaultZone: IZone = { name: "", servers: 0 };
79+
const defaultZone: IZone = { name: "", servers: 0, capacity: "", volumes: 0 };
8080

8181
const [currentElements, setCurrentElements] = useState<IZone[]>([
8282
{ ...defaultZone },

portal-ui/src/screens/Console/Tenants/ListTenants/types.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
export interface IZone {
1818
name: string;
1919
servers: number;
20+
// computed
21+
capacity: string;
22+
volumes: number;
2023
}
2124

2225
export interface IVolumeConfiguration {
@@ -32,6 +35,8 @@ export interface ITenant {
3235
creation_date: Date;
3336
volume_size: number;
3437
volume_count: number;
38+
volumes_per_server: number;
39+
zones: IZone[];
3540
// computed
3641
capacity: string;
3742
}

portal-ui/src/screens/Console/Tenants/TenantDetails/AddZoneModal.tsx

Lines changed: 12 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,19 @@ import { modalBasic } from "../../Common/FormComponents/common/styleLibrary";
55
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
66
import SelectWrapper from "../../Common/FormComponents/SelectWrapper/SelectWrapper";
77
import Grid from "@material-ui/core/Grid";
8-
import { factorForDropdown, getTotalSize } from "../../../../common/utils";
8+
import {
9+
factorForDropdown,
10+
getTotalSize,
11+
niceBytes,
12+
} from "../../../../common/utils";
913
import { Button, LinearProgress } from "@material-ui/core";
1014

1115
interface IAddZoneProps {
1216
classes: any;
1317
open: boolean;
1418
onCloseZoneAndReload: (shouldReload: boolean) => void;
19+
volumesPerInstance: number;
20+
volumeSize: number;
1521
}
1622

1723
const styles = (theme: Theme) =>
@@ -60,17 +66,14 @@ const AddZoneModal = ({
6066
classes,
6167
open,
6268
onCloseZoneAndReload,
69+
volumesPerInstance,
70+
volumeSize,
6371
}: IAddZoneProps) => {
6472
const [addSending, setAddSending] = useState<boolean>(false);
6573
const [zoneName, setZoneName] = useState<string>("");
6674
const [numberOfInstances, setNumberOfInstances] = useState<number>(0);
67-
const [volumesPerInstance, setVolumesPerInstance] = useState<number>(0);
68-
const [sizeFactor, setSizeFactor] = useState<string>("GiB");
69-
const [volumeConfiguration, setVolumeConfig] = useState<string>("");
70-
const [storageClass, setStorageClass] = useState<string>("");
7175

72-
const instanceCapacity: number =
73-
parseFloat(volumeConfiguration) * volumesPerInstance;
76+
const instanceCapacity: number = volumeSize * volumesPerInstance;
7477
const totalCapacity: number = instanceCapacity * numberOfInstances;
7578

7679
return (
@@ -112,66 +115,17 @@ const AddZoneModal = ({
112115
/>
113116
</Grid>
114117
<Grid item xs={12}>
115-
<InputBoxWrapper
116-
id="volumes_per_instance"
117-
name="volumes_per_instance"
118-
type="number"
119-
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
120-
setVolumesPerInstance(parseInt(e.target.value));
121-
}}
122-
label="Volumes per Instance"
123-
value={volumesPerInstance.toString(10)}
124-
/>
125-
</Grid>
126-
<Grid item xs={12}>
127-
<div className={classes.multiContainer}>
128-
<div>
129-
<InputBoxWrapper
130-
id="volume_size"
131-
name="volume_size"
132-
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
133-
setVolumeConfig(e.target.value);
134-
}}
135-
label="Size"
136-
value={volumeConfiguration}
137-
/>
138-
</div>
139-
<div className={classes.sizeFactorContainer}>
140-
<SelectWrapper
141-
label=""
142-
id="size_factor"
143-
name="size_factor"
144-
value={sizeFactor}
145-
onChange={(e: React.ChangeEvent<{ value: unknown }>) => {
146-
setSizeFactor(e.target.value as string);
147-
}}
148-
options={factorForDropdown()}
149-
/>
150-
</div>
151-
</div>
152-
<Grid item xs={12}>
153-
<InputBoxWrapper
154-
id="storage_class"
155-
name="storage_class"
156-
type="string"
157-
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
158-
setStorageClass(e.target.value);
159-
}}
160-
label="Volumes per Server"
161-
value={storageClass}
162-
/>
163-
</Grid>
164118
<Grid item xs={12} className={classes.bottomContainer}>
165119
<div className={classes.factorElements}>
166120
<div>
167121
<div className={classes.sizeNumber}>
168-
{getTotalSize(instanceCapacity.toString(10), sizeFactor)}
122+
{niceBytes(instanceCapacity.toString(10))}
169123
</div>
170124
<div className={classes.sizeDescription}>Instance Capacity</div>
171125
</div>
172126
<div>
173127
<div className={classes.sizeNumber}>
174-
{getTotalSize(totalCapacity.toString(10), sizeFactor)}
128+
{niceBytes(totalCapacity.toString(10))}
175129
</div>
176130
<div className={classes.sizeDescription}>Total Capacity</div>
177131
</div>

portal-ui/src/screens/Console/Tenants/TenantDetails/TenantDetails.tsx

Lines changed: 56 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ import { niceBytes } from "../../../../common/utils";
3030
import AddZoneModal from "./AddZoneModal";
3131
import AddBucket from "../../Buckets/ListBuckets/AddBucket";
3232
import ReplicationSetup from "./ReplicationSetup";
33+
import api from "../../../../common/api";
34+
import { BucketInfo } from "../../Buckets/types";
35+
import { ITenant, IZone } from "../ListTenants/types";
3336

3437
interface ITenantDetailsProps {
3538
classes: any;
@@ -106,12 +109,16 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
106109
const [capacity, setCapacity] = useState<number>(0);
107110
const [externalIDP, setExternalIDP] = useState<boolean>(false);
108111
const [externalKMS, setExternalKMS] = useState<boolean>(false);
109-
const [zones, setZones] = useState<number>(0);
112+
const [zoneCount, setZoneCount] = useState<number>(0);
113+
const [zones, setZones] = useState<IZone[]>([]);
110114
const [instances, setInstances] = useState<number>(0);
111-
const [drives, setDrives] = useState<number>(0);
115+
const [volumes, setVolumes] = useState<number>(0);
112116
const [addZoneOpen, setAddZone] = useState<boolean>(false);
113117
const [addBucketOpen, setAddBucketOpen] = useState<boolean>(false);
114118
const [addReplicationOpen, setAddReplicationOpen] = useState<boolean>(false);
119+
const [loading, setLoading] = useState<boolean>(false);
120+
const [error, setError] = useState<string>("");
121+
const [tenant, setTenant] = useState<ITenant | null>(null);
115122

116123
const onCloseZoneAndRefresh = (reload: boolean) => {
117124
setAddZone(false);
@@ -133,12 +140,50 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
133140
}
134141
};
135142

143+
const loadInfo = () => {
144+
const tenantName = match.params["tenantName"];
145+
146+
setLoading(true);
147+
148+
api
149+
.invoke("GET", `/api/v1/mkube/tenants/${tenantName}`)
150+
.then((res: ITenant) => {
151+
const total = res.volume_count * res.volume_size;
152+
153+
setCapacity(total);
154+
setZoneCount(res.zone_count);
155+
setVolumes(res.volume_count);
156+
setInstances(res.instance_count);
157+
const resZones = !res.zones ? [] : res.zones;
158+
for (let zone of resZones) {
159+
zone.volumes = res.volumes_per_server;
160+
const cap = res.volumes_per_server * res.volume_size * zone.servers;
161+
zone.capacity = niceBytes(cap + "");
162+
}
163+
setZones(resZones);
164+
165+
setTenant(res);
166+
setError("");
167+
setLoading(false);
168+
})
169+
.catch((err) => {
170+
setError(err);
171+
setLoading(false);
172+
});
173+
};
174+
175+
useEffect(() => {
176+
loadInfo();
177+
}, []);
178+
136179
return (
137180
<React.Fragment>
138-
{addZoneOpen && (
181+
{addZoneOpen && tenant !== null && (
139182
<AddZoneModal
140183
open={addZoneOpen}
141184
onCloseZoneAndReload={onCloseZoneAndRefresh}
185+
volumeSize={tenant.volume_size}
186+
volumesPerInstance={tenant.volumes_per_server}
142187
/>
143188
)}
144189
{addBucketOpen && (
@@ -156,7 +201,7 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
156201
<Grid container>
157202
<Grid item xs={12}>
158203
<Typography variant="h6">
159-
Tenant > {match.params["clusterName"]}
204+
Tenant > {match.params["tenantName"]}
160205
</Typography>
161206
</Grid>
162207
<Grid item xs={12}>
@@ -168,7 +213,7 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
168213
<div>Capacity:</div>
169214
<div>{niceBytes(capacity.toString(10))}</div>
170215
<div>Zones:</div>
171-
<div>{zones}</div>
216+
<div>{zoneCount}</div>
172217
<div>External IDP:</div>
173218
<div>
174219
{externalIDP ? "Yes" : "No"}&nbsp;&nbsp;
@@ -184,19 +229,9 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
184229
<div>Instances:</div>
185230
<div>{instances}</div>
186231
<div>External KMS:</div>
187-
<div>
188-
{externalKMS ? "Yes" : "No"}&nbsp;&nbsp;
189-
<Button
190-
variant="contained"
191-
color="primary"
192-
size="small"
193-
onClick={() => {}}
194-
>
195-
Edit
196-
</Button>
197-
</div>
198-
<div>Drives:</div>
199-
<div>{drives}</div>
232+
<div>{externalKMS ? "Yes" : "No"}&nbsp;&nbsp;</div>
233+
<div>Volumes:</div>
234+
<div>{volumes}</div>
200235
</div>
201236
</Paper>
202237
<div className={classes.masterActions}>
@@ -210,16 +245,6 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
210245
Warp
211246
</Button>
212247
</div>
213-
<div>
214-
<Button
215-
variant="contained"
216-
color="primary"
217-
fullWidth
218-
onClick={() => {}}
219-
>
220-
See as deployment
221-
</Button>
222-
</div>
223248
</div>
224249
</Grid>
225250
<Grid item xs={12}>
@@ -303,17 +328,13 @@ const TenantDetails = ({ classes, match }: ITenantDetailsProps) => {
303328
},
304329
]}
305330
columns={[
306-
{
307-
label: "Status",
308-
elementKey: "status",
309-
},
310331
{ label: "Name", elementKey: "name" },
311332
{ label: "Capacity", elementKey: "capacity" },
312-
{ label: "# of Instances", elementKey: "instances" },
313-
{ label: "# of Drives", elementKey: "drives" },
333+
{ label: "# of Instances", elementKey: "servers" },
334+
{ label: "# of Drives", elementKey: "volumes" },
314335
]}
315336
isLoading={false}
316-
records={[]}
337+
records={zones}
317338
entityName="Zones"
318339
idField="name"
319340
paginatorConfig={{

0 commit comments

Comments
 (0)