UX Policy Summary (#1996)

This commit is contained in:
Prakash Senthil Vel
2022-05-13 19:48:48 +00:00
committed by GitHub
parent e8ccfeafe1
commit bd63817e37
2 changed files with 193 additions and 68 deletions

View File

@@ -58,6 +58,7 @@ import {
import withSuspense from "../Common/Components/withSuspense";
import { AppState } from "../../../store";
import RBIconButton from "../Buckets/BucketDetails/SummaryItems/RBIconButton";
import PolicyView from "./PolicyView";
const DeletePolicy = withSuspense(React.lazy(() => import("./DeletePolicy")));
@@ -384,74 +385,7 @@ const PolicyDetails = ({
<Fragment>
<div className={classes.sectionTitle}>Policy Summary</div>
<Paper className={classes.paperContainer}>
<form
noValidate
autoComplete="off"
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
saveRecord(e);
}}
>
<Grid container>
<Grid item xs={8}>
<h4>Statements</h4>
</Grid>
<Grid item xs={4} />
<Fragment>
{policyStatements.map((stmt, i) => {
return (
<Grid
item
xs={12}
className={classes.statement}
key={`s-${i}`}
>
<Grid container>
<Grid item xs={2} className={classes.labelCol}>
Effect
</Grid>
<Grid item xs={4}>
<Fragment>{stmt.Effect}</Fragment>
</Grid>
<Grid
item
xs={2}
className={classes.labelCol}
/>
<Grid item xs={4} />
<Grid item xs={2} className={classes.labelCol}>
Actions
</Grid>
<Grid item xs={4}>
<ul>
{stmt.Action &&
stmt.Action.map((act, actIndex) => (
<li key={`${i}-r-${actIndex}`}>
{act}
</li>
))}
</ul>
</Grid>
<Grid item xs={2} className={classes.labelCol}>
Resources
</Grid>
<Grid item xs={4}>
<ul>
{stmt.Resource &&
stmt.Resource.map((res, resIndex) => (
<li key={`${i}-r-${resIndex}`}>
{res}
</li>
))}
</ul>
</Grid>
</Grid>
</Grid>
);
})}
</Fragment>
</Grid>
</form>
<PolicyView policyStatements={policyStatements} />
</Paper>
</Fragment>
),

View File

@@ -0,0 +1,191 @@
// 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, { useState } from "react";
import { IAMStatement } from "./types";
import { Box } from "@mui/material";
import Grid from "@mui/material/Grid";
import SearchBox from "../Common/SearchBox";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import { searchField } from "../Common/FormComponents/common/styleLibrary";
import withStyles from "@mui/styles/withStyles";
import { DisabledIcon, EnabledIcon } from "../../../icons";
import { STATUS_COLORS } from "../Dashboard/BasicDashboard/Utils";
const styles = (theme: Theme) =>
createStyles({
searchField: {
...searchField.searchField,
maxWidth: 380,
},
});
const rowGridStyle = {
display: "grid",
gridTemplateColumns: "60px 1fr",
gap: "15px",
};
const escapeRegExp = (str = "") =>
str.replace(/([.?*+^$[\]\\(){}|-])/g, "\\$1");
const Highlight = ({ search = "", children = "" }): any => {
const txtParts = new RegExp(`(${escapeRegExp(search)})`, "i");
const parts = String(children).split(txtParts);
if (search) {
return parts.map((part, index) =>
txtParts.test(part) ? <mark key={index}>{part}</mark> : part
);
} else {
return children;
}
};
const PolicyView = ({
policyStatements,
classes = {},
}: {
policyStatements: IAMStatement[];
classes?: any;
}) => {
const [filter, setFilter] = useState<string>("");
return (
<Grid container>
<Grid item xs={12}>
<Box
sx={{
display: "grid",
gridTemplateColumns: {
sm: "1fr 1fr",
xs: "1fr",
},
alignItems: "center",
justifyContent: "space-between",
gap: "15px",
}}
>
<Box>Statements</Box>
<SearchBox
placeholder={"Search"}
onChange={setFilter}
overrideClass={classes.searchField}
value={filter}
/>
</Box>
</Grid>
<Grid
item
xs={12}
sx={{
"& .policy-row": {
borderBottom: "1px solid #eaeaea",
},
"& .policy-row:first-child": {
borderTop: "1px solid #eaeaea",
},
"& .policy-row:last-child": {
borderBottom: "0px",
},
paddingTop: "15px",
"& mark": {
color: "#000000",
fontWeight: 500,
},
}}
>
{policyStatements.map((stmt, i) => {
const effect = stmt.Effect;
const isAllow = effect === "Allow";
return (
<Box
className="policy-row"
key={`${i}`}
sx={{
display: "grid",
gridTemplateColumns: "1fr",
gap: "15px",
fontSize: "14px",
padding: "10px 0 10px 0",
"& .label": {
fontWeight: 600,
},
}}
>
<Box sx={rowGridStyle}>
<Box className="label">Effect:</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
"& .min-icon": {
marginRight: "5px",
fill: isAllow ? STATUS_COLORS.GREEN : STATUS_COLORS.RED,
height: "14px",
width: "14px",
},
}}
>
{isAllow ? <EnabledIcon /> : <DisabledIcon />}
{effect}
</Box>
</Box>
<Box
sx={{
display: "grid",
gridTemplateColumns: {
sm: "1fr 1fr",
xs: "1fr",
},
gap: "15px",
}}
>
<Box sx={rowGridStyle}>
<Box className="label">Actions:</Box>
<Box>
{stmt.Action &&
stmt.Action.map((act, actIndex) => (
<div key={`${i}-r-${actIndex}`}>
<Highlight search={filter}>{act}</Highlight>
</div>
))}
</Box>
</Box>
<Box sx={rowGridStyle}>
<Box className="label">Resources:</Box>
<Box>
{stmt.Resource &&
stmt.Resource.map((res, resIndex) => (
<div key={`${i}-r-${resIndex}`}>
{" "}
<Highlight search={filter}>{res}</Highlight>
</div>
))}
</Box>
</Box>
</Box>
</Box>
);
})}
</Grid>
</Grid>
);
};
export default withStyles(styles)(PolicyView);