diff --git a/k8s/operator-console/operator/kustomization.yaml b/k8s/operator-console/operator/kustomization.yaml deleted file mode 100644 index e636c9b4b..000000000 --- a/k8s/operator-console/operator/kustomization.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization -# beginning of customizations -#namespace: min-ns - -resources: - - ../base - - https://github.com/minio/operator/?ref=v3.0.29 - diff --git a/portal-ui/src/common/HelpBox.tsx b/portal-ui/src/common/HelpBox.tsx index 3cd6e9f83..4831decf8 100644 --- a/portal-ui/src/common/HelpBox.tsx +++ b/portal-ui/src/common/HelpBox.tsx @@ -25,38 +25,47 @@ const styles = (theme: Theme) => root: { border: "1px solid rgb(234, 237, 238)", borderRadius: 5, + paddingTop: 10, + paddingLeft: 40, + paddingRight: 40, + paddingBottom: 40, marginTop: 10, marginBottom: 10, backgroundColor: "#fbfafa", }, icon: { - textAlign: "center", - padding: 30, - fontSize: 64, + fontSize: 16, + fontWeight: "bold", + marginBottom: 20, "& .MuiSvgIcon-root": { - fontSize: 64, + fontSize: 44, + marginRight: 15, }, }, iconSize: { fontSize: 64, }, - helpText: { padding: 30, paddingLeft: 0, fontSize: 16 }, + helpText: { + fontSize: 16, + }, }); interface IHelpBox { classes: any; iconComponent: any; + title: string; help: any; } -const HelpBox = ({ classes, iconComponent, help }: IHelpBox) => { +const HelpBox = ({ classes, iconComponent, title, help }: IHelpBox) => { return (
- + {iconComponent} + {title} - + {help} diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx index 1efa3535c..b2472b4ba 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketEventsPanel.tsx @@ -170,6 +170,7 @@ const BucketEventsPanel = ({ } help={ diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx index d38c8043c..e2c09bf72 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketLifecyclePanel.tsx @@ -210,6 +210,7 @@ const BucketLifecyclePanel = ({ } help={ diff --git a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx index 5e80bc16e..de2fd9e80 100644 --- a/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx +++ b/portal-ui/src/screens/Console/Buckets/BucketDetails/BucketReplicationPanel.tsx @@ -246,6 +246,7 @@ const BucketReplicationPanel = ({ } help={ diff --git a/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx b/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx index 501afe9e9..87e76247b 100644 --- a/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx +++ b/portal-ui/src/screens/Console/Buckets/ListBuckets/ListBuckets.tsx @@ -25,7 +25,12 @@ import TextField from "@mui/material/TextField"; import InputAdornment from "@mui/material/InputAdornment"; import FileCopyIcon from "@mui/icons-material/FileCopy"; import { Bucket, BucketList, HasPermissionResponse } from "../types"; -import { AddIcon, WatchIcon } from "../../../../icons"; +import { + AddIcon, + BucketsIcon, + TenantsIcon, + WatchIcon, +} from "../../../../icons"; import { AppState } from "../../../../store"; import { addBucketOpen, addBucketReset } from "../actions"; import { setErrorSnackMessage } from "../../../../actions"; @@ -38,6 +43,7 @@ import PageHeader from "../../Common/PageHeader/PageHeader"; import BucketListItem from "./BucketListItem"; import BulkReplicationModal from "./BulkReplicationModal"; import SearchIcon from "../../../../icons/SearchIcon"; +import HelpBox from "../../../../common/HelpBox"; const styles = (theme: Theme) => createStyles({ @@ -121,6 +127,10 @@ const styles = (theme: Theme) => constrainedContainer: { maxWidth: 1180, }, + link: { + textDecoration: "underline", + color: theme.palette.info.main, + }, }); interface IListBucketsProps { @@ -316,7 +326,7 @@ const ListBuckets = ({ className={classes.theaderSearch} variant={"outlined"} id="search-resource" - placeholder={"Search Buckets"} + placeholder={"Filter Buckets"} onChange={(val) => { setFilterBuckets(val.target.value); }} @@ -411,6 +421,39 @@ const ListBuckets = ({ /> ); })} + {filteredRecords.length == 0 && ( + + + } + title={"Buckets"} + help={ + + MinIO uses buckets to organize objects. A bucket is + similar to a folder or directory in a filesystem, where + each bucket can hold an arbitrary number of objects. +
+
+ To get started,  + { + addBucketOpen(true); + }} + > + Create a Bucket. + +
+ } + /> +
+
+ )}
diff --git a/portal-ui/src/screens/Console/Common/PageHeader/PageHeader.tsx b/portal-ui/src/screens/Console/Common/PageHeader/PageHeader.tsx index 7fcbd9f9a..56bb98b91 100644 --- a/portal-ui/src/screens/Console/Common/PageHeader/PageHeader.tsx +++ b/portal-ui/src/screens/Console/Common/PageHeader/PageHeader.tsx @@ -70,7 +70,7 @@ const PageHeader = ({   - + {!sidebarOpen && (
{operatorMode ? : } @@ -81,7 +81,7 @@ const PageHeader = ({ {actions && ( - + {actions} )} diff --git a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx index 2edb6e2ba..ef5541730 100644 --- a/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx +++ b/portal-ui/src/screens/Console/Configurations/TiersConfiguration/ListTiersConfiguration.tsx @@ -76,6 +76,10 @@ const styles = (theme: Theme) => ...settingsCommon.customTitle, marginTop: 0, }, + link: { + textDecoration: "underline", + color: theme.palette.info.main, + }, }); const ListTiersConfiguration = ({ @@ -189,130 +193,164 @@ const ListTiersConfiguration = ({ )} - - - { - setFilter(event.target.value); - }} - InputProps={{ - disableUnderline: true, - startAdornment: ( - - - - ), - }} - variant="standard" - /> - { - setIsLoading(true); - }} - size="large" - > - - - - - -
-
- - { - 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: ( + + + + ), + }} + variant="standard" + /> + { + setIsLoading(true); + }} + size="large" + > + + + - } - 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 - - . -
- } - /> +
+ {records.length > 0 && ( + + + { + 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 + + . +
+ } + /> +
+
+ )} + {records.length == 0 && ( + + + } + 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. +
+
+ To get started,{" "} + + Add Tier + + . +
+ } + /> +
+
+ )}
); diff --git a/portal-ui/src/screens/Console/Groups/Groups.tsx b/portal-ui/src/screens/Console/Groups/Groups.tsx index 143681f51..66081239e 100644 --- a/portal-ui/src/screens/Console/Groups/Groups.tsx +++ b/portal-ui/src/screens/Console/Groups/Groups.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, { useEffect, useState } from "react"; +import React, { Fragment, useEffect, useState } from "react"; import { connect } from "react-redux"; import { Theme } from "@mui/material/styles"; import createStyles from "@mui/styles/createStyles"; @@ -23,7 +23,7 @@ import Grid from "@mui/material/Grid"; import TextField from "@mui/material/TextField"; import InputAdornment from "@mui/material/InputAdornment"; import { Button } from "@mui/material"; -import { AddIcon } from "../../../icons"; +import { AddIcon, GroupsIcon, UsersIcon } from "../../../icons"; import { setErrorSnackMessage } from "../../../actions"; import { GroupsList } from "./types"; import { stringSort } from "../../../utils/sortFunctions"; @@ -40,6 +40,7 @@ import TableWrapper from "../Common/TableWrapper/TableWrapper"; import SetPolicy from "../Policies/SetPolicy"; import PageHeader from "../Common/PageHeader/PageHeader"; import SearchIcon from "../../../icons/SearchIcon"; +import HelpBox from "../../../common/HelpBox"; interface IGroupsProps { classes: any; @@ -79,6 +80,10 @@ const styles = (theme: Theme) => }, }, }, + link: { + textDecoration: "underline", + color: theme.palette.info.main, + }, ...actionsTray, ...searchField, ...containerForHeader(theme.spacing(4)), @@ -225,16 +230,81 @@ const Groups = ({ classes, setErrorSnackMessage }: IGroupsProps) => {
- - - + {records.length > 0 && ( + + + + + + } + help={ + + A group can have one attached IAM policy, where all users + with membership in that group inherit that policy. Groups + support more simplified management of user permissions on + the MinIO Tenant. +
+
+ You can learn more at our{" "} + + documentation + + . +
+ } + /> +
+
+ )} + {records.length == 0 && ( + + + } + help={ + + A group can have one attached IAM policy, where all users + with membership in that group inherit that policy. Groups + support more simplified management of user permissions on + the MinIO Tenant. +
+
+ To get started,{" "} + { + setSelectedGroup(null); + setGroupOpen(true); + }} + className={classes.link} + > + Create a Group + + . +
+ } + /> +
+
+ )}
diff --git a/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx b/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx index eda39d38f..9acbbe7a3 100644 --- a/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx +++ b/portal-ui/src/screens/Console/NotificationEndpoints/ListNotificationEndpoints.tsx @@ -73,6 +73,10 @@ const styles = (theme: Theme) => lambdaContainer: { padding: "15px 0", }, + link: { + textDecoration: "underline", + color: theme.palette.info.main, + }, }); const ListNotificationEndpoints = ({ @@ -180,48 +184,93 @@ const ListNotificationEndpoints = ({ - - - - } - 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 - - . -
- } - /> +
+ {records.length > 0 && ( + + + + + + } + 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 + + . +
+ } + /> +
+
+ )} + {records.length == 0 && ( + + + } + 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. +
+
+ To get started,{" "} + { + history.push("/notification-endpoints/add"); + }} + className={classes.link} + > + Add a Notification Target + + . +
+ } + /> +
+
+ )} ); diff --git a/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx b/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx index 6eef7b66a..5b7bdc8c9 100644 --- a/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx +++ b/portal-ui/src/screens/Console/Tenants/ListTenants/ListTenants.tsx @@ -32,7 +32,7 @@ import { searchField, } from "../../Common/FormComponents/common/styleLibrary"; import { setErrorSnackMessage } from "../../../../actions"; -import { AddIcon } from "../../../../icons"; +import { AddIcon, TenantsIcon } from "../../../../icons"; import { ErrorResponseHandler } from "../../../../common/types"; import api from "../../../../common/api"; import CredentialsPrompt from "../../Common/CredentialsPrompt/CredentialsPrompt"; @@ -41,6 +41,7 @@ import RefreshIcon from "../../../../icons/RefreshIcon"; import SearchIcon from "../../../../icons/SearchIcon"; import PageHeader from "../../Common/PageHeader/PageHeader"; import TenantListItem from "./TenantListItem"; +import HelpBox from "../../../../common/HelpBox"; interface ITenantsList { classes: any; @@ -103,6 +104,10 @@ const styles = (theme: Theme) => paddingTop: 30, paddingBottom: 30, }, + link: { + textDecoration: "underline", + color: theme.palette.info.main, + }, }); const ListTenants = ({ classes, setErrorSnackMessage }: ITenantsList) => { @@ -272,6 +277,40 @@ const ListTenants = ({ classes, setErrorSnackMessage }: ITenantsList) => { {filteredRecords.map((t) => { return ; })} + {filteredRecords.length == 0 && ( + + + } + title={"Tenants"} + help={ + + Tenant is the logical structure to represent a MinIO + deployment. A tenant can have different size and + configurations from other tenants, even a different + storage class. +
+
+ To get started,  + { + history.push("/tenants/add"); + }} + > + Create a Tenant. + +
+ } + /> +
+
+ )} diff --git a/portal-ui/src/screens/Console/Users/ListUsers.tsx b/portal-ui/src/screens/Console/Users/ListUsers.tsx index 615fb2e1d..b00eae2a1 100644 --- a/portal-ui/src/screens/Console/Users/ListUsers.tsx +++ b/portal-ui/src/screens/Console/Users/ListUsers.tsx @@ -80,6 +80,10 @@ const styles = (theme: Theme) => ...actionsTray, ...searchField, ...containerForHeader(theme.spacing(4)), + link: { + textDecoration: "underline", + color: theme.palette.info.main, + }, }); interface IUsersProps { @@ -274,50 +278,98 @@ const ListUsers = ({ classes, setErrorSnackMessage, history }: IUsersProps) => {
- - - - - } - 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 - - . -
- } - /> -
+ {records.length > 0 && ( + + + + + + } + 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 + + . +
+ } + /> +
+
+ )} + {records.length == 0 && ( + + + } + 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. +
+
+ To get started,{" "} + { + setAddScreenOpen(true); + setSelectedUser(null); + }} + className={classes.link} + > + Create a User + + . +
+ } + /> +
+
+ )} );