New Bucket Listing Style (#1223)

* New Bucket Listing Style

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* Select Multiple Icon

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
Daniel Valdivia
2021-11-12 15:02:54 -08:00
committed by GitHub
parent 2b34fbae47
commit ad240d2ec5
14 changed files with 410 additions and 330 deletions

View File

@@ -54,7 +54,7 @@ var derivedKey = func() []byte {
return pbkdf2.Key([]byte(token.GetPBKDFPassphrase()), []byte(token.GetPBKDFSalt()), 4096, 32, sha1.New)
}
// IsSessionTokenValid returns true or false depending if the provided session token is valid or not
// IsSessionTokenValid returns true or false depending upon the provided session if the token is valid or not
func IsSessionTokenValid(token string) bool {
_, err := SessionTokenAuthenticate(token)
return err == nil

View File

@@ -0,0 +1,49 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import * as React from "react";
import { SvgIcon, SvgIconProps } from "@mui/material";
const MultipleBucketsIcon = (props: SvgIconProps) => {
return (
<SvgIcon {...props}>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<g id="repliaction-icn" transform="translate(0 0)">
<g
id="Grupo_1696"
data-name="Grupo 1696"
transform="translate(3.434)"
>
<path
id="Trazado_6841"
data-name="Trazado 6841"
d="M-502.661-53.081a1.054,1.054,0,0,0-.84-.432h-10.382a1.055,1.055,0,0,0-.84.432,1.272,1.272,0,0,0-.233.983l.178,1.038h7.843a1.894,1.894,0,0,1,1.509.776,2.21,2.21,0,0,1,.342.661h1.366l-.16.932h-1.107c-.005.058-.013.117-.023.175l-.518,3.021v0h1.1l-.16.932h-1.1l-.546,3.189-.005.032-.072.422h1.06a1.124,1.124,0,0,0,1.073-.975l.52-3.036c0-.006,0-.012,0-.018l.7-4.114,0-.012.518-3.024A1.271,1.271,0,0,0-502.661-53.081Z"
transform="translate(514.975 53.513)"
/>
</g>
<path
id="Trazado_6842"
data-name="Trazado 6842"
d="M-609.21,43.432a1.055,1.055,0,0,0-.84-.432h-10.382a1.054,1.054,0,0,0-.84.432,1.271,1.271,0,0,0-.233.983c.256,1.495.8,4.646,1.226,7.16a.035.035,0,0,0,0,.005l.521,3.04a1.124,1.124,0,0,0,1.073.975h6.886a1.124,1.124,0,0,0,1.073-.975l.52-3.036,0-.018.7-4.114s0-.008,0-.012l.518-3.024A1.271,1.271,0,0,0-609.21,43.432Zm-1.924,8.519-8.214.01-.16-.932,8.534-.01Zm.708-4.131-9.629.01-.16-.932,9.949-.01Z"
transform="translate(621.524 -39.595)"
/>
</g>
</svg>
</SvgIcon>
);
};
export default MultipleBucketsIcon;

View File

@@ -0,0 +1,33 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import * as React from "react";
import { SvgIcon, SvgIconProps } from "@mui/material";
const SelectMultipleIcon = (props: SvgIconProps) => {
return (
<SvgIcon {...props}>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">
<path
id="bulk-icon"
d="M16.5,16.5V14.356H14.357V16.5H16.5m-6.429,0V14.356H7.929V16.5h2.143m-6.429,0V14.356H1.5V16.5H3.643M16.5,10.071V7.929H14.357v2.143H16.5m-6.429,0V7.929H7.929v2.143h2.143m-6.429,0V7.929H1.5v2.143H3.643M16.5,3.643V1.5H14.357V3.643H16.5m-6.429,0V1.5H7.929V3.643h2.143m-6.429,0V1.5H1.5V3.643H3.643M17,18H13.857a1,1,0,0,1-1-1V13.857a1,1,0,0,1,1-1H17a1,1,0,0,1,1,1V17A1,1,0,0,1,17,18Zm-6.429,0H7.429a1,1,0,0,1-1-1V13.857a1,1,0,0,1,1-1h3.143a1,1,0,0,1,1,1V17A1,1,0,0,1,10.571,18ZM4.143,18H1a1,1,0,0,1-1-1V13.857a1,1,0,0,1,1-1H4.143a1,1,0,0,1,1,1V17A1,1,0,0,1,4.143,18ZM17,11.571H13.857a1,1,0,0,1-1-1V7.429a1,1,0,0,1,1-1H17a1,1,0,0,1,1,1v3.143A1,1,0,0,1,17,11.571Zm-6.429,0H7.429a1,1,0,0,1-1-1V7.429a1,1,0,0,1,1-1h3.143a1,1,0,0,1,1,1v3.143A1,1,0,0,1,10.571,11.571Zm-6.429,0H1a1,1,0,0,1-1-1V7.429a1,1,0,0,1,1-1H4.143a1,1,0,0,1,1,1v3.143A1,1,0,0,1,4.143,11.571ZM17,5.143H13.857a1,1,0,0,1-1-1V1a1,1,0,0,1,1-1H17a1,1,0,0,1,1,1V4.143A1,1,0,0,1,17,5.143Zm-6.429,0H7.429a1,1,0,0,1-1-1V1a1,1,0,0,1,1-1h3.143a1,1,0,0,1,1,1V4.143A1,1,0,0,1,10.571,5.143Zm-6.429,0H1a1,1,0,0,1-1-1V1A1,1,0,0,1,1,0H4.143a1,1,0,0,1,1,1V4.143A1,1,0,0,1,4.143,5.143Z"
/>
</svg>
</SvgIcon>
);
};
export default SelectMultipleIcon;

View File

@@ -55,6 +55,7 @@ export { default as DocumentationIcon } from "./DocumentationIcon";
export { default as TrashIcon } from "./TrashIcon";
export { default as DownloadIcon } from "./DownloadIcon";
export { default as AllBucketsIcon } from "./AllBucketsIcon";
export { default as SelectMultipleIcon } from "./SelectMultipleIcon";
export { default as GroupsIcon } from "./GroupsIcon";
export { default as TenantsIcon } from "./TenantsIcon";
export { default as UploadFile } from "./UploadFile";

View File

@@ -356,32 +356,30 @@ const BucketDetails = ({
S3_DELETE_BUCKET,
S3_FORCE_DELETE_BUCKET,
]) && (
<Tooltip title={"Delete"}>
<BoxIconButton
color="primary"
aria-label="Delete"
onClick={() => {
setDeleteOpen(true);
}}
size="large"
>
<DeleteIcon />
</BoxIconButton>
</Tooltip>
)}
<Tooltip title={"Refresh"}>
<BoxIconButton
tooltip={"Delete"}
color="primary"
aria-label="Refresh List"
aria-label="Delete"
onClick={() => {
setBucketDetailsLoad(true);
setDeleteOpen(true);
}}
size="large"
variant={"contained"}
>
<RefreshIcon />
<DeleteIcon />
</BoxIconButton>
</Tooltip>
)}
<BoxIconButton
tooltip={"Refresh"}
color="primary"
aria-label="Refresh List"
onClick={() => {
setBucketDetailsLoad(true);
}}
size="large"
variant={"contained"}
>
<RefreshIcon />
</BoxIconButton>
</Fragment>
}
/>

