UX Policy Summary (#1996)
This commit is contained in:
committed by
GitHub
parent
e8ccfeafe1
commit
bd63817e37
@@ -58,6 +58,7 @@ import {
|
|||||||
import withSuspense from "../Common/Components/withSuspense";
|
import withSuspense from "../Common/Components/withSuspense";
|
||||||
import { AppState } from "../../../store";
|
import { AppState } from "../../../store";
|
||||||
import RBIconButton from "../Buckets/BucketDetails/SummaryItems/RBIconButton";
|
import RBIconButton from "../Buckets/BucketDetails/SummaryItems/RBIconButton";
|
||||||
|
import PolicyView from "./PolicyView";
|
||||||
|
|
||||||
const DeletePolicy = withSuspense(React.lazy(() => import("./DeletePolicy")));
|
const DeletePolicy = withSuspense(React.lazy(() => import("./DeletePolicy")));
|
||||||
|
|
||||||
@@ -384,74 +385,7 @@ const PolicyDetails = ({
|
|||||||
<Fragment>
|
<Fragment>
|
||||||
<div className={classes.sectionTitle}>Policy Summary</div>
|
<div className={classes.sectionTitle}>Policy Summary</div>
|
||||||
<Paper className={classes.paperContainer}>
|
<Paper className={classes.paperContainer}>
|
||||||
<form
|
<PolicyView policyStatements={policyStatements} />
|
||||||
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>
|
|
||||||
</Paper>
|
</Paper>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
),
|
),
|
||||||
|
|||||||
191
portal-ui/src/screens/Console/Policies/PolicyView.tsx
Normal file
191
portal-ui/src/screens/Console/Policies/PolicyView.tsx
Normal 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);
|
||||||
Reference in New Issue
Block a user