Migrated Access Keys page components to mds (#2834)

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
Alex
2023-05-26 11:24:34 -06:00
committed by GitHub
parent bda1cd1f25
commit 028570279c
9 changed files with 231 additions and 449 deletions

View File

@@ -18,24 +18,21 @@ import React, { Fragment, useEffect, useState } from "react";
import {
AccountIcon,
AddIcon,
Box,
Button,
DataTable,
DeleteIcon,
Grid,
HelpBox,
PageLayout,
PasswordKeyIcon,
} from "mds";
import { useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import Grid from "@mui/material/Grid";
import api from "../../../common/api";
import { Box } from "@mui/material";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import { stringSort } from "../../../utils/sortFunctions";
import {
actionsTray,
searchField,
tableStyles,
} from "../Common/FormComponents/common/styleLibrary";
@@ -54,7 +51,6 @@ import { selectSAs } from "../Configurations/utils";
import DeleteMultipleServiceAccounts from "../Users/DeleteMultipleServiceAccounts";
import ServiceAccountPolicy from "./ServiceAccountPolicy";
import { setErrorSnackMessage, setSnackBarMessage } from "../../../systemSlice";
import makeStyles from "@mui/styles/makeStyles";
import { selFeatures } from "../consoleSlice";
import { useAppDispatch } from "../../../store";
import TooltipWrapper from "../Common/TooltipWrapper/TooltipWrapper";
@@ -64,24 +60,10 @@ const DeleteServiceAccount = withSuspense(
React.lazy(() => import("./DeleteServiceAccount"))
);
const useStyles = makeStyles((theme: Theme) =>
createStyles({
...actionsTray,
...searchField,
searchField: {
...searchField.searchField,
marginRight: "auto",
maxWidth: 380,
},
...tableStyles,
})
);
const Account = () => {
const dispatch = useAppDispatch();
const navigate = useNavigate();
const classes = useStyles();
const features = useSelector(selFeatures);
const [records, setRecords] = useState<string[]>([]);
@@ -199,27 +181,29 @@ const Account = () => {
closeModalAndRefresh={closePolicyModal}
/>
)}
<ChangePasswordModal
open={changePasswordModalOpen}
closeModal={() => setChangePasswordModalOpen(false)}
/>
{changePasswordModalOpen && (
<ChangePasswordModal
open={changePasswordModalOpen}
closeModal={() => setChangePasswordModalOpen(false)}
/>
)}
<PageHeaderWrapper label="Access Keys" />
<PageLayout>
<Grid container spacing={1}>
<Grid item={true} xs={12} className={classes.actionsTray}>
<Grid container>
<Grid item xs={12} sx={{ ...actionsTray.actionsTray }}>
<SearchBox
placeholder={"Search Access Keys"}
onChange={setFilter}
overrideClass={classes.searchField}
sx={{ marginRight: "auto", maxWidth: 380 }}
value={filter}
/>
<Box
sx={{
display: "flex",
flexWrap: "nowrap",
gap: 5,
}}
>
{" "}
<TooltipWrapper tooltip={"Delete Selected"}>
<Button
id={"delete-selected-accounts"}
@@ -266,20 +250,19 @@ const Account = () => {
</Box>
</Grid>
<Grid item xs={12} className={classes.tableBlock}>
<TableWrapper
<Grid item xs={12} sx={{ ...tableStyles.tableBlock }}>
<DataTable
isLoading={loading}
records={filteredRecords}
entityName={"Access Keys"}
idField={""}
columns={[{ label: "Access Key", elementKey: "" }]}
columns={[{ label: "Access Key" }]}
itemActions={tableActions}
selectedItems={selectedSAs}
onSelect={(e) => selectSAs(e, setSelectedSAs, selectedSAs)}
onSelectAll={selectAllItems}
/>
</Grid>
<Grid item xs={12} marginTop={"15px"}>
<Grid item xs={12} sx={{ marginTop: 15 }}>
<HelpBox
title={"Learn more about ACCESS KEYS"}
iconComponent={<AccountIcon />}
@@ -295,11 +278,8 @@ const Account = () => {
<br />
<br />
You can learn more at our{" "}
{
// TODO: Change this link once it is called access keys
}
<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#id3"
target="_blank"
rel="noopener"
>

View File

@@ -15,38 +15,30 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { Fragment, useEffect, useState } from "react";
import { Theme } from "@mui/material/styles";
import { useNavigate } from "react-router-dom";
import {
BackLink,
Button,
IAMPoliciesIcon,
PageLayout,
PasswordKeyIcon,
ServiceAccountCredentialsIcon,
Grid,
Box,
FormLayout,
InputBox,
Switch,
ServiceAccountIcon,
} from "mds";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import {
formFieldStyles,
modalStyleUtils,
} from "../Common/FormComponents/common/styleLibrary";
import Grid from "@mui/material/Grid";
import { Box } from "@mui/material";
import { modalStyleUtils } from "../Common/FormComponents/common/styleLibrary";
import CodeMirrorWrapper from "../Common/FormComponents/CodeMirrorWrapper/CodeMirrorWrapper";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
import AddServiceAccountHelpBox from "./AddServiceAccountHelpBox";
import { NewServiceAccount } from "../Common/CredentialsPrompt/types";
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
import { IAM_PAGES } from "../../../common/SecureComponent/permissions";
import { ErrorResponseHandler } from "../../../../src/common/types";
import api from "../../../../src/common/api";
import CredentialsPrompt from "../Common/CredentialsPrompt/CredentialsPrompt";
import SectionTitle from "../Common/SectionTitle";
import PanelTitle from "../Common/PanelTitle/PanelTitle";
import { setErrorSnackMessage } from "../../../systemSlice";
@@ -54,17 +46,7 @@ import { useAppDispatch } from "../../../store";
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
import { getRandomString } from "../../../common/utils";
interface IAddServiceAccountProps {
classes: any;
}
const styles = (theme: Theme) =>
createStyles({
...formFieldStyles,
...modalStyleUtils,
});
const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
const AddServiceAccount = () => {
const dispatch = useAppDispatch();
const navigate = useNavigate();
@@ -75,7 +57,6 @@ const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
useState<boolean>(false);
const [newServiceAccount, setNewServiceAccount] =
useState<NewServiceAccount | null>(null);
const [showPassword, setShowPassword] = useState<boolean>(false);
const [policyJSON, setPolicyJSON] = useState<string>("");
useEffect(() => {
@@ -120,7 +101,6 @@ const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
setNewServiceAccount(null);
setAccessKey("");
setSecretKey("");
setShowPassword(false);
};
const closeCredentialsModal = () => {
@@ -150,161 +130,96 @@ const AddServiceAccount = ({ classes }: IAddServiceAccountProps) => {
}
/>
<PageLayout>
<Box
sx={{
display: "grid",
padding: "25px",
gap: "25px",
gridTemplateColumns: {
md: "2fr 1.2fr",
xs: "1fr",
},
border: "1px solid #eaeaea",
}}
<FormLayout
helpBox={<AddServiceAccountHelpBox />}
icon={<ServiceAccountCredentialsIcon />}
title={"Create Access Key"}
>
<Box>
<SectionTitle icon={<ServiceAccountCredentialsIcon />}>
Create Access Key
</SectionTitle>
<form
noValidate
autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
addServiceAccount(e);
<form
noValidate
autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
addServiceAccount(e);
}}
>
<InputBox
value={accessKey}
label={"Access Key"}
id={"accessKey"}
name={"accessKey"}
placeholder={"Enter Access Key"}
onChange={(e) => {
setAccessKey(e.target.value);
}}
>
<Grid container item spacing="20" sx={{ marginTop: 1 }}>
<Grid item xs={12}>
<Grid container item spacing="20">
<Grid item xs={12}>
<Grid container>
<Grid item xs={1}>
<PasswordKeyIcon />
</Grid>
<Grid item>
<Grid container item spacing="20">
<Grid item xs={12}>
{" "}
<div className={classes.stackedInputs}>
<InputBoxWrapper
value={accessKey}
label={"Access Key"}
id={"accessKey"}
name={"accessKey"}
placeholder={"Enter Access Key"}
onChange={(e) => {
setAccessKey(e.target.value);
}}
/>
</div>
</Grid>
<Grid item xs={12}>
<div className={classes.stackedInputs}>
<InputBoxWrapper
value={secretKey}
label={"Secret Key"}
id={"secretKey"}
name={"secretKey"}
type={showPassword ? "text" : "password"}
placeholder={"Enter Secret Key"}
onChange={(e) => {
setSecretKey(e.target.value);
}}
overlayIcon={
showPassword ? (
<VisibilityOffIcon />
) : (
<RemoveRedEyeIcon />
)
}
overlayAction={() =>
setShowPassword(!showPassword)
}
/>
</div>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
</Grid>
<Grid container item spacing="20">
<Grid item xs={12}>
<Grid container>
<Grid item xs={1}>
<IAMPoliciesIcon />
</Grid>
<Grid item xs={11}>
<FormSwitchWrapper
value="serviceAccountPolicy"
id="serviceAccountPolicy"
name="serviceAccountPolicy"
checked={isRestrictedByPolicy}
onChange={(
event: React.ChangeEvent<HTMLInputElement>
) => {
setIsRestrictedByPolicy(event.target.checked);
}}
label={"Restrict beyond user policy"}
tooltip={
"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>
</Grid>
{isRestrictedByPolicy && (
<Grid
item
xs={12}
className={classes.codeMirrorContainer}
>
<div>
<PanelTitle>
Current User Policy - edit the JSON to remove
permissions for this Access Key
</PanelTitle>
</div>
<Grid item xs={12} className={classes.formScrollable}>
<CodeMirrorWrapper
value={policyJSON}
onBeforeChange={(editor, data, value) => {
setPolicyJSON(value);
}}
editorHeight={"350px"}
/>
</Grid>
</Grid>
)}
</Grid>
<Grid item xs={12} className={classes.modalButtonBar}>
<Button
id={"clear"}
type="button"
variant="regular"
onClick={resetForm}
label={"Clear"}
/>
<Button
id={"create-sa"}
type="submit"
variant="callAction"
color="primary"
label={"Create"}
startIcon={<ServiceAccountIcon />}
/>
<InputBox
value={secretKey}
label={"Secret Key"}
id={"secretKey"}
name={"secretKey"}
type={"password"}
placeholder={"Enter Secret Key"}
onChange={(e) => {
setSecretKey(e.target.value);
}}
startIcon={<PasswordKeyIcon />}
/>
<Switch
value="serviceAccountPolicy"
id="serviceAccountPolicy"
name="serviceAccountPolicy"
checked={isRestrictedByPolicy}
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setIsRestrictedByPolicy(event.target.checked);
}}
label={"Restrict beyond user policy"}
description={
"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."
}
/>
{isRestrictedByPolicy && (
<Grid item xs={12}>
<Box>
<PanelTitle>
Current User Policy - edit the JSON to remove permissions
for this Access Key
</PanelTitle>
</Box>
<Grid item xs={12} sx={{ ...modalStyleUtils.formScrollable }}>
<CodeMirrorWrapper
value={policyJSON}
onBeforeChange={(editor, data, value) => {
setPolicyJSON(value);
}}
editorHeight={"350px"}
/>
</Grid>
</Grid>
</form>
</Box>
<AddServiceAccountHelpBox />
</Box>
)}
<Grid item xs={12} sx={{ ...modalStyleUtils.modalButtonBar }}>
<Button
id={"clear"}
type="button"
variant="regular"
onClick={resetForm}
label={"Clear"}
/>
<Button
id={"create-sa"}
type="submit"
variant="callAction"
color="primary"
label={"Create"}
/>
</Grid>
</form>
</FormLayout>
</PageLayout>
</Grid>
</Fragment>
);
};
export default withStyles(styles)(AddServiceAccount);
export default AddServiceAccount;

View File

@@ -15,53 +15,27 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React, { useState } from "react";
import { Button, ChangePasswordIcon } from "mds";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { Button, ChangePasswordIcon, InputBox, Grid, FormLayout } from "mds";
import ModalWrapper from "../Common/ModalWrapper/ModalWrapper";
import Grid from "@mui/material/Grid";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import { LinearProgress } from "@mui/material";
import {
containerForHeader,
formFieldStyles,
modalStyleUtils,
spacingUtils,
} from "../Common/FormComponents/common/styleLibrary";
import { modalStyleUtils } from "../Common/FormComponents/common/styleLibrary";
import { ChangePasswordRequest } from "../Buckets/types";
import { ErrorResponseHandler } from "../../../common/types";
import api from "../../../common/api";
import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
import { setModalErrorSnackMessage } from "../../../systemSlice";
import { useAppDispatch } from "../../../store";
const styles = (theme: Theme) =>
createStyles({
...modalStyleUtils,
...formFieldStyles,
...spacingUtils,
...containerForHeader,
});
interface IChangePasswordProps {
classes: any;
open: boolean;
closeModal: () => void;
}
const ChangePassword = ({
classes,
open,
closeModal,
}: IChangePasswordProps) => {
const ChangePassword = ({ open, closeModal }: IChangePasswordProps) => {
const dispatch = useAppDispatch();
const [currentPassword, setCurrentPassword] = useState<string>("");
const [newPassword, setNewPassword] = useState<string>("");
const [reNewPassword, setReNewPassword] = useState<string>("");
const [loading, setLoading] = useState<boolean>(false);
const [showPassword, setShowPassword] = useState<boolean>(false);
const userLoggedIn = localStorage.getItem("userLoggedIn") || "";
@@ -140,57 +114,41 @@ const ChangePassword = ({
}}
>
<Grid container>
<Grid item xs={12} className={classes.modalFormScrollable}>
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
<Grid item xs={12} sx={{ ...modalStyleUtils.modalFormScrollable }}>
<FormLayout withBorders={false} containerPadding={false}>
<InputBox
id="current-password"
name="current-password"
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setCurrentPassword(event.target.value);
}}
label="Current Password"
type={showPassword ? "text" : "password"}
type={"password"}
value={currentPassword}
overlayAction={() => setShowPassword(!showPassword)}
overlayIcon={
showPassword ? <VisibilityOffIcon /> : <RemoveRedEyeIcon />
}
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
<InputBox
id="new-password"
name="new-password"
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setNewPassword(event.target.value);
}}
label="New Password"
type={showPassword ? "text" : "password"}
type={"password"}
value={newPassword}
overlayAction={() => setShowPassword(!showPassword)}
overlayIcon={
showPassword ? <VisibilityOffIcon /> : <RemoveRedEyeIcon />
}
/>
</Grid>
<Grid item xs={12} className={classes.formFieldRow}>
<InputBoxWrapper
<InputBox
id="re-new-password"
name="re-new-password"
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
setReNewPassword(event.target.value);
}}
label="Type New Password Again"
type={showPassword ? "text" : "password"}
type={"password"}
value={reNewPassword}
overlayAction={() => setShowPassword(!showPassword)}
overlayIcon={
showPassword ? <VisibilityOffIcon /> : <RemoveRedEyeIcon />
}
/>
</Grid>
</FormLayout>
</Grid>
<Grid item xs={12} className={classes.modalButtonBar}>
<Grid item xs={12} sx={{ ...modalStyleUtils.modalButtonBar }}>
<Button
id={"save-password-modal"}
type="submit"
@@ -218,4 +176,4 @@ const ChangePassword = ({
) : null;
};
export default withStyles(styles)(ChangePassword);
export default ChangePassword;

