Tenant events UI (#1590)
This commit is contained in:
@@ -190,6 +190,8 @@ export const IAM_PAGES = {
|
||||
"/namespaces/:tenantNamespace/tenants/:tenantName/monitoring",
|
||||
NAMESPACE_TENANT_LOGGING:
|
||||
"/namespaces/:tenantNamespace/tenants/:tenantName/logging",
|
||||
NAMESPACE_TENANT_EVENTS:
|
||||
"/namespaces/:tenantNamespace/tenants/:tenantName/events",
|
||||
};
|
||||
|
||||
// roles
|
||||
|
||||
@@ -468,6 +468,11 @@ const Console = ({
|
||||
path: IAM_PAGES.NAMESPACE_TENANT_LOGGING,
|
||||
forceDisplay: true,
|
||||
},
|
||||
{
|
||||
component: TenantDetails,
|
||||
path: IAM_PAGES.NAMESPACE_TENANT_EVENTS,
|
||||
forceDisplay: true,
|
||||
},
|
||||
{
|
||||
component: License,
|
||||
path: IAM_PAGES.LICENSE,
|
||||
|
||||
@@ -58,6 +58,7 @@ const TenantLicense = withSuspense(React.lazy(() => import("./TenantLicense")));
|
||||
const PoolsSummary = withSuspense(React.lazy(() => import("./PoolsSummary")));
|
||||
const PodsSummary = withSuspense(React.lazy(() => import("./PodsSummary")));
|
||||
const TenantLogging = withSuspense(React.lazy(() => import("./TenantLogging")));
|
||||
const TenantEvents = withSuspense(React.lazy(() => import("./TenantEvents")));
|
||||
const VolumesSummary = withSuspense(
|
||||
React.lazy(() => import("./VolumesSummary"))
|
||||
);
|
||||
@@ -459,6 +460,10 @@ const TenantDetails = ({
|
||||
path="/namespaces/:tenantNamespace/tenants/:tenantName/logging"
|
||||
component={TenantLogging}
|
||||
/>
|
||||
<Route
|
||||
path="/namespaces/:tenantNamespace/tenants/:tenantName/events"
|
||||
component={TenantEvents}
|
||||
/>
|
||||
<Route
|
||||
path="/namespaces/:tenantNamespace/tenants/:tenantName"
|
||||
component={() => (
|
||||
@@ -537,6 +542,14 @@ const TenantDetails = ({
|
||||
to: getRoutePath("volumes"),
|
||||
},
|
||||
}}
|
||||
{{
|
||||
tabConfig: {
|
||||
label: "Events",
|
||||
value: "events",
|
||||
component: Link,
|
||||
to: getRoutePath("events"),
|
||||
},
|
||||
}}
|
||||
{{
|
||||
tabConfig: {
|
||||
label: "License",
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
// 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, { useEffect, useState } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import { Theme } from "@mui/material/styles";
|
||||
import createStyles from "@mui/styles/createStyles";
|
||||
import withStyles from "@mui/styles/withStyles";
|
||||
import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
searchField, tableStyles,
|
||||
} from "../../Common/FormComponents/common/styleLibrary";
|
||||
import Grid from "@mui/material/Grid";
|
||||
import { IEvent } from "../ListTenants/types";
|
||||
import { setErrorSnackMessage } from "../../../../actions";
|
||||
import { niceDays } from "../../../../common/utils";
|
||||
import { ErrorResponseHandler } from "../../../../common/types";
|
||||
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
|
||||
import api from "../../../../common/api";
|
||||
import { AppState } from "../../../../store";
|
||||
|
||||
interface ITenantEventsProps {
|
||||
classes: any;
|
||||
match: any;
|
||||
loadingTenant: boolean;
|
||||
setErrorSnackMessage: typeof setErrorSnackMessage;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
tableWrapper: {
|
||||
height: "450px",
|
||||
},
|
||||
...actionsTray,
|
||||
...searchField,
|
||||
...tableStyles,
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
const TenantEvents = ({
|
||||
classes,
|
||||
match,
|
||||
loadingTenant,
|
||||
setErrorSnackMessage,
|
||||
}: ITenantEventsProps) => {
|
||||
const [event, setEvent] = useState<IEvent[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(true);
|
||||
const tenantName = match.params["tenantName"];
|
||||
const tenantNamespace = match.params["tenantNamespace"];
|
||||
|
||||
useEffect(() => {
|
||||
if (loadingTenant) {
|
||||
setLoading(true);
|
||||
}
|
||||
}, [loadingTenant]);
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) {
|
||||
api
|
||||
.invoke(
|
||||
"GET",
|
||||
`/api/v1/namespaces/${tenantNamespace}/tenants/${tenantName}/events`
|
||||
)
|
||||
.then((res: IEvent[]) => {
|
||||
for (let i = 0; i < res.length; i++) {
|
||||
let currentTime = (Date.now() / 1000) | 0;
|
||||
|
||||
res[i].seen = niceDays((currentTime - res[i].last_seen).toString());
|
||||
}
|
||||
setEvent(res);
|
||||
setLoading(false);
|
||||
})
|
||||
.catch((err: ErrorResponseHandler) => {
|
||||
setErrorSnackMessage(err);
|
||||
setLoading(false);
|
||||
});
|
||||
}
|
||||
}, [loading, tenantNamespace, tenantName, setErrorSnackMessage]);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<h1 className={classes.sectionTitle}>Events</h1>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<TableWrapper
|
||||
itemActions={[]}
|
||||
columns={[
|
||||
{ label: "Namespace", elementKey: "namespace" },
|
||||
{ label: "Last Seen", elementKey: "seen" },
|
||||
{ label: "Message", elementKey: "message" },
|
||||
{ label: "Event Type", elementKey: "event_type" },
|
||||
{ label: "Reason", elementKey: "reason" },
|
||||
]}
|
||||
isLoading={loading}
|
||||
records={event}
|
||||
entityName="Events"
|
||||
idField="event"
|
||||
/>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
const mapState = (state: AppState) => ({
|
||||
loadingTenant: state.tenants.tenantDetails.loadingTenant,
|
||||
});
|
||||
const connector = connect(mapState, {
|
||||
setErrorSnackMessage,
|
||||
});
|
||||
|
||||
export default withStyles(styles)(connector(TenantEvents));
|
||||
Reference in New Issue
Block a user