Changed Styles & some routes for console menu (#2428)

Changed styles for menu
Changed Settings page title
Changed Service Account option to be Access Keys
Changed all Service Accounts labels to be Access keys in console

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
Alex
2022-11-07 17:32:10 -06:00
committed by GitHub
parent c929a71649
commit 55b25cb003
23 changed files with 315 additions and 178 deletions

View File

@@ -126,8 +126,8 @@ export const IAM_PAGES = {
GROUPS: "/identity/groups", GROUPS: "/identity/groups",
GROUPS_ADD: "/identity/groups/create-group", GROUPS_ADD: "/identity/groups/create-group",
GROUPS_VIEW: "/identity/groups/:groupName", GROUPS_VIEW: "/identity/groups/:groupName",
ACCOUNT: "/identity/account", ACCOUNT: "/access-keys",
ACCOUNT_ADD: "/identity/account/new-account", ACCOUNT_ADD: "/access-keys/new-account",
USER_SA_ACCOUNT_ADD: "/identity/users/new-user-sa/:userName", USER_SA_ACCOUNT_ADD: "/identity/users/new-user-sa/:userName",
POLICIES: "/identity/policies", POLICIES: "/identity/policies",

View File

@@ -40,14 +40,11 @@ const ServiceAccountCredentialsIcon = (props: SVGProps<SVGSVGElement>) => (
</defs> </defs>
<g <g
id="New_Service_Account_Created" id="New_Service_Account_Created"
data-name="New Service Account Created" data-name="New Access Key Created"
clipPath="url(#clip-New_Service_Account_Created)" clipPath="url(#clip-New_Service_Account_Created)"
> >
<rect width="256" height="256" fill="#fff" /> <rect width="256" height="256" fill="#fff" />
<g <g id="Create_Service_Account_Icon" data-name="Create Access Key Icon">
id="Create_Service_Account_Icon"
data-name="Create Service Account Icon"
>
<rect <rect
id="Rectángulo_1006" id="Rectángulo_1006"
data-name="Rectángulo 1006" data-name="Rectángulo 1006"

View File

@@ -138,7 +138,7 @@ const Account = () => {
const closeDeleteMultipleModalAndRefresh = (refresh: boolean) => { const closeDeleteMultipleModalAndRefresh = (refresh: boolean) => {
setDeleteMultipleOpen(false); setDeleteMultipleOpen(false);
if (refresh) { if (refresh) {
dispatch(setSnackBarMessage(`Service accounts deleted successfully.`)); dispatch(setSnackBarMessage(`Access keys deleted successfully.`));
setSelectedSAs([]); setSelectedSAs([]);
setLoading(true); setLoading(true);
} }
@@ -206,11 +206,11 @@ const Account = () => {
open={changePasswordModalOpen} open={changePasswordModalOpen}
closeModal={() => setChangePasswordModalOpen(false)} closeModal={() => setChangePasswordModalOpen(false)}
/> />
<PageHeader label="Service Accounts" /> <PageHeader label="Access Keys" />
<PageLayout> <PageLayout>
<Grid item={true} xs={12} className={classes.actionsTray}> <Grid item={true} xs={12} className={classes.actionsTray}>
<SearchBox <SearchBox
placeholder={"Search Service Accounts"} placeholder={"Search Access Keys"}
onChange={setFilter} onChange={setFilter}
overrideClass={classes.searchField} overrideClass={classes.searchField}
value={filter} value={filter}
@@ -254,7 +254,7 @@ const Account = () => {
onClick={() => { onClick={() => {
navigate(`${IAM_PAGES.ACCOUNT_ADD}`); navigate(`${IAM_PAGES.ACCOUNT_ADD}`);
}} }}
label={`Create service account`} label={`Create access key`}
icon={<AddIcon />} icon={<AddIcon />}
variant={"callAction"} variant={"callAction"}
/> />
@@ -265,9 +265,9 @@ const Account = () => {
<TableWrapper <TableWrapper
isLoading={loading} isLoading={loading}
records={filteredRecords} records={filteredRecords}
entityName={"Service Accounts"} entityName={"Access Keys"}
idField={""} idField={""}
columns={[{ label: "Service Account", elementKey: "" }]} columns={[{ label: "Access Key", elementKey: "" }]}
itemActions={tableActions} itemActions={tableActions}
selectedItems={selectedSAs} selectedItems={selectedSAs}
onSelect={(e) => selectSAs(e, setSelectedSAs, selectedSAs)} onSelect={(e) => selectSAs(e, setSelectedSAs, selectedSAs)}
@@ -276,20 +276,23 @@ const Account = () => {
</Grid> </Grid>
<Grid item xs={12} marginTop={"15px"}> <Grid item xs={12} marginTop={"15px"}>
<HelpBox <HelpBox
title={"Learn more about SERVICE ACCOUNTS"} title={"Learn more about ACCESS KEYS"}
iconComponent={<AccountIcon />} iconComponent={<AccountIcon />}
help={ help={
<Fragment> <Fragment>
MinIO service accounts are child identities of an authenticated MinIO access keys are child identities of an authenticated MinIO
MinIO user, including externally managed identities. Each user, including externally managed identities. Each access key
service account inherits its privileges based on the policies inherits its privileges based on the policies attached to its
attached to its parent user or those groups in which the parent parent user or those groups in which the parent user has
user has membership. Service accounts also support an optional membership. Access Keys also support an optional inline policy
inline policy which further restricts access to a subset of which further restricts access to a subset of actions and
actions and resources available to the parent user. resources available to the parent user.
<br /> <br />
<br /> <br />
You can learn more at our{" "} You can learn more at our{" "}
{
// TODO: Change this link once it is called access keys
}
<a <a
href="https://min.io/docs/minio/linux/administration/identity-access-management/minio-user-management.html?ref=con#service-accounts" href="https://min.io/docs/minio/linux/administration/identity-access-management/minio-user-management.html?ref=con#service-accounts"
target="_blank" target="_blank"

View File

@@ -80,18 +80,18 @@ const AddServiceAccountHelpBox = () => {
}} }}
> >
<HelpIconFilled /> <HelpIconFilled />
<div>Learn more about Service Accounts</div> <div>Learn more about Access Keys</div>
</Box> </Box>
<Box sx={{ fontSize: "14px", marginBottom: "15px" }}> <Box sx={{ fontSize: "14px", marginBottom: "15px" }}>
<Box sx={{ paddingBottom: "20px" }}> <Box sx={{ paddingBottom: "20px" }}>
<FeatureItem <FeatureItem
icon={<ServiceAccountIcon />} icon={<ServiceAccountIcon />}
description={`Create Service Accounts`} description={`Create Access Keys`}
/> />
<Box sx={{ paddingTop: "20px" }}> <Box sx={{ paddingTop: "20px" }}>
Service Accounts inherit the policies explicitly attached to the Access Keys inherit the policies explicitly attached to the parent
parent user, and the policies attached to each group in which the user, and the policies attached to each group in which the parent
parent user has membership. user has membership.
</Box> </Box>
</Box> </Box>
<Box sx={{ paddingBottom: "20px" }}> <Box sx={{ paddingBottom: "20px" }}>
@@ -102,13 +102,13 @@ const AddServiceAccountHelpBox = () => {
<Box sx={{ paddingTop: "10px" }}> <Box sx={{ paddingTop: "10px" }}>
Randomized access credentials are recommended, and provided by Randomized access credentials are recommended, and provided by
default. You may use your own custom Access Key and Secret Key by default. You may use your own custom Access Key and Secret Key by
replacing the default values. After creation of any Service Account, replacing the default values. After creation of any Access Key, you
you will be given the opportunity to view and download the account will be given the opportunity to view and download the account
credentials. credentials.
</Box> </Box>
<Box sx={{ paddingTop: "10px" }}> <Box sx={{ paddingTop: "10px" }}>
Service Accounts support programmatic access by applications. You Access Keys support programmatic access by applications. You cannot
cannot use a Service Account to log into the MinIO Console. use a Access Key to log into the MinIO Console.
</Box> </Box>
</Box> </Box>
<Box sx={{ paddingBottom: "20px" }}> <Box sx={{ paddingBottom: "20px" }}>
@@ -118,14 +118,13 @@ const AddServiceAccountHelpBox = () => {
/> />
<Box sx={{ paddingTop: "10px" }}> <Box sx={{ paddingTop: "10px" }}>
You can specify an optional JSON-formatted IAM policy to further You can specify an optional JSON-formatted IAM policy to further
restrict Service Account access to a subset of the actions and restrict Access Key access to a subset of the actions and resources
resources explicitly allowed for the parent user. Additional access explicitly allowed for the parent user. Additional access beyond
beyond that of the parent user cannot be implemented through these that of the parent user cannot be implemented through these
policies. policies.
</Box> </Box>
<Box sx={{ paddingTop: "10px" }}> <Box sx={{ paddingTop: "10px" }}>
You cannot modify the optional Service Account IAM policy after You cannot modify the optional Access Key IAM policy after saving.
saving.
</Box> </Box>
</Box> </Box>
</Box> </Box>

View File

@@ -149,12 +149,12 @@ const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
closeModal={() => { closeModal={() => {
closeCredentialsModal(); closeCredentialsModal();
}} }}
entity="Service Account" entity="Access Key"
/> />
)} )}
<Grid item xs={12}> <Grid item xs={12}>
<PageHeader <PageHeader
label={<BackLink to={IAM_PAGES.ACCOUNT} label={"Service Accounts"} />} label={<BackLink to={IAM_PAGES.ACCOUNT} label={"Access Keys"} />}
/> />
<PageLayout> <PageLayout>
<Box <Box
@@ -171,7 +171,7 @@ const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
> >
<Box> <Box>
<SectionTitle icon={<ServiceAccountCredentialsIcon />}> <SectionTitle icon={<ServiceAccountCredentialsIcon />}>
Create Service Account Create Access Key
</SectionTitle> </SectionTitle>
<form <form
@@ -256,7 +256,7 @@ const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
}} }}
label={"Restrict beyond user policy"} label={"Restrict beyond user policy"}
tooltip={ tooltip={
"You can specify an optional JSON-formatted IAM policy to further restrict Service Account access to a subset of the actions and resources explicitly allowed for the parent user. Additional access beyond that of the parent user cannot be implemented through these policies." "You can specify an optional JSON-formatted IAM policy to further restrict Access Key access to a subset of the actions and resources explicitly allowed for the parent user. Additional access beyond that of the parent user cannot be implemented through these policies."
} }
/> />
</Grid> </Grid>
@@ -271,7 +271,7 @@ const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
<div> <div>
<PanelTitle> <PanelTitle>
Current User Policy - edit the JSON to remove Current User Policy - edit the JSON to remove
permissions for this service account permissions for this Access Key
</PanelTitle> </PanelTitle>
</div> </div>
<Grid item xs={12} className={classes.formScrollable}> <Grid item xs={12} className={classes.formScrollable}>

View File

@@ -72,7 +72,7 @@ const DeleteServiceAccount = ({
return ( return (
<ConfirmDialog <ConfirmDialog
title={`Delete Service Account`} title={`Delete Access Key`}
confirmText={"Delete"} confirmText={"Delete"}
isOpen={deleteOpen} isOpen={deleteOpen}
titleIcon={<ConfirmDeleteIcon />} titleIcon={<ConfirmDeleteIcon />}
@@ -81,7 +81,7 @@ const DeleteServiceAccount = ({
onClose={onClose} onClose={onClose}
confirmationContent={ confirmationContent={
<DialogContentText> <DialogContentText>
Are you sure you want to delete service account{" "} Are you sure you want to delete Access Key{" "}
<b className={classes.wrapText}>{selectedServiceAccount}</b>? <b className={classes.wrapText}>{selectedServiceAccount}</b>?
</DialogContentText> </DialogContentText>
} }

View File

@@ -112,7 +112,7 @@ const ServiceAccountPolicy = ({
return ( return (
<ModalWrapper <ModalWrapper
title="Service Account Policy" title="Access Key Policy"
modalOpen={open} modalOpen={open}
onClose={() => { onClose={() => {
closeModalAndRefresh(); closeModalAndRefresh();
@@ -129,7 +129,7 @@ const ServiceAccountPolicy = ({
<Grid container> <Grid container>
<Grid item xs={12} className={classes.codeMirrorContainer}> <Grid item xs={12} className={classes.codeMirrorContainer}>
<CodeMirrorWrapper <CodeMirrorWrapper
label={`Service Account Policy`} label={`Access Key Policy`}
value={policyDefinition} value={policyDefinition}
onBeforeChange={(editor, data, value) => { onBeforeChange={(editor, data, value) => {
setPolicyDefinition(value); setPolicyDefinition(value);

View File

@@ -68,7 +68,7 @@ const ConfigurationOptions = ({ classes }: IConfigurationOptions) => {
return ( return (
<Fragment> <Fragment>
<PageHeader label={"Configurations"} /> <PageHeader label={"Settings"} />
<PageLayout> <PageLayout>
<Grid item xs={12}> <Grid item xs={12}>
@@ -76,7 +76,10 @@ const ConfigurationOptions = ({ classes }: IConfigurationOptions) => {
id="settings-container" id="settings-container"
className={classes.settingsOptionsContainer} className={classes.settingsOptionsContainer}
> >
<ScreenTitle icon={<SettingsIcon />} title={"Configuration:"} /> <ScreenTitle
icon={<SettingsIcon />}
title={"MinIO Configuration:"}
/>
<VerticalTabs <VerticalTabs
selectedTab={selConfigTab} selectedTab={selConfigTab}
isRouteTabs isRouteTabs

View File

@@ -1,5 +1,5 @@
// This file is part of MinIO Console Server // This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc. // Copyright (c) 2022 MinIO, Inc.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU Affero General Public License as published by
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License // 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/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useEffect, useState } from "react"; import React, { useEffect, useState, Fragment } from "react";
import { Box } from "@mui/material"; import { Box } from "@mui/material";
import { useLocation } from "react-router-dom"; import { useLocation } from "react-router-dom";
import ListItem from "@mui/material/ListItem"; import ListItem from "@mui/material/ListItem";
@@ -23,21 +23,24 @@ import LogoutIcon from "../../../icons/LogoutIcon";
import ListItemText from "@mui/material/ListItemText"; import ListItemText from "@mui/material/ListItemText";
import List from "@mui/material/List"; import List from "@mui/material/List";
import { import {
LogoutItemIconStyle,
menuItemContainerStyles, menuItemContainerStyles,
menuItemIconStyles,
menuItemMiniStyles, menuItemMiniStyles,
menuItemTextStyles, menuItemTextStyles,
} from "./MenuStyleUtils"; } from "./MenuStyleUtils";
import MenuItem from "./MenuItem"; import MenuItem from "./MenuItem";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions"; import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import MenuSectionHeader from "./MenuSectionHeader";
const ConsoleMenuList = ({ const ConsoleMenuList = ({
menuItems, menuItems,
isOpen, isOpen,
displayHeaders = false,
}: { }: {
menuItems: any[]; menuItems: any[];
isOpen: boolean; isOpen: boolean;
displayHeaders?: boolean;
}) => { }) => {
const stateClsName = isOpen ? "wide" : "mini"; const stateClsName = isOpen ? "wide" : "mini";
const { pathname = "" } = useLocation(); const { pathname = "" } = useLocation();
@@ -58,6 +61,7 @@ const ConsoleMenuList = ({
}, [groupToSelect]); }, [groupToSelect]);
let basename = document.baseURI.replace(window.location.origin, ""); let basename = document.baseURI.replace(window.location.origin, "");
let header = "";
return ( return (
<Box <Box
@@ -76,6 +80,9 @@ const ConsoleMenuList = ({
"&.mini": { "&.mini": {
marginLeft: "10px", marginLeft: "10px",
"& .menuHeader": {
display: "none",
},
}, },
}} }}
> >
@@ -100,7 +107,16 @@ const ConsoleMenuList = ({
<React.Fragment> <React.Fragment>
{(menuItems || []).map((menuGroup: any, index) => { {(menuItems || []).map((menuGroup: any, index) => {
if (menuGroup) { if (menuGroup) {
let grHeader = null;
if (menuGroup.group !== header && displayHeaders) {
grHeader = <MenuSectionHeader label={menuGroup.group} />;
header = menuGroup.group;
}
return ( return (
<Fragment>
{grHeader}
<MenuItem <MenuItem
stateClsName={stateClsName} stateClsName={stateClsName}
page={menuGroup} page={menuGroup}
@@ -114,6 +130,7 @@ const ConsoleMenuList = ({
previewMenuGroup={previewMenuGroup} previewMenuGroup={previewMenuGroup}
setPreviewMenuGroup={setPreviewMenuGroup} setPreviewMenuGroup={setPreviewMenuGroup}
/> />
</Fragment>
); );
} }
return null; return null;
@@ -148,13 +165,13 @@ const ConsoleMenuList = ({
> >
<ListItemIcon <ListItemIcon
sx={{ sx={{
...menuItemIconStyles, ...LogoutItemIconStyle,
}} }}
> >
<LogoutIcon /> <LogoutIcon />
</ListItemIcon> </ListItemIcon>
<ListItemText <ListItemText
primary="Logout" primary="Sign Out"
id={"logout"} id={"logout"}
sx={{ ...menuItemTextStyles }} sx={{ ...menuItemTextStyles }}
className={stateClsName} className={stateClsName}

View File

@@ -38,14 +38,8 @@ const LicenseBadge = () => {
<Box <Box
sx={{ sx={{
position: "absolute", position: "absolute",
border: 0, top: 1,
}} transform: "translateX(5px)",
>
<Box
sx={{
position: "absolute",
right: -19,
top: -29,
zIndex: 400, zIndex: 400,
border: 0, border: 0,
}} }}
@@ -55,15 +49,14 @@ const LicenseBadge = () => {
> >
<CircleIcon <CircleIcon
style={{ style={{
fill: "#c83b51", fill: "#FF3958",
border: "1px solid #002148", border: "1px solid #FF3958",
borderRadius: "100%", borderRadius: "100%",
width: 12, width: 8,
height: 12, height: 8,
}} }}
/> />
</Box> </Box>
</Box>
); );
}; };

View File

@@ -1,5 +1,5 @@
// This file is part of MinIO Console Server // This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc. // Copyright (c) 2022 MinIO, Inc.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU Affero General Public License as published by
@@ -116,7 +116,11 @@ const Menu = ({ classes }: IMenuProps) => {
isOpen={sidebarOpen} isOpen={sidebarOpen}
/> />
<ConsoleMenuList menuItems={allowedMenuItems} isOpen={sidebarOpen} /> <ConsoleMenuList
menuItems={allowedMenuItems}
isOpen={sidebarOpen}
displayHeaders={!operatorMode && !directPVMode}
/>
</Drawer> </Drawer>
); );
}; };

View File

@@ -150,7 +150,6 @@ const MenuItem = ({
<Suspense fallback={<div>...</div>}> <Suspense fallback={<div>...</div>}>
<page.icon /> <page.icon />
</Suspense> </Suspense>
{page.badge ? <page.badge /> : null}
</ListItemIcon> </ListItemIcon>
</Tooltip> </Tooltip>
)} )}
@@ -159,23 +158,24 @@ const MenuItem = ({
className={stateClsName} className={stateClsName}
sx={{ ...menuItemTextStyles }} sx={{ ...menuItemTextStyles }}
primary={page.name} primary={page.name}
secondary={page.badge ? <page.badge /> : null}
/> />
)} )}
{hasChildren ? ( {hasChildren ? (
isActiveGroup || previewMenuGroup === page.id ? ( isActiveGroup || previewMenuGroup === page.id ? (
<MenuCollapsedIcon
height={15}
width={15}
className="group-icon"
style={{ color: "white" }}
/>
) : (
<MenuExpandedIcon <MenuExpandedIcon
height={15} height={15}
width={15} width={15}
className="group-icon" className="group-icon"
style={{ color: "white" }} style={{ color: "#8399AB" }}
/>
) : (
<MenuCollapsedIcon
height={15}
width={15}
className="group-icon"
style={{ color: "#8399AB" }}
/> />
) )
) : null} ) : null}

View File

@@ -0,0 +1,39 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 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";
interface IMenuSectionHeader {
label: string;
}
const MenuSectionHeader = ({ label }: IMenuSectionHeader) => {
return (
<div
style={{
fontSize: 18,
color: "#fff",
marginTop: 20,
marginBottom: 10,
}}
className={"menuHeader"}
>
{label}
</div>
);
};
export default MenuSectionHeader;

View File

@@ -1,5 +1,5 @@
// This file is part of MinIO Console Server // This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc. // Copyright (c) 2022 MinIO, Inc.
// //
// This program is free software: you can redistribute it and/or modify // 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 // it under the terms of the GNU Affero General Public License as published by
@@ -15,43 +15,95 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
export const menuItemContainerStyles: any = { export const menuItemContainerStyles: any = {
paddingLeft: 0, padding: "12px 0",
paddingBottom: "18px", "div:nth-of-type(2)": {
"&.active div:nth-of-type(1)": { flexGrow: 0,
border: "2px solid #ffffff", marginRight: "15px",
}, },
"&.active": {
background:
"transparent linear-gradient(270deg, #00000000 0%, #051d39 53%, #54545400 100%) 0% 0% no-repeat padding-box",
backgroundBlendMode: "multiply",
"& span": {
color: "#fff",
},
"& svg": {
fill: "#fff",
},
"& div:nth-of-type(1)": {
border: "1px solid #fff",
},
"&:hover, &:focus": { "&:hover, &:focus": {
background: "none",
"& div:nth-of-type(1)": { "& div:nth-of-type(1)": {
background: "none", background: "none",
"& svg": { "& svg": {
fill: "#ffffff", fill: "#fff",
},
}, },
}, },
}, },
}; };
export const menuItemIconStyles: any = { export const menuItemIconStyles: any = {
width: 37, width: 30,
minWidth: 37, minWidth: 30,
height: 37, height: 30,
background: "#00274D",
border: "1px solid #002148",
display: "flex",
alignItems: "center",
borderRadius: "50%",
justifyContent: "center",
"& svg": {
width: 12,
height: 12,
fill: "#8399AB",
},
"&.active": {
"& span": {
color: "#fff",
},
"& svg": {
fill: "#fff",
},
},
};
export const LogoutItemIconStyle: any = {
width: 40,
minWidth: 40,
height: 40,
background: "#00274D", background: "#00274D",
border: "2px solid #002148", border: "2px solid #002148",
display: "flex", display: "flex",
alignItems: "center", alignItems: "center",
borderRadius: "50%", borderRadius: "50%",
justifyContent: "center", justifyContent: "center",
"& svg": { "& svg": {
width: 16, width: 16,
height: 16, height: 16,
fill: "#8399AB", fill: "#8399AB",
}, },
"&.active": {
"& span": {
color: "#fff",
},
"& svg": {
fill: "#fff",
},
},
}; };
export const menuItemTextStyles: any = { export const menuItemTextStyles: any = {
color: "#BCC7D1", color: "#8399AB",
fontSize: "14px", fontSize: "14px",
marginLeft: "11px", marginLeft: "18px",
display: "flex",
position: "relative",
"& span": { "& span": {
fontSize: "14px", fontSize: "14px",
}, },
@@ -90,11 +142,16 @@ export const menuItemStyle: any = {
borderRadius: "2px", borderRadius: "2px",
marginTop: "2px", marginTop: "2px",
"&.active": { "&.active": {
backgroundColor: "hsla(0,0%,100%,.1)",
".menu-icon": { ".menu-icon": {
border: "1px solid hsla(0,0%,100%,.1)", border: "1px solid #fff",
borderRadius: "50%", borderRadius: "50%",
background: "#072549", background: "#072549",
"& svg": {
fill: "#fff",
},
},
"& span": {
color: "#fff",
}, },
}, },
"& .menu-icon": { "& .menu-icon": {
@@ -103,9 +160,13 @@ export const menuItemStyle: any = {
minWidth: "28px", minWidth: "28px",
height: "28px", height: "28px",
background: "none", background: "none",
"& svg": {
width: "12px",
height: "12px",
fill: "#8399AB",
},
}, },
"&:hover, &:focus": { "&:hover, &:focus": {
background: "hsla(0,0%,100%,.25)",
"& .menu-icon": { "& .menu-icon": {
background: "#072549", background: "#072549",
borderRadius: "50%", borderRadius: "50%",

View File

@@ -71,7 +71,14 @@ const MenuToggle = ({ isOpen, onToggle }: MenuToggleProps) => {
<Box <Box
sx={{ sx={{
width: "100%", width: "100%",
boxShadow: "0 3px 10px -6px #426198", "&::after": {
width: "80%",
height: "1px",
display: "block",
content: "' '",
backgroundColor: "#0F446C",
margin: "0px auto",
},
}} }}
> >
<Box <Box

View File

@@ -43,7 +43,7 @@ const AddUserServiceAccount = ({
closeModalAndRefresh, closeModalAndRefresh,
user, user,
}: IAddUserServiceAccountProps) => { }: IAddUserServiceAccountProps) => {
return <Fragment>zxzzzz</Fragment>; return <Fragment />;
}; };
export default withStyles(styles)(AddUserServiceAccount); export default withStyles(styles)(AddUserServiceAccount);

View File

@@ -80,18 +80,18 @@ const AddUserServiceAccountHelpBox = () => {
}} }}
> >
<HelpIconFilled /> <HelpIconFilled />
<div>Learn more about Service Accounts</div> <div>Learn more about Access Keys</div>
</Box> </Box>
<Box sx={{ fontSize: "14px", marginBottom: "15px" }}> <Box sx={{ fontSize: "14px", marginBottom: "15px" }}>
<Box sx={{ paddingBottom: "20px" }}> <Box sx={{ paddingBottom: "20px" }}>
<FeatureItem <FeatureItem
icon={<ServiceAccountIcon />} icon={<ServiceAccountIcon />}
description={`Create Service Accounts`} description={`Create Access Keys`}
/> />
<Box sx={{ paddingTop: "20px" }}> <Box sx={{ paddingTop: "20px" }}>
Service Accounts inherit the policies explicitly attached to the Access Keys inherit the policies explicitly attached to the parent
parent user, and the policies attached to each group in which the user, and the policies attached to each group in which the parent
parent user has membership. user has membership.
</Box> </Box>
</Box> </Box>
<Box sx={{ paddingBottom: "20px" }}> <Box sx={{ paddingBottom: "20px" }}>
@@ -102,13 +102,13 @@ const AddUserServiceAccountHelpBox = () => {
<Box sx={{ paddingTop: "10px" }}> <Box sx={{ paddingTop: "10px" }}>
Randomized access credentials are recommended, and provided by Randomized access credentials are recommended, and provided by
default. You may use your own custom Access Key and Secret Key by default. You may use your own custom Access Key and Secret Key by
replacing the default values. After creation of any Service Account, replacing the default values. After creation of any Access Key, you
you will be given the opportunity to view and download the account will be given the opportunity to view and download the account
credentials. credentials.
</Box> </Box>
<Box sx={{ paddingTop: "10px" }}> <Box sx={{ paddingTop: "10px" }}>
Service Accounts support programmatic access by applications. You Access Keys support programmatic access by applications. You cannot
cannot use a Service Account to log into the MinIO Console. use a Access Key to log into the MinIO Console.
</Box> </Box>
</Box> </Box>
<Box sx={{ paddingBottom: "20px" }}> <Box sx={{ paddingBottom: "20px" }}>
@@ -118,14 +118,13 @@ const AddUserServiceAccountHelpBox = () => {
/> />
<Box sx={{ paddingTop: "10px" }}> <Box sx={{ paddingTop: "10px" }}>
You can specify an optional JSON-formatted IAM policy to further You can specify an optional JSON-formatted IAM policy to further
restrict Service Account access to a subset of the actions and restrict Access Key access to a subset of the actions and resources
resources explicitly allowed for the parent user. Additional access explicitly allowed for the parent user. Additional access beyond
beyond that of the parent user cannot be implemented through these that of the parent user cannot be implemented through these
policies. policies.
</Box> </Box>
<Box sx={{ paddingTop: "10px" }}> <Box sx={{ paddingTop: "10px" }}>
You cannot modify the optional Service Account IAM policy after You cannot modify the optional Access Key IAM policy after saving.
saving.
</Box> </Box>
</Box> </Box>
</Box> </Box>

View File

@@ -169,7 +169,7 @@ const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
closeModal={() => { closeModal={() => {
closeCredentialsModal(); closeCredentialsModal();
}} }}
entity="Service Account" entity="Access Key"
/> />
)} )}
<Grid item xs={12}> <Grid item xs={12}>
@@ -196,7 +196,7 @@ const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
> >
<Box> <Box>
<SectionTitle icon={<ServiceAccountCredentialsIcon />}> <SectionTitle icon={<ServiceAccountCredentialsIcon />}>
{`Create Service Account for ${userName}`} {`Create Access Key for ${userName}`}
</SectionTitle> </SectionTitle>
<form <form
noValidate noValidate
@@ -280,7 +280,7 @@ const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
}} }}
label={"Restrict beyond user policy"} label={"Restrict beyond user policy"}
tooltip={ tooltip={
"You can specify an optional JSON-formatted IAM policy to further restrict Service Account access to a subset of the actions and resources explicitly allowed for the parent user. Additional access beyond that of the parent user cannot be implemented through these policies." "You can specify an optional JSON-formatted IAM policy to further restrict Access Key access to a subset of the actions and resources explicitly allowed for the parent user. Additional access beyond that of the parent user cannot be implemented through these policies."
} }
/> />
</Grid> </Grid>

View File

@@ -52,7 +52,7 @@ const DeleteMultipleSAs = ({
}; };
return ( return (
<ConfirmDialog <ConfirmDialog
title={`Delete Service Accounts`} title={`Delete Access Keys`}
confirmText={"Delete"} confirmText={"Delete"}
isOpen={deleteOpen} isOpen={deleteOpen}
titleIcon={<ConfirmDeleteIcon />} titleIcon={<ConfirmDeleteIcon />}
@@ -62,7 +62,7 @@ const DeleteMultipleSAs = ({
confirmationContent={ confirmationContent={
<DialogContentText> <DialogContentText>
Are you sure you want to delete the selected {selectedSAs.length}{" "} Are you sure you want to delete the selected {selectedSAs.length}{" "}
service accounts?{" "} Access Keys?{" "}
</DialogContentText> </DialogContentText>
} }
/> />

View File

@@ -139,21 +139,21 @@ const DeleteUser = ({
{hasSA ? ( {hasSA ? (
<Fragment> <Fragment>
<WarningMessage <WarningMessage
label="Click on a user to view the full listing of asociated Service Accounts. All Service Accounts associated with a user will be deleted along with the user. Are you sure you want to continue?" label="Click on a user to view the full listing of asociated Access Keys. All Access Keys associated with a user will be deleted along with the user. Are you sure you want to continue?"
title="Warning: One or more users selected has associated Service Accounts. " title="Warning: One or more users selected has associated Access Keys. "
/> />
<TableWrapper <TableWrapper
itemActions={tableActions} itemActions={tableActions}
columns={[ columns={[
{ label: "Username", elementKey: "userName" }, { label: "Username", elementKey: "userName" },
{ {
label: "# Associated Service Accounts", label: "# Associated Access Keys",
elementKey: "numSAs", elementKey: "numSAs",
}, },
]} ]}
isLoading={loadingSA} isLoading={loadingSA}
records={userSAList} records={userSAList}
entityName="User Service Accounts" entityName="User Access Keys"
idField="userName" idField="userName"
customPaperHeight="250" customPaperHeight="250"
/> />

View File

@@ -140,7 +140,7 @@ const UserServiceAccountsPanel = ({
const closeDeleteMultipleModalAndRefresh = (refresh: boolean) => { const closeDeleteMultipleModalAndRefresh = (refresh: boolean) => {
setDeleteMultipleOpen(false); setDeleteMultipleOpen(false);
if (refresh) { if (refresh) {
dispatch(setSnackBarMessage(`Service accounts deleted successfully.`)); dispatch(setSnackBarMessage(`Access Keys deleted successfully.`));
setSelectedSAs([]); setSelectedSAs([]);
setLoading(true); setLoading(true);
} }
@@ -213,7 +213,7 @@ const UserServiceAccountsPanel = ({
closeModal={() => { closeModal={() => {
closeCredentialsModal(); closeCredentialsModal();
}} }}
entity="Service Account" entity="Access Key"
/> />
)} )}
{policyOpen && ( {policyOpen && (
@@ -224,7 +224,7 @@ const UserServiceAccountsPanel = ({
/> />
)} )}
<div className={classes.actionsTray}> <div className={classes.actionsTray}>
<PanelTitle>Service Accounts</PanelTitle> <PanelTitle>Access Keys</PanelTitle>
<Box sx={{ display: "flex", justifyContent: "flex-end" }}> <Box sx={{ display: "flex", justifyContent: "flex-end" }}>
<TooltipWrapper tooltip={"Delete Selected"}> <TooltipWrapper tooltip={"Delete Selected"}>
<Button <Button
@@ -249,10 +249,10 @@ const UserServiceAccountsPanel = ({
matchAll matchAll
errorProps={{ disabled: true }} errorProps={{ disabled: true }}
> >
<TooltipWrapper tooltip={"Create service account"}> <TooltipWrapper tooltip={"Create Access Key"}>
<Button <Button
id={"create-service-account"} id={"create-service-account"}
label={"Create service account"} label={"Create Access Key"}
variant="callAction" variant="callAction"
icon={<AddIcon />} icon={<AddIcon />}
onClick={() => { onClick={() => {
@@ -270,9 +270,9 @@ const UserServiceAccountsPanel = ({
<TableWrapper <TableWrapper
isLoading={loading} isLoading={loading}
records={records} records={records}
entityName={"Service Accounts"} entityName={"Access Keys"}
idField={""} idField={""}
columns={[{ label: "Service Account", elementKey: "" }]} columns={[{ label: "Access Key", elementKey: "" }]}
itemActions={tableActions} itemActions={tableActions}
selectedItems={selectedSAs} selectedItems={selectedSAs}
onSelect={(e) => selectSAs(e, setSelectedSAs, selectedSAs)} onSelect={(e) => selectSAs(e, setSelectedSAs, selectedSAs)}

View File

@@ -68,6 +68,7 @@ export const validRoutes = (
const ldapIsEnabled = (features && features.includes("ldap-idp")) || false; const ldapIsEnabled = (features && features.includes("ldap-idp")) || false;
let consoleMenus: IMenuItem[] = [ let consoleMenus: IMenuItem[] = [
{ {
group: "User",
name: "Buckets", name: "Buckets",
id: "buckets", id: "buckets",
component: NavLink, component: NavLink,
@@ -77,6 +78,38 @@ export const validRoutes = (
children: [], children: [],
}, },
{ {
group: "User",
component: NavLink,
id: "nav-accesskeys",
to: IAM_PAGES.ACCOUNT,
name: "Access Keys",
icon: AccountsMenuIcon,
forceDisplay: true,
},
{
group: "User",
type: "item",
component: NavLink,
to: IAM_PAGES.DOCUMENTATION,
name: "Documentation",
icon: DocumentationIcon,
forceDisplay: true,
onClick: (
e:
| React.MouseEvent<HTMLLIElement>
| React.MouseEvent<HTMLAnchorElement>
| React.MouseEvent<HTMLDivElement>
) => {
e.preventDefault();
window.open(
"https://min.io/docs/minio/linux/index.html?ref=con",
"_blank"
);
},
},
{
group: "Administrator",
name: "Identity", name: "Identity",
id: "identity", id: "identity",
icon: IdentityMenuIcon, icon: IdentityMenuIcon,
@@ -101,14 +134,6 @@ export const validRoutes = (
icon: GroupsMenuIcon, icon: GroupsMenuIcon,
fsHidden: ldapIsEnabled, fsHidden: ldapIsEnabled,
}, },
{
component: NavLink,
id: "serviceaccounts",
to: IAM_PAGES.ACCOUNT,
name: "Service Accounts",
icon: AccountsMenuIcon,
forceDisplay: true,
},
{ {
name: "Policies", name: "Policies",
component: NavLink, component: NavLink,
@@ -120,6 +145,7 @@ export const validRoutes = (
}, },
{ {
group: "Administrator",
name: "Monitoring", name: "Monitoring",
id: "tools", id: "tools",
icon: MonitoringMenuIcon, icon: MonitoringMenuIcon,
@@ -169,6 +195,7 @@ export const validRoutes = (
], ],
}, },
{ {
group: "Administrator",
component: NavLink, component: NavLink,
to: IAM_PAGES.NOTIFICATIONS_ENDPOINTS, to: IAM_PAGES.NOTIFICATIONS_ENDPOINTS,
name: "Notifications", name: "Notifications",
@@ -176,6 +203,7 @@ export const validRoutes = (
id: "lambda", id: "lambda",
}, },
{ {
group: "Administrator",
component: NavLink, component: NavLink,
to: IAM_PAGES.TIERS, to: IAM_PAGES.TIERS,
name: "Tiers", name: "Tiers",
@@ -183,6 +211,7 @@ export const validRoutes = (
id: "tiers", id: "tiers",
}, },
{ {
group: "Administrator",
component: NavLink, component: NavLink,
to: IAM_PAGES.SITE_REPLICATION, to: IAM_PAGES.SITE_REPLICATION,
name: "Site Replication", name: "Site Replication",
@@ -190,13 +219,15 @@ export const validRoutes = (
id: "sitereplication", id: "sitereplication",
}, },
{ {
group: "Administrator",
component: NavLink, component: NavLink,
to: IAM_PAGES.SETTINGS, to: IAM_PAGES.SETTINGS,
name: "Configurations", name: "Settings",
id: "configurations", id: "configurations",
icon: SettingsIcon, icon: SettingsIcon,
}, },
{ {
group: "Subscription",
component: NavLink, component: NavLink,
to: IAM_PAGES.LICENSE, to: IAM_PAGES.LICENSE,
name: "License", name: "License",
@@ -206,6 +237,7 @@ export const validRoutes = (
forceDisplay: true, forceDisplay: true,
}, },
{ {
group: "Subscription",
name: "Support", name: "Support",
id: "support", id: "support",
icon: SupportMenuIcon, icon: SupportMenuIcon,
@@ -248,26 +280,6 @@ export const validRoutes = (
}, },
], ],
}, },
{
type: "item",
component: NavLink,
to: IAM_PAGES.DOCUMENTATION,
name: "Documentation",
icon: DocumentationIcon,
forceDisplay: true,
onClick: (
e:
| React.MouseEvent<HTMLLIElement>
| React.MouseEvent<HTMLAnchorElement>
| React.MouseEvent<HTMLDivElement>
) => {
e.preventDefault();
window.open(
"https://min.io/docs/minio/linux/index.html?ref=con",
"_blank"
);
},
},
]; ];
let operatorMenus: IMenuItem[] = [ let operatorMenus: IMenuItem[] = [

View File

@@ -48,6 +48,11 @@ export const watchElement = monitoringChildren
export const bucketsElement = sidebarItem.withAttribute("href", "/buckets"); export const bucketsElement = sidebarItem.withAttribute("href", "/buckets");
export const serviceAcctsElement = sidebarItem.withAttribute(
"href",
IAM_PAGES.ACCOUNT
);
export const identityElement = Selector(".MuiPaper-root") export const identityElement = Selector(".MuiPaper-root")
.find("ul") .find("ul")
.child("#identity"); .child("#identity");
@@ -59,9 +64,7 @@ export const usersElement = identityChildren
export const groupsElement = identityChildren export const groupsElement = identityChildren
.find("a") .find("a")
.withAttribute("href", IAM_PAGES.GROUPS); .withAttribute("href", IAM_PAGES.GROUPS);
export const serviceAcctsElement = identityChildren
.find("a")
.withAttribute("href", IAM_PAGES.ACCOUNT);
export const iamPoliciesElement = identityChildren export const iamPoliciesElement = identityChildren
.find("a") .find("a")
.withAttribute("href", IAM_PAGES.POLICIES); .withAttribute("href", IAM_PAGES.POLICIES);