mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-21 22:59:07 +00:00
add active alerts to home page
This commit is contained in:
parent
6acb0fb486
commit
4be7675b74
@ -10,6 +10,7 @@ import UserProfilePicture from "./Pages/Global/UserProfile/Picture";
|
||||
// Pages
|
||||
import Home from "./Pages/Home/Home";
|
||||
import NotOperationalMonitors from "./Pages/Home/NotOperationalMonitors";
|
||||
import HomeActiveAlerts from "./Pages/Home/ActiveAlerts";
|
||||
import OngoingScheduledEvents from "./Pages/Home/OngoingScheduledMaintenance";
|
||||
import Logout from "./Pages/Logout/Logout";
|
||||
import Sso from "./Pages/Onboarding/SSO";
|
||||
@ -265,6 +266,16 @@ const App: () => JSX.Element = () => {
|
||||
}
|
||||
/>
|
||||
|
||||
<PageRoute
|
||||
path={RouteMap[PageMap.HOME_ACTIVE_ALERTS]?.toString() || ""}
|
||||
element={
|
||||
<HomeActiveAlerts
|
||||
{...commonPageProps}
|
||||
pageRoute={RouteMap[PageMap.HOME_ACTIVE_ALERTS] as Route}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
|
||||
<PageRoute
|
||||
path={
|
||||
RouteMap[
|
||||
|
96
Dashboard/src/Pages/Home/ActiveAlerts.tsx
Normal file
96
Dashboard/src/Pages/Home/ActiveAlerts.tsx
Normal file
@ -0,0 +1,96 @@
|
||||
import AlertsTable from "../../Components/Alert/AlertsTable";
|
||||
import AlertStateUtil from "../../Utils/AlertState";
|
||||
import DashboardNavigation from "../../Utils/Navigation";
|
||||
import PageMap from "../../Utils/PageMap";
|
||||
import RouteMap, { RouteUtil } from "../../Utils/RouteMap";
|
||||
import PageComponentProps from "../PageComponentProps";
|
||||
import DashboardSideMenu from "./SideMenu";
|
||||
import Route from "Common/Types/API/Route";
|
||||
import Includes from "Common/Types/BaseDatabase/Includes";
|
||||
import { PromiseVoidFunction } from "Common/Types/FunctionTypes";
|
||||
import ErrorMessage from "Common/UI/Components/ErrorMessage/ErrorMessage";
|
||||
import PageLoader from "Common/UI/Components/Loader/PageLoader";
|
||||
import Page from "Common/UI/Components/Page/Page";
|
||||
import API from "Common/UI/Utils/API/API";
|
||||
import AlertState from "Common/Models/DatabaseModels/AlertState";
|
||||
import React, {
|
||||
FunctionComponent,
|
||||
ReactElement,
|
||||
useEffect,
|
||||
useState,
|
||||
} from "react";
|
||||
|
||||
const Home: FunctionComponent<PageComponentProps> = (
|
||||
props: PageComponentProps,
|
||||
): ReactElement => {
|
||||
const [unresolvedAlertStates, setUnresolvedAlertStates] = useState<
|
||||
Array<AlertState>
|
||||
>([]);
|
||||
const [error, setError] = useState<string>("");
|
||||
const [isLoading, setIsLoading] = useState<boolean>(false);
|
||||
|
||||
const fetchAlertStates: PromiseVoidFunction = async (): Promise<void> => {
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
setUnresolvedAlertStates(
|
||||
await AlertStateUtil.getUnresolvedAlertStates(
|
||||
DashboardNavigation.getProjectId()!,
|
||||
),
|
||||
);
|
||||
setError("");
|
||||
} catch (err) {
|
||||
setError(API.getFriendlyMessage(err));
|
||||
}
|
||||
|
||||
setIsLoading(false);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchAlertStates().catch((err: Error) => {
|
||||
setError(API.getFriendlyMessage(err));
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Page
|
||||
title={"Home"}
|
||||
breadcrumbLinks={[
|
||||
{
|
||||
title: "Project",
|
||||
to: RouteUtil.populateRouteParams(RouteMap[PageMap.HOME] as Route),
|
||||
},
|
||||
{
|
||||
title: "Home",
|
||||
to: RouteUtil.populateRouteParams(RouteMap[PageMap.HOME] as Route),
|
||||
},
|
||||
]}
|
||||
sideMenu={
|
||||
<DashboardSideMenu project={props.currentProject || undefined} />
|
||||
}
|
||||
>
|
||||
<div>
|
||||
{isLoading && <PageLoader isVisible={true} />}
|
||||
{error && <ErrorMessage error={error} />}
|
||||
|
||||
{!isLoading && !error && unresolvedAlertStates.length > 0 && (
|
||||
<AlertsTable
|
||||
query={{
|
||||
projectId: DashboardNavigation.getProjectId()!,
|
||||
currentAlertStateId: new Includes(
|
||||
unresolvedAlertStates.map((state: AlertState) => {
|
||||
return state.id!;
|
||||
}),
|
||||
),
|
||||
}}
|
||||
noItemsMessage="Nice work! No Active Alerts so far."
|
||||
title="Active Alerts"
|
||||
description="Here is a list of all the Active Alerts for this project."
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</Page>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
@ -20,6 +20,9 @@ import React, {
|
||||
useEffect,
|
||||
useState,
|
||||
} from "react";
|
||||
import AlertState from "Common/Models/DatabaseModels/AlertState";
|
||||
import Alert from "Common/Models/DatabaseModels/Alert";
|
||||
import AlertStateUtil from "../../Utils/AlertState";
|
||||
|
||||
export interface ComponentProps {
|
||||
project?: Project | undefined;
|
||||
@ -32,6 +35,10 @@ const DashboardSideMenu: FunctionComponent<ComponentProps> = (
|
||||
Array<IncidentState>
|
||||
>([]);
|
||||
|
||||
const [unresolvedAlertStates, setUnresolvedAlertStates] = useState<
|
||||
Array<AlertState>
|
||||
>([]);
|
||||
|
||||
const fetchIncidentStates: PromiseVoidFunction = async (): Promise<void> => {
|
||||
try {
|
||||
if (props.project?.id) {
|
||||
@ -46,10 +53,26 @@ const DashboardSideMenu: FunctionComponent<ComponentProps> = (
|
||||
}
|
||||
};
|
||||
|
||||
const fetchAlertStates: PromiseVoidFunction = async (): Promise<void> => {
|
||||
try {
|
||||
if (props.project?.id) {
|
||||
const unresolvedAlertStates: Array<AlertState> =
|
||||
await AlertStateUtil.getUnresolvedAlertStates(props.project?.id);
|
||||
setUnresolvedAlertStates(unresolvedAlertStates);
|
||||
}
|
||||
} catch (err) {
|
||||
// maybe show an error message
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
fetchIncidentStates().catch((_err: Error) => {
|
||||
// do nothing
|
||||
});
|
||||
|
||||
fetchAlertStates().catch((_err: Error) => {
|
||||
// do nothing
|
||||
});
|
||||
}, []);
|
||||
|
||||
return (
|
||||
@ -74,6 +97,28 @@ const DashboardSideMenu: FunctionComponent<ComponentProps> = (
|
||||
/>
|
||||
</SideMenuSection>
|
||||
|
||||
<SideMenuSection title="Alerts">
|
||||
<SideMenuItem<Alert>
|
||||
link={{
|
||||
title: "Active",
|
||||
to: RouteUtil.populateRouteParams(
|
||||
RouteMap[PageMap.HOME_ACTIVE_ALERTS] as Route,
|
||||
),
|
||||
}}
|
||||
icon={IconProp.ExclaimationCircle}
|
||||
badgeType={BadgeType.DANGER}
|
||||
modelType={Alert}
|
||||
countQuery={{
|
||||
projectId: props.project?._id,
|
||||
currentAlertStateId: new Includes(
|
||||
unresolvedAlertStates.map((state: AlertState) => {
|
||||
return state.id!;
|
||||
}),
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</SideMenuSection>
|
||||
|
||||
<SideMenuSection title="Monitors">
|
||||
<SideMenuItem<Monitor>
|
||||
link={{
|
||||
|
41
Dashboard/src/Utils/AlertState.ts
Normal file
41
Dashboard/src/Utils/AlertState.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import SortOrder from "Common/Types/BaseDatabase/SortOrder";
|
||||
import { LIMIT_PER_PROJECT } from "Common/Types/Database/LimitMax";
|
||||
import ObjectID from "Common/Types/ObjectID";
|
||||
import ListResult from "Common/UI/Utils/BaseDatabase/ListResult";
|
||||
import ModelAPI from "Common/UI/Utils/ModelAPI/ModelAPI";
|
||||
import AlertState from "Common/Models/DatabaseModels/AlertState";
|
||||
|
||||
export default class AlertStateUtil {
|
||||
public static async getUnresolvedAlertStates(
|
||||
projectId: ObjectID,
|
||||
): Promise<AlertState[]> {
|
||||
const alertStates: ListResult<AlertState> =
|
||||
await ModelAPI.getList<AlertState>({
|
||||
modelType: AlertState,
|
||||
query: {
|
||||
projectId: projectId,
|
||||
},
|
||||
skip: 0,
|
||||
limit: LIMIT_PER_PROJECT,
|
||||
sort: {
|
||||
order: SortOrder.Ascending,
|
||||
},
|
||||
select: {
|
||||
_id: true,
|
||||
isResolvedState: true,
|
||||
},
|
||||
});
|
||||
|
||||
const unresolvedAlertStates: Array<AlertState> = [];
|
||||
|
||||
for (const state of alertStates.data) {
|
||||
if (!state.isResolvedState) {
|
||||
unresolvedAlertStates.push(state);
|
||||
} else {
|
||||
break; // everything after resolved state is resolved
|
||||
}
|
||||
}
|
||||
|
||||
return unresolvedAlertStates;
|
||||
}
|
||||
}
|
@ -74,6 +74,7 @@ enum PageMap {
|
||||
HOME = "HOME",
|
||||
HOME_NOT_OPERATIONAL_MONITORS = "HOME_NOT_OPERATIONAL_MONITORS",
|
||||
HOME_ONGOING_SCHEDULED_MAINTENANCE_EVENTS = "HOME_ONGOING_SCHEDULED_MAINTENANCE_EVENTS",
|
||||
HOME_ACTIVE_ALERTS = "HOME_ACTIVE_ALERTS",
|
||||
|
||||
INCIDENTS_ROOT = "INCIDENTS_ROOT",
|
||||
INCIDENTS = "INCIDENTS",
|
||||
|
@ -267,6 +267,10 @@ const RouteMap: Dictionary<Route> = {
|
||||
`/dashboard/${RouteParams.ProjectID}/home/monitors-inoperational`,
|
||||
),
|
||||
|
||||
[PageMap.HOME_ACTIVE_ALERTS]: new Route(
|
||||
`/dashboard/${RouteParams.ProjectID}/home/active-alerts`,
|
||||
),
|
||||
|
||||
[PageMap.HOME_ONGOING_SCHEDULED_MAINTENANCE_EVENTS]: new Route(
|
||||
`/dashboard/${RouteParams.ProjectID}/home/scheduled-maintenance-ongoing`,
|
||||
),
|
||||
|
Loading…
Reference in New Issue
Block a user