Skip to content

Commit 25c1c85

Browse files
authored
Add new section to register tenants with API key in operator (#2222)
1 parent 5be2cc1 commit 25c1c85

File tree

5 files changed

+213
-4
lines changed

5 files changed

+213
-4
lines changed

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ const Heal = React.lazy(() => import("./Heal/Heal"));
6666
const Watch = React.lazy(() => import("./Watch/Watch"));
6767
const HealthInfo = React.lazy(() => import("./HealthInfo/HealthInfo"));
6868
const Hop = React.lazy(() => import("./Tenants/TenantDetails/hop/Hop"));
69+
const RegisterOperator = React.lazy(() => import("./Support/RegisterOperator"));
6970

7071
const AddTenant = React.lazy(() => import("./Tenants/AddTenant/AddTenant"));
7172

@@ -462,6 +463,11 @@ const Console = ({ classes }: IConsoleProps) => {
462463
path: IAM_PAGES.LICENSE,
463464
forceDisplay: true,
464465
},
466+
{
467+
component: RegisterOperator,
468+
path: IAM_PAGES.REGISTER_SUPPORT,
469+
forceDisplay: true,
470+
},
465471
{
466472
component: Marketplace,
467473
path: IAM_PAGES.OPERATOR_MARKETPLACE,

portal-ui/src/screens/Console/Support/ApiKeyRegister.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import withStyles from "@mui/styles/withStyles";
3434

3535
interface IApiKeyRegister {
3636
classes: any;
37+
registerEndpoint: string;
3738
afterRegister: () => void;
3839
}
3940

@@ -45,7 +46,11 @@ const styles = (theme: Theme) =>
4546
...spacingUtils,
4647
});
4748

