Skip to content

Commit e3a47d9

Browse files
authored
Events details component (#1596)
* Events details component Signed-off-by: Daniel Valdivia <[email protected]> * lint Signed-off-by: Daniel Valdivia <[email protected]>
1 parent 1053992 commit e3a47d9

File tree

5 files changed

+159
-72
lines changed

5 files changed

+159
-72
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ import BackLink from "../../../../common/BackLink";
5050
import VerticalTabs from "../../Common/VerticalTabs/VerticalTabs";
5151
import BoxIconButton from "../../Common/BoxIconButton/BoxIconButton";
5252
import withSuspense from "../../Common/Components/withSuspense";
53-
import PVCDetails from "./PVCDetails";
53+
import PVCDetails from "./pvcs/PVCDetails";
5454

5555
const TenantYAML = withSuspense(React.lazy(() => import("./TenantYAML")));
5656
const TenantSummary = withSuspense(React.lazy(() => import("./TenantSummary")));

portal-ui/src/screens/Console/Tenants/TenantDetails/TenantEvents.tsx

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ import { IEvent } from "../ListTenants/types";
2929
import { setErrorSnackMessage } from "../../../../actions";
3030
import { niceDays } from "../../../../common/utils";
3131
import { ErrorResponseHandler } from "../../../../common/types";
32-
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
3332
import api from "../../../../common/api";
3433
import { AppState } from "../../../../store";
34+
import EventsList from "./events/EventsList";
3535

3636
interface ITenantEventsProps {
3737
classes: any;
@@ -57,7 +57,7 @@ const TenantEvents = ({
5757
loadingTenant,
5858
setErrorSnackMessage,
5959
}: ITenantEventsProps) => {
60-
const [event, setEvent] = useState<IEvent[]>([]);
60+
const [events, setEvents] = useState<IEvent[]>([]);
6161
const [loading, setLoading] = useState<boolean>(true);
6262
const tenantName = match.params["tenantName"];
6363
const tenantNamespace = match.params["tenantNamespace"];
@@ -81,7 +81,7 @@ const TenantEvents = ({
8181

8282
res[i].seen = niceDays((currentTime - res[i].last_seen).toString());
8383
}
84-
setEvent(res);
84+
setEvents(res);
8585
setLoading(false);
8686
})
8787
.catch((err: ErrorResponseHandler) => {
@@ -94,21 +94,8 @@ const TenantEvents = ({
9494
return (
9595
<React.Fragment>
9696
<h1 className={classes.sectionTitle}>Events</h1>
97-
<Grid item xs={12} className={classes.actionsTray}>
98-
<TableWrapper
99-
itemActions={[]}
100-
columns={[
101-
{ label: "Namespace", elementKey: "namespace" },
102-
{ label: "Last Seen", elementKey: "seen" },
103-
{ label: "Message", elementKey: "message" },
104-
{ label: "Event Type", elementKey: "event_type" },
105-
{ label: "Reason", elementKey: "reason" },
106-
]}
107-
isLoading={loading}
108-
records={event}
109-
entityName="Events"
110-
idField="event"
111-
/>
97+
<Grid item xs={12}>
98+
<EventsList events={events} loading={loading} />
11299
</Grid>
113100
</React.Fragment>
114101
);
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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 License as published by
6+
// the Free Software Foundation, either version 3 of the License, 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 License for more details.
13+
//
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
16+
17+
import React from "react";
18+
import { Theme } from "@mui/material/styles";
19+
import createStyles from "@mui/styles/createStyles";
20+
import withStyles from "@mui/styles/withStyles";
21+
import { LinearProgress } from "@mui/material";
22+
import { IEvent } from "../../ListTenants/types";
23+
import Table from "@mui/material/Table";
24+
import TableBody from "@mui/material/TableBody";
25+
import TableCell from "@mui/material/TableCell";
26+
import TableHead from "@mui/material/TableHead";
27+
import TableRow from "@mui/material/TableRow";
28+
import Box from "@mui/material/Box";
29+
import Collapse from "@mui/material/Collapse";
30+
import Typography from "@mui/material/Typography";
31+
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown";
32+
import KeyboardArrowUpIcon from "@mui/icons-material/KeyboardArrowUp";
33+
import TableContainer from "@mui/material/TableContainer";
34+
import Paper from "@mui/material/Paper";
35+
36+
interface IEventsListProps {
37+
classes: any;
38+
events: IEvent[];
39+
loading: boolean;
40+
}
41+
42+
const styles = (theme: Theme) =>
43+
createStyles({
44+
events: {
45+
"& .MuiTypography-root": {
46+
fontSize: 14,
47+
},
48+
"& .Mui-expanded": {
49+
"& .eventMessage": {
50+
display: "none",
51+
},
52+
},
53+
},
54+
});
55+
56+
const Event = (props: { event: IEvent }) => {
57+
const { event } = props;
58+
const [open, setOpen] = React.useState(false);
59+
60+
return (
61+
<React.Fragment>
62+
<TableRow sx={{ "& > *": { borderBottom: "unset" }, cursor: "pointer" }}>
63+
<TableCell component="th" scope="row" onClick={() => setOpen(!open)}>
64+
{event.event_type}
65+
</TableCell>
66+
<TableCell onClick={() => setOpen(!open)}>{event.reason}</TableCell>
67+
<TableCell onClick={() => setOpen(!open)}>{event.seen}</TableCell>
68+
<TableCell onClick={() => setOpen(!open)}>
69+
{event.message.length >= 30
70+
? `${event.message.substr(0, 30)}...`
71+
: event.message}
72+
</TableCell>
73+
<TableCell onClick={() => setOpen(!open)}>
74+
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
75+
</TableCell>
76+
</TableRow>
77+
<TableRow>
78+
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={5}>
79+
<Collapse in={open} timeout="auto" unmountOnExit>
80+
<Box sx={{ margin: 1 }}>
81+
<Typography
82+
style={{
83+
background: "#efefef",
84+
border: "1px solid #dedede",
85+
padding: 4,
86+
fontSize: 14,
87+
color: "#666666",
88+
}}
89+
>
90+
{event.message}
91+
</Typography>
92+
</Box>
93+
</Collapse>
94+
</TableCell>
95+
</TableRow>
96+
</React.Fragment>
97+
);
98+
};
99+
100+
const EventsList = ({ classes, events, loading }: IEventsListProps) => {
101+
if (loading) {
102+
return <LinearProgress />;
103+
}
104+
return (
105+
<TableContainer component={Paper}>
106+
<Table aria-label="collapsible table">
107+
<TableHead>
108+
<TableRow>
109+
<TableCell>Type</TableCell>
110+
<TableCell>Reason</TableCell>
111+
<TableCell>Age</TableCell>
112+
<TableCell>Message</TableCell>
113+
<TableCell />
114+
</TableRow>
115+
</TableHead>
116+
<TableBody>
117+
{events.map((event) => (
118+
<Event key={`${event.event_type}-${event.seen}`} event={event} />
119+
))}
120+
</TableBody>
121+
</Table>
122+
</TableContainer>
123+
);
124+
};
125+
126+
export default withStyles(styles)(EventsList);

portal-ui/src/screens/Console/Tenants/TenantDetails/pods/PodEvents.tsx

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,9 @@ import { IEvent } from "../../ListTenants/types";
3030
import { setErrorSnackMessage } from "../../../../../actions";
3131
import { niceDays } from "../../../../../common/utils";
3232
import { ErrorResponseHandler } from "../../../../../common/types";
33-
import TableWrapper from "../../../Common/TableWrapper/TableWrapper";
3433
import api from "../../../../../common/api";
3534
import { AppState } from "../../../../../store";
35+
import EventsList from "../events/EventsList";
3636

3737
interface IPodEventsProps {
3838
classes: any;
@@ -65,7 +65,7 @@ const PodEvents = ({
6565
setErrorSnackMessage,
6666
loadingTenant,
6767
}: IPodEventsProps) => {
68-
const [event, setEvent] = useState<IEvent[]>([]);
68+
const [events, setEvents] = useState<IEvent[]>([]);
6969
const [loading, setLoading] = useState<boolean>(true);
7070

7171
useEffect(() => {
@@ -93,7 +93,7 @@ const PodEvents = ({
9393

9494
res[i].seen = niceDays((currentTime - res[i].last_seen).toString());
9595
}
96-
setEvent(res);
96+
setEvents(res);
9797
setLoading(false);
9898
})
9999
.catch((err: ErrorResponseHandler) => {
@@ -105,21 +105,8 @@ const PodEvents = ({
105105

106106
return (
107107
<React.Fragment>
108-
<Grid item xs={12} className={classes.actionsTray}>
109-
<TableWrapper
110-
itemActions={[]}
111-
columns={[
112-
{ label: "Namespace", elementKey: "namespace" },
113-
{ label: "Last Seen", elementKey: "seen" },
114-
{ label: "Message", elementKey: "message" },
115-
{ label: "Event Type", elementKey: "event_type" },
116-
{ label: "Reason", elementKey: "reason" },
117-
]}
118-
isLoading={loading}
119-
records={event}
120-
entityName="Events"
121-
idField="event"
122-
/>
108+
<Grid item xs={12}>
109+
<EventsList events={events} loading={loading} />
123110
</Grid>
124111
</React.Fragment>
125112
);

portal-ui/src/screens/Console/Tenants/TenantDetails/PVCDetails.tsx renamed to portal-ui/src/screens/Console/Tenants/TenantDetails/pvcs/PVCDetails.tsx

Lines changed: 22 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,32 @@
1-
// This file is part of MinIO Console Server
2-
// Copyright (c) 2021 MinIO, Inc.
1+
// This file is part of MinIO Console Server
2+
// Copyright (c) 2022 MinIO, Inc.
33
//
4-
// This program is free software: you can redistribute it and/or modify
5-
// it under the terms of the GNU Affero General Public License as published by
6-
// the Free Software Foundation, either version 3 of the License, or
7-
// (at your option) any later version.
4+
// This program is free software: you can redistribute it and/or modify
5+
// it under the terms of the GNU Affero General Public License as published by
6+
// the Free Software Foundation, either version 3 of the License, or
7+
// (at your option) any later version.
88
//
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 License for more details.
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 License for more details.
1313
//
14-
// You should have received a copy of the GNU Affero General Public License
15-
// along with this program. If not, see <http://www.gnu.org/licenses/>.
14+
// You should have received a copy of the GNU Affero General Public License
15+
// along with this program. If not, see <http://www.gnu.org/licenses/>.
1616

1717
import React, { Fragment, useEffect, useState } from "react";
1818
import { Theme } from "@mui/material/styles";
1919
import createStyles from "@mui/styles/createStyles";
2020
import withStyles from "@mui/styles/withStyles";
21-
import { containerForHeader } from "../../Common/FormComponents/common/styleLibrary";
21+
import { containerForHeader } from "../../../Common/FormComponents/common/styleLibrary";
2222
import Grid from "@mui/material/Grid";
2323
import { Link } from "react-router-dom";
24-
import { setErrorSnackMessage } from "../../../../actions";
25-
import api from "../../../../common/api";
26-
import { IEvent } from "../ListTenants/types";
27-
import { niceDays } from "../../../../common/utils";
28-
import { ErrorResponseHandler } from "../../../../common/types";
29-
import TableWrapper from "../../Common/TableWrapper/TableWrapper";
24+
import { setErrorSnackMessage } from "../../../../../actions";
25+
import api from "../../../../../common/api";
26+
import { IEvent } from "../../ListTenants/types";
27+
import { niceDays } from "../../../../../common/utils";
28+
import { ErrorResponseHandler } from "../../../../../common/types";
29+
import EventsList from "../events/EventsList";
3030

3131
interface IPVCDetailsProps {
3232
classes: any;
@@ -52,7 +52,7 @@ const PVCDetails = ({
5252
const tenantNamespace = match.params["tenantNamespace"];
5353
const tenantName = match.params["tenantName"];
5454
const PVCName = match.params["PVCName"];
55-
const [event, setEvent] = useState<IEvent[]>([]);
55+
const [events, setEvents] = useState<IEvent[]>([]);
5656

5757
useEffect(() => {
5858
if (loading) {
@@ -67,7 +67,7 @@ const PVCDetails = ({
6767

6868
res[i].seen = niceDays((currentTime - res[i].last_seen).toString());
6969
}
70-
setEvent(res);
70+
setEvents(res);
7171
setLoading(false);
7272
})
7373
.catch((err: ErrorResponseHandler) => {
@@ -92,20 +92,7 @@ const PVCDetails = ({
9292
</Grid>
9393
<Grid container>
9494
<h1 className={classes.sectionTitle}>Events</h1>
95-
<TableWrapper
96-
itemActions={[]}
97-
columns={[
98-
{ label: "Namespace", elementKey: "namespace" },
99-
{ label: "Last Seen", elementKey: "seen" },
100-
{ label: "Message", elementKey: "message" },
101-
{ label: "Event Type", elementKey: "event_type" },
102-
{ label: "Reason", elementKey: "reason" },
103-
]}
104-
isLoading={loading}
105-
records={event}
106-
entityName="Events"
107-
idField="event"
108-
/>
95+
<EventsList events={events} loading={loading} />
10996
</Grid>
11097
</Fragment>
11198
);

0 commit comments

Comments
 (0)