Skip to content

Commit 003eaae

Browse files
authored
Group bucket users and policies under access tab. Rename ViewBuckets to BucketDetails (#766)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
1 parent d835062 commit 003eaae

15 files changed

+201
-122
lines changed
Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
// This file is part of MinIO Console Server
2+
// Copyright (c) 2021 MinIO, Inc.
3+
//
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
8+
//
9+
// This program is distributed in the hope that it will be useful,
10+
// but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
// GNU Affero General Public License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
import React, { useEffect, useState } from "react";
18+
import { connect } from "react-redux";
19+
import { AppState } from "../../../../store";
20+
import { setErrorSnackMessage } from "../../../../actions";
21+
import Tabs from "@material-ui/core/Tabs";
22+
import Tab from "@material-ui/core/Tab";
23+
import { Paper } from "@material-ui/core";
24+
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
25+
import { TabPanel } from "../../../shared/tabs";
26+
import { Policy } from "../../Policies/types";
27+
import { ISessionResponse } from "../../types";
28+
import { User } from "../../Users/types";
29+
import api from "../../../../common/api";
30+
import history from "../../../../history";
31+
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
32+
33+
const styles = (theme: Theme) => createStyles({});
34+
35+
const mapState = (state: AppState) => ({
36+
session: state.console.session,
37+
});
38+
39+
const connector = connect(mapState, { setErrorSnackMessage });
40+
41+
function a11yProps(index: any) {
42+
return {
43+
id: `simple-tab-${index}`,
44+
"aria-controls": `simple-tabpanel-${index}`,
45+
};
46+
}
47+
48+
interface IAccessDetailsProps {
49+
bucketName: string;
50+
session: ISessionResponse;
51+
setErrorSnackMessage: typeof setErrorSnackMessage;
52+
classes: any;
53+
}
54+
55+
const AccessDetails = ({
56+
bucketName,
57+
classes,
58+
setErrorSnackMessage,
59+
session,
60+
}: IAccessDetailsProps) => {
61+
const [curTab, setCurTab] = useState<number>(0);
62+
const [loadingPolicies, setLoadingPolicies] = useState<boolean>(true);
63+
const [bucketPolicy, setBucketPolicy] = useState<Policy[]>([]);
64+
const [loadingUsers, setLoadingUsers] = useState<boolean>(true);
65+
const [bucketUsers, setBucketUsers] = useState<User[]>([]);
66+
67+
const usersEnabled = session.pages?.indexOf("/users") > -1;
68+
69+
const PolicyActions = [
70+
{
71+
type: "view",
72+
onClick: (policy: any) => {
73+
history.push(`/policies/${policy.name}`);
74+
},
75+
},
76+
];
77+
78+
const userTableActions = [
79+
{
80+
type: "view",
81+
onClick: (user: any) => {
82+
history.push(`/users/${user}`);
83+
},
84+
},
85+
];
86+
87+
useEffect(() => {
88+
if (loadingUsers && usersEnabled) {
89+
api
90+
.invoke("GET", `/api/v1/bucket-users/${bucketName}`)
91+
.then((res: any) => {
92+
setBucketUsers(res);
93+
setLoadingUsers(false);
94+
})
95+
.catch((err: any) => {
96+
setErrorSnackMessage(err);
97+
setLoadingUsers(false);
98+
});
99+
}
100+
}, [loadingUsers, setErrorSnackMessage, bucketName, usersEnabled]);
101+
102+
useEffect(() => {
103+
if (loadingPolicies) {
104+
api
105+
.invoke("GET", `/api/v1/bucket-policy/${bucketName}`)
106+
.then((res: any) => {
107+
setBucketPolicy(res.policies);
108+
setLoadingPolicies(false);
109+
})
110+
.catch((err: any) => {
111+
setErrorSnackMessage(err);
112+
setLoadingPolicies(false);
113+
});
114+
}
115+
}, [loadingPolicies, setErrorSnackMessage, bucketName]);
116+
117+
return (
118+
<Paper>
119+
<Tabs
120+
value={curTab}
121+
onChange={(e: React.ChangeEvent<{}>, newValue: number) => {
122+
setCurTab(newValue);
123+
}}
124+
indicatorColor="primary"
125+
textColor="primary"
126+
aria-label="cluster-tabs"
127+
variant="scrollable"
128+
scrollButtons="auto"
129+
>
130+
<Tab label="Policies" {...a11yProps(0)} />
131+
{usersEnabled && <Tab label="Users" {...a11yProps(1)} />}
132+
</Tabs>
133+
<TabPanel index={0} value={curTab}>
134+
<TableWrapper
135+
noBackground={true}
136+
itemActions={PolicyActions}
137+
columns={[{ label: "Name", elementKey: "name" }]}
138+
isLoading={loadingPolicies}
139+
records={bucketPolicy}
140+
entityName="Policies"
141+
idField="name"
142+
/>
143+
</TabPanel>
144+
{usersEnabled && (
145+
<TabPanel index={1} value={curTab}>
146+
<TableWrapper
147+
noBackground={true}
148+
itemActions={userTableActions}
149+
columns={[{ label: "User", elementKey: "accessKey" }]}
150+
isLoading={loadingUsers}
151+
records={bucketUsers}
152+
entityName="Users"
153+
idField="accessKey"
154+
/>
155+
</TabPanel>
156+
)}
157+
</Paper>
158+
);
159+
};
160+
161+
export default withStyles(styles)(connector(AccessDetails));

0 commit comments

Comments
 (0)