- Note: If this machine does not have internet connection,
- Copy paste the following URL in a browser where you access
- SUBNET and follow the instructions to complete the
- registration
-
-
-
-
- {
- setLicenseKey(e.target.value);
- }}
- />
-
-
-
+
+
+
+ Click on the link to register this cluster in SUBNET and get
+ a License Key for this Air-Gap deployment
+
+
+
+ https://subnet.min.io/cluster/register
+
+
+
+
+ }
+ color={"primary"}
+ variant={"regular"}
+ />
+
+
+
+
+
+ Note: If this machine does not have internet connection, Copy
+ paste the following URL in a browser where you access SUBNET
+ and follow the instructions to complete the registration
+
+
+
+
+ {
+ setLicenseKey(e.target.value);
+ }}
+ />
+
+
+
+
-
-
+
)}
diff --git a/portal-ui/src/screens/Console/Support/OnlineRegistration.tsx b/portal-ui/src/screens/Console/Support/OnlineRegistration.tsx
index 82611ae6a..2114ab6f8 100644
--- a/portal-ui/src/screens/Console/Support/OnlineRegistration.tsx
+++ b/portal-ui/src/screens/Console/Support/OnlineRegistration.tsx
@@ -14,38 +14,23 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-import React, { Fragment } from "react";
-import { Box } from "@mui/material";
-import { FormTitle } from "./utils";
-import { Button, OnlineRegistrationIcon, UsersIcon } from "mds";
-import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
-import VisibilityOffIcon from "@mui/icons-material/VisibilityOff";
-import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye";
+import React from "react";
+import {
+ Box,
+ Button,
+ FormLayout,
+ InputBox,
+ OnlineRegistrationIcon,
+ UsersIcon,
+} from "mds";
import RegisterHelpBox from "./RegisterHelpBox";
-import { Theme } from "@mui/material/styles";
-import createStyles from "@mui/styles/createStyles";
-import { spacingUtils } from "../Common/FormComponents/common/styleLibrary";
-import makeStyles from "@mui/styles/makeStyles";
+import { modalStyleUtils } from "../Common/FormComponents/common/styleLibrary";
import { useSelector } from "react-redux";
import { AppState, useAppDispatch } from "../../../store";
-import {
- setShowPassword,
- setSubnetEmail,
- setSubnetPassword,
-} from "./registerSlice";
+import { setSubnetEmail, setSubnetPassword } from "./registerSlice";
import { subnetLogin } from "./registerThunks";
-const useStyles = makeStyles((theme: Theme) =>
- createStyles({
- sizedLabel: {
- minWidth: "75px",
- },
- ...spacingUtils,
- }),
-);
-
const OnlineRegistration = () => {
- const classes = useStyles();
const dispatch = useAppDispatch();
const subnetPassword = useSelector(
@@ -54,131 +39,79 @@ const OnlineRegistration = () => {
const subnetEmail = useSelector(
(state: AppState) => state.register.subnetEmail,
);
- const showPassword = useSelector(
- (state: AppState) => state.register.showPassword,
- );
const loading = useSelector((state: AppState) => state.register.loading);
return (
-
-
- }
- title={`Online activation of MinIO Subscription Network License`}
- />
-
+ }
+ title={"Online activation of MinIO Subscription Network License"}
+ withBorders={false}
+ containerPadding={false}
+ helpBox={}
+ >
-
-
- Use your MinIO Subscription Network login credentials to register
- this cluster.
-
-
- ) =>
- dispatch(setSubnetEmail(event.target.value))
- }
- label="Email"
- value={subnetEmail}
- overlayIcon={}
- />
- ) =>
- dispatch(setSubnetPassword(event.target.value))
- }
- label="Password"
- type={showPassword ? "text" : "password"}
- value={subnetPassword}
- overlayIcon={
- showPassword ? :
- }
- overlayAction={() => dispatch(setShowPassword(!showPassword))}
- />
-
-
- {
- e.preventDefault();
- window.open(`https://min.io/signup?ref=con`, "_blank");
- }}
- label={"Sign up"}
- />
- dispatch(subnetLogin())}
- label={"Register"}
- />
-
-
-
-
+ Use your MinIO Subscription Network login credentials to register this
+ cluster.
-
+
+ ) =>
+ dispatch(setSubnetEmail(event.target.value))
+ }
+ label="Email"
+ value={subnetEmail}
+ overlayIcon={}
+ />
+ ) =>
+ dispatch(setSubnetPassword(event.target.value))
+ }
+ label="Password"
+ type={"password"}
+ value={subnetPassword}
+ />
+
+
+ {
+ e.preventDefault();
+ window.open(`https://min.io/signup?ref=con`, "_blank");
+ }}
+ label={"Sign up"}
+ />
+ dispatch(subnetLogin())}
+ label={"Register"}
+ />
+
+
+
);
};
diff --git a/portal-ui/src/screens/Console/Support/Register.tsx b/portal-ui/src/screens/Console/Support/Register.tsx
index 06a0c769b..cc28a08c0 100644
--- a/portal-ui/src/screens/Console/Support/Register.tsx
+++ b/portal-ui/src/screens/Console/Support/Register.tsx
@@ -15,23 +15,13 @@
// along with this program. If not, see .
import React, { Fragment, useEffect, useState } from "react";
-import { Theme } from "@mui/material/styles";
-import createStyles from "@mui/styles/createStyles";
-import { spacingUtils } from "../Common/FormComponents/common/styleLibrary";
-import withStyles from "@mui/styles/withStyles";
-import { Box } from "@mui/material";
-import api from "../../../common/api";
-
+import { Box, PageLayout, Tabs } from "mds";
import { SubnetRegTokenResponse } from "../License/types";
import { ErrorResponseHandler } from "../../../common/types";
import { useSelector } from "react-redux";
import { setErrorSnackMessage, setHelpName } from "../../../systemSlice";
import { AppState, useAppDispatch } from "../../../store";
-import Tabs from "@mui/material/Tabs";
-import Tab from "@mui/material/Tab";
-import { TabPanel } from "../../shared/tabs";
import { ClusterRegistered, ProxyConfiguration } from "./utils";
-import ApiKeyRegister from "./ApiKeyRegister";
import { fetchLicenseInfo } from "./registerThunks";
import {
resetRegisterForm,
@@ -44,22 +34,11 @@ import SubnetMFAToken from "./SubnetMFAToken";
import ClusterRegistrationForm from "./ClusterRegistrationForm";
import OnlineRegistration from "./OnlineRegistration";
import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper";
-import { PageLayout } from "mds";
import HelpMenu from "../HelpMenu";
+import api from "../../../common/api";
+import ApiKeyRegister from "./ApiKeyRegister";
-interface IRegister {
- classes: any;
-}
-
-const styles = (theme: Theme) =>
- createStyles({
- sizedLabel: {
- minWidth: "75px",
- },
- ...spacingUtils,
- });
-
-const Register = ({ classes }: IRegister) => {
+const Register = () => {
const dispatch = useAppDispatch();
const subnetMFAToken = useSelector(
@@ -98,25 +77,27 @@ const Register = ({ classes }: IRegister) => {
};
}, [dispatch]);
- const fetchSubnetRegToken = () => {
- if (loading || subnetRegToken) {
- return;
+ useEffect(() => {
+ if (curTab === "simple-tab-2" && !loading && !subnetRegToken) {
+ const fetchSubnetRegToken = () => {
+ dispatch(setLoading(true));
+ api
+ .invoke("GET", "/api/v1/subnet/registration-token")
+ .then((resp: SubnetRegTokenResponse) => {
+ dispatch(setLoading(false));
+ if (resp && resp.regToken) {
+ dispatch(setSubnetRegToken(resp.regToken));
+ }
+ })
+ .catch((err: ErrorResponseHandler) => {
+ console.error(err);
+ dispatch(setErrorSnackMessage(err));
+ dispatch(setLoading(false));
+ });
+ };
+ fetchSubnetRegToken();
}
- dispatch(setLoading(true));
- api
- .invoke("GET", "/api/v1/subnet/registration-token")
- .then((resp: SubnetRegTokenResponse) => {
- dispatch(setLoading(false));
- if (resp && resp.regToken) {
- dispatch(setSubnetRegToken(resp.regToken));
- }
- })
- .catch((err: ErrorResponseHandler) => {
- console.error(err);
- dispatch(setErrorSnackMessage(err));
- dispatch(setLoading(false));
- });
- };
+ }, [curTab, loading, subnetRegToken, dispatch]);
useEffect(() => {
if (initialLicenseLoading) {
@@ -125,7 +106,7 @@ const Register = ({ classes }: IRegister) => {
}
}, [initialLicenseLoading, setInitialLicenseLoading, dispatch]);
- let clusterRegistrationForm: JSX.Element = ;
+ let clusterRegistrationForm: React.ReactElement = ;
if (subnetAccessToken && subnetOrganizations.length > 0) {
clusterRegistrationForm = ;
@@ -138,9 +119,8 @@ const Register = ({ classes }: IRegister) => {
const apiKeyRegistration = (
{
const regUi = (
{
, newValue: number) => {
+ horizontal
+ currentTabOrPath={curTab}
+ onTabClick={(newValue: string) => {
dispatch(setCurTab(newValue));
}}
- indicatorColor="primary"
- textColor="primary"
- aria-label="cluster-tabs"
- variant="scrollable"
- scrollButtons="auto"
- >
-
-
- fetchSubnetRegToken()}
- />
-
-
-
- {uiToShow}
-
-
- {apiKeyRegistration}
-
-
- {offlineRegistration}
-
+ options={[
+ {
+ tabConfig: {
+ label: "Credentials",
+ id: "simple-tab-0",
+ },
+ content: uiToShow,
+ },
+ {
+ tabConfig: {
+ label: "API Key",
+ id: "simple-tab-1",
+ },
+ content: apiKeyRegistration,
+ },
+ {
+ tabConfig: {
+ label: "Air-Gap",
+ id: "simple-tab-2",
+ },
+ content: offlineRegistration,
+ },
+ ]}
+ />
);
};
-export default withStyles(styles)(Register);
+export default Register;
diff --git a/portal-ui/src/screens/Console/Support/RegisterCluster.tsx b/portal-ui/src/screens/Console/Support/RegisterCluster.tsx
index c4d9461e0..7900e497c 100644
--- a/portal-ui/src/screens/Console/Support/RegisterCluster.tsx
+++ b/portal-ui/src/screens/Console/Support/RegisterCluster.tsx
@@ -16,8 +16,7 @@
import React, { Fragment } from "react";
import { useNavigate } from "react-router-dom";
-import { Box } from "@mui/material";
-import { Button, Grid, HelpBox, WarnIcon } from "mds";
+import { Box, breakPoints, Button, Grid, HelpBox, WarnIcon } from "mds";
interface IRegisterCluster {
compactMode?: boolean;
@@ -81,11 +80,11 @@ const RegisterCluster = ({ compactMode = false }: IRegisterCluster) => {
display: "flex",
alignItems: "center",
justifyContent: "center",
- flexFlow: {
- sm: "row",
- xs: "column",
- },
+ flexFlow: "row",
marginBottom: "15px",
+ [`@media (max-width: ${breakPoints.sm}px)`]: {
+ flexFlow: "column",
+ },
}}
>
@@ -113,9 +112,9 @@ const RegisterCluster = ({ compactMode = false }: IRegisterCluster) => {
diff --git a/portal-ui/src/screens/Console/Support/RegisterHelpBox.tsx b/portal-ui/src/screens/Console/Support/RegisterHelpBox.tsx
index 3e91fdf41..a74383d12 100644
--- a/portal-ui/src/screens/Console/Support/RegisterHelpBox.tsx
+++ b/portal-ui/src/screens/Console/Support/RegisterHelpBox.tsx
@@ -14,14 +14,15 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-import React from "react";
-import { Box, Link } from "@mui/material";
+import React, { Fragment } from "react";
import {
CallHomeFeatureIcon,
DiagnosticsFeatureIcon,
ExtraFeaturesIcon,
HelpIconFilled,
PerformanceFeatureIcon,
+ Box,
+ HelpBox,
} from "mds";
const FeatureItem = ({
@@ -44,92 +45,55 @@ const FeatureItem = ({
}}
>
{icon}{" "}
-
+
{description}
-
+
);
};
-const RegisterHelpBox = ({ hasMargin = true }: { hasMargin?: boolean }) => {
+const RegisterHelpBox = () => {
return (
-
- }
+ help={
+
+
+ Registering this cluster with the MinIO Subscription Network
+ (SUBNET) provides the following benefits in addition to the
+ commercial license and SLA backed support.
+
- "& .min-icon": {
- height: "21px",
- width: "21px",
- marginRight: "15px",
- },
- }}
- >
-
-
Why should I register?
-
-
- Registering this cluster with the MinIO Subscription Network (SUBNET)
- provides the following benefits in addition to the commercial license
- and SLA backed support.
-
-
-
- }
- description={`Call Home Monitoring`}
- />
- }
- description={`Health Diagnostics`}
- />
- }
- description={`Performance Analysis`}
- />
- }
- description={
-
- More Features
-
- }
- />
-
-
+
+ }
+ description={`Call Home Monitoring`}
+ />
+ }
+ description={`Health Diagnostics`}
+ />
+ }
+ description={`Performance Analysis`}
+ />
+ }
+ description={
+
+ More Features
+
+ }
+ />
+
+
+ }
+ />
);
};
diff --git a/portal-ui/src/screens/Console/Support/RegistrationStatusBanner.tsx b/portal-ui/src/screens/Console/Support/RegistrationStatusBanner.tsx
index 513ce534e..72ac14089 100644
--- a/portal-ui/src/screens/Console/Support/RegistrationStatusBanner.tsx
+++ b/portal-ui/src/screens/Console/Support/RegistrationStatusBanner.tsx
@@ -1,17 +1,32 @@
+// This file is part of MinIO Console Server
+// Copyright (c) 2022 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 from "react";
-import { Box } from "@mui/material";
-import { VerifiedIcon } from "mds";
+import { VerifiedIcon, Box, breakPoints } from "mds";
const RegistrationStatusBanner = ({ email = "" }: { email?: string }) => {
return (
{
sx={{
alignItems: "center",
justifyContent: "flex-start",
- display: {
- sm: "flex",
- xs: "none",
+ display: "flex",
+ [`@media (max-width: ${breakPoints.sm}px)`]: {
+ display: "none",
},
}}
>
diff --git a/portal-ui/src/screens/Console/Support/SubnetMFAToken.tsx b/portal-ui/src/screens/Console/Support/SubnetMFAToken.tsx
index f53a1ed50..e3e3c9526 100644
--- a/portal-ui/src/screens/Console/Support/SubnetMFAToken.tsx
+++ b/portal-ui/src/screens/Console/Support/SubnetMFAToken.tsx
@@ -15,15 +15,13 @@
// along with this program. If not, see .
import React from "react";
-import { Box } from "@mui/material";
-import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
-import LockOutlinedIcon from "@mui/icons-material/LockOutlined";
-import { setSubnetOTP } from "./registerSlice";
-import { Button } from "mds";
-import RegisterHelpBox from "./RegisterHelpBox";
-import { AppState, useAppDispatch } from "../../../store";
+import { Box, Button, FormLayout, InputBox, LockIcon } from "mds";
import { useSelector } from "react-redux";
+import { setSubnetOTP } from "./registerSlice";
+import { AppState, useAppDispatch } from "../../../store";
import { subnetLoginWithMFA } from "./registerThunks";
+import { modalStyleUtils } from "../Common/FormComponents/common/styleLibrary";
+import RegisterHelpBox from "./RegisterHelpBox";
const SubnetMFAToken = () => {
const dispatch = useAppDispatch();
@@ -35,76 +33,51 @@ const SubnetMFAToken = () => {
const loading = useSelector((state: AppState) => state.register.loading);
return (
- }
+ withBorders={false}
+ containerPadding={false}
>
-
- Two-Factor Authentication
-
-
-
- Please enter the 6-digit verification code that was sent to your email
- address. This code will be valid for 5 minutes.
-
-
-
- }
- id="subnet-otp"
- name="subnet-otp"
- onChange={(event: React.ChangeEvent) =>
- dispatch(setSubnetOTP(event.target.value))
- }
- placeholder=""
- label=""
- value={subnetOTP}
- />
-
-
- dispatch(subnetLoginWithMFA())}
- disabled={
- loading ||
- subnetOTP.trim().length === 0 ||
- subnetMFAToken.trim().length === 0
- }
- variant="callAction"
- label={"Verify"}
- />
-
+ Please enter the 6-digit verification code that was sent to your email
+ address. This code will be valid for 5 minutes.
-
-
+
+ }
+ id="subnet-otp"
+ name="subnet-otp"
+ onChange={(event: React.ChangeEvent) =>
+ dispatch(setSubnetOTP(event.target.value))
+ }
+ placeholder=""
+ label=""
+ value={subnetOTP}
+ />
+
+
+ dispatch(subnetLoginWithMFA())}
+ disabled={
+ loading ||
+ subnetOTP.trim().length === 0 ||
+ subnetMFAToken.trim().length === 0
+ }
+ variant="callAction"
+ label={"Verify"}
+ />
+
+
);
};
export default SubnetMFAToken;
diff --git a/portal-ui/src/screens/Console/Support/registerSlice.ts b/portal-ui/src/screens/Console/Support/registerSlice.ts
index 3f04fdfe9..389901d69 100644
--- a/portal-ui/src/screens/Console/Support/registerSlice.ts
+++ b/portal-ui/src/screens/Console/Support/registerSlice.ts
@@ -27,12 +27,11 @@ export interface RegisterState {
selectedSubnetOrganization: string;
subnetRegToken: string;
subnetOrganizations: SubnetOrganization[];
- showPassword: boolean;
loading: boolean;
loadingLicenseInfo: boolean;
clusterRegistered: boolean;
licenseInfo: SubnetInfo | undefined;
- curTab: number;
+ curTab: string;
}
const initialState: RegisterState = {
@@ -45,12 +44,11 @@ const initialState: RegisterState = {
selectedSubnetOrganization: "",
subnetRegToken: "",
subnetOrganizations: [],
- showPassword: false,
loading: false,
loadingLicenseInfo: false,
clusterRegistered: false,
licenseInfo: undefined,
- curTab: 0,
+ curTab: "simple-tab-0",
};
export const registerSlice = createSlice({
@@ -87,9 +85,6 @@ export const registerSlice = createSlice({
) => {
state.subnetOrganizations = action.payload;
},
- setShowPassword: (state, action: PayloadAction) => {
- state.showPassword = action.payload;
- },
setLoading: (state, action: PayloadAction) => {
state.loading = action.payload;
},
@@ -102,7 +97,7 @@ export const registerSlice = createSlice({
setLicenseInfo: (state, action: PayloadAction) => {
state.licenseInfo = action.payload;
},
- setCurTab: (state, action: PayloadAction) => {
+ setCurTab: (state, action: PayloadAction) => {
state.curTab = action.payload;
},
resetRegisterForm: () => initialState,
@@ -120,7 +115,6 @@ export const {
setSelectedSubnetOrganization,
setSubnetRegToken,
setSubnetOrganizations,
- setShowPassword,
setLoading,
setLoadingLicenseInfo,
setClusterRegistered,
diff --git a/portal-ui/src/screens/Console/Support/utils.tsx b/portal-ui/src/screens/Console/Support/utils.tsx
index 060cf6111..6d4cce324 100644
--- a/portal-ui/src/screens/Console/Support/utils.tsx
+++ b/portal-ui/src/screens/Console/Support/utils.tsx
@@ -1,56 +1,37 @@
-import { Box, Grid, Link } from "@mui/material";
-import { Fragment, useState } from "react";
-import { CopyIcon, SettingsIcon } from "mds";
-import FormSwitchWrapper from "../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper";
-import InputBoxWrapper from "../Common/FormComponents/InputBoxWrapper/InputBoxWrapper";
-import RegistrationStatusBanner from "./RegistrationStatusBanner";
+// This file is part of MinIO Console Server
+// Copyright (c) 2022 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 .
-export const FormTitle = ({
- icon = null,
- title,
-}: {
- icon?: any;
- title: any;
-}) => {
- return (
-
- {icon}
-
{title}
-
- );
-};
+import React, { Fragment, useState } from "react";
+import { CopyIcon, SettingsIcon, Box, Grid, Switch, InputBox } from "mds";
+import RegistrationStatusBanner from "./RegistrationStatusBanner";
export const ClusterRegistered = ({ email }: { email: string }) => {
return (
-
+
Login to{" "}
-
+
SUBNET
- {" "}
+ {" "}
to avail support for this MinIO cluster
@@ -65,9 +46,8 @@ export const ProxyConfiguration = () => {
return (
{
}}
>
For airgap/firewalled environments it is possible to{" "}
-
configure a proxy
- {" "}
+ {" "}
to connect to SUBNET .
{displaySubnetProxy && (
- {
label=""
value={proxyConfigurationCommand}
overlayIcon={}
- extraInputProps={{
- readOnly: true,
- }}
overlayAction={() =>
navigator.clipboard.writeText(proxyConfigurationCommand)
}
@@ -141,7 +114,7 @@ export const ProxyConfiguration = () => {
display: "flex",
}}
>
-