Skip to content

Commit 9fa49b4

Browse files
authored
Console help menu (#2804)
Authored-by: Jillian Inapurapu <jillii@Jillians-MBP.attlocal.net>
1 parent de13119 commit 9fa49b4

File tree

71 files changed

+5435
-372
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+5435
-372
lines changed

portal-ui/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"react-dom": "^18.1.0",
2727
"react-dropzone": "^14.2.3",
2828
"react-grid-layout": "^1.2.0",
29+
"react-markdown": "8.0.7",
2930
"react-redux": "^8.0.7",
3031
"react-router-dom": "6.11.2",
3132
"react-virtualized": "^9.22.5",

portal-ui/src/common/MoreLink.tsx

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// This file is part of MinIO Console Server
2+
// Copyright (c) 2023 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 from "react";
18+
import { ArrowIcon } from "mds";
19+
20+
const MoreLink = ({
21+
LeadingIcon,
22+
text,
23+
link,
24+
color,
25+
}: {
26+
LeadingIcon?: React.FunctionComponent;
27+
text: string;
28+
link: string;
29+
color: string;
30+
}) => {
31+
return (
32+
<a
33+
style={{
34+
color: color,
35+
font: "normal normal bold 12px/55px Inter",
36+
display: "block",
37+
textDecoration: "none",
38+
}}
39+
href={link}
40+
target={"_blank"}
41+
>
42+
<div
43+
style={{
44+
display: "flex",
45+
flexDirection: "row",
46+
alignItems: "center",
47+
height: 20,
48+
gap: 2,
49+
}}
50+
>
51+
{LeadingIcon && (
52+
<div style={{ flexGrow: 0, flexShrink: 1, lineHeight: "12px" }}>
53+
{/*@ts-ignore*/}
54+
<LeadingIcon style={{ height: 16, width: 16 }} />
55+
</div>
56+
)}
57+
<div style={{ flexGrow: 0, flexShrink: 1, lineHeight: "12px" }}>
58+
{text}
59+
</div>
60+
<div
61+
style={{
62+
flexGrow: 0,
63+
flexShrink: 1,
64+
lineHeight: "12px",
65+
marginTop: 2,
66+
}}
67+
>
68+
<ArrowIcon style={{ width: 12 }} />
69+
</div>
70+
</div>
71+
</a>
72+
);
73+
};
74+
75+
export default MoreLink;

portal-ui/src/screens/Console/Account/Account.tsx

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,16 @@ import { SecureComponent } from "../../../common/SecureComponent";
4747
import { selectSAs } from "../Configurations/utils";
4848
import DeleteMultipleServiceAccounts from "../Users/DeleteMultipleServiceAccounts";
4949
import ServiceAccountPolicy from "./ServiceAccountPolicy";
50-
import { setErrorSnackMessage, setSnackBarMessage } from "../../../systemSlice";
50+
import {
51+
setErrorSnackMessage,
52+
setHelpName,
53+
setSnackBarMessage,
54+
} from "../../../systemSlice";
5155
import { selFeatures } from "../consoleSlice";
5256
import { useAppDispatch } from "../../../store";
5357
import TooltipWrapper from "../Common/TooltipWrapper/TooltipWrapper";
5458
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
59+
import HelpMenu from "../HelpMenu";
5560

5661
const DeleteServiceAccount = withSuspense(
5762
React.lazy(() => import("./DeleteServiceAccount"))
@@ -82,6 +87,11 @@ const Account = () => {
8287
fetchRecords();
8388
}, []);
8489

90+
useEffect(() => {
91+
dispatch(setHelpName("accessKeys"));
92+
// eslint-disable-next-line react-hooks/exhaustive-deps
93+
}, []);
94+
8595
useEffect(() => {
8696
if (loading) {
8797
api
@@ -179,13 +189,12 @@ const Account = () => {
179189
closeModalAndRefresh={closePolicyModal}
180190
/>
181191
)}
182-
{changePasswordModalOpen && (
183-
<ChangePasswordModal
184-
open={changePasswordModalOpen}
185-
closeModal={() => setChangePasswordModalOpen(false)}
186-
/>
187-
)}
188-
<PageHeaderWrapper label="Access Keys" />
192+
<ChangePasswordModal
193+
open={changePasswordModalOpen}
194+
closeModal={() => setChangePasswordModalOpen(false)}
195+
/>
196+
<PageHeaderWrapper label="Access Keys" actions={<HelpMenu />} />
197+
189198
<PageLayout>
190199
<Grid container>
191200
<Grid item xs={12} sx={{ ...actionsTray.actionsTray }}>

portal-ui/src/screens/Console/Account/AddServiceAccountScreen.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,11 @@ import CredentialsPrompt from "../Common/CredentialsPrompt/CredentialsPrompt";
4141

4242
import PanelTitle from "../Common/PanelTitle/PanelTitle";
4343

44-
import { setErrorSnackMessage } from "../../../systemSlice";
44+
import { setErrorSnackMessage, setHelpName } from "../../../systemSlice";
4545
import { useAppDispatch } from "../../../store";
4646
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
4747
import { getRandomString } from "../../../common/utils";
48+
import HelpMenu from "../HelpMenu";
4849

4950
const AddServiceAccount = () => {
5051
const dispatch = useAppDispatch();
@@ -59,6 +60,11 @@ const AddServiceAccount = () => {
5960
useState<NewServiceAccount | null>(null);
6061
const [policyJSON, setPolicyJSON] = useState<string>("");
6162

63+
useEffect(() => {
64+
dispatch(setHelpName("add_service_account"));
65+
// eslint-disable-next-line react-hooks/exhaustive-deps
66+
}, []);
67+
6268
useEffect(() => {
6369
if (addSending) {
6470
api
@@ -128,6 +134,7 @@ const AddServiceAccount = () => {
128134
onClick={() => navigate(IAM_PAGES.ACCOUNT)}
129135
/>
130136
}
137+
actions={<HelpMenu />}
131138
/>
132139
<PageLayout>
133140
<FormLayout

portal-ui/src/screens/Console/Buckets/BucketDetails/AccessDetailsPanel.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ import {
3737
SecureComponent,
3838
} from "../../../../common/SecureComponent";
3939
import { encodeURLString } from "../../../../common/utils";
40-
import { setErrorSnackMessage } from "../../../../systemSlice";
40+
import { setErrorSnackMessage, setHelpName } from "../../../../systemSlice";
4141
import { selBucketDetailsLoading } from "./bucketDetailsSlice";
4242
import { useAppDispatch } from "../../../../store";
4343
import { Policy } from "../../../../api/consoleApi";
@@ -133,6 +133,11 @@ const AccessDetails = () => {
133133
}
134134
}, [loadingUsers, dispatch, bucketName, displayUsersList]);
135135

136+
useEffect(() => {
137+
dispatch(setHelpName("bucket_detail_access"));
138+
// eslint-disable-next-line react-hooks/exhaustive-deps
139+
}, []);
140+
136141
useEffect(() => {
137142
if (loadingPolicies) {
138143
if (displayPoliciesList) {

portal-ui/src/screens/Console/Buckets/BucketDetails/AccessRulePanel.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import {
3838
} from "../../../../common/SecureComponent";
3939

4040
import withSuspense from "../../Common/Components/withSuspense";
41-
import { setErrorSnackMessage } from "../../../../systemSlice";
41+
import { setErrorSnackMessage, setHelpName } from "../../../../systemSlice";
4242
import makeStyles from "@mui/styles/makeStyles";
4343
import { selBucketDetailsLoading } from "./bucketDetailsSlice";
4444
import { useAppDispatch } from "../../../../store";
@@ -130,6 +130,11 @@ const AccessRule = () => {
130130
},
131131
];
132132

133+
useEffect(() => {
134+
dispatch(setHelpName("bucket_detail_prefix"));
135+
// eslint-disable-next-line react-hooks/exhaustive-deps
136+
}, []);
137+
133138
useEffect(() => {
134139
if (loadingAccessRules) {
135140
if (displayAccessRules) {

portal-ui/src/screens/Console/Buckets/BucketDetails/BucketDetails.tsx

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import {
6767
selDistSet,
6868
selSiteRep,
6969
setErrorSnackMessage,
70+
setHelpName,
7071
} from "../../../../systemSlice";
7172
import {
7273
selBucketDetailsInfo,
@@ -77,6 +78,7 @@ import {
7778
import { useAppDispatch } from "../../../../store";
7879
import TooltipWrapper from "../../Common/TooltipWrapper/TooltipWrapper";
7980
import PageHeaderWrapper from "../../Common/PageHeaderWrapper/PageHeaderWrapper";
81+
import HelpMenu from "../../HelpMenu";
8082

8183
const DeleteBucket = withSuspense(
8284
React.lazy(() => import("../ListBuckets/DeleteBucket"))
@@ -142,6 +144,11 @@ const BucketDetails = ({ classes }: IBucketDetailsProps) => {
142144
setActiveTab(selTab);
143145
}, [selTab]);
144146

147+
useEffect(() => {
148+
dispatch(setHelpName("bucket_details"));
149+
// eslint-disable-next-line react-hooks/exhaustive-deps
150+
}, []);
151+
145152
useEffect(() => {
146153
if (!iniLoad) {
147154
dispatch(setBucketDetailsLoad(true));
@@ -208,31 +215,36 @@ const BucketDetails = ({ classes }: IBucketDetailsProps) => {
208215
<BackLink label={"Buckets"} onClick={() => navigate("/buckets")} />
209216
}
210217
actions={
211-
<TooltipWrapper
212-
tooltip={
213-
canBrowse
214-
? "Browse Bucket"
215-
: permissionTooltipHelper(
216-
IAM_PERMISSIONS[IAM_ROLES.BUCKET_VIEWER],
217-
"browsing this bucket"
218-
)
219-
}
220-
>
221-
<Button
222-
id={"switch-browse-view"}
223-
aria-label="Browse Bucket"
224-
onClick={() => {
225-
navigate(`/browser/${bucketName}`);
226-
}}
227-
icon={
228-
<FolderIcon style={{ width: 20, height: 20, marginTop: -3 }} />
218+
<Fragment>
219+
<TooltipWrapper
220+
tooltip={
221+
canBrowse
222+
? "Browse Bucket"
223+
: permissionTooltipHelper(
224+
IAM_PERMISSIONS[IAM_ROLES.BUCKET_VIEWER],
225+
"browsing this bucket"
226+
)
229227
}
230-
style={{
231-
padding: "0 10px",
232-
}}
233-
disabled={!canBrowse}
234-
/>
235-
</TooltipWrapper>
228+
>
229+
<Button
230+
id={"switch-browse-view"}
231+
aria-label="Browse Bucket"
232+
onClick={() => {
233+
navigate(`/browser/${bucketName}`);
234+
}}
235+
icon={
236+
<FolderIcon
237+
style={{ width: 20, height: 20, marginTop: -3 }}
238+
/>
239+
}
240+
style={{
241+
padding: "0 10px",
242+
}}
243+
disabled={!canBrowse}
244+
/>
245+
</TooltipWrapper>
246+
<HelpMenu />
247+
</Fragment>
236248
}
237249
/>
238250
<PageLayout className={classes.pageContainer}>

portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ import {
4040
import { IAM_SCOPES } from "../../../../common/SecureComponent/permissions";
4141

4242
import withSuspense from "../../Common/Components/withSuspense";
43-
import { setErrorSnackMessage } from "../../../../systemSlice";
43+
import { setErrorSnackMessage, setHelpName } from "../../../../systemSlice";
4444
import { selBucketDetailsLoading } from "./bucketDetailsSlice";
4545
import { useAppDispatch } from "../../../../store";
4646
import TooltipWrapper from "../../Common/TooltipWrapper/TooltipWrapper";
@@ -86,6 +86,11 @@ const BucketEventsPanel = ({ classes }: IBucketEventsProps) => {
8686
}
8787
}, [loadingBucket, setLoadingEvents]);
8888

89+
useEffect(() => {
90+
dispatch(setHelpName("bucket_detail_events"));
91+
// eslint-disable-next-line react-hooks/exhaustive-deps
92+
}, []);
93+
8994
useEffect(() => {
9095
if (loadingEvents) {
9196
if (displayEvents) {

portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ import DeleteBucketLifecycleRule from "./DeleteBucketLifecycleRule";
4242
import { selBucketDetailsLoading } from "./bucketDetailsSlice";
4343
import { useParams } from "react-router-dom";
4444
import TooltipWrapper from "../../Common/TooltipWrapper/TooltipWrapper";
45+
import { setHelpName } from "../../../../systemSlice";
46+
import { useAppDispatch } from "../../../../store";
4547

4648
const styles = (theme: Theme) =>
4749
createStyles({
@@ -69,6 +71,7 @@ const BucketLifecyclePanel = ({ classes }: IBucketLifecyclePanelProps) => {
6971
const [deleteLifecycleOpen, setDeleteLifecycleOpen] =
7072
useState<boolean>(false);
7173
const [selectedID, setSelectedID] = useState<string | null>(null);
74+
const dispatch = useAppDispatch();
7275

7376
const bucketName = params.bucketName || "";
7477

@@ -83,6 +86,11 @@ const BucketLifecyclePanel = ({ classes }: IBucketLifecyclePanelProps) => {
8386
}
8487
}, [loadingBucket, setLoadingLifecycle]);
8588

89+
useEffect(() => {
90+
dispatch(setHelpName("bucket_detail_lifecycle"));
91+
// eslint-disable-next-line react-hooks/exhaustive-deps
92+
}, []);
93+
8694
useEffect(() => {
8795
if (loadingLifecycle) {
8896
if (displayLifeCycleRules) {

portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import TableWrapper from "../../Common/TableWrapper/TableWrapper";
4242
import PanelTitle from "../../Common/PanelTitle/PanelTitle";
4343
import withSuspense from "../../Common/Components/withSuspense";
4444
import EditReplicationModal from "./EditReplicationModal";
45-
import { setErrorSnackMessage } from "../../../../systemSlice";
45+
import { setErrorSnackMessage, setHelpName } from "../../../../systemSlice";
4646
import { selBucketDetailsLoading } from "./bucketDetailsSlice";
4747
import { useParams } from "react-router-dom";
4848
import { useAppDispatch } from "../../../../store";
@@ -95,6 +95,11 @@ const BucketReplicationPanel = ({ classes }: IBucketReplicationProps) => {
9595
IAM_SCOPES.S3_GET_ACTIONS,
9696
]);
9797

98+
useEffect(() => {
99+
dispatch(setHelpName("bucket_detail_replication"));
100+
// eslint-disable-next-line react-hooks/exhaustive-deps
101+
}, []);
102+
98103
useEffect(() => {
99104
if (loadingBucket) {
100105
setLoadingReplication(true);

0 commit comments

Comments
 (0)