Adding PVC events UI (#1448)

* adding PVC events UI

* adding label

Co-authored-by: Prakash Senthil Vel <23444145+prakashsvmx@users.noreply.github.com>
Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
adfost
2022-01-25 14:02:50 -08:00
committed by GitHub
parent 83a4c351dd
commit cc8d5abcd6
5 changed files with 137 additions and 1 deletions

View File

@@ -199,6 +199,8 @@ export const IAM_PAGES = {
NAMESPACE_TENANT_HOP: "/namespaces/:tenantNamespace/tenants/:tenantName/hop",
NAMESPACE_TENANT_PODS:
"/namespaces/:tenantNamespace/tenants/:tenantName/pods/:podName",
NAMESPACE_TENANT_PVCS:
"/namespaces/:tenantNamespace/tenants/:tenantName/pvcs/:PVCName",
NAMESPACE_TENANT_PODS_LIST:
"/namespaces/:tenantNamespace/tenants/:tenantName/pods",
NAMESPACE_TENANT_SUMMARY:

View File

@@ -416,6 +416,11 @@ const Console = ({
path: IAM_PAGES.NAMESPACE_TENANT_PODS,
forceDisplay: true,
},
{
component: TenantDetails,
path: IAM_PAGES.NAMESPACE_TENANT_PVCS,
forceDisplay: true,
},
{
component: TenantDetails,
path: IAM_PAGES.NAMESPACE_TENANT_SUMMARY,

View File

@@ -0,0 +1,114 @@
// 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, useEffect, useState } from "react";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { containerForHeader } from "../../Common/FormComponents/common/styleLibrary";
import Grid from "@mui/material/Grid";
import { Link } from "react-router-dom";
import { setErrorSnackMessage } from "../../../../actions";
import api from "../../../../common/api";
import { IEvent } from "../ListTenants/types";
import { niceDays } from "../../../../common/utils";
import { ErrorResponseHandler } from "../../../../common/types";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
interface IPVCDetailsProps {
classes: any;
match: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
}
const styles = (theme: Theme) =>
createStyles({
breadcrumLink: {
textDecoration: "none",
color: "black",
},
...containerForHeader(theme.spacing(4)),
});
const PVCDetails = ({
classes,
match,
setErrorSnackMessage,
}: IPVCDetailsProps) => {
const [loading, setLoading] = useState<boolean>(true);
const tenantNamespace = match.params["tenantNamespace"];
const tenantName = match.params["tenantName"];
const PVCName = match.params["PVCName"];
const [event, setEvent] = useState<IEvent[]>([]);
useEffect(() => {
if (loading) {
api
.invoke(
"GET",
`/api/v1/namespaces/${tenantNamespace}/tenants/${tenantName}/pvcs/${PVCName}/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, PVCName, tenantNamespace, tenantName, setErrorSnackMessage]);
return (
<Fragment>
<Grid item xs={12}>
<h1 className={classes.sectionTitle}>
<Link
to={`/namespaces/${tenantNamespace}/tenants/${tenantName}/volumes`}
className={classes.breadcrumLink}
>
PVCs
</Link>{" "}
&gt; {PVCName}
</h1>
</Grid>
<Grid container>
<h1 className={classes.sectionTitle}>Events</h1>
<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>
</Fragment>
);
};
export default withStyles(styles)(PVCDetails);

View File

@@ -50,6 +50,7 @@ import BackLink from "../../../../common/BackLink";
import VerticalTabs from "../../Common/VerticalTabs/VerticalTabs";
import BoxIconButton from "../../Common/BoxIconButton/BoxIconButton";
import withSuspense from "../../Common/Components/withSuspense";
import PVCDetails from "./PVCDetails";
const TenantYAML = withSuspense(React.lazy(() => import("./TenantYAML")));
const TenantSummary = withSuspense(React.lazy(() => import("./TenantSummary")));
@@ -438,6 +439,10 @@ const TenantDetails = ({
path="/namespaces/:tenantNamespace/tenants/:tenantName/pods"
component={PodsSummary}
/>
<Route
path="/namespaces/:tenantNamespace/tenants/:tenantName/pvcs/:PVCName"
component={PVCDetails}
/>
<Route
path="/namespaces/:tenantNamespace/tenants/:tenantName/volumes"
component={VolumesSummary}

View File

@@ -33,6 +33,7 @@ import { ErrorResponseHandler } from "../../../../common/types";
import api from "../../../../common/api";
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
import SearchIcon from "../../../../icons/SearchIcon";
import { IPodListElement } from "../ListTenants/types";
import withSuspense from "../../Common/Components/withSuspense";
import { setTenantDetailsLoad } from "../actions";
import { AppState } from "../../../../store";
@@ -42,6 +43,7 @@ const DeletePVC = withSuspense(React.lazy(() => import("./DeletePVC")));
interface ITenantVolumesProps {
classes: any;
setErrorSnackMessage: typeof setErrorSnackMessage;
history: any;
match: any;
loadingTenant: boolean;
setTenantDetailsLoad: typeof setTenantDetailsLoad;
@@ -61,6 +63,7 @@ const styles = (theme: Theme) =>
const TenantVolumes = ({
classes,
setErrorSnackMessage,
history,
match,
loadingTenant,
}: ITenantVolumesProps) => {
@@ -106,6 +109,13 @@ const TenantVolumes = ({
elementItem.name.includes(filter)
);
const PVCViewAction = (PVC: IPodListElement) => {
history.push(
`/namespaces/${tenantNamespace}/tenants/${tenantName}/pvcs/${PVC.name}`
);
return;
};
const closeDeleteModalAndRefresh = (reloadData: boolean) => {
setDeleteOpen(false);
setLoading(true);
@@ -152,7 +162,7 @@ const TenantVolumes = ({
</Grid>
<Grid item xs={12} className={classes.tableBlock}>
<TableWrapper
itemActions={[{ type: "delete", onClick: confirmDeletePVC }]}
itemActions={[{ type: "view", onClick: PVCViewAction }, { type: "delete", onClick: confirmDeletePVC }]}
columns={[
{
label: "Name",