From 1d69024e3af8301abda54e514aa4524854bf2dbe Mon Sep 17 00:00:00 2001
From: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
Date: Tue, 19 Oct 2021 19:15:58 -0700
Subject: [PATCH] Add Help Box to multiple Screens (#1129)
---
portal-ui/src/common/HelpBox.tsx | 66 +++++
.../BucketDetails/BucketEventsPanel.tsx | 30 ++-
.../BucketDetails/BucketLifecyclePanel.tsx | 30 ++-
.../BucketDetails/BucketReplicationPanel.tsx | 28 ++-
.../ListTiersConfiguration.tsx | 236 ++++++++++--------
.../src/screens/Console/License/License.tsx | 52 ++--
.../ListNotificationEndpoints.tsx | 77 +++---
.../NotificationEndpoints.tsx | 6 +-
.../src/screens/Console/Users/ListUsers.tsx | 157 +++++++-----
9 files changed, 445 insertions(+), 237 deletions(-)
create mode 100644 portal-ui/src/common/HelpBox.tsx
diff --git a/portal-ui/src/common/HelpBox.tsx b/portal-ui/src/common/HelpBox.tsx
new file mode 100644
index 000000000..b395641db
--- /dev/null
+++ b/portal-ui/src/common/HelpBox.tsx
@@ -0,0 +1,66 @@
+// This file is part of MinIO Console Server
+// Copyright (c) 2021 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 .
+
+import React, { Component } from "react";
+import Grid from "@material-ui/core/Grid";
+import { createStyles } from "@material-ui/core";
+import { Theme, withStyles } from "@material-ui/core/styles";
+
+const styles = (theme: Theme) =>
+ createStyles({
+ root: {
+ border: "1px solid rgb(234, 237, 238)",
+ borderRadius: 5,
+ marginTop: 10,
+ marginBottom: 10,
+ backgroundColor: "#fbfafa",
+ },
+ icon: {
+ textAlign: "center",
+ padding: 30,
+ fontSize: 64,
+ "& .MuiSvgIcon-root": {
+ fontSize: 64,
+ },
+ },
+ iconSize: {
+ fontSize: 64,
+ },
+ helpText: { padding: 30, paddingLeft: 0, fontSize: 16 },
+ });
+
+interface IHelpBox {
+ classes: any;
+ iconComponent: any;
+ help: any;
+}
+
+const HelpBox = ({ classes, iconComponent, help }: IHelpBox) => {
+ return (
+
+
+
+ {iconComponent}
+
+
+ {help}
+
+
+
+ );
+};
+
+export default withStyles(styles)(HelpBox);
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx
index 2ec150f95..a4d2e3a13 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx
@@ -20,7 +20,7 @@ import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { Button } from "@material-ui/core";
import get from "lodash/get";
import Grid from "@material-ui/core/Grid";
-import { AddIcon } from "../../../../icons";
+import { AddIcon, LambdaIcon, TiersIcon } from "../../../../icons";
import { BucketEvent, BucketEventList } from "../types";
import { setErrorSnackMessage } from "../../../../actions";
import { AppState } from "../../../../store";
@@ -33,6 +33,7 @@ import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import api from "../../../../common/api";
import DeleteEvent from "./DeleteEvent";
import AddEvent from "./AddEvent";
+import HelpBox from "../../../../common/HelpBox";
const styles = (theme: Theme) =>
createStyles({
@@ -41,6 +42,9 @@ const styles = (theme: Theme) =>
actionsTray: {
...actionsTray.actionsTray,
},
+ twHeight: {
+ minHeight: 400,
+ },
});
interface IBucketEventsProps {
@@ -159,6 +163,30 @@ const BucketEventsPanel = ({
records={records}
entityName="Events"
idField="id"
+ customPaperHeight={classes.twHeight}
+ />
+
+
+ }
+ help={
+
+ MinIO bucket notifications allow administrators to send
+ notifications to supported external services on certain object
+ or bucket events. MinIO supports bucket and object-level S3
+ events similar to the Amazon S3 Event Notifications.
+
+
+ You can learn more at our{" "}
+
+ documentation
+
+ .
+
+ }
/>
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx
index 8a695f82f..dd6d636d6 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx
@@ -22,7 +22,7 @@ import get from "lodash/get";
import * as reactMoment from "react-moment";
import Grid from "@material-ui/core/Grid";
import { LifeCycleItem } from "../types";
-import { AddIcon } from "../../../../icons";
+import { AddIcon, TiersIcon } from "../../../../icons";
import {
actionsTray,
searchField,
@@ -34,11 +34,15 @@ import api from "../../../../common/api";
import EditLifecycleConfiguration from "./EditLifecycleConfiguration";
import AddLifecycleModal from "./AddLifecycleModal";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
+import HelpBox from "../../../../common/HelpBox";
const styles = (theme: Theme) =>
createStyles({
...searchField,
...actionsTray,
+ twHeight: {
+ minHeight: 400,
+ },
});
interface IBucketLifecyclePanelProps {
@@ -199,6 +203,30 @@ const BucketLifecyclePanel = ({
entityName="Lifecycle"
customEmptyMessage="There are no Lifecycle rules yet"
idField="id"
+ customPaperHeight={classes.twHeight}
+ />
+
+
+ }
+ help={
+
+ MinIO Object Lifecycle Management allows creating rules for time
+ or date based automatic transition or expiry of objects. For
+ object transition, MinIO automatically moves the object to a
+ configured remote storage tier.
+
+
+ You can learn more at our{" "}
+
+ documentation
+
+ .
+
+ }
/>
diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx
index fca9d6b5f..0949388d4 100644
--- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx
+++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx
@@ -19,7 +19,7 @@ import { connect } from "react-redux";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import { Button } from "@material-ui/core";
import Grid from "@material-ui/core/Grid";
-import { AddIcon } from "../../../../icons";
+import { AddIcon, BucketsIcon, TiersIcon } from "../../../../icons";
import { setErrorSnackMessage } from "../../../../actions";
import {
actionsTray,
@@ -37,6 +37,7 @@ import api from "../../../../common/api";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import AddReplicationModal from "./AddReplicationModal";
import DeleteReplicationRule from "./DeleteReplicationRule";
+import HelpBox from "../../../../common/HelpBox";
interface IBucketReplicationProps {
classes: any;
@@ -49,6 +50,9 @@ const styles = (theme: Theme) =>
createStyles({
...searchField,
...actionsTray,
+ twHeight: {
+ minHeight: 400,
+ },
});
const BucketReplicationPanel = ({
@@ -235,6 +239,28 @@ const BucketReplicationPanel = ({
records={replicationRules}
entityName="Replication Rules"
idField="id"
+ customPaperHeight={classes.twHeight}
+ />
+
+
+ }
+ help={
+
+ MinIO supports server-side and client-side replication of
+ objects between source and destination buckets.
+
+
+ You can learn more at our{" "}
+
+ documentation
+
+ .
+
+ }
/>
diff --git a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx
index 5d7fff061..2d3318ebf 100644
--- a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx
+++ b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx
@@ -14,7 +14,13 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-import React, { useEffect, useState, Fragment } from "react";
+import React, {
+ useEffect,
+ useState,
+ Fragment,
+ ReactComponentElement,
+ Component,
+} from "react";
import get from "lodash/get";
import { connect } from "react-redux";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
@@ -29,7 +35,7 @@ import {
settingsCommon,
typesSelection,
} from "../../Common/FormComponents/common/styleLibrary";
-import { AddIcon } from "../../../../icons";
+import { AddIcon, TiersIcon } from "../../../../icons";
import { setErrorSnackMessage } from "../../../../actions";
import { ITierElement, ITierResponse } from "./types";
import { ErrorResponseHandler } from "../../../../common/types";
@@ -40,6 +46,8 @@ import UpdateTierCredentiasModal from "./UpdateTierCredentiasModal";
import RefreshIcon from "../../../../icons/RefreshIcon";
import SearchIcon from "../../../../icons/SearchIcon";
import PageHeader from "../../Common/PageHeader/PageHeader";
+import theme from "../../../../theme/main";
+import HelpBox from "../../../../common/HelpBox";
interface IListTiersConfig {
classes: any;
@@ -64,14 +72,7 @@ const styles = (theme: Theme) =>
lineHeight: "24px",
},
customConfigurationPage: {
- height: "calc(100vh - 210px)",
- scrollbarWidth: "none" as const,
- "&::-webkit-scrollbar": {
- display: "none",
- },
- },
- lambdaContainer: {
- padding: "15px 0",
+ minHeight: 400,
},
actionsTray: {
...actionsTray.actionsTray,
@@ -193,105 +194,122 @@ const ListTiersConfiguration = ({
)}
-
-
-
- {
- setFilter(event.target.value);
- }}
- InputProps={{
- disableUnderline: true,
- startAdornment: (
-
-
-
- ),
- }}
- />
- {
- setIsLoading(true);
- }}
- >
-
-
- }
- onClick={addTier}
- >
- Add Tier
-
-
-
-
-
-
- {
- setSelectedTier(tierData);
- setUpdateCredentialsOpen(true);
- },
- },
- ]}
- columns={[
- {
- label: "Tier Name",
- elementKey: "type",
- renderFunction: renderTierName,
- renderFullObject: true,
- },
- {
- label: "Type",
- elementKey: "type",
- width: 150,
- },
- {
- label: "Endpoint",
- elementKey: "type",
- renderFunction: renderTierEndpoint,
- renderFullObject: true,
- },
- {
- label: "Bucket",
- elementKey: "type",
- renderFunction: renderTierBucket,
- renderFullObject: true,
- },
- {
- label: "Prefix",
- elementKey: "type",
- renderFunction: renderTierPrefix,
- renderFullObject: true,
- },
- {
- label: "Region",
- elementKey: "type",
- renderFunction: renderTierRegion,
- renderFullObject: true,
- },
- ]}
- isLoading={isLoading}
- records={filteredRecords}
- entityName="Tiers"
- idField="service_name"
- customPaperHeight={classes.customConfigurationPage}
- />
-
-
-
+
+ {
+ setFilter(event.target.value);
+ }}
+ InputProps={{
+ disableUnderline: true,
+ startAdornment: (
+
+
+
+ ),
+ }}
+ />
+ {
+ setIsLoading(true);
+ }}
+ >
+
+
+ }
+ onClick={addTier}
+ >
+ Add Tier
+
+
+
+ {
+ setSelectedTier(tierData);
+ setUpdateCredentialsOpen(true);
+ },
+ },
+ ]}
+ columns={[
+ {
+ label: "Tier Name",
+ elementKey: "type",
+ renderFunction: renderTierName,
+ renderFullObject: true,
+ },
+ {
+ label: "Type",
+ elementKey: "type",
+ width: 150,
+ },
+ {
+ label: "Endpoint",
+ elementKey: "type",
+ renderFunction: renderTierEndpoint,
+ renderFullObject: true,
+ },
+ {
+ label: "Bucket",
+ elementKey: "type",
+ renderFunction: renderTierBucket,
+ renderFullObject: true,
+ },
+ {
+ label: "Prefix",
+ elementKey: "type",
+ renderFunction: renderTierPrefix,
+ renderFullObject: true,
+ },
+ {
+ label: "Region",
+ elementKey: "type",
+ renderFunction: renderTierRegion,
+ renderFullObject: true,
+ },
+ ]}
+ isLoading={isLoading}
+ records={filteredRecords}
+ entityName="Tiers"
+ idField="service_name"
+ customPaperHeight={classes.customConfigurationPage}
+ />
+
+
+ }
+ help={
+
+ Tiers are used by the MinIO Object Lifecycle Management which
+ allows creating rules for time or date based automatic
+ transition or expiry of objects. For object transition, MinIO
+ automatically moves the object to a configured remote storage
+ tier.
+
+
+ You can learn more at our{" "}
+
+ documentation
+
+ .
+
+ }
+ />
+
);
diff --git a/portal-ui/src/screens/Console/License/License.tsx b/portal-ui/src/screens/Console/License/License.tsx
index d91a24c06..b71b28f73 100644
--- a/portal-ui/src/screens/Console/License/License.tsx
+++ b/portal-ui/src/screens/Console/License/License.tsx
@@ -369,7 +369,7 @@ const License = ({ classes, operatorMode }: ILicenseProps) => {
{licenseInfo ? (
@@ -519,7 +519,7 @@ const License = ({ classes, operatorMode }: ILicenseProps) => {
)}
-
+
{licenseInfo ? (
{
more about the compliance policy.
-
- Open Source Policy Compliance
-
-
-
-
- Trademark Policy
-
+
)}
diff --git a/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx
index be0dc5c5b..8079a8bd5 100644
--- a/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx
+++ b/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx
@@ -29,7 +29,7 @@ import {
TransformedEndpointItem,
} from "./types";
import { notificationTransform } from "./utils";
-import { AddIcon } from "../../../icons";
+import { AddIcon, LambdaIcon } from "../../../icons";
import TableWrapper from "../Common/TableWrapper/TableWrapper";
import { setErrorSnackMessage } from "../../../actions";
import {
@@ -43,6 +43,7 @@ import api from "../../../common/api";
import RefreshIcon from "../../../icons/RefreshIcon";
import SearchIcon from "../../../icons/SearchIcon";
import history from "../../../history";
+import HelpBox from "../../../common/HelpBox";
interface IListNotificationEndpoints {
classes: any;
@@ -64,12 +65,8 @@ const styles = (theme: Theme) =>
iconText: {
lineHeight: "24px",
},
- customConfigurationPage: {
- height: "calc(100vh - 410px)",
- scrollbarWidth: "none" as const,
- "&::-webkit-scrollbar": {
- display: "none",
- },
+ twHeight: {
+ minHeight: 400,
},
lambdaContainer: {
padding: "15px 0",
@@ -138,7 +135,7 @@ const ListNotificationEndpoints = ({
return (
-
+
-
-
+
+
+
+ }
+ help={
-
-
-
-
-
+ MinIO bucket notifications allow administrators to send
+ notifications to supported external services on certain object
+ or bucket events. MinIO supports bucket and object-level S3
+ events similar to the Amazon S3 Event Notifications.
+
+
+ You can learn more at our{" "}
+
+ documentation
+
+ .
-
-
+ }
+ />
diff --git a/portal-ui/src/screens/Console/NotificationEndpoints/NotificationEndpoints.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/NotificationEndpoints.tsx
index a370a7a6e..ce043c344 100644
--- a/portal-ui/src/screens/Console/NotificationEndpoints/NotificationEndpoints.tsx
+++ b/portal-ui/src/screens/Console/NotificationEndpoints/NotificationEndpoints.tsx
@@ -50,11 +50,7 @@ const NotificationEndpoints = ({
return (
-
-
-
-
-
+
);
};
diff --git a/portal-ui/src/screens/Console/Users/ListUsers.tsx b/portal-ui/src/screens/Console/Users/ListUsers.tsx
index b43e80492..b6081bf69 100644
--- a/portal-ui/src/screens/Console/Users/ListUsers.tsx
+++ b/portal-ui/src/screens/Console/Users/ListUsers.tsx
@@ -14,7 +14,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-import React, { useCallback, useEffect, useState } from "react";
+import React, { Fragment, useCallback, useEffect, useState } from "react";
import { connect } from "react-redux";
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
import api from "../../../common/api";
@@ -22,7 +22,7 @@ import { Button, Grid, InputAdornment, TextField } from "@material-ui/core";
import GroupIcon from "@material-ui/icons/Group";
import { User, UsersList } from "./types";
import { usersSort } from "../../../utils/sortFunctions";
-import { AddIcon } from "../../../icons";
+import { AddIcon, LambdaIcon, UsersIcon } from "../../../icons";
import {
actionsTray,
containerForHeader,
@@ -38,6 +38,7 @@ import SetPolicy from "../Policies/SetPolicy";
import PageHeader from "../Common/PageHeader/PageHeader";
import SearchIcon from "../../../icons/SearchIcon";
import { decodeFileName } from "../../../common/utils";
+import HelpBox from "../../../common/HelpBox";
const styles = (theme: Theme) =>
createStyles({
@@ -71,6 +72,9 @@ const styles = (theme: Theme) =>
},
},
},
+ twHeight: {
+ minHeight: 600,
+ },
...actionsTray,
...searchField,
...containerForHeader(theme.spacing(4)),
@@ -219,67 +223,96 @@ const ListUsers = ({ classes, setErrorSnackMessage, history }: IUsersProps) => {
/>
)}
-
-
-
-
-
-
- ),
- }}
- onChange={(e) => {
- setFilter(e.target.value);
- }}
- />
- }
- disabled={checkedUsers.length <= 0}
- onClick={() => {
- if (checkedUsers.length > 0) {
- setAddGroupOpen(true);
- }
- }}
- >
- Add to Group
-
- }
- onClick={() => {
- setAddScreenOpen(true);
- setSelectedUser(null);
- }}
- >
- Create User
-
-
+
+
+
+
+
+ ),
+ }}
+ onChange={(e) => {
+ setFilter(e.target.value);
+ }}
+ />
+ }
+ disabled={checkedUsers.length <= 0}
+ onClick={() => {
+ if (checkedUsers.length > 0) {
+ setAddGroupOpen(true);
+ }
+ }}
+ >
+ Add to Group
+
+ }
+ onClick={() => {
+ setAddScreenOpen(true);
+ setSelectedUser(null);
+ }}
+ >
+ Create User
+
+
-
-
-
-
-
-
+
+
+
+
+
+
+
+ }
+ help={
+
+ A MinIO user consists of a unique access key (username) and
+ corresponding secret key (password). Clients must authenticate
+ their identity by specifying both a valid access key (username)
+ and the corresponding secret key (password) of an existing MinIO
+ user.
+
+
+ Each user can have one or more assigned policies that explicitly
+ list the actions and resources to which that user has access.
+ Users can also inherit policies from the groups in which they
+ have membership.
+
+
+ You can learn more at our{" "}
+
+ documentation
+
+ .
+
+ }
+ />