48-
const ApiKeyRegister = ({ classes, afterRegister }: IApiKeyRegister) => {
49+
const ApiKeyRegister = ({
50+
classes,
51+
registerEndpoint,
52+
afterRegister,
53+
}: IApiKeyRegister) => {
4954
const [showApiKeyModal, setShowApiKeyModal] = useState(false);
5055
const [apiKey, setApiKey] = useState("");
5156
const [loading, setLoading] = useState(false);
@@ -59,7 +64,7 @@ const ApiKeyRegister = ({ classes, afterRegister }: IApiKeyRegister) => {
5964
setLoading(true);
6065
let request: SubnetLoginRequest = { apiKey };
6166
api
62-
.invoke("POST", "/api/v1/subnet/login", request)
67+
.invoke("POST", registerEndpoint, request)
6368
.then((resp: SubnetLoginResponse) => {
6469
setLoading(false);
6570
if (resp && resp.registered) {
@@ -72,7 +77,7 @@ const ApiKeyRegister = ({ classes, afterRegister }: IApiKeyRegister) => {
7277
setLoading(false);
7378
reset();
7479
});
75-
}, [afterRegister, apiKey, dispatch, loading]);
80+
}, [afterRegister, apiKey, dispatch, loading, registerEndpoint]);
7681

7782
useEffect(() => {
7883
if (fromModal) {

portal-ui/src/screens/Console/Support/Register.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -607,7 +607,10 @@ const Register = ({ classes }: IRegister) => {
607607
linkClass={classes.link}
608608
/>
609609
) : (
610-
<ApiKeyRegister afterRegister={fetchLicenseInfo} />
610+
<ApiKeyRegister
611+
afterRegister={fetchLicenseInfo}
612+
registerEndpoint={"/api/v1/subnet/login"}
613+
/>
611614
)}
612615
</Box>
613616
<ProxyConfiguration linkClass={classes.link} />
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
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 APIKey as published by
6+
// the Free Software Foundation, either version 3 of the APIKey, 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 APIKey for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public APIKey
15+
// along with this program. If not, see <http://www.gnu.org/APIKeys/>.
16+
17+
import React, { Fragment, useCallback, useEffect, useState } from "react";
18+
import { Theme } from "@mui/material/styles";
19+
import createStyles from "@mui/styles/createStyles";
20+
import {
21+
actionsTray,
22+
containerForHeader,
23+
searchField,
24+
spacingUtils,
25+
} from "../Common/FormComponents/common/styleLibrary";
26+
import withStyles from "@mui/styles/withStyles";
27+
import { Box } from "@mui/material";
28+
import PageHeader from "../Common/PageHeader/PageHeader";
29+
import PageLayout from "../Common/Layout/PageLayout";
30+
import api from "../../../common/api";
31+
32+
import { ErrorResponseHandler } from "../../../common/types";
33+
34+
import Tabs from "@mui/material/Tabs";
35+
import Tab from "@mui/material/Tab";
36+
import { TabPanel } from "../../shared/tabs";
37+
import { ClusterRegistered } from "./utils";
38+
import ApiKeyRegister from "./ApiKeyRegister";
39+
40+
interface IRegister {
41+
classes: any;
42+
}
43+
44+
const styles = (theme: Theme) =>
45+
createStyles({
46+
registerActivationIcon: {
47+
color: theme.palette.primary.main,
48+
fontSize: 16,
49+
fontWeight: "bold",
50+
marginBottom: 20,
51+
"& .min-icon": {
52+
width: 32.12,
53+
height: 25,
54+
marginRight: 10,
55+
verticalAlign: "middle",
56+
},
57+
},
58+
registerActivationMode: {
59+
textAlign: "right",
60+
"& a": {
61+
cursor: "pointer",
62+
},
63+
},
64+
subnetDescription: {
65+
textAlign: "left",
66+
Font: "normal normal normal 14px/17px Lato",
67+
letterSpacing: 0,
68+
color: "#000000",
69+
"& span": {
70+
fontWeight: "bold",
71+
},
72+
},
73+
registeredStatus: {
74+
border: "1px solid #E2E2E2",
75+
padding: "24px 24px 24px 24px",
76+
borderRadius: 2,
77+
marginBottom: 25,
78+
backgroundColor: "#FBFAFA",
79+
"& .min-icon": {
80+
width: 20,
81+
height: 20,
82+
marginLeft: 48,
83+
marginRight: 13,
84+
verticalAlign: "middle",
85+
marginTop: -3,
86+
},
87+
"& span": {
88+
fontWeight: "bold",
89+
},
90+
},
91+
copyInputBox: {
92+
"& button": {
93+
border: "1px solid #5E5E5E",
94+
borderRadius: 2,
95+
},
96+
},
97+
link: {
98+
color: "#2781B0",
99+
cursor: "pointer",
100+
},
101+
sizedLabel: {
102+
minWidth: "75px",
103+
},
104+
...actionsTray,
105+
...searchField,
106+
...spacingUtils,
107+
...containerForHeader(theme.spacing(4)),
108+
});
109+
110+
const RegisterOperator = ({ classes }: IRegister) => {
111+
const [apiKeyRegistered, setAPIKeyRegistered] = useState<boolean>(false);
112+
const [curTab, setCurTab] = useState<number>(0);
113+
114+
const fetchAPIKeyInfo = useCallback(() => {
115+
api
116+
.invoke("GET", `/api/v1/subnet/apikey/info`)
117+
.then((res: any) => {
118+
setAPIKeyRegistered(true);
119+
})
120+
.catch((err: ErrorResponseHandler) => {
121+
setAPIKeyRegistered(false);
122+
});
123+
}, []);
124+
125+
useEffect(() => {
126+
fetchAPIKeyInfo();
127+
}, [fetchAPIKeyInfo]);
128+
129+
const apiKeyRegistration = (
130+
<Fragment>
131+
<Box
132+
sx={{
133+
border: "1px solid #eaeaea",
134+
borderRadius: "2px",
135+
display: "flex",
136+
flexFlow: "column",
137+
padding: "43px",
138+
}}
139+
>
140+
{apiKeyRegistered ? (
141+
<ClusterRegistered email={"Operator"} linkClass={classes.link} />
142+
) : (
143+
<ApiKeyRegister
144+
registerEndpoint={"/api/v1/subnet/apikey/register"}
145+
afterRegister={fetchAPIKeyInfo}
146+
/>
147+
)}
148+
</Box>
149+
</Fragment>
150+
);
151+
152+
return (
153+
<Fragment>
154+
<PageHeader
155+
label="Register to MinIO Subscription Network"
156+
actions={<React.Fragment />}
157+
/>
158+
159+
<PageLayout>
160+
<Tabs
161+
value={curTab}
162+
onChange={(e: React.ChangeEvent<{}>, newValue: number) => {
163+
setCurTab(newValue);
164+
}}
165+
indicatorColor="primary"
166+
textColor="primary"
167+
aria-label="cluster-tabs"
168+
variant="scrollable"
169+
scrollButtons="auto"
170+
>
171+
<Tab
172+
label="API Key Activation"
173+
id="simple-tab-0"
174+
aria-controls="simple-tabpanel-1"
175+
/>
176+
</Tabs>
177+
<TabPanel index={0} value={curTab}>
178+
{apiKeyRegistration}
179+
</TabPanel>
180+
</PageLayout>
181+
</Fragment>
182+
);
183+
};
184+
185+
export default withStyles(styles)(RegisterOperator);

portal-ui/src/screens/Console/valid-routes.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,16 @@ export const validRoutes = (
293293
icon: LicenseIcon,
294294
forceDisplay: true,
295295
},
296+
{
297+
group: "Operator",
298+
type: "item",
299+
id: "Register",
300+
component: NavLink,
301+
to: IAM_PAGES.REGISTER_SUPPORT,
302+
name: "Register",
303+
icon: RegisterMenuIcon,
304+
forceDisplay: true,
305+
},
296306
{
297307
group: "Operator",
298308
type: "item",

0 commit comments

Comments
 (0)