Service account ux (#1229)
Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
373bfbfe3f
commit
70a4d76283
81
portal-ui/src/icons/NewAccountIcon.tsx
Normal file
81
portal-ui/src/icons/NewAccountIcon.tsx
Normal file
@@ -0,0 +1,81 @@
|
||||
// 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 { SvgIcon } from "@mui/material";
|
||||
const NewAccountIcon = () => {
|
||||
return (
|
||||
<SvgIcon>
|
||||
<svg
|
||||
id="Account_Icon"
|
||||
data-name="Account Icon"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 16.409 13.096"
|
||||
>
|
||||
<path
|
||||
id="Trazado_391"
|
||||
data-name="Trazado 391"
|
||||
d="M-4332.855-1143.481a3.023,3.023,0,0,0,2.958-3.078,3.023,3.023,0,0,0-2.958-3.078,3.023,3.023,0,0,0-2.958,3.078A3.023,3.023,0,0,0-4332.855-1143.481Zm0-5.194a2.078,2.078,0,0,1,2.03,2.116,2.077,2.077,0,0,1-2.03,2.116,2.075,2.075,0,0,1-2.028-2.116A2.076,2.076,0,0,1-4332.855-1148.675Z"
|
||||
transform="translate(4339.12 1149.637)"
|
||||
fill="#07193e"
|
||||
/>
|
||||
<path
|
||||
id="Trazado_392"
|
||||
data-name="Trazado 392"
|
||||
d="M-4337.952-1130.053a1.374,1.374,0,0,0,1.252.775h4.993a1.354,1.354,0,0,0,1.25-.786,1.675,1.675,0,0,0-.164-1.686,4.521,4.521,0,0,0-1.7-1.405,4.361,4.361,0,0,0-2.125-.438,4.483,4.483,0,0,0-3.318,1.808c-.026.035-.051.071-.075.106A1.641,1.641,0,0,0-4337.952-1130.053Zm6.663-.437a.426.426,0,0,1-.417.25h-4.993a.453.453,0,0,1-.427-.254.64.64,0,0,1,.053-.632h0c.017-.027.037-.054.057-.08a3.539,3.539,0,0,1,2.622-1.424c.056,0,.113,0,.168,0a3.606,3.606,0,0,1,2.864,1.466A.686.686,0,0,1-4331.29-1130.49Z"
|
||||
transform="translate(4340.467 1140.236)"
|
||||
fill="#07193e"
|
||||
/>
|
||||
<path
|
||||
id="Trazado_393"
|
||||
data-name="Trazado 393"
|
||||
d="M-4329.387-1146.951h-3.506a.476.476,0,0,0-.477.476.477.477,0,0,0,.477.476h3.506a1.047,1.047,0,0,1,1.046,1.045v7.99a1.047,1.047,0,0,1-1.046,1.045H-4341.8a1.047,1.047,0,0,1-1.046-1.045v-7.99A1.048,1.048,0,0,1-4341.8-1146a.476.476,0,0,0,.476-.476.476.476,0,0,0-.476-.476,2,2,0,0,0-2,2v7.99a2,2,0,0,0,2,2h12.412a2,2,0,0,0,2-2v-7.99A2,2,0,0,0-4329.387-1146.951Z"
|
||||
transform="translate(4343.797 1148.063)"
|
||||
fill="#07193e"
|
||||
/>
|
||||
<rect
|
||||
id="Rectángulo_809"
|
||||
data-name="Rectángulo 809"
|
||||
width="3.266"
|
||||
height="2.781"
|
||||
rx="1.024"
|
||||
transform="translate(11.002 3.376)"
|
||||
fill="#07193e"
|
||||
/>
|
||||
<rect
|
||||
id="Rectángulo_810"
|
||||
data-name="Rectángulo 810"
|
||||
width="3.266"
|
||||
height="1.336"
|
||||
rx="0.668"
|
||||
transform="translate(11.002 7.328)"
|
||||
fill="#07193e"
|
||||
/>
|
||||
<rect
|
||||
id="Rectángulo_811"
|
||||
data-name="Rectángulo 811"
|
||||
width="3.266"
|
||||
height="1.336"
|
||||
rx="0.668"
|
||||
transform="translate(11.002 9.621)"
|
||||
fill="#07193e"
|
||||
/>
|
||||
</svg>
|
||||
</SvgIcon>
|
||||
);
|
||||
};
|
||||
|
||||
export default NewAccountIcon;
|
||||
35
portal-ui/src/icons/WarnIcon.tsx
Normal file
35
portal-ui/src/icons/WarnIcon.tsx
Normal file
@@ -0,0 +1,35 @@
|
||||
// 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";
|
||||
|
||||
const WarnIcon = () => {
|
||||
return (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
|
||||
<circle
|
||||
cx="8"
|
||||
cy="8"
|
||||
r="7"
|
||||
fill="none"
|
||||
stroke="#e04006"
|
||||
stroke-width="2"
|
||||
/>
|
||||
<path fill="none" stroke="#e04006" stroke-width="2" d="M8 4v6m0 1v2" />
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default WarnIcon;
|
||||
@@ -21,7 +21,10 @@ import { Button, LinearProgress } from "@mui/material";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { modalBasic } from "../Common/FormComponents/common/styleLibrary";
|
||||
import {
|
||||
modalBasic,
|
||||
serviceAccountStyles,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import { NewServiceAccount } from "../Common/CredentialsPrompt/types";
|
||||
import { setModalErrorSnackMessage } from "../../../actions";
|
||||
import { ErrorResponseHandler } from "../../../common/types";
|
||||
@@ -33,26 +36,7 @@ import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWr
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
jsonPolicyEditor: {
|
||||
minHeight: 400,
|
||||
width: "100%",
|
||||
},
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
infoDetails: {
|
||||
color: "#393939",
|
||||
fontSize: 12,
|
||||
fontStyle: "italic",
|
||||
marginBottom: "8px",
|
||||
},
|
||||
containerScrollable: {
|
||||
maxHeight: "calc(100vh - 300px)" as const,
|
||||
overflowY: "auto" as const,
|
||||
},
|
||||
codeMirrorContainer: {
|
||||
marginBottom: 20,
|
||||
},
|
||||
...serviceAccountStyles,
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
@@ -156,19 +140,11 @@ const AddServiceAccount = ({
|
||||
after saving.
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
value="locking"
|
||||
id="locking"
|
||||
name="locking"
|
||||
checked={isRestrictedByPolicy}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setIsRestrictedByPolicy(event.target.checked);
|
||||
}}
|
||||
label={"Restrict with policy"}
|
||||
/>
|
||||
<FormSwitchWrapper
|
||||
value="locking"
|
||||
classes={classes}
|
||||
id="locking"
|
||||
name="locking"
|
||||
checked={addCredentials}
|
||||
@@ -177,19 +153,9 @@ const AddServiceAccount = ({
|
||||
}}
|
||||
label={"Customize Credentials"}
|
||||
/>
|
||||
</Grid>
|
||||
{isRestrictedByPolicy && (
|
||||
<Grid item xs={12} className={classes.codeMirrorContainer}>
|
||||
<CodeMirrorWrapper
|
||||
value={policyDefinition}
|
||||
onBeforeChange={(editor, data, value) => {
|
||||
setPolicyDefinition(value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
{addCredentials && (
|
||||
<Grid item xs={12}>
|
||||
<div className={classes.stackedInputs}>
|
||||
<InputBoxWrapper
|
||||
value={accessKey}
|
||||
label={"Access Key"}
|
||||
@@ -210,19 +176,47 @@ const AddServiceAccount = ({
|
||||
setSecretKey(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
value="locking"
|
||||
id="locking"
|
||||
name="locking"
|
||||
classes={classes}
|
||||
checked={isRestrictedByPolicy}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setIsRestrictedByPolicy(event.target.checked);
|
||||
}}
|
||||
label={"Restrict with policy"}
|
||||
/>
|
||||
{isRestrictedByPolicy && (
|
||||
<Grid item xs={12} className={classes.codeMirrorContainer}>
|
||||
<CodeMirrorWrapper
|
||||
label={"Policy "}
|
||||
value={policyDefinition}
|
||||
onBeforeChange={(editor, data, value) => {
|
||||
setPolicyDefinition(value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<button
|
||||
<Button
|
||||
type="button"
|
||||
color="primary"
|
||||
className={classes.clearButton}
|
||||
variant="outlined"
|
||||
className={classes.buttonSpacer}
|
||||
onClick={resetForm}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
// 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 { InputAdornment, OutlinedInput } from "@mui/material";
|
||||
import BoxIconButton from "../BoxIconButton/BoxIconButton";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import CopyToClipboard from "react-copy-to-clipboard";
|
||||
import { CopyIcon } from "../../../../icons";
|
||||
|
||||
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 .MuiSvgIcon-root": {
|
||||
fontSize: ".8rem",
|
||||
},
|
||||
},
|
||||
inputLabel: {
|
||||
fontSize: ".8rem",
|
||||
fontWeight: 600,
|
||||
},
|
||||
});
|
||||
|
||||
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">
|
||||
<CopyToClipboard text={value}>
|
||||
<BoxIconButton
|
||||
aria-label="copy"
|
||||
tooltip={"Copy"}
|
||||
onClick={() => {}}
|
||||
onMouseDown={() => {}}
|
||||
edge="end"
|
||||
>
|
||||
<CopyIcon />
|
||||
</BoxIconButton>
|
||||
</CopyToClipboard>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(CredentialItem);
|
||||
@@ -21,22 +21,52 @@ import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { NewServiceAccount } from "./types";
|
||||
import { Button } from "@mui/material";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import ModalWrapper from "../ModalWrapper/ModalWrapper";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import CredentialItem from "./CredentialItem";
|
||||
import NewAccountIcon from "../../../../icons/NewAccountIcon";
|
||||
import WarnIcon from "../../../../icons/WarnIcon";
|
||||
import { DownloadIcon } from "../../../../icons";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
warningBlock: {
|
||||
color: "red",
|
||||
fontSize: ".85rem",
|
||||
margin: ".5rem 0 .5rem 0",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
"& svg ": {
|
||||
marginRight: ".3rem",
|
||||
},
|
||||
},
|
||||
credentialTitle: {
|
||||
padding: ".8rem 0 0 0",
|
||||
fontWeight: 600,
|
||||
fontSize: ".9rem",
|
||||
},
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
marginTop: "1rem",
|
||||
},
|
||||
credentialsPanel: {
|
||||
overflowY: "auto",
|
||||
maxHeight: 350,
|
||||
},
|
||||
promptTitle: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
},
|
||||
buttonSpacer: {
|
||||
marginRight: ".9rem",
|
||||
},
|
||||
promptIcon: {
|
||||
marginRight: ".1rem",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
height: "2rem",
|
||||
width: "2rem",
|
||||
},
|
||||
});
|
||||
|
||||
interface ICredentialsPromptProps {
|
||||
@@ -83,62 +113,80 @@ const CredentialsPrompt = ({
|
||||
onClose={() => {
|
||||
closeModal();
|
||||
}}
|
||||
title={`New ${entity} Created`}
|
||||
title={
|
||||
<div className={classes.promptTitle}>
|
||||
<div className={classes.promptIcon}>
|
||||
<NewAccountIcon />
|
||||
</div>{" "}
|
||||
<div>New {entity} Created</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<React.Fragment>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.formScrollable}>
|
||||
A new {entity} has been created with the following details:
|
||||
{!idp && consoleCreds && (
|
||||
<React.Fragment>
|
||||
<Grid item xs={12} className={classes.credentialsPanel}>
|
||||
<strong>Console Credentials</strong>
|
||||
<div className={classes.credentialTitle}>
|
||||
Console Credentials
|
||||
</div>
|
||||
{Array.isArray(consoleCreds) &&
|
||||
consoleCreds.map((credentialsPair, index) => {
|
||||
return (
|
||||
<ul key={`creds-item-${index.toString()}`}>
|
||||
<li>
|
||||
<b>Access Key:</b> {credentialsPair.accessKey}
|
||||
</li>
|
||||
<li>
|
||||
<b>Secret Key:</b> {credentialsPair.secretKey}
|
||||
</li>
|
||||
</ul>
|
||||
<>
|
||||
<CredentialItem
|
||||
label="Access Key"
|
||||
value={credentialsPair.accessKey}
|
||||
/>
|
||||
<CredentialItem
|
||||
label="Secret Key"
|
||||
value={credentialsPair.secretKey}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
})}
|
||||
{!Array.isArray(consoleCreds) && (
|
||||
<ul>
|
||||
<li>
|
||||
<b>Access Key:</b> {consoleCreds.accessKey}
|
||||
</li>
|
||||
<li>
|
||||
<b>Secret Key:</b> {consoleCreds.secretKey}
|
||||
</li>
|
||||
</ul>
|
||||
<>
|
||||
<CredentialItem
|
||||
label="Access Key"
|
||||
value={consoleCreds.accessKey}
|
||||
/>
|
||||
<CredentialItem
|
||||
label="Secret Key"
|
||||
value={consoleCreds.secretKey}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{idp ? (
|
||||
<Typography
|
||||
component="p"
|
||||
variant="body1"
|
||||
className={classes.warningBlock}
|
||||
>
|
||||
<div className={classes.warningBlock}>
|
||||
Please Login via the configured external identity provider.
|
||||
</Typography>
|
||||
</div>
|
||||
) : (
|
||||
<Typography
|
||||
component="p"
|
||||
variant="body1"
|
||||
className={classes.warningBlock}
|
||||
>
|
||||
<div className={classes.warningBlock}>
|
||||
<WarnIcon />
|
||||
<span>
|
||||
Write these down, as this is the only time the secret will be
|
||||
displayed.
|
||||
</Typography>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<Button
|
||||
variant="outlined"
|
||||
className={classes.buttonSpacer}
|
||||
onClick={() => {
|
||||
closeModal();
|
||||
}}
|
||||
color="primary"
|
||||
>
|
||||
Done
|
||||
</Button>
|
||||
|
||||
{!idp && (
|
||||
<Button
|
||||
onClick={() => {
|
||||
@@ -175,23 +223,15 @@ const CredentialsPrompt = ({
|
||||
})
|
||||
);
|
||||
}}
|
||||
endIcon={<DownloadIcon />}
|
||||
variant="contained"
|
||||
color="primary"
|
||||
>
|
||||
Download
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
onClick={() => {
|
||||
closeModal();
|
||||
}}
|
||||
color="secondary"
|
||||
autoFocus
|
||||
>
|
||||
Done
|
||||
</Button>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
</ModalWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -253,7 +253,13 @@ const FormSwitchWrapper = ({
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
<Grid item xs={12} sm={2} textAlign={"right"}>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
sm={2}
|
||||
textAlign={"right"}
|
||||
className={classes.switchContainer}
|
||||
>
|
||||
{switchComponent}
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -1011,3 +1011,51 @@ export const linkStyles = (color: string) => ({
|
||||
cursor: "pointer",
|
||||
},
|
||||
});
|
||||
|
||||
export const serviceAccountStyles: any = {
|
||||
jsonPolicyEditor: {
|
||||
minHeight: 400,
|
||||
width: "100%",
|
||||
},
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
infoDetails: {
|
||||
color: "#393939",
|
||||
fontSize: 12,
|
||||
fontStyle: "italic",
|
||||
marginBottom: "8px",
|
||||
},
|
||||
containerScrollable: {
|
||||
maxHeight: "calc(100vh - 200px)" as const,
|
||||
overflowY: "auto" as const,
|
||||
},
|
||||
codeMirrorContainer: {
|
||||
marginBottom: 20,
|
||||
paddingLeft: 15,
|
||||
"&:nth-child(2) .MuiGrid-root:nth-child(3)": {
|
||||
border: "1px solid #EAEAEA",
|
||||
},
|
||||
"& label": {
|
||||
marginBottom: ".5rem",
|
||||
},
|
||||
"& label + div": {
|
||||
display: "none",
|
||||
},
|
||||
},
|
||||
stackedInputs: {
|
||||
display: "flex",
|
||||
gap: 15,
|
||||
paddingBottom: "1rem",
|
||||
paddingLeft: "1rem",
|
||||
flexFlow: "column",
|
||||
},
|
||||
buttonSpacer: {
|
||||
marginRight: "1rem",
|
||||
},
|
||||
switchContainer: {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "flex-end",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -31,7 +31,7 @@ interface IModalProps {
|
||||
classes: any;
|
||||
onClose: () => void;
|
||||
modalOpen: boolean;
|
||||
title: string;
|
||||
title: string | React.ReactNode;
|
||||
children: any;
|
||||
wideLimit?: boolean;
|
||||
modalSnackMessage?: snackBarMessage;
|
||||
@@ -56,8 +56,8 @@ const styles = (theme: Theme) =>
|
||||
textAlign: "right",
|
||||
},
|
||||
closeButton: {
|
||||
width: 45,
|
||||
height: 45,
|
||||
height: 16,
|
||||
width: 16,
|
||||
padding: 0,
|
||||
backgroundColor: "initial",
|
||||
"&:hover": {
|
||||
@@ -79,31 +79,29 @@ const styles = (theme: Theme) =>
|
||||
"&::before": {
|
||||
...baseCloseLine,
|
||||
transform: "rotate(45deg)",
|
||||
height: 12,
|
||||
},
|
||||
"&::after": {
|
||||
...baseCloseLine,
|
||||
transform: "rotate(-45deg)",
|
||||
height: 12,
|
||||
},
|
||||
"&:hover::before, &:hover::after": {
|
||||
borderColor: "#9C9C9C",
|
||||
},
|
||||
width: 24,
|
||||
height: 24,
|
||||
display: "block",
|
||||
position: "relative",
|
||||
height: 12,
|
||||
width: 12,
|
||||
},
|
||||
titleClass: {
|
||||
padding: "0px 50px 12px",
|
||||
"& h2": {
|
||||
fontSize: "1.2rem",
|
||||
fontWeight: 600,
|
||||
color: "#000",
|
||||
fontSize: 22,
|
||||
width: "100%",
|
||||
overflow: "hidden",
|
||||
whiteSpace: "nowrap",
|
||||
textOverflow: "ellipsis",
|
||||
},
|
||||
},
|
||||
modalContent: {
|
||||
padding: "0 50px",
|
||||
},
|
||||
|
||||
@@ -21,7 +21,10 @@ import { Button, LinearProgress } from "@mui/material";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import { modalBasic } from "../Common/FormComponents/common/styleLibrary";
|
||||
import {
|
||||
modalBasic,
|
||||
serviceAccountStyles,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import { NewServiceAccount } from "../Common/CredentialsPrompt/types";
|
||||
import { setModalErrorSnackMessage } from "../../../actions";
|
||||
import { ErrorResponseHandler } from "../../../common/types";
|
||||
@@ -33,23 +36,7 @@ import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWr
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
jsonPolicyEditor: {
|
||||
minHeight: 400,
|
||||
width: "100%",
|
||||
},
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
infoDetails: {
|
||||
color: "#393939",
|
||||
fontSize: 12,
|
||||
fontStyle: "italic",
|
||||
marginBottom: "8px",
|
||||
},
|
||||
containerScrollable: {
|
||||
maxHeight: "calc(100vh - 300px)" as const,
|
||||
overflowY: "auto" as const,
|
||||
},
|
||||
...serviceAccountStyles,
|
||||
...modalBasic,
|
||||
});
|
||||
|
||||
@@ -156,18 +143,10 @@ const AddUserServiceAccount = ({
|
||||
after saving.
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
value="locking"
|
||||
id="locking"
|
||||
name="locking"
|
||||
checked={isRestrictedByPolicy}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setIsRestrictedByPolicy(event.target.checked);
|
||||
}}
|
||||
label={"Restrict with policy"}
|
||||
/>
|
||||
<FormSwitchWrapper
|
||||
classes={classes}
|
||||
value="locking"
|
||||
id="locking"
|
||||
name="locking"
|
||||
@@ -177,19 +156,10 @@ const AddUserServiceAccount = ({
|
||||
}}
|
||||
label={"Customize Credentials"}
|
||||
/>
|
||||
</Grid>
|
||||
{isRestrictedByPolicy && (
|
||||
<Grid item xs={12}>
|
||||
<CodeMirrorWrapper
|
||||
value={policyDefinition}
|
||||
onBeforeChange={(editor, data, value) => {
|
||||
setPolicyDefinition(value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
{addCredentials && (
|
||||
<Grid item xs={12}>
|
||||
<div className={classes.stackedInputs}>
|
||||
<InputBoxWrapper
|
||||
value={accessKey}
|
||||
label={"Access Key"}
|
||||
@@ -210,19 +180,48 @@ const AddUserServiceAccount = ({
|
||||
setSecretKey(e.target.value);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<FormSwitchWrapper
|
||||
value="locking"
|
||||
id="locking"
|
||||
name="locking"
|
||||
classes={classes}
|
||||
checked={isRestrictedByPolicy}
|
||||
onChange={(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setIsRestrictedByPolicy(event.target.checked);
|
||||
}}
|
||||
label={"Restrict with policy"}
|
||||
/>
|
||||
|
||||
{isRestrictedByPolicy && (
|
||||
<Grid item xs={12} className={classes.codeMirrorContainer}>
|
||||
<CodeMirrorWrapper
|
||||
label={"Policy "}
|
||||
value={policyDefinition}
|
||||
onBeforeChange={(editor, data, value) => {
|
||||
setPolicyDefinition(value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<button
|
||||
<Button
|
||||
type="button"
|
||||
color="primary"
|
||||
className={classes.clearButton}
|
||||
variant="outlined"
|
||||
className={classes.buttonSpacer}
|
||||
onClick={resetForm}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
</Button>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
|
||||
Reference in New Issue
Block a user