Support for Hop into tenants (#878)
Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
@@ -58,6 +58,7 @@ import HealthInfo from "./HealthInfo/HealthInfo";
|
||||
import Storage from "./Storage/Storage";
|
||||
import PodDetails from "./Tenants/TenantDetails/pods/PodDetails";
|
||||
import Metrics from "./Dashboard/Metrics";
|
||||
import Hop from "./Tenants/TenantDetails/hop/Hop";
|
||||
|
||||
const drawerWidth = 245;
|
||||
|
||||
@@ -359,6 +360,10 @@ const Console = ({
|
||||
component: TenantDetails,
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName",
|
||||
},
|
||||
{
|
||||
component: Hop,
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/hop",
|
||||
},
|
||||
{
|
||||
component: PodDetails,
|
||||
path: "/namespaces/:tenantNamespace/tenants/:tenantName/pods/:podName",
|
||||
@@ -410,12 +415,19 @@ const Console = ({
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
let hideMenu = false;
|
||||
if (location.pathname === "/metrics") {
|
||||
hideMenu = true;
|
||||
} else if (location.pathname.endsWith("/hop")) {
|
||||
hideMenu = true;
|
||||
}
|
||||
|
||||
return (
|
||||
<Fragment>
|
||||
{session.status === "ok" ? (
|
||||
<div className={classes.root}>
|
||||
<CssBaseline />
|
||||
{location.pathname !== "/metrics" && (
|
||||
{!hideMenu && (
|
||||
<Drawer
|
||||
variant="permanent"
|
||||
classes={{
|
||||
|
||||
@@ -26,8 +26,8 @@ import Tab from "@material-ui/core/Tab";
|
||||
import { setErrorSnackMessage } from "../../../../actions";
|
||||
import {
|
||||
setTenantDetailsLoad,
|
||||
setTenantName,
|
||||
setTenantInfo,
|
||||
setTenantName,
|
||||
setTenantTab,
|
||||
} from "../actions";
|
||||
import { ITenant } from "../ListTenants/types";
|
||||
@@ -193,7 +193,7 @@ const TenantDetails = ({
|
||||
label={
|
||||
<Fragment>
|
||||
<Link to={"/tenants"} className={classes.breadcrumLink}>
|
||||
Tenant
|
||||
Tenants
|
||||
</Link>
|
||||
{` > ${match.params["tenantName"]}`}
|
||||
<IconButton
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
// You should have received a copy of the GNU Affero General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment, useState } from "react";
|
||||
import React, { useState } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import get from "lodash/get";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
|
||||
@@ -31,6 +31,7 @@ import { ITenant } from "../ListTenants/types";
|
||||
import UsageBarWrapper from "../../Common/UsageBarWrapper/UsageBarWrapper";
|
||||
import UpdateTenantModal from "./UpdateTenantModal";
|
||||
import { AppState } from "../../../../store";
|
||||
import history from "./../../../../history";
|
||||
|
||||
interface ITenantsSummary {
|
||||
classes: any;
|
||||
@@ -319,6 +320,19 @@ const TenantSummary = ({
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<Button
|
||||
size={"small"}
|
||||
color={"primary"}
|
||||
variant="contained"
|
||||
style={{ textDecoration: "none !important" }}
|
||||
onClick={() => {
|
||||
history.push(
|
||||
`/namespaces/${tenantNamespace}/tenants/${tenantName}/hop`
|
||||
);
|
||||
}}
|
||||
>
|
||||
Management UI
|
||||
</Button>
|
||||
</Fragment>
|
||||
)}
|
||||
</Grid>
|
||||
|
||||
137
portal-ui/src/screens/Console/Tenants/TenantDetails/hop/Hop.tsx
Normal file
137
portal-ui/src/screens/Console/Tenants/TenantDetails/hop/Hop.tsx
Normal file
@@ -0,0 +1,137 @@
|
||||
// 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
import React, { Fragment, useState } from "react";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { Link } from "react-router-dom";
|
||||
import { CircularProgress, IconButton } from "@material-ui/core";
|
||||
import RefreshIcon from "@material-ui/icons/Refresh";
|
||||
import PageHeader from "../../../Common/PageHeader/PageHeader";
|
||||
import { containerForHeader } from "../../../Common/FormComponents/common/styleLibrary";
|
||||
import ExitToAppIcon from "@material-ui/icons/ExitToApp";
|
||||
import history from "./../../../../../history";
|
||||
|
||||
interface IHopSimple {
|
||||
classes: any;
|
||||
match: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
breadcrumLink: {
|
||||
textDecoration: "none",
|
||||
color: "black",
|
||||
},
|
||||
iframeStyle: {
|
||||
border: 0,
|
||||
position: "absolute",
|
||||
height: "calc(100vh - 77px)",
|
||||
width: "100%",
|
||||
},
|
||||
divContainer: {
|
||||
position: "absolute",
|
||||
left: 0,
|
||||
top: 77,
|
||||
height: "calc(100vh - 77px)",
|
||||
width: "100%",
|
||||
},
|
||||
loader: {
|
||||
width: 100,
|
||||
margin: "auto",
|
||||
marginTop: 80,
|
||||
},
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
const Hop = ({ classes, match }: IHopSimple) => {
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
|
||||
const tenantName = match.params["tenantName"];
|
||||
const tenantNamespace = match.params["tenantNamespace"];
|
||||
const consoleFrame = React.useRef<HTMLIFrameElement>(null);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<PageHeader
|
||||
label={
|
||||
<Fragment>
|
||||
<Link to={"/tenants"} className={classes.breadcrumLink}>
|
||||
Tenants
|
||||
</Link>
|
||||
{` > `}
|
||||
<Link
|
||||
to={`/namespaces/${tenantNamespace}/tenants/${tenantName}`}
|
||||
className={classes.breadcrumLink}
|
||||
>
|
||||
{match.params["tenantName"]}
|
||||
</Link>
|
||||
{` > Management`}
|
||||
</Fragment>
|
||||
}
|
||||
actions={
|
||||
<React.Fragment>
|
||||
<IconButton
|
||||
color="primary"
|
||||
aria-label="Refresh List"
|
||||
component="span"
|
||||
onClick={() => {
|
||||
if (
|
||||
consoleFrame !== null &&
|
||||
consoleFrame.current !== null &&
|
||||
consoleFrame.current.contentDocument !== null
|
||||
) {
|
||||
consoleFrame.current.contentDocument.location.reload(true);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<RefreshIcon />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
color="primary"
|
||||
aria-label="Refresh List"
|
||||
component="span"
|
||||
onClick={() => {
|
||||
history.push(
|
||||
`/namespaces/${tenantNamespace}/tenants/${tenantName}`
|
||||
);
|
||||
}}
|
||||
>
|
||||
<ExitToAppIcon />
|
||||
</IconButton>
|
||||
</React.Fragment>
|
||||
}
|
||||
/>
|
||||
<div className={classes.divContainer}>
|
||||
{loading && (
|
||||
<div className={classes.loader}>
|
||||
<CircularProgress />
|
||||
</div>
|
||||
)}
|
||||
<iframe
|
||||
ref={consoleFrame}
|
||||
className={classes.iframeStyle}
|
||||
title={"metrics"}
|
||||
src={`/api/proxy/${tenantNamespace}/${tenantName}/`}
|
||||
onLoad={(val) => {
|
||||
setLoading(false);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(Hop);
|
||||
Reference in New Issue
Block a user