Operator UI Adjustments (#1805)

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
Daniel Valdivia
2022-04-06 19:08:24 -07:00
committed by GitHub
parent 4647671f07
commit 02a35fb8d1
11 changed files with 1275 additions and 1149 deletions

View File

@@ -44,9 +44,6 @@ interface IFormSwitch {
const styles = (theme: Theme) => const styles = (theme: Theme) =>
createStyles({ createStyles({
divContainer: {
marginBottom: 20,
},
indicatorLabelOn: { indicatorLabelOn: {
fontWeight: "bold", fontWeight: "bold",
color: "#081C42 !important", color: "#081C42 !important",
@@ -172,7 +169,7 @@ const FormSwitchWrapper = ({
} }
return ( return (
<div className={classes.divContainer}> <div>
<Grid container alignItems={"center"}> <Grid container alignItems={"center"}>
<Grid item xs={12} sm={8} md={8}> <Grid item xs={12} sm={8} md={8}>
{label !== "" && ( {label !== "" && (
@@ -193,8 +190,8 @@ const FormSwitchWrapper = ({
<Grid <Grid
item item
xs={12} xs={12}
sm={4} sm={label !== "" ? 4 : 12}
md={4} md={label !== "" ? 4 : 12}
textAlign={"right"} textAlign={"right"}
justifyContent={"end"} justifyContent={"end"}
className={classes.switchContainer} className={classes.switchContainer}

View File

@@ -803,7 +803,15 @@ const AddTenant = ({
entity="Tenant" entity="Tenant"
/> />
)} )}
<PageHeader label={"Create New Tenant"} /> <PageHeader
label={
<BackLink
to={"/tenants"}
label={"Tenants"}
executeOnClick={resetAddTenantForm}
/>
}
/>
<PageLayout> <PageLayout>
{addSending && ( {addSending && (
@@ -811,14 +819,6 @@ const AddTenant = ({
<LinearProgress /> <LinearProgress />
</Grid> </Grid>
)} )}
<Grid item xs={12}>
<BackLink
to={"/tenants"}
label={"Tenant List"}
executeOnClick={resetAddTenantForm}
/>
</Grid>
<Grid item xs={12} className={classes.pageBox}> <Grid item xs={12} className={classes.pageBox}>
<GenericWizard wizardSteps={filteredWizardSteps} /> <GenericWizard wizardSteps={filteredWizardSteps} />
</Grid> </Grid>

View File

@@ -20,13 +20,25 @@ interface IInformationItemProps {
label: string; label: string;
value: string; value: string;
unit?: string; unit?: string;
variant?: "normal" | "faded";
} }
const InformationItem = ({ label, value, unit }: IInformationItemProps) => { const InformationItem = ({
label,
value,
unit,
variant = "normal",
}: IInformationItemProps) => {
return ( return (
<div style={{ margin: "0px 20px" }}> <div style={{ margin: "0px 20px" }}>
<div style={{ textAlign: "center" }}> <div style={{ textAlign: "center" }}>
<span style={{ fontSize: 18, color: "#000", fontWeight: 400 }}> <span
style={{
fontSize: 18,
color: variant === "normal" ? "#000" : "#999",
fontWeight: 400,
}}
>
{value} {value}
</span> </span>
{unit && ( {unit && (
@@ -43,7 +55,7 @@ const InformationItem = ({ label, value, unit }: IInformationItemProps) => {
<div <div
style={{ style={{
textAlign: "center", textAlign: "center",
color: "#767676", color: variant === "normal" ? "#767676" : "#bababa",
fontSize: 12, fontSize: 12,
whiteSpace: "nowrap", whiteSpace: "nowrap",
}} }}

View File

@@ -95,7 +95,6 @@ const styles = (theme: Theme) =>
marginBottom: 8, marginBottom: 8,
}, },
tenantsList: { tenantsList: {
marginTop: 25,
height: "calc(100vh - 195px)", height: "calc(100vh - 195px)",
}, },
}); });

View File

@@ -24,10 +24,9 @@ import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles"; import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles"; import withStyles from "@mui/styles/withStyles";
import { niceBytes, niceBytesInt } from "../../../../common/utils"; import { niceBytes, niceBytesInt } from "../../../../common/utils";
import { tenantIsOnline } from "./utils";
import { Button } from "@mui/material";
import InformationItem from "./InformationItem"; import InformationItem from "./InformationItem";
import TenantCapacity from "./TenantCapacity"; import TenantCapacity from "./TenantCapacity";
import { DrivesIcon } from "../../../../icons";
const styles = (theme: Theme) => const styles = (theme: Theme) =>
createStyles({ createStyles({
@@ -76,9 +75,8 @@ const styles = (theme: Theme) =>
height: 10, height: 10,
}, },
tenantItem: { tenantItem: {
border: "1px solid #EAEDEE", border: "1px solid #EAEAEA",
borderRadius: 3, marginBottom: 16,
marginBottom: 20,
padding: "15px 30px", padding: "15px 30px",
"&:hover": { "&:hover": {
backgroundColor: "#FAFAFA", backgroundColor: "#FAFAFA",
@@ -154,6 +152,8 @@ const TenantListItem = ({ tenant, classes }: ITenantListItem) => {
let raw: ValueUnit = { value: "n/a", unit: "" }; let raw: ValueUnit = { value: "n/a", unit: "" };
let capacity: ValueUnit = { value: "n/a", unit: "" }; let capacity: ValueUnit = { value: "n/a", unit: "" };
let used: ValueUnit = { value: "n/a", unit: "" }; let used: ValueUnit = { value: "n/a", unit: "" };
let localUse: ValueUnit = { value: "n/a", unit: "" };
let tieredUse: ValueUnit = { value: "n/a", unit: "" };
if (tenant.capacity_raw) { if (tenant.capacity_raw) {
const b = niceBytes(`${tenant.capacity_raw}`, true); const b = niceBytes(`${tenant.capacity_raw}`, true);
@@ -175,7 +175,6 @@ const TenantListItem = ({ tenant, classes }: ITenantListItem) => {
} }
let spaceVariants: CapacityValues[] = []; let spaceVariants: CapacityValues[] = [];
if (!tenant.tiers || tenant.tiers.length === 0) { if (!tenant.tiers || tenant.tiers.length === 0) {
spaceVariants = [ spaceVariants = [
{ value: tenant.capacity_usage || 0, variant: "STANDARD" }, { value: tenant.capacity_usage || 0, variant: "STANDARD" },
@@ -184,6 +183,26 @@ const TenantListItem = ({ tenant, classes }: ITenantListItem) => {
spaceVariants = tenant.tiers.map((itemTenant) => { spaceVariants = tenant.tiers.map((itemTenant) => {
return { value: itemTenant.size, variant: itemTenant.name }; return { value: itemTenant.size, variant: itemTenant.name };
}); });
let internalUsage = tenant.tiers
.filter((itemTenant) => {
return itemTenant.type === "internal";
})
.reduce((sum, itemTenant) => sum + itemTenant.size, 0);
let tieredUsage = tenant.tiers
.filter((itemTenant) => {
return itemTenant.type !== "internal";
})
.reduce((sum, itemTenant) => sum + itemTenant.size, 0);
const t = niceBytesInt(tieredUsage, true);
const parts = t.split(" ");
tieredUse.value = parts[0];
tieredUse.unit = parts[1];
const is = niceBytesInt(internalUsage, true);
const partsInternal = is.split(" ");
localUse.value = partsInternal[0];
localUse.unit = partsInternal[1];
} }
const openTenantDetails = () => { const openTenantDetails = () => {
@@ -238,14 +257,10 @@ const TenantListItem = ({ tenant, classes }: ITenantListItem) => {
value={capacity.value} value={capacity.value}
unit={capacity.unit} unit={capacity.unit}
/> />
<InformationItem
label={"Usage"}
value={used.value}
unit={used.unit}
/>
<InformationItem <InformationItem
label={"Pools"} label={"Pools"}
value={tenant.pool_count.toString()} value={tenant.pool_count.toString()}
variant={"faded"}
/> />
</Grid> </Grid>
<Grid <Grid
@@ -258,40 +273,86 @@ const TenantListItem = ({ tenant, classes }: ITenantListItem) => {
</span> </span>
</Grid> </Grid>
</Grid> </Grid>
<Grid <Grid item xs={3}>
item <Fragment>
xs={2} <Grid container>
sx={{ <Grid
display: "flex", item
alignItems: "center", xs={2}
justifyContent: "flex-end", textAlign={"center"}
}} justifyContent={"center"}
> justifyItems={"center"}
<Button >
id={"manage-tenant-" + tenant.name} <DrivesIcon
disabled={!tenantIsOnline(tenant)} style={{ width: 25, color: "rgb(91,91,91)" }}
onClick={(e) => { />
e.preventDefault(); <div
e.stopPropagation(); style={{
color: "rgb(118, 118, 118)",
fontSize: 12,
fontWeight: "400",
}}
>
Usage
</div>
</Grid>
<Grid item xs={1} />
<Grid item style={{ paddingTop: 8 }}>
{(!tenant.tiers || tenant.tiers.length === 0) && (
<div
style={{
fontSize: 14,
fontWeight: 400,
}}
>
<span
style={{
color: "rgb(62,62,62)",
}}
>
Internal:{" "}
</span>{" "}
{`${used.value} ${used.unit}`}
</div>
)}
history.push( {tenant.tiers && tenant.tiers.length > 0 && (
`/namespaces/${tenant.namespace}/tenants/${tenant.name}/hop` <Fragment>
); <div
}} style={{
disableTouchRipple fontSize: 14,
disableRipple fontWeight: 400,
focusRipple={false} }}
sx={{ >
color: "#5E5E5E", <span
border: "#5E5E5E 1px solid", style={{
whiteSpace: "nowrap", color: "rgb(62,62,62)",
paddingLeft: 4.5, }}
paddingRight: 4.5, >
}} Internal:{" "}
variant={"outlined"} </span>{" "}
> {`${localUse.value} ${localUse.unit}`}
Manage </div>
</Button> <div
style={{
fontSize: 14,
fontWeight: 400,
}}
>
<span
style={{
color: "rgb(62,62,62)",
}}
>
Tiered:{" "}
</span>{" "}
{`${tieredUse.value} ${tieredUse.unit}`}
</div>
</Fragment>
)}
</Grid>
</Grid>
</Fragment>
</Grid> </Grid>
</Grid> </Grid>
</Grid> </Grid>

View File

@@ -128,10 +128,6 @@ const PoolsListing = ({
variant={"contained"} variant={"contained"}
/> />
</Grid> </Grid>
<Grid item xs={12}>
<br />
</Grid>
<Grid item xs={12} className={classes.tableBlock}> <Grid item xs={12} className={classes.tableBlock}>
<TableWrapper <TableWrapper
itemActions={listActions} itemActions={listActions}

View File

@@ -39,7 +39,7 @@ import { AppState } from "../../../../store";
import { ErrorResponseHandler } from "../../../../common/types"; import { ErrorResponseHandler } from "../../../../common/types";
import api from "../../../../common/api"; import api from "../../../../common/api";
import PageHeader from "../../Common/PageHeader/PageHeader"; import PageHeader from "../../Common/PageHeader/PageHeader";
import { CircleIcon, TrashIcon } from "../../../../icons"; import { CircleIcon, MinIOTierIconXs, TrashIcon } from "../../../../icons";
import { niceBytes } from "../../../../common/utils"; import { niceBytes } from "../../../../common/utils";
import ScreenTitle from "../../Common/ScreenTitle/ScreenTitle"; import ScreenTitle from "../../Common/ScreenTitle/ScreenTitle";
import EditIcon from "../../../../icons/EditIcon"; import EditIcon from "../../../../icons/EditIcon";
@@ -51,6 +51,7 @@ import VerticalTabs from "../../Common/VerticalTabs/VerticalTabs";
import BoxIconButton from "../../Common/BoxIconButton/BoxIconButton"; import BoxIconButton from "../../Common/BoxIconButton/BoxIconButton";
import withSuspense from "../../Common/Components/withSuspense"; import withSuspense from "../../Common/Components/withSuspense";
import { IAM_PAGES } from "../../../../common/SecureComponent/permissions"; import { IAM_PAGES } from "../../../../common/SecureComponent/permissions";
import { tenantIsOnline } from "../ListTenants/utils";
const TenantYAML = withSuspense(React.lazy(() => import("./TenantYAML"))); const TenantYAML = withSuspense(React.lazy(() => import("./TenantYAML")));
const TenantSummary = withSuspense(React.lazy(() => import("./TenantSummary"))); const TenantSummary = withSuspense(React.lazy(() => import("./TenantSummary")));
@@ -377,7 +378,7 @@ const TenantDetails = ({
}} }}
size="large" size="large"
> >
<span>Delete Tenant</span> <TrashIcon /> <span>Delete</span> <TrashIcon />
</BoxIconButton> </BoxIconButton>
<BoxIconButton <BoxIconButton
classes={{ classes={{
@@ -392,9 +393,26 @@ const TenantDetails = ({
}} }}
size="large" size="large"
> >
<span>Edit Tenant</span> <span>YAML</span>
<EditIcon /> <EditIcon />
</BoxIconButton> </BoxIconButton>
<BoxIconButton
classes={{
root: classes.tenantActionButton,
}}
tooltip={"Management Console"}
onClick={() => {
history.push(
`/namespaces/${tenantNamespace}/tenants/${tenantName}/hop`
);
}}
disabled={!tenantInfo || !tenantIsOnline(tenantInfo)}
variant={"outlined"}
color="primary"
>
<span>Console</span>{" "}
<MinIOTierIconXs style={{ height: 16 }} />
</BoxIconButton>
<BoxIconButton <BoxIconButton
classes={{ classes={{
root: classes.tenantActionButton, root: classes.tenantActionButton,
@@ -407,7 +425,7 @@ const TenantDetails = ({
setTenantDetailsLoad(true); setTenantDetailsLoad(true);
}} }}
> >
<span>Reload</span> <RefreshIcon /> <span>Refresh</span> <RefreshIcon />
</BoxIconButton> </BoxIconButton>
</div> </div>
} }

View File

@@ -207,43 +207,52 @@ const TenantLogging = ({
dbMemRequest={logInfo.logDBMemRequest} dbMemRequest={logInfo.logDBMemRequest}
/> />
)} )}
<h1 className={classes.sectionTitle}>Logging</h1> <Grid container alignItems={"center"}>
<div className={classes.actionsTray}> <Grid item xs>
<FormSwitchWrapper <h1 className={classes.sectionTitle}>Logging</h1>
value="enableLogging" </Grid>
id="enableLogging" <Grid item xs={4}>
name="enableLogging" <FormSwitchWrapper
checked={!preDisabled} value="enableLogging"
onChange={(e) => { id="enableLogging"
const targetD = e.target; name="enableLogging"
const checked = targetD.checked; checked={!preDisabled}
if (checked) { onChange={(e) => {
setEnableDialogOpen(true); const targetD = e.target;
} else { const checked = targetD.checked;
setDisableDialogOpen(true); if (checked) {
} setEnableDialogOpen(true);
}} } else {
label={"Logging"} setDisableDialogOpen(true);
indicatorLabels={["Enabled", "Disabled"]} }
/>
{!disabled && !loadingTenantLogs && (
<RBIconButton
tooltip={"Edit Logging configuration"}
text={"Edit"}
onClick={() => {
setEdit(true);
}} }}
icon={<EditIcon />} indicatorLabels={["Enabled", "Disabled"]}
color="primary"
variant={"contained"}
/> />
)} </Grid>
</div> </Grid>
{!disabled && !loadingTenantLogs && ( {!disabled && !loadingTenantLogs && (
<Paper className={classes.paperContainer}> <Paper className={classes.paperContainer}>
<Grid container> <Grid container>
<Grid item xs={12}> <Grid item xs={12}>
<h2>Logging API Service Details</h2> <Grid container alignItems={"center"}>
<Grid xs={8}>
<h3>Configuration</h3>
</Grid>
<Grid xs={4} justifyContent={"end"} textAlign={"right"}>
<RBIconButton
tooltip={"Edit Logging configuration"}
text={"Edit"}
onClick={() => {
setEdit(true);
}}
icon={<EditIcon />}
color="primary"
variant={"contained"}
/>
</Grid>
</Grid>
</Grid>
<Grid item xs={12}>
<hr className={classes.hrClass} /> <hr className={classes.hrClass} />
<table width={"100%"}> <table width={"100%"}>
<tbody> <tbody>

View File

@@ -188,37 +188,48 @@ const TenantMonitoring = ({
/> />
)} )}
<h1 className={classes.sectionTitle}>Monitoring</h1> <Grid container alignItems={"center"}>
<div className={classes.actionsTray}> <Grid item xs>
<FormSwitchWrapper <h1 className={classes.sectionTitle}>Monitoring</h1>
label={"Prometheus Monitoring"} </Grid>
indicatorLabels={["Enabled", "Disabled"]} <Grid item xs={4}>
checked={prometheusMonitoringEnabled} <FormSwitchWrapper
value={"monitoring_status"} indicatorLabels={["Enabled", "Disabled"]}
id="monitoring-status" checked={prometheusMonitoringEnabled}
name="monitoring-status" value={"monitoring_status"}
onChange={(e) => { id="monitoring-status"
setConfirmOpen(true); name="monitoring-status"
}} onChange={(e) => {
description="" setConfirmOpen(true);
/>
{prometheusMonitoringEnabled && (
<RBIconButton
tooltip={"Edit Monitoring configuration"}
text={"Edit"}
onClick={() => {
setEdit(true);
}} }}
icon={<EditIcon />} description=""
color="primary"
variant={"contained"}
/> />
)} </Grid>
</div> </Grid>
{prometheusMonitoringEnabled && monitoringInfo !== undefined && ( {prometheusMonitoringEnabled && monitoringInfo !== undefined && (
<Paper className={classes.paperContainer}> <Paper className={classes.paperContainer}>
<Grid container> <Grid container>
<Grid item xs={12}> <Grid item xs={12}>
<Grid container alignItems={"center"}>
<Grid xs={8}>
<h3>Configuration</h3>
</Grid>
<Grid xs={4} justifyContent={"end"} textAlign={"right"}>
<RBIconButton
tooltip={"Edit Monitoring configuration"}
text={"Edit"}
onClick={() => {
setEdit(true);
}}
icon={<EditIcon />}
color="primary"
variant={"contained"}
/>
</Grid>
</Grid>
</Grid>
<Grid item xs={12}>
<hr className={classes.hrClass} />
<table width={"100%"}> <table width={"100%"}>
<tbody> <tbody>
{loadingTenant ? ( {loadingTenant ? (

View File

@@ -29,16 +29,12 @@ import Paper from "@mui/material/Paper";
import { ITenant } from "../ListTenants/types"; import { ITenant } from "../ListTenants/types";
import UpdateTenantModal from "./UpdateTenantModal"; import UpdateTenantModal from "./UpdateTenantModal";
import { AppState } from "../../../../store"; import { AppState } from "../../../../store";
import history from "./../../../../history";
import { tenantIsOnline } from "../ListTenants/utils";
import AButton from "../../Common/AButton/AButton"; import AButton from "../../Common/AButton/AButton";
import { styled } from "@mui/styles"; import { styled } from "@mui/styles";
import SummaryUsageBar from "../../Common/UsageBarWrapper/SummaryUsageBar"; import SummaryUsageBar from "../../Common/UsageBarWrapper/SummaryUsageBar";
import LabelValuePair from "../../Common/UsageBarWrapper/LabelValuePair"; import LabelValuePair from "../../Common/UsageBarWrapper/LabelValuePair";
import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import StackRow from "../../Common/UsageBarWrapper/StackRow"; import StackRow from "../../Common/UsageBarWrapper/StackRow";
import { SettingsIcon } from "../../../../icons";
import RBIconButton from "../../Buckets/BucketDetails/SummaryItems/RBIconButton";
interface ITenantsSummary { interface ITenantsSummary {
classes: any; classes: any;
@@ -237,21 +233,7 @@ const TenantSummary = ({
<StackItem> <StackItem>
<h3>Details</h3> <h3>Details</h3>
</StackItem> </StackItem>
<StackItem> <StackItem></StackItem>
<RBIconButton
tooltip={"Manage Tenant"}
text={"Manage Tenant"}
onClick={() => {
history.push(
`/namespaces/${tenantNamespace}/tenants/${tenantName}/hop`
);
}}
disabled={!tenant || !tenantIsOnline(tenant)}
icon={<SettingsIcon />}
color="primary"
variant={"contained"}
/>
</StackItem>
</Stack> </Stack>
<StorageSummary tenant={tenant} classes={classes} /> <StorageSummary tenant={tenant} classes={classes} />