View File

@@ -14,42 +14,37 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import { Link } from "react-router-dom";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import {
ArrowRightIcon,
BucketsIcon,
CalendarIcon,
LockIcon,
ReportedUsageIcon,
SettingsIcon,
TotalObjectsIcon,
} from "../../../../icons";
import { Bucket } from "../types";
import {
Box,
Button,
Card,
CardContent,
CardHeader,
Grid,
Typography,
} from "@mui/material";
import { Box, Button, Grid, Typography } from "@mui/material";
import { niceBytes, prettyNumber } from "../../../../common/utils";
import CheckboxWrapper from "../../Common/FormComponents/CheckboxWrapper/CheckboxWrapper";
import { Link } from "react-router-dom";
const styles = (theme: Theme) =>
createStyles({
root: {
marginBottom: 30,
border: 0,
borderRadius: 10,
padding: 20,
color: theme.palette.primary.main,
boxShadow: "0px 0px 15px #00000029",
border: "#E5E5E5 1px solid",
borderRadius: 2,
"& .MuiSvgIcon-root": {
height: 13,
height: 14,
width: 14,
marginRight: 4,
},
"& .MuiTypography-body2": {
fontSize: 14,
},
"& .MuiCardHeader-content": {
wordWrap: "break-word",
@@ -90,7 +85,7 @@ const styles = (theme: Theme) =>
viewButton: {
width: 111,
color: "white",
backgroundColor: "#C83B51",
marginLeft: 8,
fontSize: 12,
fontWeight: "normal",
boxShadow: "unset",
@@ -115,18 +110,29 @@ const styles = (theme: Theme) =>
marginBottom: 4,
},
metricLabel: {
fontSize: 16,
fontSize: 14,
fontWeight: "bold",
},
metricText: {
fontSize: 50,
fontSize: 24,
fontWeight: "bold",
marginBottom: 10,
},
unit: {
fontSize: 12,
fontWeight: "normal",
},
bucketName: {
padding: 0,
margin: 0,
fontSize: 22,
},
bucketIcon: {
"& .MuiSvgIcon-root": {
height: 48,
width: 48,
fontSize: 48,
},
},
});
interface IBucketListItem {
@@ -165,105 +171,106 @@ const BucketListItem = ({
};
return (
<Card className={classes.root}>
<CardHeader
disableTypography={true}
title={
<Typography variant={"body1"}>
{bulkSelect && (
<div
className={classes.checkBoxElement}
onClick={(e) => {
e.stopPropagation();
}}
>
<CheckboxWrapper
checked={selected}
id={`select-${bucket.name}`}
label={""}
name={`select-${bucket.name}`}
onChange={onCheckboxClick}
value={bucket.name}
/>
</div>
)}
<BucketsIcon />
{bucket.name}
</Typography>
}
/>
<CardContent>
<Grid container>
<Grid item xs={12} sm={8} md={10}>
<Grid container className={classes.root} spacing={1}>
<Grid item xs={12}>
<Grid container justifyContent={"space-between"}>
<Grid item xs={12} sm={8}>
<Grid container>
<Grid item xs={12} md={6}>
<Typography variant="body2">
<CalendarIcon /> Created: <b>{bucket.creation_date}</b>
</Typography>
<Typography variant="body2">
<LockIcon /> Access: <b> {accessToStr(bucket)}</b>
</Typography>
<Grid item xs={12}>
{bulkSelect && (
<div
className={classes.checkBoxElement}
onClick={(e) => {
e.stopPropagation();
}}
>
<CheckboxWrapper
checked={selected}
id={`select-${bucket.name}`}
label={""}
name={`select-${bucket.name}`}
onChange={onCheckboxClick}
value={bucket.name}
/>
</div>
)}
<h1 className={classes.bucketName}>{bucket.name}</h1>
</Grid>
<Grid item xs={6} md={3}>
<Typography variant="body1" className={classes.metricLabel}>
<ReportedUsageIcon /> USAGE
</Typography>
<div className={classes.metricText}>
{usageScalar}
<span className={classes.unit}>{usageUnit}</span>
</div>
</Grid>
<Grid item xs={6} md={3}>
<Typography variant="body1" className={classes.metricLabel}>
<TotalObjectsIcon /> OBJECTS
</Typography>
<div className={classes.metricText}>
{bucket.objects ? prettyNumber(bucket.objects) : 0}
</div>
<Grid item xs={12}>
<Grid container>
<Grid item xs={12} sm>
<Typography variant="body2">
Created: <b>{bucket.creation_date}</b>
</Typography>
</Grid>
<Grid item xs={12} sm>
<Typography variant="body2">
Access: <b> {accessToStr(bucket)}</b>
</Typography>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid item xs={12} sm={4} md={2} className={classes.buttonTray}>
<Grid container>
<Grid item xs={6} sm={12} md={12}>
<Link
to={`/buckets/${bucket.name}/browse`}
style={{ textDecoration: "none" }}
<Grid item xs={12} sm={4} textAlign={"right"}>
{bucket.manage && (
<Link
to={`/buckets/${bucket.name}/admin`}
style={{ textDecoration: "none" }}
>
<Button
variant={"outlined"}
endIcon={<SettingsIcon />}
className={classes.manageButton}
>
<Button
variant="contained"
endIcon={<ArrowRightIcon />}
className={classes.viewButton}
>
Browse
</Button>
</Link>
<Box display={{ xs: "none", sm: "block" }}>
<div style={{ marginBottom: 10 }} />
</Box>
</Grid>
{bucket.manage && (
<Grid item xs={6} sm={12} md={12}>
<Link
to={`/buckets/${bucket.name}/admin`}
style={{ textDecoration: "none" }}
>
<Button
variant={"outlined"}
endIcon={<SettingsIcon />}
className={classes.manageButton}
>
Manage
</Button>
</Link>
</Grid>
)}
</Grid>
Manage
</Button>
</Link>
)}
<Link
to={`/buckets/${bucket.name}/browse`}
style={{ textDecoration: "none" }}
>
<Button
variant="contained"
endIcon={<ArrowRightIcon />}
className={classes.viewButton}
>
Browse
</Button>
</Link>
<Box display={{ xs: "none", sm: "block" }}>
<div style={{ marginBottom: 10 }} />
</Box>
</Grid>
</Grid>
</CardContent>
</Card>
</Grid>
<Grid item xs={12}>
<hr />
</Grid>
<Grid item xs={12}>
<Grid container justifyContent={"flex-start"} spacing={4}>
<Grid item className={classes.bucketIcon}>
<BucketsIcon />
</Grid>
<Grid item textAlign={"left"}>
<ReportedUsageIcon />
<span className={classes.metricLabel}>Usage</span>
<div className={classes.metricText}>
{usageScalar}
<span className={classes.unit}>{usageUnit}</span>
</div>
</Grid>
<Grid item textAlign={"left"}>
<TotalObjectsIcon />
<span className={classes.metricLabel}>Objects</span>
<div className={classes.metricText}>
{bucket.objects ? prettyNumber(bucket.objects) : 0}
</div>
</Grid>
</Grid>
</Grid>
</Grid>
);
};

View File

@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState, useEffect, Fragment } from "react";
import React, { Fragment, useEffect, useState } from "react";
import { connect } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
@@ -29,7 +29,7 @@ import {
wizardCommon,
} from "../../Common/FormComponents/common/styleLibrary";
import { setModalErrorSnackMessage } from "../../../../actions";
import { BulkReplicationResponse, BulkReplicationItem } from "../types";
import { BulkReplicationItem, BulkReplicationResponse } from "../types";
import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import ModalWrapper from "../../Common/ModalWrapper/ModalWrapper";
import PredefinedList from "../../Common/FormComponents/PredefinedList/PredefinedList";

View File

@@ -21,9 +21,8 @@ import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Button, LinearProgress } from "@mui/material";
import Grid from "@mui/material/Grid";
import FileCopyIcon from "@mui/icons-material/FileCopy";
import { Bucket, BucketList, HasPermissionResponse } from "../types";
import { AddIcon, BucketsIcon, WatchIcon } from "../../../../icons";
import { AddIcon, BucketsIcon } from "../../../../icons";
import { AppState } from "../../../../store";
import { setErrorSnackMessage } from "../../../../actions";
import {
@@ -44,6 +43,8 @@ import SearchIcon from "../../../../icons/SearchIcon";
import BoxIconButton from "../../Common/BoxIconButton/BoxIconButton";
import RefreshIcon from "../../../../icons/RefreshIcon";
import AButton from "../../Common/AButton/AButton";
import MultipleBucketsIcon from "../../../../icons/MultipleBucketsIcon";
import SelectMultipleIcon from "../../../../icons/SelectMultipleIcon";
const styles = (theme: Theme) =>
createStyles({
@@ -306,32 +307,32 @@ const ListBuckets = ({
/>
</Grid>
<Grid item xs={12} sm={"auto"}>
<Button
<BoxIconButton
variant={bulkSelect ? "contained" : "outlined"}
tooltip={"Select Multiple"}
onClick={() => {
setBulkSelect(!bulkSelect);
}}
endIcon={<WatchIcon />}
size={"small"}
className={classes.bulkSelect}
>
Bulk Select
</Button>
<Button
<SelectMultipleIcon />
</BoxIconButton>
<BoxIconButton
variant="outlined"
endIcon={<FileCopyIcon />}
tooltip={"Set Replication"}
onClick={() => {
setReplicationModalOpen(true);
}}
disabled={selectedBuckets.length === 0}
size={"small"}
>
Set Replication
</Button>
<MultipleBucketsIcon />
</BoxIconButton>
<BoxIconButton
color="primary"
aria-label="Refresh List"
aria-label="Refresh"
tooltip={"Refresh"}
onClick={() => {
setLoading(true);
}}

View File

@@ -45,7 +45,7 @@ import {
objectBrowserCommon,
searchField,
} from "../../../../Common/FormComponents/common/styleLibrary";
import { Badge, Button, Tooltip, Typography } from "@mui/material";
import { Badge, Button, Typography } from "@mui/material";
import * as reactMoment from "react-moment";
import BrowserBreadcrumbs from "../../../../ObjectBrowser/BrowserBreadcrumbs";
import {
@@ -1087,35 +1087,32 @@ const ListObjects = ({
<Fragment>
{displayPutObject && (
<Fragment>
<Tooltip title={"Choose or create a new path"}>
<BoxIconButton
color="primary"
aria-label="Add a new folder"
onClick={() => {
setCreateFolderOpen(true);
}}
disabled={rewindEnabled}
size="large"
>
<AddFolderIcon />
</BoxIconButton>
</Tooltip>
<Tooltip title={"Upload file"}>
<BoxIconButton
color="primary"
aria-label="Refresh List"
onClick={() => {
if (fileUpload && fileUpload.current) {
fileUpload.current.click();
}
}}
disabled={rewindEnabled}
size="large"
>
<UploadIcon />
</BoxIconButton>
</Tooltip>
<BoxIconButton
tooltip={"Choose or create a new path"}
color="primary"
aria-label="Add a new folder"
onClick={() => {
setCreateFolderOpen(true);
}}
disabled={rewindEnabled}
size="large"
>
<AddFolderIcon />
</BoxIconButton>
<BoxIconButton
tooltip={"Upload file"}
color="primary"
aria-label="Refresh List"
onClick={() => {
if (fileUpload && fileUpload.current) {
fileUpload.current.click();
}
}}
disabled={rewindEnabled}
size="large"
>
<UploadIcon />
</BoxIconButton>
<input
type="file"
multiple={true}
@@ -1126,42 +1123,39 @@ const ListObjects = ({
/>
</Fragment>
)}
<Tooltip title={"Rewind"}>
<Badge
badgeContent=" "
color="secondary"
variant="dot"
invisible={!rewindEnabled}
className={classes.badgeOverlap}
>
<BoxIconButton
color="primary"
aria-label="Rewind"
onClick={() => {
setRewindSelect(true);
}}
disabled={!isVersioned}
size="large"
>
<HistoryIcon />
</BoxIconButton>
</Badge>
</Tooltip>
<Tooltip title={"Refresh list"}>
<Badge
badgeContent=" "
color="secondary"
variant="dot"
invisible={!rewindEnabled}
className={classes.badgeOverlap}
>
<BoxIconButton
tooltip={"Rewind"}
color="primary"
aria-label="Refresh List"
aria-label="Rewind"
onClick={() => {
setLoading(true);
setRewindSelect(true);
}}
disabled={rewindEnabled}
disabled={!isVersioned}
size="large"
variant={"contained"}
>
<RefreshIcon />
<HistoryIcon />
</BoxIconButton>
</Tooltip>
</Badge>
<BoxIconButton
tooltip={"Refresh list"}
color="primary"
aria-label="Refresh List"
onClick={() => {
setLoading(true);
}}
disabled={rewindEnabled}
size="large"
variant={"contained"}
>
<RefreshIcon />
</BoxIconButton>
</Fragment>
}
/>

View File

@@ -30,7 +30,6 @@ import {
TableBody,
TableCell,
TableRow,
Tooltip,
} from "@mui/material";
import Grid from "@mui/material/Grid";
import Chip from "@mui/material/Chip";
@@ -646,19 +645,18 @@ const ObjectDetails = ({
}
actions={
<Fragment>
<Tooltip title="Share">
<BoxIconButton
color="primary"
aria-label="share"
onClick={() => {
shareObject();
}}
disabled={actualInfo.is_delete_marker}
size="large"
>
<ShareIcon />
</BoxIconButton>
</Tooltip>
<BoxIconButton
tooltip={"Share"}
color="primary"
aria-label="share"
onClick={() => {
shareObject();
}}
disabled={actualInfo.is_delete_marker}
size="large"
>
<ShareIcon />
</BoxIconButton>
{downloadingFiles.includes(
`${bucketName}/${actualInfo.name}`
@@ -671,35 +669,32 @@ const ObjectDetails = ({
/>
</div>
) : (
<Tooltip title="Download">
<BoxIconButton
color="primary"
aria-label="download"
onClick={() => {
downloadObject(actualInfo);
}}
disabled={actualInfo.is_delete_marker}
size="large"
>
<DownloadIcon />
</BoxIconButton>
</Tooltip>
<BoxIconButton
tooltip={"Download"}
color="primary"
aria-label="download"
onClick={() => {
downloadObject(actualInfo);
}}
disabled={actualInfo.is_delete_marker}
size="large"
>
<DownloadIcon />
</BoxIconButton>
)}
{displayDeleteObject && (
<Tooltip title="Delete Object">
<BoxIconButton
color="primary"
aria-label="delete"
onClick={() => {
setDeleteOpen(true);
}}
disabled={actualInfo.is_delete_marker}
size="large"
>
<DeleteIcon />
</BoxIconButton>
</Tooltip>
<BoxIconButton
tooltip={"Delete Object"}
color="primary"
aria-label="delete"
onClick={() => {
setDeleteOpen(true);
}}
disabled={actualInfo.is_delete_marker}
size="large"
>
<DeleteIcon />
</BoxIconButton>
)}
</Fragment>
}

View File

@@ -18,7 +18,7 @@ import React from "react";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { IconButton, IconButtonProps } from "@mui/material";
import { IconButton, IconButtonProps, Tooltip } from "@mui/material";
import clsx from "clsx";
const styles = (theme: Theme) =>
@@ -64,15 +64,17 @@ interface IBoxIconButton extends IconButtonProps {
classes: any;
children: any;
variant?: "outlined" | "contained";
tooltip?: string;
}
const BoxIconButton = ({
classes,
children,
variant = "outlined",
tooltip,
...rest
}: IBoxIconButton) => {
return (
const button = (
<IconButton
{...rest}
className={clsx(classes.root, {
@@ -82,6 +84,16 @@ const BoxIconButton = ({
{children}
</IconButton>
);
if (tooltip && tooltip !== "") {
return (
<Tooltip title={tooltip}>
<span>{button}</span>
</Tooltip>
);
}
return button;
};
export default withStyles(styles)(BoxIconButton);

View File

@@ -27,7 +27,7 @@ import {
} from "../Common/FormComponents/common/styleLibrary";
import Paper from "@mui/material/Paper";
import Grid from "@mui/material/Grid";
import { Button, LinearProgress, Tooltip } from "@mui/material";
import { Button, LinearProgress } from "@mui/material";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import api from "../../../common/api";
import PageHeader from "../Common/PageHeader/PageHeader";
@@ -373,30 +373,27 @@ const PolicyDetails = ({
subTitle={<Fragment>IAM Policy</Fragment>}
actions={
<Fragment>
<Tooltip title="Delete Policy">
<BoxIconButton
color="primary"
aria-label="Delete Policy"
onClick={deletePolicy}
>
<TrashIcon />
</BoxIconButton>
</Tooltip>
<Tooltip title={"Refresh"}>
<BoxIconButton
color="primary"
aria-label="Refresh List"
onClick={() => {
setLoadingUsers(true);
setLoadingGroups(true);
setLoadingPolicy(true);
}}
size="large"
>
<RefreshIcon />
</BoxIconButton>
</Tooltip>
<BoxIconButton
tooltip={"Delete Policy"}
color="primary"
aria-label="Delete Policy"
onClick={deletePolicy}
>
<TrashIcon />
</BoxIconButton>
<BoxIconButton
tooltip={"Refresh"}
color="primary"
aria-label="Refresh List"
onClick={() => {
setLoadingUsers(true);
setLoadingGroups(true);
setLoadingPolicy(true);
}}
size="large"
>
<RefreshIcon />
</BoxIconButton>
</Fragment>
}
/>

View File

@@ -20,7 +20,6 @@ import { Link, Redirect, Route, Router, Switch } from "react-router-dom";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Tooltip } from "@mui/material";
import get from "lodash/get";
import Grid from "@mui/material/Grid";
import { setErrorSnackMessage, setSnackBarMessage } from "../../../../actions";
@@ -325,41 +324,38 @@ const TenantDetails = ({
}
actions={
<div>
<Tooltip title={"Delete"}>
<BoxIconButton
color="primary"
aria-label="Delete"
onClick={() => {
confirmDeleteTenant();
}}
size="large"
>
<DeleteIcon />
</BoxIconButton>
</Tooltip>
<Tooltip title={"Edit YAML"}>
<BoxIconButton
color="primary"
aria-label="Edit YAML"
onClick={() => {
editYaml();
}}
size="large"
>
<EditIcon />
</BoxIconButton>
</Tooltip>
<Tooltip title={"Refresh"}>
<BoxIconButton
color="primary"
aria-label="Refresh List"
onClick={() => {
setTenantDetailsLoad(true);
}}
>
<RefreshIcon />
</BoxIconButton>
</Tooltip>
<BoxIconButton
tooltip={"Delete"}
color="primary"
aria-label="Delete"
onClick={() => {
confirmDeleteTenant();
}}
size="large"
>
<DeleteIcon />
</BoxIconButton>
<BoxIconButton
tooltip={"Edit YAML"}
color="primary"
aria-label="Edit YAML"
onClick={() => {
editYaml();
}}
size="large"
>
<EditIcon />
</BoxIconButton>
<BoxIconButton
tooltip={"Refresh"}
color="primary"
aria-label="Refresh List"
onClick={() => {
setTenantDetailsLoad(true);
}}
>
<RefreshIcon />
</BoxIconButton>
</div>
}
/>

View File

@@ -21,7 +21,7 @@ import { Link } from "react-router-dom";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Button, Grid, Tooltip } from "@mui/material";
import { Button, Grid } from "@mui/material";
import {
AddIcon,
DeleteIcon,
@@ -319,27 +319,24 @@ const UserDetails = ({ classes, match }: IUserDetailsProps) => {
}}
switchOnly
/>
<Tooltip title="Delete User">
<BoxIconButton
color="primary"
aria-label="Delete User"
onClick={deleteUser}
size="large"
>
<DeleteIcon />
</BoxIconButton>
</Tooltip>
<Tooltip title="Change Password">
<BoxIconButton
color="primary"
aria-label="Change Password"
onClick={changeUserPassword}
size="large"
>
<LockIcon />
</BoxIconButton>
</Tooltip>
<BoxIconButton
tooltip={"Delete User"}
color="primary"
aria-label="Delete User"
onClick={deleteUser}
size="large"
>
<DeleteIcon />
</BoxIconButton>
<BoxIconButton
tooltip={"Change Password"}
color="primary"
aria-label="Change Password"
onClick={changeUserPassword}
size="large"
>
<LockIcon />
</BoxIconButton>
</Fragment>
}
/>