github.com/minio/console@v1.4.1/web-app/src/screens/Console/Support/Register.tsx (about) 1 // This file is part of MinIO Console Server 2 // Copyright (c) 2022 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, { Fragment, useEffect, useState } from "react"; 18 import { Box, PageLayout, Tabs } from "mds"; 19 import { SubnetRegTokenResponse } from "../License/types"; 20 import { ErrorResponseHandler } from "../../../common/types"; 21 import { useSelector } from "react-redux"; 22 import { setErrorSnackMessage, setHelpName } from "../../../systemSlice"; 23 import { AppState, useAppDispatch } from "../../../store"; 24 import { ClusterRegistered, ProxyConfiguration } from "./utils"; 25 import { fetchLicenseInfo } from "./registerThunks"; 26 import { 27 resetRegisterForm, 28 setCurTab, 29 setLoading, 30 setSubnetRegToken, 31 } from "./registerSlice"; 32 import OfflineRegistration from "./OfflineRegistration"; 33 import SubnetMFAToken from "./SubnetMFAToken"; 34 import ClusterRegistrationForm from "./ClusterRegistrationForm"; 35 import OnlineRegistration from "./OnlineRegistration"; 36 import PageHeaderWrapper from "../Common/PageHeaderWrapper/PageHeaderWrapper"; 37 import HelpMenu from "../HelpMenu"; 38 import api from "../../../common/api"; 39 import ApiKeyRegister from "./ApiKeyRegister"; 40 41 const Register = () => { 42 const dispatch = useAppDispatch(); 43 44 const subnetMFAToken = useSelector( 45 (state: AppState) => state.register.subnetMFAToken, 46 ); 47 const subnetAccessToken = useSelector( 48 (state: AppState) => state.register.subnetAccessToken, 49 ); 50 51 const subnetRegToken = useSelector( 52 (state: AppState) => state.register.subnetRegToken, 53 ); 54 const subnetOrganizations = useSelector( 55 (state: AppState) => state.register.subnetOrganizations, 56 ); 57 58 const loading = useSelector((state: AppState) => state.register.loading); 59 const loadingLicenseInfo = useSelector( 60 (state: AppState) => state.register.loadingLicenseInfo, 61 ); 62 const clusterRegistered = useSelector( 63 (state: AppState) => state.register.clusterRegistered, 64 ); 65 const licenseInfo = useSelector( 66 (state: AppState) => state.register.licenseInfo, 67 ); 68 const curTab = useSelector((state: AppState) => state.register.curTab); 69 70 const [initialLicenseLoading, setInitialLicenseLoading] = 71 useState<boolean>(true); 72 73 useEffect(() => { 74 // when unmounted, reset 75 return () => { 76 dispatch(resetRegisterForm()); 77 }; 78 }, [dispatch]); 79 80 useEffect(() => { 81 if (curTab === "simple-tab-2" && !loading && !subnetRegToken) { 82 const fetchSubnetRegToken = () => { 83 dispatch(setLoading(true)); 84 api 85 .invoke("GET", "/api/v1/subnet/registration-token") 86 .then((resp: SubnetRegTokenResponse) => { 87 dispatch(setLoading(false)); 88 if (resp && resp.regToken) { 89 dispatch(setSubnetRegToken(resp.regToken)); 90 } 91 }) 92 .catch((err: ErrorResponseHandler) => { 93 console.error(err); 94 dispatch(setErrorSnackMessage(err)); 95 dispatch(setLoading(false)); 96 }); 97 }; 98 fetchSubnetRegToken(); 99 } 100 }, [curTab, loading, subnetRegToken, dispatch]); 101 102 useEffect(() => { 103 if (initialLicenseLoading) { 104 dispatch(fetchLicenseInfo()); 105 setInitialLicenseLoading(false); 106 } 107 }, [initialLicenseLoading, setInitialLicenseLoading, dispatch]); 108 109 let clusterRegistrationForm: React.ReactElement = <Fragment />; 110 111 if (subnetAccessToken && subnetOrganizations.length > 0) { 112 clusterRegistrationForm = <ClusterRegistrationForm />; 113 } else if (subnetMFAToken) { 114 clusterRegistrationForm = <SubnetMFAToken />; 115 } else { 116 clusterRegistrationForm = <OnlineRegistration />; 117 } 118 119 const apiKeyRegistration = ( 120 <Fragment> 121 <Box 122 withBorders 123 sx={{ 124 display: "flex", 125 flexFlow: "column", 126 padding: "43px", 127 }} 128 > 129 {clusterRegistered && licenseInfo ? ( 130 <ClusterRegistered email={licenseInfo.email} /> 131 ) : ( 132 <ApiKeyRegister registerEndpoint={"/api/v1/subnet/login"} /> 133 )} 134 </Box> 135 <ProxyConfiguration /> 136 </Fragment> 137 ); 138 139 const offlineRegistration = <OfflineRegistration />; 140 141 const regUi = ( 142 <Fragment> 143 <Box 144 withBorders 145 sx={{ 146 display: "flex", 147 flexFlow: "column", 148 padding: "43px", 149 }} 150 > 151 {clusterRegistered && licenseInfo ? ( 152 <ClusterRegistered email={licenseInfo.email} /> 153 ) : ( 154 clusterRegistrationForm 155 )} 156 </Box> 157 158 {!clusterRegistered && <ProxyConfiguration />} 159 </Fragment> 160 ); 161 162 const loadingUi = <div>Loading..</div>; 163 const uiToShow = loadingLicenseInfo ? loadingUi : regUi; 164 165 useEffect(() => { 166 dispatch(setHelpName("register")); 167 // eslint-disable-next-line react-hooks/exhaustive-deps 168 }, []); 169 170 return ( 171 <Fragment> 172 <PageHeaderWrapper 173 label="Register to MinIO Subscription Network" 174 actions={<HelpMenu />} 175 /> 176 177 <PageLayout> 178 <Tabs 179 horizontal 180 currentTabOrPath={curTab} 181 onTabClick={(newValue: string) => { 182 dispatch(setCurTab(newValue)); 183 }} 184 options={[ 185 { 186 tabConfig: { 187 label: "Credentials", 188 id: "simple-tab-0", 189 }, 190 content: uiToShow, 191 }, 192 { 193 tabConfig: { 194 label: "API Key", 195 id: "simple-tab-1", 196 }, 197 content: apiKeyRegistration, 198 }, 199 { 200 tabConfig: { 201 label: "Air-Gap", 202 id: "simple-tab-2", 203 }, 204 content: offlineRegistration, 205 }, 206 ]} 207 /> 208 </PageLayout> 209 </Fragment> 210 ); 211 }; 212 213 export default Register;