Events details component (#1596)

* Events details component

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>

* lint

Signed-off-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
Daniel Valdivia
2022-02-16 19:33:05 -08:00
committed by GitHub
parent 10539929e1
commit e3a47d980c
5 changed files with 159 additions and 72 deletions

View File

@@ -50,7 +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";
import PVCDetails from "./pvcs/PVCDetails";
const TenantYAML = withSuspense(React.lazy(() => import("./TenantYAML")));
const TenantSummary = withSuspense(React.lazy(() => import("./TenantSummary")));

View File

@@ -29,9 +29,9 @@ 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";
import EventsList from "./events/EventsList";
interface ITenantEventsProps {
classes: any;
@@ -57,7 +57,7 @@ const TenantEvents = ({
loadingTenant,
setErrorSnackMessage,
}: ITenantEventsProps) => {
const [event, setEvent] = useState<IEvent[]>([]);
const [events, setEvents] = useState<IEvent[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const tenantName = match.params["tenantName"];
const tenantNamespace = match.params["tenantNamespace"];
@@ -81,7 +81,7 @@ const TenantEvents = ({
res[i].seen = niceDays((currentTime - res[i].last_seen).toString());
}
setEvent(res);
setEvents(res);
setLoading(false);
})
.catch((err: ErrorResponseHandler) => {
@@ -94,21 +94,8 @@ const TenantEvents = ({
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 item xs={12}>
<EventsList events={events} loading={loading} />
</Grid>
</React.Fragment>
);

View File

@@ -0,0 +1,126 @@
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 from "react";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import withStyles from "@mui/styles/withStyles";
import { LinearProgress } from "@mui/material";
import { IEvent } from "../../ListTenants/types";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import Box from "@mui/material/Box";
import Collapse from "@mui/material/Collapse";
import Typography from "@mui/material/Typography";
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
import TableContainer from "@mui/material/TableContainer";
import Paper from "@mui/material/Paper";
interface IEventsListProps {
classes: any;
events: IEvent[];
loading: boolean;
}
const styles = (theme: Theme) =>
createStyles({
events: {
"& .MuiTypography-root": {
fontSize: 14,
},
"& .Mui-expanded": {
"& .eventMessage": {
display: "none",
},
},
},
});
const Event = (props: { event: IEvent }) => {
const { event } = props;
const [open, setOpen] = React.useState(false);
return (
<React.Fragment>
<TableRow sx={{ "& > *": { borderBottom: "unset" }, cursor: "pointer" }}>
<TableCell component="th" scope="row" onClick={() => setOpen(!open)}>
{event.event_type}
</TableCell>
<TableCell onClick={() => setOpen(!open)}>{event.reason}</TableCell>
<TableCell onClick={() => setOpen(!open)}>{event.seen}</TableCell>
<TableCell onClick={() => setOpen(!open)}>
{event.message.length >= 30
? `${event.message.substr(0, 30)}...`
: event.message}
</TableCell>
<TableCell onClick={() => setOpen(!open)}>
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
</TableCell>
</TableRow>
<TableRow>
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={5}>
<Collapse in={open} timeout="auto" unmountOnExit>
<Box sx={{ margin: 1 }}>
<Typography
style={{
background: "#efefef",
border: "1px solid #dedede",
padding: 4,
fontSize: 14,
color: "#666666",
}}
>
{event.message}
</Typography>
</Box>
</Collapse>
</TableCell>
</TableRow>
</React.Fragment>
);
};
const EventsList = ({ classes, events, loading }: IEventsListProps) => {
if (loading) {
return <LinearProgress />;
}
return (
<TableContainer component={Paper}>
<Table aria-label="collapsible table">
<TableHead>
<TableRow>
<TableCell>Type</TableCell>
<TableCell>Reason</TableCell>
<TableCell>Age</TableCell>
<TableCell>Message</TableCell>
<TableCell />
</TableRow>
</TableHead>
<TableBody>
{events.map((event) => (
<Event key={`${event.event_type}-${event.seen}`} event={event} />
))}
</TableBody>
</Table>
</TableContainer>
);
};
export default withStyles(styles)(EventsList);

View File

@@ -30,9 +30,9 @@ 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";
import EventsList from "../events/EventsList";
interface IPodEventsProps {
classes: any;
@@ -65,7 +65,7 @@ const PodEvents = ({
setErrorSnackMessage,
loadingTenant,
}: IPodEventsProps) => {
const [event, setEvent] = useState<IEvent[]>([]);
const [events, setEvents] = useState<IEvent[]>([]);
const [loading, setLoading] = useState<boolean>(true);
useEffect(() => {
@@ -93,7 +93,7 @@ const PodEvents = ({
res[i].seen = niceDays((currentTime - res[i].last_seen).toString());
}
setEvent(res);
setEvents(res);
setLoading(false);
})
.catch((err: ErrorResponseHandler) => {
@@ -105,21 +105,8 @@ const PodEvents = ({
return (
<React.Fragment>
<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 item xs={12}>
<EventsList events={events} loading={loading} />
</Grid>
</React.Fragment>
);

View File

@@ -1,32 +1,32 @@
// This file is part of MinIO Console Server
// Copyright (c) 2021 MinIO, Inc.
// This file is part of MinIO Console Server
// Copyright (c) 2022 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 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.
// 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/>.
// 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 { 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";
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 EventsList from "../events/EventsList";
interface IPVCDetailsProps {
classes: any;
@@ -52,7 +52,7 @@ const PVCDetails = ({
const tenantNamespace = match.params["tenantNamespace"];
const tenantName = match.params["tenantName"];
const PVCName = match.params["PVCName"];
const [event, setEvent] = useState<IEvent[]>([]);
const [events, setEvents] = useState<IEvent[]>([]);
useEffect(() => {
if (loading) {
@@ -67,7 +67,7 @@ const PVCDetails = ({
res[i].seen = niceDays((currentTime - res[i].last_seen).toString());
}
setEvent(res);
setEvents(res);
setLoading(false);
})
.catch((err: ErrorResponseHandler) => {
@@ -92,20 +92,7 @@ const PVCDetails = ({
</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"
/>
<EventsList events={events} loading={loading} />
</Grid>
</Fragment>
);