Set Policy UI (#138)

This commit is contained in:
Daniel Valdivia
2020-05-22 08:48:55 -07:00
committed by GitHub
parent 13ef83cee4
commit 37195fefa8
5 changed files with 245 additions and 2 deletions

View File

@@ -20,6 +20,7 @@ import ViewIcon from "./TableActionIcons/ViewIcon";
import PencilIcon from "./TableActionIcons/PencilIcon";
import DeleteIcon from "./TableActionIcons/DeleteIcon";
import { Link } from "react-router-dom";
import DescriptionIcon from "@material-ui/icons/Description";
interface IActionButton {
type: string;
@@ -39,6 +40,8 @@ const defineIcon = (type: string, selected: boolean) => {
return <PencilIcon active={selected} />;
case "delete":
return <DeleteIcon active={selected} />;
case "description":
return <DescriptionIcon />;
}
return null;
@@ -51,13 +54,14 @@ const TableActionButton = ({
idField,
selected,
to,
sendOnlyId = false
sendOnlyId = false,
}: IActionButton) => {
const valueClick = sendOnlyId ? valueToSend[idField] : valueToSend;
const buttonElement = (
<IconButton
aria-label={type}
size={"small"}
onClick={
onClick
? () => {

View File

@@ -130,7 +130,7 @@ const styles = (theme: Theme) =>
},
},
actionsContainer: {
width: 120,
width: 150,
borderColor: borderColor,
},
paginatorComponent: {

View File

@@ -0,0 +1,201 @@
// This file is part of MinIO Console Server
// Copyright (c) 2020 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, { useCallback, useEffect, useState } from "react";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import {
Button,
FormControlLabel,
LinearProgress,
Paper,
Switch,
Table,
TableBody,
TableCell,
TableContainer,
TableHead,
TableRow,
} from "@material-ui/core";
import Grid from "@material-ui/core/Grid";
import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
import { RadioGroupSelector } from "../Common/FormComponents/RadioGroupSelector/RadioGroupSelector";
import { modalBasic } from "../Common/FormComponents/common/styleLibrary";
import { IElementValue } from "../Configurations/types";
import { User } from "../Users/types";
import ModalWrapper from "../Common/ModalWrapper/ModalWrapper";
import { Policy, PolicyList } from "./types";
import api from "../../../common/api";
import { policySort } from "../../../utils/sortFunctions";
interface ISetPolicyProps {
classes: any;
closeModalAndRefresh: () => void;
selectedUser: User | null;
open: boolean;
}
const styles = (theme: Theme) =>
createStyles({
...modalBasic,
});
const SetPolicy = ({
classes,
closeModalAndRefresh,
selectedUser,
open,
}: ISetPolicyProps) => {
//Local States
const [useConnectionString, setUseConnectionString] = useState<boolean>(
false
);
const [connectionString, setConnectionString] = useState<string>("");
const [host, setHostname] = useState<string>("");
const [dbName, setDbName] = useState<string>("");
const [port, setPort] = useState<string>("");
const [user, setUser] = useState<string>("");
const [password, setPassword] = useState<string>("");
const [sslMode, setSslMode] = useState<string>("require");
const [table, setTable] = useState<string>("");
const [format, setFormat] = useState<string>("namespace");
const [queueDir, setQueueDir] = useState<string>("");
const [queueLimit, setQueueLimit] = useState<string>("");
const [comment, setComment] = useState<string>("");
const [records, setRecords] = useState<Policy[]>([]);
const [loading, setLoading] = useState<boolean>(false);
const [error, setError] = useState<string>("");
const fetchRecords = () => {
setLoading(true);
api
.invoke("GET", `/api/v1/policies?limit=1000`)
.then((res: PolicyList) => {
const policies = res.policies === null ? [] : res.policies;
setLoading(false);
setRecords(policies.sort(policySort));
setError("");
})
.catch((err) => {
setLoading(false);
setError(err);
});
};
const setPolicyAction = (policyName: string) => {
if (selectedUser === null) {
return;
}
setLoading(true);
api
.invoke("PUT", `/api/v1/set-policy/${policyName}`, {
entityName: selectedUser!.accessKey,
entityType: "user",
})
.then((res: any) => {
setLoading(false);
setError("");
closeModalAndRefresh();
})
.catch((err) => {
setLoading(false);
setError(err);
});
};
useEffect(() => {
if (open) {
console.log("im open");
console.log(selectedUser);
fetchRecords();
}
}, []);
return (
<ModalWrapper
onClose={() => {
closeModalAndRefresh();
}}
modalOpen={open}
title={
selectedUser !== null ? "Set Policy to User" : "Set Policy to Group"
}
>
<Grid container className={classes.formScrollable}>
<Grid item xs={12}>
<TableContainer component={Paper}>
<Table
className={classes.table}
size="small"
aria-label="a dense table"
>
<TableHead>
<TableRow>
<TableCell>Policy</TableCell>
<TableCell align="right"></TableCell>
</TableRow>
</TableHead>
<TableBody>
{records.map((row) => (
<TableRow key={row.name}>
<TableCell component="th" scope="row">
{row.name}
</TableCell>
<TableCell align="right">
<Button
variant="contained"
color="primary"
size={"small"}
onClick={() => {
setPolicyAction(row.name);
}}
>
Set
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TableContainer>
</Grid>
<Grid item xs={12} className={classes.buttonContainer}>
<Button
type="submit"
variant="contained"
color="primary"
size={"small"}
onClick={() => {
closeModalAndRefresh();
}}
>
Cancel
</Button>
</Grid>
{loading && (
<Grid item xs={12}>
<LinearProgress />
</Grid>
)}
</Grid>
</ModalWrapper>
);
};
export default withStyles(styles)(SetPolicy);

View File

@@ -34,6 +34,8 @@ import AddUser from "./AddUser";
import DeleteUser from "./DeleteUser";
import AddToGroup from "./AddToGroup";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import DescriptionIcon from "@material-ui/icons/Description";
import SetPolicy from "../Policies/SetPolicy";
const styles = (theme: Theme) =>
createStyles({
@@ -102,6 +104,7 @@ interface IUsersState {
addGroupOpen: boolean;
filter: string;
checkedUsers: string[];
setPolicyOpen: boolean;
}
class Users extends React.Component<IUsersProps, IUsersState> {
@@ -119,6 +122,7 @@ class Users extends React.Component<IUsersProps, IUsersState> {
addGroupOpen: false,
filter: "",
checkedUsers: [],
setPolicyOpen: false,
};
fetchRecords() {
@@ -192,6 +196,7 @@ class Users extends React.Component<IUsersProps, IUsersState> {
filter,
checkedUsers,
addGroupOpen,
setPolicyOpen,
} = this.state;
const handleChangePage = (event: unknown, newPage: number) => {
@@ -243,6 +248,14 @@ class Users extends React.Component<IUsersProps, IUsersState> {
});
};
const setPolicyAction = (selectionElement: any): void => {
console.log("click");
this.setState({
setPolicyOpen: true,
selectedUser: selectionElement,
});
};
const deleteAction = (selectionElement: any): void => {
this.setState({
deleteOpen: true,
@@ -251,6 +264,7 @@ class Users extends React.Component<IUsersProps, IUsersState> {
};
const tableActions = [
{ type: "description", onClick: setPolicyAction },
{ type: "view", onClick: viewAction },
{ type: "delete", onClick: deleteAction },
];
@@ -266,6 +280,15 @@ class Users extends React.Component<IUsersProps, IUsersState> {
}}
/>
)}
{setPolicyOpen && (
<SetPolicy
open={setPolicyOpen}
selectedUser={selectedUser}
closeModalAndRefresh={() => {
this.setState({ setPolicyOpen: false });
}}
/>
)}
{deleteOpen && (
<DeleteUser
deleteOpen={deleteOpen}

View File

@@ -18,6 +18,10 @@ interface userInterface {
accessKey: string;
}
interface policyInterface {
name: string;
}
export const usersSort = (a: userInterface, b: userInterface) => {
if (a.accessKey > b.accessKey) {
return 1;
@@ -29,6 +33,17 @@ export const usersSort = (a: userInterface, b: userInterface) => {
return 0;
};
export const policySort = (a: policyInterface, b: policyInterface) => {
if (a.name > b.name) {
return 1;
}
if (a.name < b.name) {
return -1;
}
// a must be equal to b
return 0;
};
export const stringSort = (a: string, b: string) => {
if (a > b) {
return 1;