Skip to content

Commit 9c04ecd

Browse files
authored
Merge pull request #1663 from bluewave-labs/fix/fe/consistent-initial-state
Fix/fe/consistent initial state
2 parents c250f52 + 4559215 commit 9c04ecd

File tree

29 files changed

+313
-239
lines changed

29 files changed

+313
-239
lines changed

Client/src/Components/Fallback/index.css

+16
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,22 @@
1919
font-size: var(--env-var-font-size-medium);
2020
}
2121

22+
[class*="fallback__"] .background-pattern-svg {
23+
position: absolute;
24+
top: 0;
25+
left: 50%;
26+
transform: translate(-50%, -50%);
27+
z-index: 0;
28+
29+
width: 100%;
30+
max-width: 800px;
31+
height: 100%;
32+
max-height: 800px;
33+
34+
background-position: center;
35+
background-size: cover;
36+
background-repeat: no-repeat;
37+
}
2238
.fallback__status > .MuiStack-root {
2339
margin-left: var(--env-var-spacing-2);
2440
}

Client/src/Components/Layouts/HomeLayout/index.css

-17
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,3 @@
2626
min-height: calc(100vh - var(--env-var-spacing-2) * 2);
2727
flex: 1;
2828
}
29-
30-
.home-layout > div:has(> [class*="fallback__"]) .background-pattern-svg {
31-
position: absolute;
32-
top: 0;
33-
left: 50%;
34-
transform: translate(-50%, -50%);
35-
z-index: 0;
36-
37-
width: 100%;
38-
max-width: 800px;
39-
height: 100%;
40-
max-height: 800px;
41-
42-
background-position: center;
43-
background-size: cover;
44-
background-repeat: no-repeat;
45-
}

Client/src/Components/MonitorStatusHeader/index.jsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import ConfigButton from "./ConfigButton";
88
import SkeletonLayout from "./skeleton";
99
import PropTypes from "prop-types";
1010