View File

@@ -14,13 +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 from "react";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { DialogContentText } from "@mui/material";
import React, { Fragment } from "react";
import { ErrorResponseHandler } from "../../../common/types";
import useApi from "../Common/Hooks/useApi";
import ConfirmDialog from "../Common/ModalWrapper/ConfirmDialog";
@@ -29,24 +23,13 @@ import { encodeURLString } from "../../../common/utils";
import { setErrorSnackMessage } from "../../../systemSlice";
import { useAppDispatch } from "../../../store";
const styles = (theme: Theme) =>
createStyles({
wrapText: {
maxWidth: "200px",
whiteSpace: "normal",
wordWrap: "break-word",
},
});
interface IDeleteServiceAccountProps {
classes: any;
closeDeleteModalAndRefresh: (refresh: boolean) => void;
deleteOpen: boolean;
selectedServiceAccount: string | null;
}
const DeleteServiceAccount = ({
classes,
closeDeleteModalAndRefresh,
deleteOpen,
selectedServiceAccount,
@@ -80,13 +63,22 @@ const DeleteServiceAccount = ({
onConfirm={onConfirmDelete}
onClose={onClose}
confirmationContent={
<DialogContentText>
<Fragment>
Are you sure you want to delete Access Key{" "}
<b className={classes.wrapText}>{selectedServiceAccount}</b>?
</DialogContentText>
<b
style={{
maxWidth: "200px",
whiteSpace: "normal",
wordWrap: "break-word",
}}
>
{selectedServiceAccount}
</b>
?
</Fragment>
}
/>
);
};
export default withStyles(styles)(DeleteServiceAccount);
export default DeleteServiceAccount;

View File

@@ -15,87 +15,46 @@
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import React from "react";
import { InputAdornment, OutlinedInput } from "@mui/material";
import withStyles from "@mui/styles/withStyles";
import { Theme } from "@mui/material/styles";
import { Button, CopyIcon } from "mds";
import createStyles from "@mui/styles/createStyles";
import { Button, CopyIcon, InputLabel, ReadBox, Box } from "mds";
import CopyToClipboard from "react-copy-to-clipboard";
import { fieldBasic } from "../FormComponents/common/styleLibrary";
import TooltipWrapper from "../TooltipWrapper/TooltipWrapper";
import { setModalSnackMessage } from "../../../../systemSlice";
import { useAppDispatch } from "../../../../store";
const styles = (theme: Theme) =>
createStyles({
container: {
display: "flex",
flexFlow: "column",
padding: "20px 0 8px 0",
},
inputWithCopy: {
"& .MuiInputBase-root ": {
width: "100%",
background: "#FBFAFA",
"& .MuiInputBase-input": {
height: ".8rem",
},
"& .MuiInputAdornment-positionEnd": {
marginRight: ".5rem",
"& .MuiButtonBase-root": {
height: "2rem",
},
},
},
"& .MuiButtonBase-root .min-icon": {
width: ".8rem",
height: ".8rem",
},
},
inputLabel: {
...fieldBasic.inputLabel,
fontSize: ".8rem",
},
});
interface ICredentialsItem {
label?: string;
value?: string;
}
const CredentialItem = ({ label = "", value = "" }: ICredentialsItem) => {
const dispatch = useAppDispatch();
const CredentialItem = ({
label = "",
value = "",
classes = {},
}: {
label: string;
value: string;
classes: any;
}) => {
return (
<div className={classes.container}>
<div className={classes.inputLabel}>{label}:</div>
<div className={classes.inputWithCopy}>
<OutlinedInput
value={value}
readOnly
endAdornment={
<InputAdornment position="end">
<TooltipWrapper tooltip={"Copy"}>
<CopyToClipboard text={value}>
<Button
id={"copy-clipboard"}
aria-label="copy"
onClick={() => {}}
onMouseDown={() => {}}
style={{
width: "28px",
height: "28px",
padding: "0px",
}}
icon={<CopyIcon />}
/>
</CopyToClipboard>
</TooltipWrapper>
</InputAdornment>
}
/>
</div>
</div>
<Box sx={{ marginTop: 12 }}>
<InputLabel>{label}</InputLabel>
<ReadBox
actionButton={
<CopyToClipboard text={value}>
<Button
id={"copy-path"}
variant="regular"
onClick={() => {
dispatch(setModalSnackMessage(`${label} copied to clipboard`));
}}
style={{
marginRight: "5px",
width: "28px",
height: "28px",
padding: "0px",
}}
icon={<CopyIcon />}
/>
</CopyToClipboard>
}
>
{value}
</ReadBox>
</Box>
);
};
export default withStyles(styles)(CredentialItem);
export default CredentialItem;

View File

@@ -14,62 +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 React, { Fragment } from "react";
import get from "lodash/get";
import { Theme } from "@mui/material/styles";
import styled from "styled-components";
import {
Box,
Button,
DownloadIcon,
ServiceAccountCredentialsIcon,
WarnIcon,
Grid,
} from "mds";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { NewServiceAccount } from "./types";
import ModalWrapper from "../ModalWrapper/ModalWrapper";
import Grid from "@mui/material/Grid";
import CredentialItem from "./CredentialItem";
import TooltipWrapper from "../TooltipWrapper/TooltipWrapper";
import { modalStyleUtils } from "../FormComponents/common/styleLibrary";
const styles = (theme: Theme) =>
createStyles({
warningBlock: {
color: "red",
fontSize: ".85rem",
margin: ".5rem 0 .5rem 0",
display: "flex",
alignItems: "center",
"& svg ": {
marginRight: ".3rem",
height: 16,
width: 16,
},
},
credentialTitle: {
padding: ".8rem 0 0 0",
fontWeight: 600,
fontSize: ".9rem",
},
buttonContainer: {
display: "flex",
justifyContent: "flex-end",
marginTop: "1rem",
},
credentialsPanel: {
overflowY: "auto",
maxHeight: 350,
},
promptTitle: {
display: "flex",
alignItems: "center",
},
buttonSpacer: {
marginRight: ".9rem",
},
});
const WarningBlock = styled.div(({ theme }) => ({
color: "red", // TODO: Change this to themed color variant in mds
fontSize: ".85rem",
margin: ".5rem 0 .5rem 0",
display: "flex",
alignItems: "center",
"& svg ": {
marginRight: ".3rem",
height: 16,
width: 16,
},
}));
interface ICredentialsPromptProps {
classes: any;
newServiceAccount: NewServiceAccount | null;
open: boolean;
entity: string;
@@ -89,7 +64,6 @@ const download = (filename: string, text: string) => {
};
const CredentialsPrompt = ({
classes,
newServiceAccount,
open,
closeModal,
@@ -172,26 +146,35 @@ const CredentialsPrompt = ({
onClose={() => {
closeModal();
}}
title={
<div className={classes.promptTitle}>
<div>New {entity} Created</div>
</div>
}
title={`New ${entity} Created`}
titleIcon={<ServiceAccountCredentialsIcon />}
>
<Grid container>
<Grid item xs={12} className={classes.formScrollable}>
<Grid item xs={12}>
A new {entity} has been created with the following details:
{!idp && consoleCreds && (
<React.Fragment>
<Grid item xs={12} className={classes.credentialsPanel}>
<div className={classes.credentialTitle}>
<Fragment>
<Grid
item
xs={12}
sx={{
overflowY: "auto",
maxHeight: 350,
}}
>
<Box
sx={{
padding: ".8rem 0 0 0",
fontWeight: 600,
fontSize: ".9rem",
}}
>
Console Credentials
</div>
</Box>
{Array.isArray(consoleCreds) &&
consoleCreds.map((credentialsPair, index) => {
return (
<>
<Fragment>
<CredentialItem
label="Access Key"
value={credentialsPair.accessKey}
@@ -200,11 +183,11 @@ const CredentialsPrompt = ({
label="Secret Key"
value={credentialsPair.secretKey}
/>
</>
</Fragment>
);
})}
{!Array.isArray(consoleCreds) && (
<>
<Fragment>
<CredentialItem
label="Access Key"
value={consoleCreds.accessKey}
@@ -213,10 +196,10 @@ const CredentialsPrompt = ({
label="Secret Key"
value={consoleCreds.secretKey}
/>
</>
</Fragment>
)}
</Grid>
</React.Fragment>
</Fragment>
)}
{(consoleCreds === null || consoleCreds === undefined) && (
<>
@@ -231,22 +214,22 @@ const CredentialsPrompt = ({
</>
)}
{idp ? (
<div className={classes.warningBlock}>
<WarningBlock>
Please Login via the configured external identity provider.
</div>
</WarningBlock>
) : (
<div className={classes.warningBlock}>
<WarningBlock>
<WarnIcon />
<span>
Write these down, as this is the only time the secret will be
displayed.
</span>
</div>
</WarningBlock>
)}
</Grid>
<Grid item xs={12} className={classes.buttonContainer}>
<Grid item xs={12} sx={{ ...modalStyleUtils.modalButtonBar }}>
{!idp && (
<>
<Fragment>
<TooltipWrapper
tooltip={
"Download credentials in a JSON file formatted for import using mc alias import. This will only include the default login credentials."
@@ -255,7 +238,6 @@ const CredentialsPrompt = ({
<Button
id={"download-button"}
label={"Download for import"}
className={classes.buttonSpacer}
onClick={downloadImport}
icon={<DownloadIcon />}
variant="callAction"
@@ -271,7 +253,6 @@ const CredentialsPrompt = ({
<Button
id={"download-all-button"}
label={"Download all access credentials"}
className={classes.buttonSpacer}
onClick={downloaddAllCredentials}
icon={<DownloadIcon />}
variant="callAction"
@@ -279,7 +260,7 @@ const CredentialsPrompt = ({
/>
</TooltipWrapper>
)}
</>
</Fragment>
)}
</Grid>
</Grid>
@@ -287,4 +268,4 @@ const CredentialsPrompt = ({
);
};
export default withStyles(styles)(CredentialsPrompt);
export default CredentialsPrompt;

View File

@@ -908,13 +908,7 @@ export const modalStyleUtils: any = {
display: "flex",
alignItems: "center",
justifyContent: "flex-end",
"& button": {
marginRight: 10,
},
"& button:last-child": {
marginRight: 0,
},
gap: 10,
},
modalFormScrollable: {
maxHeight: "calc(100vh - 300px)",

View File

@@ -16,12 +16,14 @@
import React from "react";
import { InputBox, SearchIcon } from "mds";
import { CSSObject } from "styled-components";
type SearchBoxProps = {
placeholder?: string;
value: string;
onChange: (value: string) => void;
overrideClass?: any;
sx?: CSSObject;
};
const SearchBox = ({
@@ -29,6 +31,7 @@ const SearchBox = ({
onChange,
overrideClass,
value,
sx,
}: SearchBoxProps) => {
return (
<InputBox
@@ -45,6 +48,7 @@ const SearchBox = ({
style={{ width: 16, height: 16, marginTop: 5, marginRight: 5 }}
/>
}
sx={sx}
/>
);
};

View File

@@ -13,13 +13,12 @@
//
// 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 { DialogContentText } from "@mui/material";
import React, { Fragment } from "react";
import { ConfirmDeleteIcon } from "mds";
import { ErrorResponseHandler } from "../../../common/types";
import useApi from "../../../screens/Console/Common/Hooks/useApi";
import ConfirmDialog from "../../../screens/Console/Common/ModalWrapper/ConfirmDialog";
import { ConfirmDeleteIcon } from "mds";
import { setErrorSnackMessage } from "../../../systemSlice";
import { useAppDispatch } from "../../../store";
@@ -60,10 +59,10 @@ const DeleteMultipleSAs = ({
onConfirm={onConfirmDelete}
onClose={onClose}
confirmationContent={
<DialogContentText>
<Fragment>
Are you sure you want to delete the selected {selectedSAs.length}{" "}
Access Keys?{" "}
</DialogContentText>
</Fragment>
}
/>
);