Match button's height. Remove Margin+Padding on Panel Titles. Move List bucket Buttons. (#1191)

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
Daniel Valdivia
2021-11-04 15:29:31 -07:00
committed by GitHub
parent 6e3c0bdc49
commit 9b06748cef
16 changed files with 231 additions and 195 deletions

View File

@@ -21,9 +21,9 @@ import Routes from "./Routes";
import configureStore from "./store";
import * as serviceWorker from "./serviceWorker";
import {
ThemeProvider,
Theme,
StyledEngineProvider,
Theme,
ThemeProvider,
} from "@mui/material/styles";
import withStyles from "@mui/styles/withStyles";
import "react-virtualized/styles.css";
@@ -42,10 +42,13 @@ const GlobalCss = withStyles({
// @global is handled by jss-plugin-global.
"@global": {
// You should target [class*="MuiButton-root"] instead if you nest themes.
".MuiButton-root": {
height: 38,
},
".MuiButton-contained": {
fontSize: "14px",
textTransform: "capitalize",
padding: "16px 25px 16px 25px",
padding: "15px 25px 15px 25px",
borderRadius: 3,
},
".MuiButton-sizeSmall": {

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, { useEffect, useState, 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";
@@ -40,6 +40,7 @@ import {
ADMIN_LIST_USER_POLICIES,
ADMIN_LIST_USERS,
} from "../../../../types";
import PanelTitle from "../../Common/PanelTitle";
const styles = (theme: Theme) => createStyles({});
@@ -159,7 +160,7 @@ const AccessDetails = ({
return (
<Fragment>
<h1 className={classes.sectionTitle}>Access Audit</h1>
<PanelTitle>Access Audit</PanelTitle>
<Tabs
value={curTab}
onChange={(e: React.ChangeEvent<{}>, newValue: number) => {

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, { useEffect, useState, 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";
@@ -40,6 +40,7 @@ import {
import { BucketInfo } from "../types";
import { displayComponent } from "../../../../utils/permissions";
import { S3_GET_BUCKET_POLICY, S3_PUT_BUCKET_POLICY } from "../../../../types";
import PanelTitle from "../../Common/PanelTitle";
const styles = (theme: Theme) =>
createStyles({
@@ -240,7 +241,7 @@ const AccessRule = ({
/>
)}
<Grid item xs={12} className={classes.actionsTray}>
<h1 className={classes.sectionTitle}>Access Rules</h1>
<PanelTitle>Access Rules</PanelTitle>
{displayAddAccessRules && (
<Button
variant="contained"
@@ -256,9 +257,6 @@ const AccessRule = ({
</Button>
)}
</Grid>
<Grid item xs={12}>
<br />
</Grid>
<Paper>
<TableWrapper
disabled={!displayAccessRules}

View File

@@ -42,6 +42,7 @@ import {
S3_GET_BUCKET_NOTIFICATIONS,
S3_PUT_BUCKET_NOTIFICATIONS,
} from "../../../../types";
import PanelTitle from "../../Common/PanelTitle";
const styles = (theme: Theme) =>
createStyles({
@@ -157,7 +158,7 @@ const BucketEventsPanel = ({
<Grid container>
<Grid item xs={12} className={classes.actionsTray}>
<h1 className={classes.sectionTitle}>Events</h1>
<PanelTitle>Events</PanelTitle>
{displaySubscribeToEvents && (
<Button
variant="contained"

View File

@@ -41,10 +41,9 @@ import { displayComponent } from "../../../../utils/permissions";
import {
ADMIN_LIST_TIERS,
S3_GET_LIFECYCLE_CONFIGURATION,
S3_GET_REPLICATION_CONFIGURATION,
S3_PUT_LIFECYCLE_CONFIGURATION,
S3_PUT_REPLICATION_CONFIGURATION,
} from "../../../../types";
import PanelTitle from "../../Common/PanelTitle";
const styles = (theme: Theme) =>
createStyles({
@@ -207,7 +206,7 @@ const BucketLifecyclePanel = ({
)}
<Grid container>
<Grid item xs={12} className={classes.actionsTray}>
<h1 className={classes.sectionTitle}>Lifecycle Rules</h1>
<PanelTitle>Lifecycle Rules</PanelTitle>
{displayAddLifeCycleRules && (
<Button
variant="contained"

View File

@@ -32,7 +32,6 @@ import {
BucketReplication,
BucketReplicationDestination,
BucketReplicationRule,
HasPermissionResponse,
} from "../types";
import { ErrorResponseHandler } from "../../../../common/types";
import { AppState } from "../../../../store";
@@ -43,12 +42,10 @@ import DeleteReplicationRule from "./DeleteReplicationRule";
import HelpBox from "../../../../common/HelpBox";
import { displayComponent } from "../../../../utils/permissions";
import {
ADMIN_SERVER_INFO,
S3_GET_BUCKET_NOTIFICATIONS,
S3_GET_REPLICATION_CONFIGURATION,
S3_PUT_BUCKET_NOTIFICATIONS,
S3_PUT_REPLICATION_CONFIGURATION,
} from "../../../../types";
import PanelTitle from "../../Common/PanelTitle";
interface IBucketReplicationProps {
classes: any;
@@ -179,7 +176,7 @@ const BucketReplicationPanel = ({
)}
<Grid container>
<Grid item xs={12} className={classes.actionsTray}>
<h1 className={classes.sectionTitle}>Replication</h1>
<PanelTitle>Replication</PanelTitle>
{displayAddReplicationRules && (
<Button
variant="contained"

View File

@@ -68,6 +68,7 @@ import {
S3_PUT_BUCKET_VERSIONING,
S3_PUT_OBJECT_RETENTION,
} from "../../../../types";
import PanelTitle from "../../Common/PanelTitle";
interface IBucketSummaryProps {
classes: any;
@@ -483,7 +484,7 @@ const BucketSummary = ({
)}
<Grid container>
<Grid item xs={12} className={classes.actionsTray}>
<h1 className={classes.sectionTitle}>Summary</h1>
<PanelTitle>Summary</PanelTitle>
</Grid>
</Grid>
<Paper className={classes.paperContainer}>

View File

@@ -19,10 +19,8 @@ import { connect } from "react-redux";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Box, Button, LinearProgress } from "@mui/material";
import { Button, LinearProgress } from "@mui/material";
import Grid from "@mui/material/Grid";
import TextField from "@mui/material/TextField";
import InputAdornment from "@mui/material/InputAdornment";
import FileCopyIcon from "@mui/icons-material/FileCopy";
import { Bucket, BucketList, HasPermissionResponse } from "../types";
import { AddIcon, BucketsIcon, WatchIcon } from "../../../../icons";
@@ -32,6 +30,7 @@ import { setErrorSnackMessage } from "../../../../actions";
import {
containerForHeader,
linkStyles,
searchField,
} from "../../Common/FormComponents/common/styleLibrary";
import { ErrorResponseHandler } from "../../../../common/types";
import api from "../../../../common/api";
@@ -40,9 +39,13 @@ import DeleteBucket from "./DeleteBucket";
import PageHeader from "../../Common/PageHeader/PageHeader";
import BucketListItem from "./BucketListItem";
import BulkReplicationModal from "./BulkReplicationModal";
import SearchIcon from "../../../../icons/SearchIcon";
import HelpBox from "../../../../common/HelpBox";
import { ISessionResponse } from "../../types";
import TextField from "@mui/material/TextField";
import InputAdornment from "@mui/material/InputAdornment";
import SearchIcon from "../../../../icons/SearchIcon";
import BoxIconButton from "../../Common/BoxIconButton";
import RefreshIcon from "../../../../icons/RefreshIcon";
const styles = (theme: Theme) =>
createStyles({
@@ -78,13 +81,14 @@ const styles = (theme: Theme) =>
borderColor: theme.palette.grey["300"],
color: theme.palette.grey["300"],
textTransform: "capitalize",
marginRight: 6,
marginLeft: 8,
},
"& .MuiButton-contained": {
color: "white",
},
},
bulkSelect: {
marginLeft: 8,
"&:hover": {
backgroundColor: theme.palette.primary.main,
},
@@ -98,7 +102,7 @@ const styles = (theme: Theme) =>
fontWeight: "bold",
},
addBucket: {
marginRight: 8,
marginLeft: 8,
},
theaderSearch: {
borderColor: theme.palette.grey["200"],
@@ -123,6 +127,7 @@ const styles = (theme: Theme) =>
marginLeft: 10,
},
...containerForHeader(theme.spacing(4)),
...searchField,
constrainedContainer: {
maxWidth: 1180,
},
@@ -301,163 +306,154 @@ const ListBuckets = ({
closeModalAndRefresh={closeBulkReplicationModal}
/>
)}
<PageHeader
label={"Buckets"}
actions={
<Fragment>
<Grid
container
direction="row"
justifyContent="flex-end"
alignItems="center"
className={classes.actionHeaderItems}
>
<Box display={{ xs: "none", sm: "none", md: "block" }}>
<Grid item>
<div className={classes.theaderSearchLabel}>
Search Buckets:
</div>
</Grid>
</Box>
<Box display={{ xs: "block", sm: "block", md: "none" }}>
<TextField
className={classes.theaderSearch}
variant={"outlined"}
id="search-resource"
placeholder={"Filter Buckets"}
onChange={(val) => {
setFilterBuckets(val.target.value);
}}
inputProps={{
disableUnderline: true,
endadornment: (
<InputAdornment position="end">
<SearchIcon />
</InputAdornment>
),
}}
/>
</Box>
<Box display={{ xs: "none", sm: "none", md: "block" }}>
<TextField
className={classes.theaderSearch}
variant={"outlined"}
id="search-resource"
onChange={(val) => {
setFilterBuckets(val.target.value);
}}
inputProps={{
disableUnderline: true,
endadornment: (
<InputAdornment position="end">
<SearchIcon />
</InputAdornment>
),
}}
/>
</Box>
<PageHeader label={"Buckets"} />
<Grid container className={classes.container}>
<Grid item xs={12} className={classes.buttonTray}>
<Grid container>
<Grid item xs={12} sm>
<TextField
placeholder="Filter Buckets"
className={classes.searchField}
id="search-resource"
label=""
InputProps={{
disableUnderline: true,
startAdornment: (
<InputAdornment position="start">
<SearchIcon />
</InputAdornment>
),
}}
onChange={(e) => {
setFilterBuckets(e.target.value);
}}
variant="standard"
/>
</Grid>
<Grid item xs={12} sm={"auto"}>
<Button
variant={bulkSelect ? "contained" : "outlined"}
onClick={() => {
setBulkSelect(!bulkSelect);
}}
endIcon={<WatchIcon />}
size={"small"}
className={classes.bulkSelect}
>
Bulk Select
</Button>
<Button
variant="outlined"
endIcon={<FileCopyIcon />}
onClick={() => {
setReplicationModalOpen(true);
}}
disabled={selectedBuckets.length === 0}
size={"small"}
>
Set Replication
</Button>
<BoxIconButton
color="primary"
aria-label="Refresh List"
onClick={() => {
setLoading(true);
}}
size="large"
>
<RefreshIcon />
</BoxIconButton>
{canCreateBucket && (
<Grid item>
<Button
variant="contained"
color="primary"
endIcon={<AddIcon />}
onClick={() => {
addBucketOpen(true);
}}
className={classes.addBucket}
>
Create Bucket
</Button>
</Grid>
)}
</Grid>
</Fragment>
}
/>
<Grid container>
<Grid item xs={12} className={classes.container}>
<Grid item xs={12} className={classes.buttonTray}>
<Button
variant={bulkSelect ? "contained" : "outlined"}
onClick={() => {
setBulkSelect(!bulkSelect);
}}
endIcon={<WatchIcon />}
size={"small"}
className={classes.bulkSelect}
>
Bulk Select
</Button>
<Button
variant="outlined"
endIcon={<FileCopyIcon />}
onClick={() => {
setReplicationModalOpen(true);
}}
disabled={selectedBuckets.length === 0}
size={"small"}
>
Set Replication
</Button>
</Grid>
<Grid item xs={12}>
<br />
</Grid>
{loading && <LinearProgress />}
{!loading && (
<Grid item xs={12}>
{filteredRecords.map((bucket, index) => {
return (
<BucketListItem
bucket={bucket}
key={`bucketListItem-${index.toString()}`}
onDelete={confirmDeleteBucket}
onSelect={selectListBuckets}
selected={selectedBuckets.includes(bucket.name)}
bulkSelect={bulkSelect}
/>
);
})}
{filteredRecords.length === 0 && (
<Grid
container
justifyContent={"center"}
alignContent={"center"}
alignItems={"center"}
<Button
variant="contained"
color="primary"
endIcon={<AddIcon />}
onClick={() => {
addBucketOpen(true);
}}
className={classes.addBucket}
>
<Grid item xs={8}>
<HelpBox
iconComponent={<BucketsIcon />}
title={"Buckets"}
help={
<Fragment>
MinIO uses buckets to organize objects. A bucket is
similar to a folder or directory in a filesystem,
where each bucket can hold an arbitrary number of
objects.
<br />
<br />
To get started,&nbsp;
<button
className={classes.link}
onClick={() => {
addBucketOpen(true);
}}
>
Create a Bucket.
</button>
</Fragment>
}
/>
</Grid>
</Grid>
Create Bucket
</Button>
)}
</Grid>
)}
</Grid>
</Grid>
<Grid item xs={12}>
<br />
</Grid>
{loading && <LinearProgress />}
{!loading && (
<Grid item xs={12}>
{filteredRecords.map((bucket, index) => {
return (
<BucketListItem
bucket={bucket}
key={`bucketListItem-${index.toString()}`}
onDelete={confirmDeleteBucket}
onSelect={selectListBuckets}
selected={selectedBuckets.includes(bucket.name)}
bulkSelect={bulkSelect}
/>
);
})}
{filteredRecords.length === 0 && filterBuckets !== "" && (
<Grid
container
justifyContent={"center"}
alignContent={"center"}
alignItems={"center"}
>
<Grid item xs={8}>
<HelpBox
iconComponent={<BucketsIcon />}
title={"No Results"}
help={
<Fragment>
No buckets match the filtering condition
</Fragment>
}
/>
</Grid>
</Grid>
)}
{filteredRecords.length === 0 && filterBuckets === "" && (
<Grid
container
justifyContent={"center"}
alignContent={"center"}
alignItems={"center"}
>
<Grid item xs={8}>
<HelpBox
iconComponent={<BucketsIcon />}
title={"Buckets"}
help={
<Fragment>
MinIO uses buckets to organize objects. A bucket is
similar to a folder or directory in a filesystem, where
each bucket can hold an arbitrary number of objects.
<br />
<br />
To get started,&nbsp;
<button
className={classes.link}
onClick={() => {
addBucketOpen(true);
}}
>
Create a Bucket.
</button>
</Fragment>
}
/>
</Grid>
</Grid>
)}
</Grid>
)}
</Grid>
</Fragment>
);

View File

@@ -24,7 +24,7 @@ const styles = (theme: Theme) =>
createStyles({
root: {
padding: 8,
marginLeft: 14,
marginLeft: 8,
borderWidth: 1,
borderColor: theme.palette.primary.main,
borderStyle: "solid",

View File

@@ -201,7 +201,7 @@ export const actionsTray = {
justifyContent: "space-between" as const,
"& button": {
flexGrow: 0,
marginLeft: 15,
marginLeft: 8,
},
},
filterContainer: {
@@ -222,9 +222,9 @@ export const actionsTray = {
export const searchField = {
searchField: {
flexGrow: 1,
height: 40,
height: 38,
background: "#FFFFFF",
borderRadius: 5,
borderRadius: 3,
border: "#EAEDEE 1px solid",
display: "flex",
justifyContent: "center",

View File

@@ -70,7 +70,7 @@ const PageHeader = ({
&nbsp;
</Grid>
</Box>
<Grid item xs={12} sm={12} md={3} className={classes.label}>
<Grid item xs={12} sm={12} md={6} className={classes.label}>
{!sidebarOpen && (
<div className={classes.logo}>
{operatorMode ? <OperatorLogo /> : <ConsoleLogo />}
@@ -81,7 +81,7 @@ const PageHeader = ({
</Typography>
</Grid>
{actions && (
<Grid item xs={12} sm={12} md={9} className={classes.rightMenu}>
<Grid item xs={12} sm={12} md={6} className={classes.rightMenu}>
{actions}
</Grid>
)}

View File

@@ -0,0 +1,40 @@
// 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 React from "react";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { IconButtonProps } from "@mui/material";
const styles = (theme: Theme) =>
createStyles({
root: {
padding: 0,
margin: 0,
},
});
interface IPanelTitle extends IconButtonProps {
classes: any;
children: any;
}
const PanelTitle = ({ classes, children }: IPanelTitle) => {
return <h1 className={classes.root}>{children}</h1>;
};
export default withStyles(styles)(PanelTitle);

View File

@@ -28,6 +28,7 @@ import SetPolicy from "../Policies/SetPolicy";
import AddGroupMember from "./AddGroupMember";
import { ErrorResponseHandler } from "../../../common/types";
import DeleteGroup from "./DeleteGroup";
import PanelTitle from "../Common/PanelTitle";
const styles = (theme: Theme) =>
createStyles({
@@ -219,7 +220,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
<Grid item xs={12}>
<TabPanel index={0} value={currentTab}>
<div className={classes.actionsTray}>
<h1 className={classes.sectionTitle}>Members</h1>
<PanelTitle>Members</PanelTitle>
<Button
variant="contained"
color="primary"
@@ -232,7 +233,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
{memberActionText}
</Button>
</div>
<br />
<TableWrapper
//itemActions={tableActions}
columns={[{ label: "Access Key", elementKey: "" }]}
@@ -247,7 +248,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
</TabPanel>
<TabPanel index={1} value={currentTab}>
<div className={classes.actionsTray}>
<h1 className={classes.sectionTitle}>Policies</h1>
<PanelTitle>Policies</PanelTitle>
<Button
variant="contained"
color="primary"
@@ -260,7 +261,7 @@ const GroupsDetails = ({ classes }: IGroupDetailsProps) => {
Set Policies
</Button>
</div>
<br />
<TableWrapper
itemActions={[
{

View File

@@ -251,7 +251,7 @@ const ListUsers = ({ classes, setErrorSnackMessage, history }: IUsersProps) => {
variant="standard"
/>
<Button
variant="contained"
variant="outlined"
color="primary"
startIcon={<GroupIcon />}
disabled={checkedUsers.length <= 0}

View File

@@ -55,6 +55,7 @@ import List from "@mui/material/List";
import LockIcon from "@mui/icons-material/Lock";
import ScreenTitle from "../Common/ScreenTitle/ScreenTitle";
import BoxIconButton from "../Common/BoxIconButton";
import PanelTitle from "../Common/PanelTitle";
const styles = (theme: Theme) =>
createStyles({
@@ -362,7 +363,7 @@ const UserDetails = ({ classes, match }: IUserDetailsProps) => {
<Grid item xs={12}>
<TabPanel index={0} value={curTab}>
<div className={classes.actionsTray}>
<h1 className={classes.sectionTitle}>Groups</h1>
<PanelTitle>Groups</PanelTitle>
<Button
variant="contained"
color="primary"
@@ -375,7 +376,6 @@ const UserDetails = ({ classes, match }: IUserDetailsProps) => {
Add to Groups
</Button>
</div>
<br />
<TableWrapper
// itemActions={userTableActions}
columns={[{ label: "Name", elementKey: "group" }]}
@@ -394,7 +394,7 @@ const UserDetails = ({ classes, match }: IUserDetailsProps) => {
</TabPanel>
<TabPanel index={2} value={curTab}>
<div className={classes.actionsTray}>
<h1 className={classes.sectionTitle}>Policies</h1>
<PanelTitle>Policies</PanelTitle>
<Button
variant="contained"
color="primary"
@@ -407,7 +407,6 @@ const UserDetails = ({ classes, match }: IUserDetailsProps) => {
Assign Policies
</Button>
</div>
<br />
<TableWrapper
itemActions={[
{

View File

@@ -35,6 +35,7 @@ import DeleteServiceAccount from "../Account/DeleteServiceAccount";
import CredentialsPrompt from "../Common/CredentialsPrompt/CredentialsPrompt";
import { AddIcon } from "../../../icons";
import Button from "@mui/material/Button";
import PanelTitle from "../Common/PanelTitle";
interface IUserServiceAccountsProps {
classes: any;
@@ -162,7 +163,7 @@ const UserServiceAccountsPanel = ({
/>
)}
<div className={classes.actionsTray}>
<h1 className={classes.sectionTitle}>Service Accounts</h1>
<PanelTitle>Service Accounts</PanelTitle>
<Button
variant="contained"
color="primary"
@@ -177,7 +178,6 @@ const UserServiceAccountsPanel = ({
Create service account
</Button>
</div>
<br />
<TableWrapper
isLoading={loading}
records={records}