11-
const MonitorHeader = ({ shouldRender = true, isAdmin, monitor }) => {
11+
const MonitorStatusHeader = ({ shouldRender = true, isAdmin, monitor }) => {
1212
const theme = useTheme();
1313
const { statusColor, statusMsg, determineState } = useUtils();
1414
if (!shouldRender) {
@@ -21,7 +21,7 @@ const MonitorHeader = ({ shouldRender = true, isAdmin, monitor }) => {
2121
justifyContent="space-between"
2222
>
2323
<Stack>
24-
<Typography variant="h1">{monitor.name}</Typography>
24+
<Typography variant="h1">{monitor?.name}</Typography>
2525
<Stack
2626
direction="row"
2727
alignItems={"center"}
@@ -39,16 +39,16 @@ const MonitorHeader = ({ shouldRender = true, isAdmin, monitor }) => {
3939
</Stack>
4040
<ConfigButton
4141
shouldRender={isAdmin}
42-
monitorId={monitor._id}
42+
monitorId={monitor?._id}
4343
/>
4444
</Stack>
4545
);
4646
};
4747

48-
MonitorHeader.propTypes = {
48+
MonitorStatusHeader.propTypes = {
4949
shouldRender: PropTypes.bool,
5050
isAdmin: PropTypes.bool,
5151
monitor: PropTypes.object,
5252
};
5353

54-
export default MonitorHeader;
54+
export default MonitorStatusHeader;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
import { useTheme } from "@emotion/react";
2+
import { Box, Stack, Typography } from "@mui/material";
3+
import Skeleton from "../../assets/Images/create-placeholder.svg?react";
4+
import SkeletonDark from "../../assets/Images/create-placeholder-dark.svg?react";
5+
import Background from "../../assets/Images/background-grid.svg?react";
6+
import { useSelector } from "react-redux";
7+
8+
/**
9+
* Fallback component to display a fallback UI for network errors
10+
*
11+
* @returns {JSX.Element} The rendered fallback UI.
12+
*/
13+
14+
const NetworkErrorFallback = () => {
15+
const theme = useTheme();
16+
const mode = useSelector((state) => state.ui.mode);
17+
18+
return (
19+
<Box
20+
className="page-speed"
21+
position="relative"
22+
border={1}
23+
borderColor={theme.palette.primary.lowContrast}
24+
borderRadius={theme.shape.borderRadius}
25+
backgroundColor={theme.palette.primary.main}
26+
overflow="hidden"
27+
sx={{
28+
borderStyle: "dashed",
29+
}}
30+
>
31+
<Stack
32+
alignItems="center"
33+
gap={theme.spacing(20)}
34+
sx={{
35+
width: "fit-content",
36+
margin: "auto",
37+
marginTop: "100px",
38+
}}
39+
>
40+
{mode === "light" ? (
41+
<Skeleton style={{ zIndex: 1 }} />
42+
) : (
43+
<SkeletonDark style={{ zIndex: 1 }} />
44+
)}
45+
<Box
46+
sx={{
47+
"& svg g g:last-of-type path": {
48+
stroke: theme.palette.primary.lowContrast,
49+
},
50+
position: "absolute",
51+
top: "0",
52+
left: "50%",
53+
transform: "translate(-50%, -50%)",
54+
width: "100%",
55+
maxWidth: "800px",
56+
height: "100%",
57+
maxHeight: "800px",
58+
backgroundPosition: "center",
59+
backgroundSize: "cover",
60+
backgroundRepeat: "no-repeat",
61+
}}
62+
>
63+
<Background style={{ width: "100%" }} />
64+
</Box>
65+
<Stack
66+
gap={theme.spacing(4)}
67+
alignItems="center"
68+
maxWidth={"300px"}
69+
zIndex={1}
70+
>
71+
<Typography
72+
variant="h1"
73+
marginY={theme.spacing(4)}
74+
color={theme.palette.primary.contrastTextTertiary}
75+
>
76+
Network error
77+
</Typography>
78+
<Typography>Please check your connection</Typography>
79+
</Stack>
80+
</Stack>
81+
</Box>
82+
);
83+
};
84+
85+
export default NetworkErrorFallback;

Client/src/Components/Table/TablePagination/index.jsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import SelectorVertical from "../../../assets/icons/selector-vertical.svg?react"
66

77
Pagination.propTypes = {
88
paginationLabel: PropTypes.string, // Label for the pagination.
9-
itemCount: PropTypes.number.isRequired, // Total number of items for pagination.
10-
page: PropTypes.number.isRequired, // Current page index.
9+
itemCount: PropTypes.number, // Total number of items for pagination.
10+
page: PropTypes.number, // Current page index.
1111
rowsPerPage: PropTypes.number.isRequired, // Number of rows displayed per page.
1212
handleChangePage: PropTypes.func.isRequired, // Function to handle page changes.
1313
handleChangeRowsPerPage: PropTypes.func, // Function to handle changes in rows per page.
@@ -29,9 +29,9 @@ const ROWS_PER_PAGE_OPTIONS = [5, 10, 15, 25];
2929
*/
3030
function Pagination({
3131
paginationLabel,
32-
itemCount,
33-
page,
34-
rowsPerPage,
32+
itemCount = 0,
33+
page = 0,
34+
rowsPerPage = 5,
3535
handleChangePage,
3636
handleChangeRowsPerPage,
3737
}) {

Client/src/Components/Table/index.jsx

+10-3
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,14 @@ import { useTheme } from "@emotion/react";
3232
* @returns {JSX.Element} The rendered table component.
3333
*/
3434

35-
const DataTable = ({ headers, data, config = { emptyView: "No data" } }) => {
35+
const DataTable = ({
36+
headers = [],
37+
data = [],
38+
config = {
39+
emptyView: "No data",
40+
onRowClick: () => {},
41+
},
42+
}) => {
3643
const theme = useTheme();
3744
if ((headers?.length ?? 0) === 0) {
3845
return "No data";
@@ -117,9 +124,9 @@ DataTable.propTypes = {
117124
render: PropTypes.func.isRequired,
118125
})
119126
).isRequired,
120-
data: PropTypes.array.isRequired,
127+
data: PropTypes.array,
121128
config: PropTypes.shape({
122-
onRowClick: PropTypes.func.isRequired,
129+
onRowClick: PropTypes.func,
123130
rowSX: PropTypes.object,
124131
emptyView: PropTypes.node,
125132
}),

Client/src/Pages/PageSpeed/Details/Components/Charts/PieChart.jsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,6 @@ const PieChart = ({ audits }) => {
118118
const [highlightedItem, setHighLightedItem] = useState(null);
119119
const [expand, setExpand] = useState(false);
120120

121-
if (typeof audits === "undefined") return null;
122-
123121
/**
124122
* Retrieves color properties based on the performance value.
125123
*
@@ -166,6 +164,8 @@ const PieChart = ({ audits }) => {
166164
*/
167165
let performance = 0;
168166
const getPieData = (audits) => {
167+
if (typeof audits === "undefined") return undefined;
168+
169169
let data = [];
170170
let startAngle = 0;
171171
const padding = 3; // padding between arcs

Client/src/Pages/PageSpeed/Details/Components/Charts/PieChartLegend.jsx

+65-65
Original file line numberDiff line numberDiff line change
@@ -7,84 +7,84 @@ import PropTypes from "prop-types";
77
const PieChartLegend = ({ audits }) => {
88
const theme = useTheme();
99

10-
if (typeof audits === "undefined") return null;
1110
return (
1211
<LegendBox
1312
icon={<SpeedometerIcon />}
1413
header="Performance metrics"
1514
sx={{ flex: 1 }}
1615
>
17-
{Object.keys(audits).map((key) => {
18-
if (key === "_id") return;
16+
{typeof audits !== "undefined" &&
17+
Object.keys(audits).map((key) => {
18+
if (key === "_id") return;
1919

20-
let audit = audits[key];
21-
let score = audit.score * 100;
22-
let bg =
23-
score >= 90
24-
? theme.palette.success.main
25-
: score >= 50
26-
? theme.palette.warning.main
27-
: score >= 0
28-
? theme.palette.error.main
29-
: theme.palette.tertiary.main;
20+
let audit = audits[key];
21+
let score = audit.score * 100;
22+
let bg =
23+
score >= 90
24+
? theme.palette.success.main
25+
: score >= 50
26+
? theme.palette.warning.main
27+
: score >= 0
28+
? theme.palette.error.main
29+
: theme.palette.tertiary.main;
3030

31-
// Find the position where the number ends and the unit begins
32-
const match = audit.displayValue.match(/(\d+\.?\d*)\s*([a-zA-Z]+)/);
33-
let value;
34-
let unit;
35-
if (match) {
36-
value = match[1];
37-
match[2] === "s" ? (unit = "seconds") : (unit = match[2]);
38-
} else {
39-
value = audit.displayValue;
40-
}
31+
// Find the position where the number ends and the unit begins
32+
const match = audit.displayValue.match(/(\d+\.?\d*)\s*([a-zA-Z]+)/);
33+
let value;
34+
let unit;
35+
if (match) {
36+
value = match[1];
37+
match[2] === "s" ? (unit = "seconds") : (unit = match[2]);
38+
} else {
39+
value = audit.displayValue;
40+
}
4141

42-
return (
43-
<Stack
44-
flex={1}
45-
key={`${key}-box`}
46-
justifyContent="space-between"
47-
direction="row"
48-
gap={theme.spacing(4)}
49-
p={theme.spacing(3)}
50-
border={1}
51-
borderColor={theme.palette.primary.lowContrast}
52-
borderRadius={4}
53-
>
54-
<Box>
55-
<Typography
56-
fontSize={12}
57-
fontWeight={500}
58-
lineHeight={1}
59-
mb={1}
60-
textTransform="uppercase"
61-
>
62-
{audit.title}
63-
</Typography>
64-
<Typography
65-
component="span"
66-
fontSize={14}
67-
fontWeight={500}
68-
color={theme.palette.primary.contrastText}
69-
>
70-
{value}
42+
return (
43+
<Stack
44+
flex={1}
45+
key={`${key}-box`}
46+
justifyContent="space-between"
47+
direction="row"
48+
gap={theme.spacing(4)}
49+
p={theme.spacing(3)}
50+
border={1}
51+
borderColor={theme.palette.primary.lowContrast}
52+
borderRadius={4}
53+
>
54+
<Box>
55+
<Typography
56+
fontSize={12}
57+
fontWeight={500}
58+
lineHeight={1}
59+
mb={1}
60+
textTransform="uppercase"
61+
>
62+
{audit.title}
63+
</Typography>
7164
<Typography
7265
component="span"
73-
variant="body2"
74-
ml={2}
66+
fontSize={14}
67+
fontWeight={500}
68+
color={theme.palette.primary.contrastText}
7569
>
76-
{unit}
70+
{value}
71+
<Typography
72+
component="span"
73+
variant="body2"
74+
ml={2}
75+
>
76+
{unit}
77+
</Typography>
7778
</Typography>
78-
</Typography>
79-
</Box>
80-
<Box
81-
width={4}
82-
backgroundColor={bg}
83-
borderRadius={4}
84-
/>
85-
</Stack>
86-
);
87-
})}
79+
</Box>
80+
<Box
81+
width={4}
82+
backgroundColor={bg}
83+
borderRadius={4}
84+
/>
85+
</Stack>
86+
);
87+
})}
8888
</LegendBox>
8989
);
9090
};

Client/src/Pages/PageSpeed/Details/Components/PageSpeedAreaChart/index.jsx

-4
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ const PageSpeedAreaChart = ({ shouldRender, monitor, metrics, handleMetrics }) =
1515
return <SkeletonLayout />;
1616
}
1717

18-
if (typeof monitor === "undefined") {
19-
return null;
20-
}
21-
2218
const data = monitor?.checks ? [...monitor.checks].reverse() : [];
2319

2420
return (

0 commit comments

Comments
 (0)