feat create pagestate wrapper
This commit is contained in:
1 parent
2f6a0913dc
commit
8e13855b66
7 files changed
+139
-177
No files matched your search
@@ -0,0 +1,66 @@
|
||||
import GenericFallback from "../GenericFallback";
|
||||
import Fallback from "../Fallback";
|
||||
import { Typography } from "@mui/material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useIsAdmin } from "../../Hooks/useIsAdmin";
|
||||
import PropTypes from "prop-types";
|
||||
const PageStateWrapper = ({
|
||||
networkError,
|
||||
isLoading,
|
||||
items,
|
||||
type,
|
||||
fallbackLink,
|
||||
fallbackChildren,
|
||||
children,
|
||||
}) => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const isAdmin = useIsAdmin();
|
||||
const hasInitialized = !isLoading && items !== undefined;
|
||||
const showEmpty = items == undefined || items.length === 0;
|
||||
|
||||
if (networkError) {
|
||||
return (
|
||||
<GenericFallback>
|
||||
<Typography
|
||||
variant="h1"
|
||||
marginY={theme.spacing(4)}
|
||||
color={theme.palette.primary.contrastTextTertiary}
|
||||
>
|
||||
{t("common.toasts.networkError")}
|
||||
</Typography>
|
||||
<Typography>{t("common.toasts.checkConnection")}</Typography>
|
||||
</GenericFallback>
|
||||
);
|
||||
}
|
||||
if (!hasInitialized) {
|
||||
return null;
|
||||
}
|
||||
if (showEmpty) {
|
||||
return (
|
||||
<Fallback
|
||||
type={type}
|
||||
title={t(`${type}.fallback.title`)}
|
||||
checks={t(`${type}.fallback.checks`, { returnObjects: true })}
|
||||
link={fallbackLink}
|
||||
isAdmin={isAdmin}
|
||||
>
|
||||
{fallbackChildren}
|
||||
</Fallback>
|
||||
);
|
||||
}
|
||||
return <>{children}</>;
|
||||
};
|
||||
|
||||
PageStateWrapper.propTypes = {
|
||||
networkError: PropTypes.any,
|
||||
isLoading: PropTypes.bool,
|
||||
items: PropTypes.oneOfType([PropTypes.array, PropTypes.oneOf([null])]),
|
||||
type: PropTypes.string,
|
||||
fallbackLink: PropTypes.string,
|
||||
fallbackChildren: PropTypes.node,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
export default PageStateWrapper;
|
||||
@@ -1,12 +1,11 @@
|
||||
// Components
|
||||
import { Stack, Typography } from "@mui/material";
|
||||
import { Stack } from "@mui/material";
|
||||
import Breadcrumbs from "../../../Components/Breadcrumbs";
|
||||
import MonitorCountHeader from "../../../Components/MonitorCountHeader";
|
||||
import MonitorCreateHeader from "../../../Components/MonitorCreateHeader";
|
||||
import MonitorsTable from "./Components/MonitorsTable";
|
||||
import Pagination from "../../..//Components/Table/TablePagination";
|
||||
import GenericFallback from "../../../Components/GenericFallback";
|
||||
import Fallback from "../../../Components/Fallback";
|
||||
import PageStateWrapper from "../../../Components/PageStateWrapper";
|
||||
import Filter from "./Components/Filters";
|
||||
import SearchComponent from "../../Uptime/Monitors/Components/SearchComponent";
|
||||
// Utils
|
||||
@@ -81,34 +80,15 @@ const InfrastructureMonitors = () => {
|
||||
updateTrigger,
|
||||
});
|
||||
|
||||
if (networkError === true) {
|
||||
return (
|
||||
<GenericFallback>
|
||||
<Typography
|
||||
variant="h1"
|
||||
marginY={theme.spacing(4)}
|
||||
color={theme.palette.primary.contrastTextTertiary}
|
||||
>
|
||||
{t("common.toasts.networkError")}
|
||||
</Typography>
|
||||
<Typography>{t("common.toasts.checkConnection")}</Typography>
|
||||
</GenericFallback>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isLoading && typeof summary?.totalMonitors === "undefined") {
|
||||
return (
|
||||
<Fallback
|
||||
<>
|
||||
<PageStateWrapper
|
||||
networkError={networkError}
|
||||
isLoading={isLoading}
|
||||
items={monitors}
|
||||
type="infrastructureMonitor"
|
||||
title={t("infrastructureMonitor.fallback.title")}
|
||||
checks={t("infrastructureMonitor.fallback.checks", { returnObjects: true })}
|
||||
link="/infrastructure/create"
|
||||
isAdmin={isAdmin}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
fallbackLink="/infrastructure/create"
|
||||
>
|
||||
<Stack gap={theme.spacing(10)}>
|
||||
<Breadcrumbs list={BREADCRUMBS} />
|
||||
<MonitorCreateHeader
|
||||
@@ -150,6 +130,8 @@ const InfrastructureMonitors = () => {
|
||||
handleChangeRowsPerPage={handleChangeRowsPerPage}
|
||||
/>
|
||||
</Stack>
|
||||
</PageStateWrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Stack, Button } from "@mui/material";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import Fallback from "../../Components/Fallback";
|
||||
import { useState, useEffect } from "react";
|
||||
import "./index.css";
|
||||
import MaintenanceTable from "./MaintenanceTable";
|
||||
@@ -8,24 +7,21 @@ import { useSelector } from "react-redux";
|
||||
import { networkService } from "../../main";
|
||||
import Breadcrumbs from "../../Components/Breadcrumbs";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useIsAdmin } from "../../Hooks/useIsAdmin";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Typography } from "@mui/material";
|
||||
import GenericFallback from "../../Components/GenericFallback";
|
||||
import PageStateWrapper from "../../Components/PageStateWrapper";
|
||||
|
||||
const Maintenance = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
const rowsPerPage = useSelector((state) => state?.ui?.maintenance?.rowsPerPage ?? 5);
|
||||
const isAdmin = useIsAdmin();
|
||||
const [maintenanceWindows, setMaintenanceWindows] = useState([]);
|
||||
const [maintenanceWindowCount, setMaintenanceWindowCount] = useState(0);
|
||||
const [page, setPage] = useState(0);
|
||||
const [sort, setSort] = useState({});
|
||||
const [updateTrigger, setUpdateTrigger] = useState(false);
|
||||
const [networkError, setNetworkError] = useState(false);
|
||||
const [isDataFetched, setIsDataFetched] = useState(false);
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const handleActionMenuDelete = () => {
|
||||
setUpdateTrigger((prev) => !prev);
|
||||
@@ -34,6 +30,7 @@ const Maintenance = () => {
|
||||
useEffect(() => {
|
||||
const fetchMaintenanceWindows = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const response = await networkService.getMaintenanceWindowsByTeamId({
|
||||
page: page,
|
||||
rowsPerPage: rowsPerPage,
|
||||
@@ -44,40 +41,21 @@ const Maintenance = () => {
|
||||
} catch (error) {
|
||||
setNetworkError(true);
|
||||
} finally {
|
||||
setIsDataFetched(true);
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
fetchMaintenanceWindows();
|
||||
}, [page, rowsPerPage, updateTrigger]);
|
||||
|
||||
if (networkError) {
|
||||
return (
|
||||
<GenericFallback>
|
||||
<Typography
|
||||
variant="h1"
|
||||
marginY={theme.spacing(4)}
|
||||
color={theme.palette.primary.contrastTextTertiary}
|
||||
>
|
||||
{t("common.toasts.networkError")}
|
||||
</Typography>
|
||||
<Typography>{t("common.toasts.checkConnection")}</Typography>
|
||||
</GenericFallback>
|
||||
);
|
||||
}
|
||||
// Only show the fallback if we've fetched data and there are no maintenance windows
|
||||
if (isDataFetched && maintenanceWindows.length === 0) {
|
||||
return (
|
||||
<Fallback
|
||||
<>
|
||||
<PageStateWrapper
|
||||
networkError={networkError}
|
||||
isLoading={isLoading}
|
||||
items={maintenanceWindows}
|
||||
type="maintenanceWindow"
|
||||
title={t("maintenanceWindow.fallback.title")}
|
||||
checks={t("maintenanceWindow.fallback.checks", { returnObjects: true })}
|
||||
link="/maintenance/create"
|
||||
isAdmin={isAdmin}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
fallbackLink="/maintenance/create"
|
||||
>
|
||||
<Stack gap={theme.spacing(10)}>
|
||||
<Stack
|
||||
direction="row"
|
||||
@@ -108,6 +86,8 @@ const Maintenance = () => {
|
||||
updateCallback={handleActionMenuDelete}
|
||||
/>
|
||||
</Stack>
|
||||
</PageStateWrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -4,11 +4,10 @@ import Typography from "@mui/material/Typography";
|
||||
import Breadcrumbs from "../../Components/Breadcrumbs";
|
||||
import Button from "@mui/material/Button";
|
||||
import DataTable from "../../Components/Table";
|
||||
import Fallback from "../../Components/Fallback";
|
||||
import ActionMenu from "./components/ActionMenu";
|
||||
import PageStateWrapper from "../../Components/PageStateWrapper";
|
||||
|
||||
// Utils
|
||||
import { useIsAdmin } from "../../Hooks/useIsAdmin";
|
||||
import { useState } from "react";
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
@@ -23,7 +22,6 @@ const Notifications = () => {
|
||||
const theme = useTheme();
|
||||
const BREADCRUMBS = [{ name: "notifications", path: "/notifications" }];
|
||||
const [updateTrigger, setUpdateTrigger] = useState(false);
|
||||
const isAdmin = useIsAdmin();
|
||||
const [notifications, isLoading, error] = useGetNotificationsByTeamId(updateTrigger);
|
||||
const [deleteNotification, isDeleting, deleteError] = useDeleteNotification();
|
||||
const { t } = useTranslation();
|
||||
@@ -76,19 +74,15 @@ const Notifications = () => {
|
||||
},
|
||||
];
|
||||
|
||||
if (notifications?.length === 0) {
|
||||
return (
|
||||
<Fallback
|
||||
<>
|
||||
<PageStateWrapper
|
||||
networkError={error}
|
||||
isLoading={isLoading}
|
||||
items={notifications}
|
||||
type="notifications"
|
||||
title={t("notifications.fallback.title")}
|
||||
checks={t("notifications.fallback.checks", { returnObjects: true })}
|
||||
link="/notifications/create"
|
||||
isAdmin={isAdmin}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
fallbackLink="/notifications/create"
|
||||
>
|
||||
<Stack gap={theme.spacing(10)}>
|
||||
<Breadcrumbs list={BREADCRUMBS} />
|
||||
<Stack
|
||||
@@ -119,6 +113,8 @@ const Notifications = () => {
|
||||
data={notifications}
|
||||
/>
|
||||
</Stack>
|
||||
</PageStateWrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,18 +1,16 @@
|
||||
// Components
|
||||
import { useState } from "react";
|
||||
import Breadcrumbs from "../../../Components/Breadcrumbs";
|
||||
import { Stack, Typography } from "@mui/material";
|
||||
import { Stack } from "@mui/material";
|
||||
import CreateMonitorHeader from "../../../Components/MonitorCreateHeader";
|
||||
import MonitorCountHeader from "../../../Components/MonitorCountHeader";
|
||||
import MonitorGrid from "./Components/MonitorGrid";
|
||||
import Fallback from "../../../Components/Fallback";
|
||||
import GenericFallback from "../../../Components/GenericFallback";
|
||||
import PageStateWrapper from "../../../Components/PageStateWrapper";
|
||||
import FallbackPageSpeedWarning from "../../../Components/Fallback/FallbackPageSpeedWarning";
|
||||
|
||||
// Utils
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useFetchMonitorsByTeamId } from "../../../Hooks/monitorHooks";
|
||||
import { useFetchSettings } from "../../../Hooks/settingsHooks";
|
||||
// Constants
|
||||
@@ -20,7 +18,6 @@ const BREADCRUMBS = [{ name: `pagespeed`, path: "/pagespeed" }];
|
||||
const TYPES = ["pagespeed"];
|
||||
const PageSpeed = () => {
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const isAdmin = useIsAdmin();
|
||||
|
||||
const [monitors, monitorsSummary, isLoading, networkError] = useFetchMonitorsByTeamId({
|
||||
@@ -40,38 +37,22 @@ const PageSpeed = () => {
|
||||
setIsEmailPasswordSet: () => {},
|
||||
});
|
||||
|
||||
if (networkError === true) {
|
||||
return (
|
||||
<GenericFallback>
|
||||
<Typography
|
||||
variant="h1"
|
||||
marginY={theme.spacing(4)}
|
||||
color={theme.palette.primary.contrastTextTertiary}
|
||||
>
|
||||
{t("common.toasts.networkError")}
|
||||
</Typography>
|
||||
<Typography>{t("common.toasts.checkConnection")}</Typography>
|
||||
</GenericFallback>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isLoading && monitors?.length === 0) {
|
||||
return (
|
||||
<Fallback
|
||||
<>
|
||||
<PageStateWrapper
|
||||
networkError={networkError}
|
||||
isLoading={isLoading}
|
||||
items={monitors}
|
||||
type="pageSpeed"
|
||||
title={t("pageSpeed.fallback.title")}
|
||||
checks={t("pageSpeed.fallback.checks", { returnObjects: true })}
|
||||
link="/pagespeed/create"
|
||||
isAdmin={isAdmin}
|
||||
>
|
||||
{isAdmin && settingsData && !settingsData.pagespeedApiKey && (
|
||||
fallbackLink="/pagespeed/create"
|
||||
fallbackChildren={
|
||||
isAdmin &&
|
||||
settingsData &&
|
||||
!settingsData.pagespeedApiKey && (
|
||||
<FallbackPageSpeedWarning settingsData={settingsData} />
|
||||
)}
|
||||
</Fallback>
|
||||
);
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
>
|
||||
<Stack gap={theme.spacing(10)}>
|
||||
<Breadcrumbs list={BREADCRUMBS} />
|
||||
<CreateMonitorHeader
|
||||
@@ -90,6 +71,8 @@ const PageSpeed = () => {
|
||||
monitors={monitors}
|
||||
/>
|
||||
</Stack>
|
||||
</PageStateWrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,14 +1,11 @@
|
||||
// Components
|
||||
import { Stack, Typography } from "@mui/material";
|
||||
import { Stack } from "@mui/material";
|
||||
import Breadcrumbs from "../../../Components/Breadcrumbs";
|
||||
import Fallback from "../../../Components/Fallback";
|
||||
import MonitorCreateHeader from "../../../Components/MonitorCreateHeader";
|
||||
import GenericFallback from "../../../Components/GenericFallback";
|
||||
import StatusPagesTable from "./Components/StatusPagesTable";
|
||||
import SkeletonLayout from "../../../Components/Skeletons/FullPage";
|
||||
import PageStateWrapper from "../../../Components/PageStateWrapper";
|
||||
// Utils
|
||||
import { useTheme } from "@emotion/react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { useStatusPagesFetch } from "./Hooks/useStatusPagesFetch";
|
||||
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
|
||||
const BREADCRUMBS = [{ name: `Status Pages`, path: "" }];
|
||||
@@ -16,42 +13,18 @@ const BREADCRUMBS = [{ name: `Status Pages`, path: "" }];
|
||||
const StatusPages = () => {
|
||||
// Utils
|
||||
const theme = useTheme();
|
||||
const { t } = useTranslation();
|
||||
const isAdmin = useIsAdmin();
|
||||
const [isLoading, networkError, statusPages] = useStatusPagesFetch();
|
||||
|
||||
if (isLoading) {
|
||||
return <SkeletonLayout />;
|
||||
}
|
||||
|
||||
if (networkError === true) {
|
||||
return (
|
||||
<GenericFallback>
|
||||
<Typography
|
||||
variant="h1"
|
||||
marginY={theme.spacing(4)}
|
||||
color={theme.palette.primary.contrastTextTertiary}
|
||||
>
|
||||
{t("common.toasts.networkError")}
|
||||
</Typography>
|
||||
<Typography>{t("common.toasts.checkConnection")}</Typography>
|
||||
</GenericFallback>
|
||||
);
|
||||
}
|
||||
|
||||
if (!isLoading && typeof statusPages !== "undefined" && statusPages.length === 0) {
|
||||
return (
|
||||
<Fallback
|
||||
title={t("statusPage.fallback.title")}
|
||||
checks={t("statusPage.fallback.checks", { returnObjects: true })}
|
||||
<>
|
||||
<PageStateWrapper
|
||||
networkError={networkError}
|
||||
isLoading={isLoading}
|
||||
items={statusPages}
|
||||
type="statusPage"
|
||||
link="/status/uptime/create"
|
||||
isAdmin={isAdmin}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
fallbackLink="/status/uptime/create"
|
||||
>
|
||||
<Stack gap={theme.spacing(10)}>
|
||||
<Breadcrumbs list={BREADCRUMBS} />
|
||||
<MonitorCreateHeader
|
||||
@@ -62,6 +35,8 @@ const StatusPages = () => {
|
||||
/>
|
||||
<StatusPagesTable data={statusPages} />
|
||||
</Stack>
|
||||
</PageStateWrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -10,16 +10,14 @@ import StatusBoxes from "./Components/StatusBoxes";
|
||||
import UptimeDataTable from "./Components/UptimeDataTable";
|
||||
import Pagination from "../../../Components/Table/TablePagination";
|
||||
import CreateMonitorHeader from "../../../Components/MonitorCreateHeader";
|
||||
import Fallback from "../../../Components/Fallback";
|
||||
import GenericFallback from "../../../Components/GenericFallback";
|
||||
import SearchComponent from "./Components/SearchComponent";
|
||||
import Filter from "./Components/Filter";
|
||||
import PageStateWrapper from "../../../Components/PageStateWrapper";
|
||||
|
||||
import MonitorCountHeader from "../../../Components/MonitorCountHeader";
|
||||
|
||||
// MUI Components
|
||||
import { Stack, Box, Button, Typography } from "@mui/material";
|
||||
|
||||
import { Stack, Box, Button } from "@mui/material";
|
||||
// Utils
|
||||
import { useState, useCallback, useEffect } from "react";
|
||||
import { useIsAdmin } from "../../../Hooks/useIsAdmin";
|
||||
@@ -153,36 +151,16 @@ const UptimeMonitors = () => {
|
||||
}, [isSearching]);
|
||||
|
||||
const isLoading = monitorsWithSummaryIsLoading || monitorsWithChecksIsLoading;
|
||||
if (networkError) {
|
||||
|
||||
return (
|
||||
<GenericFallback>
|
||||
<Typography
|
||||
variant="h1"
|
||||
marginY={theme.spacing(4)}
|
||||
color={theme.palette.primary.contrastTextTertiary}
|
||||
>
|
||||
{t("common.toasts.networkError")}
|
||||
</Typography>
|
||||
<Typography>{t("common.toasts.checkConnection")}</Typography>
|
||||
</GenericFallback>
|
||||
);
|
||||
}
|
||||
if (
|
||||
!isLoading &&
|
||||
(monitorsSummary?.totalMonitors === 0 ||
|
||||
typeof monitorsSummary?.totalMonitors === "undefined")
|
||||
) {
|
||||
return (
|
||||
<Fallback
|
||||
<>
|
||||
<PageStateWrapper
|
||||
networkError={networkError}
|
||||
isLoading={isLoading}
|
||||
items={monitors}
|
||||
type="uptimeMonitor"
|
||||
title={t("uptimeMonitor.fallback.title")}
|
||||
checks={t("uptimeMonitor.fallback.checks", { returnObjects: true })}
|
||||
link="/uptime/create"
|
||||
isAdmin={isAdmin}
|
||||
/>
|
||||
);
|
||||
}
|
||||
return (
|
||||
fallbackLink="/uptime/create"
|
||||
>
|
||||
<Stack
|
||||
className="monitors"
|
||||
gap={theme.spacing(10)}
|
||||
@@ -240,6 +218,8 @@ const UptimeMonitors = () => {
|
||||
handleChangeRowsPerPage={handleChangeRowsPerPage}
|
||||
/>
|
||||
</Stack>
|
||||
</PageStateWrapper>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
Reference in new issue
Block a user