initial
This commit is contained in:
1 parent
b1b27be731
commit
cdbaad5bd9
7 files changed
+72
-42
No files matched your search
@@ -50,6 +50,7 @@ export const useFetchMonitorsWithChecks = ({
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
const [count, setCount] = useState(undefined);
|
||||
const [monitors, setMonitors] = useState(undefined);
|
||||
const [summary, setSummary] = useState(undefined);
|
||||
const [networkError, setNetworkError] = useState(false);
|
||||
|
||||
const theme = useTheme();
|
||||
@@ -68,10 +69,11 @@ export const useFetchMonitorsWithChecks = ({
|
||||
order,
|
||||
});
|
||||
|
||||
const { count, monitors } = res?.data?.data ?? {};
|
||||
const { count, monitors, summary } = res?.data?.data ?? {};
|
||||
const mappedMonitors = monitors.map((monitor) =>
|
||||
getMonitorWithPercentage(monitor, theme)
|
||||
);
|
||||
setSummary(summary);
|
||||
setMonitors(mappedMonitors);
|
||||
setCount(count || 0);
|
||||
} catch (error) {
|
||||
@@ -97,7 +99,7 @@ export const useFetchMonitorsWithChecks = ({
|
||||
types,
|
||||
monitorUpdateTrigger,
|
||||
]);
|
||||
return [monitors, count, isLoading, networkError];
|
||||
return [summary, monitors, count, isLoading, networkError];
|
||||
};
|
||||
|
||||
export const useFetchMonitorsByTeamId = ({ types, filter, updateTrigger }) => {
|
||||
|
||||
@@ -26,10 +26,7 @@ import { useNavigate } from "react-router-dom";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { setRowsPerPage } from "../../../Features/UI/uiSlice.js";
|
||||
import PropTypes from "prop-types";
|
||||
import {
|
||||
useFetchMonitorsWithSummary,
|
||||
useFetchMonitorsWithChecks,
|
||||
} from "@/Hooks/monitorHooks.js";
|
||||
import { useFetchMonitorsWithChecks } from "@/Hooks/monitorHooks.js";
|
||||
import { useTranslation } from "react-i18next";
|
||||
|
||||
const TYPES = ["http", "ping", "docker", "port", "game"];
|
||||
@@ -103,12 +100,6 @@ const UptimeMonitors = () => {
|
||||
setMonitorUpdateTrigger((prev) => !prev);
|
||||
}, []);
|
||||
|
||||
const [monitors, monitorsSummary, monitorsWithSummaryIsLoading, networkError] =
|
||||
useFetchMonitorsWithSummary({
|
||||
types: TYPES,
|
||||
monitorUpdateTrigger,
|
||||
});
|
||||
|
||||
const handleReset = () => {
|
||||
setSelectedState(undefined);
|
||||
setSelectedTypes(undefined);
|
||||
@@ -129,10 +120,11 @@ const UptimeMonitors = () => {
|
||||
const effectiveTypes = selectedTypes?.length ? selectedTypes : TYPES;
|
||||
|
||||
const [
|
||||
summary,
|
||||
monitorsWithChecks,
|
||||
monitorsWithChecksCount,
|
||||
monitorsWithChecksIsLoading,
|
||||
monitorsWithChecksNetworkError,
|
||||
networkError,
|
||||
] = useFetchMonitorsWithChecks({
|
||||
types: effectiveTypes,
|
||||
limit: 25,
|
||||
@@ -150,14 +142,14 @@ const UptimeMonitors = () => {
|
||||
}
|
||||
}, [isSearching]);
|
||||
|
||||
const isLoading = monitorsWithSummaryIsLoading || monitorsWithChecksIsLoading;
|
||||
const isLoading = monitorsWithChecksIsLoading;
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageStateWrapper
|
||||
networkError={networkError}
|
||||
isLoading={isLoading}
|
||||
items={monitors}
|
||||
items={monitorsWithChecks}
|
||||
type="uptimeMonitor"
|
||||
fallbackLink="/uptime/create"
|
||||
>
|
||||
@@ -174,14 +166,14 @@ const UptimeMonitors = () => {
|
||||
/>
|
||||
<Greeting type="uptime" />
|
||||
<StatusBoxes
|
||||
monitorsSummary={monitorsSummary}
|
||||
shouldRender={!monitorsWithSummaryIsLoading}
|
||||
monitorsSummary={summary}
|
||||
shouldRender={!monitorsWithChecksIsLoading}
|
||||
/>
|
||||
|
||||
<Stack direction={"row"}>
|
||||
<MonitorCountHeader
|
||||
isLoading={monitorsWithSummaryIsLoading}
|
||||
monitorCount={monitorsSummary?.totalMonitors}
|
||||
isLoading={monitorsWithChecksIsLoading}
|
||||
monitorCount={summary?.totalMonitors}
|
||||
/>
|
||||
<Filter
|
||||
selectedTypes={selectedTypes}
|
||||
@@ -195,7 +187,7 @@ const UptimeMonitors = () => {
|
||||
handleReset={handleReset}
|
||||
/>
|
||||
<SearchComponent
|
||||
monitors={monitors}
|
||||
monitors={monitorsWithChecks}
|
||||
onSearchChange={setSearch}
|
||||
setIsSearching={setIsSearching}
|
||||
/>
|
||||
|
||||
@@ -318,23 +318,22 @@ class MonitorModule {
|
||||
}
|
||||
};
|
||||
|
||||
getMonitorsAndSummaryByTeamId = async ({ type, explain, teamId }) => {
|
||||
findMonitorsSummaryByTeamId = async ({ type, teamId, explain }) => {
|
||||
try {
|
||||
const matchStage = { teamId: new this.ObjectId(teamId) };
|
||||
if (type !== undefined) {
|
||||
matchStage.type = Array.isArray(type) ? { $in: type } : type;
|
||||
}
|
||||
|
||||
const pipeline = buildMonitorsSummaryByTeamIdPipeline({ matchStage });
|
||||
if (explain === true) {
|
||||
return this.Monitor.aggregate(buildMonitorsAndSummaryByTeamIdPipeline({ matchStage })).explain("executionStats");
|
||||
return this.Monitor.aggregate(pipeline).explain("executionStats");
|
||||
}
|
||||
|
||||
const queryResult = await this.Monitor.aggregate(buildMonitorsAndSummaryByTeamIdPipeline({ matchStage }));
|
||||
const { monitors, summary } = queryResult?.[0] ?? {};
|
||||
return { monitors, summary };
|
||||
const [summary] = await this.Monitor.aggregate(pipeline);
|
||||
return summary ?? { totalMonitors: 0, upMonitors: 0, downMonitors: 0, pausedMonitors: 0 };
|
||||
} catch (error) {
|
||||
error.service = SERVICE_NAME;
|
||||
error.method = "getMonitorsAndSummaryByTeamId";
|
||||
error.method = "findMonitorsSummaryByTeamId";
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -10,6 +10,10 @@ export interface TeamQueryConfig {
|
||||
order?: "asc" | "desc";
|
||||
}
|
||||
|
||||
export interface SummaryConfig {
|
||||
type?: MonitorType | MonitorType[];
|
||||
}
|
||||
|
||||
export interface IMonitorsRepository {
|
||||
// create
|
||||
create(monitor: Monitor, teamId: string, userId: string): Promise<Monitor | null>;
|
||||
@@ -27,4 +31,7 @@ export interface IMonitorsRepository {
|
||||
|
||||
// counts
|
||||
findMonitorCountByTeamIdAndType(teamId: string, config: TeamQueryConfig): Promise<number>;
|
||||
|
||||
// other
|
||||
findMonitorsSummaryByTeamId(teamId: string, config?: SummaryConfig): Promise<any>;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { MonitorModel } from "@/db/models/index.js";
|
||||
import type { MonitorDocument } from "@/db/models/Monitor.js";
|
||||
import type { Monitor, MonitorType } from "@/types/monitor.js";
|
||||
import type { MonitorDocument } from "@/db/models/index.js";
|
||||
import type { Monitor, MonitorType } from "@/types/index.js";
|
||||
import mongoose, { type FilterQuery } from "mongoose";
|
||||
import type { IMonitorsRepository, TeamQueryConfig } from "./IMonitorsRepository.js";
|
||||
import type { IMonitorsRepository, TeamQueryConfig, SummaryConfig } from "./IMonitorsRepository.js";
|
||||
import { AppError } from "@/utils/AppError.js";
|
||||
|
||||
class MongoMonitorsRepository implements IMonitorsRepository {
|
||||
@@ -120,6 +120,44 @@ class MongoMonitorsRepository implements IMonitorsRepository {
|
||||
return { monitors: this.mapDocuments(monitors), deletedCount };
|
||||
};
|
||||
|
||||
findMonitorsSummaryByTeamId = async (
|
||||
teamId: string,
|
||||
config?: SummaryConfig
|
||||
): Promise<{ totalMonitors: number; upMonitors: number; downMonitors: number; pausedMonitors: number }> => {
|
||||
const match: FilterQuery<MonitorDocument> = { teamId: new mongoose.Types.ObjectId(teamId) };
|
||||
if (config?.type !== undefined) {
|
||||
match.type = Array.isArray(config.type) ? { $in: config.type } : config.type;
|
||||
}
|
||||
const pipeline = [
|
||||
{ $match: match },
|
||||
{
|
||||
$group: {
|
||||
_id: null,
|
||||
totalMonitors: { $sum: 1 },
|
||||
upMonitors: {
|
||||
$sum: {
|
||||
$cond: [{ $eq: ["$status", true] }, 1, 0],
|
||||
},
|
||||
},
|
||||
downMonitors: {
|
||||
$sum: {
|
||||
$cond: [{ $eq: ["$status", false] }, 1, 0],
|
||||
},
|
||||
},
|
||||
pausedMonitors: {
|
||||
$sum: {
|
||||
$cond: [{ $eq: ["$isActive", false] }, 1, 0],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{ $project: { _id: 0 } },
|
||||
];
|
||||
|
||||
const [summary] = await MonitorModel.aggregate(pipeline);
|
||||
return summary ?? { totalMonitors: 0, upMonitors: 0, downMonitors: 0, pausedMonitors: 0 };
|
||||
};
|
||||
|
||||
private mapDocuments = (documents: MonitorDocument[]): Monitor[] => {
|
||||
if (!documents?.length) {
|
||||
return [];
|
||||
|
||||
@@ -47,7 +47,7 @@ export interface IMonitorService {
|
||||
field?: string;
|
||||
order?: "asc" | "desc";
|
||||
explain?: boolean;
|
||||
}): Promise<{ count: number; monitors: any[] }>;
|
||||
}): Promise<{ summary: any; count: number; monitors: any[] }>;
|
||||
getAllGames(): any;
|
||||
getGroupsByTeamId(args: { teamId: string }): Promise<any[]>;
|
||||
|
||||
@@ -399,7 +399,8 @@ export class MonitorService implements IMonitorService {
|
||||
field?: string;
|
||||
order?: "asc" | "desc";
|
||||
explain?: boolean;
|
||||
}): Promise<{ count: number; monitors: any[] }> => {
|
||||
}): Promise<{ summary: any; count: number; monitors: any[] }> => {
|
||||
const summary = await this.monitorsRepository.findMonitorsSummaryByTeamId(teamId);
|
||||
const count = await this.monitorsRepository.findMonitorCountByTeamIdAndType(teamId, { type, filter });
|
||||
const monitors = await this.monitorsRepository.findByTeamId(teamId, {
|
||||
limit,
|
||||
@@ -433,7 +434,7 @@ export class MonitorService implements IMonitorService {
|
||||
};
|
||||
});
|
||||
|
||||
return { count, monitors: monitorsWithChecks };
|
||||
return { summary: summary ?? null, count, monitors: monitorsWithChecks };
|
||||
};
|
||||
|
||||
getAllGames = (): any => {
|
||||
|
||||
@@ -5,15 +5,6 @@ const SERVICE_NAME = "StatusService";
|
||||
class StatusService {
|
||||
static SERVICE_NAME = SERVICE_NAME;
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
* db: any
|
||||
* logger: any
|
||||
* buffer: import("./bufferService.js").BufferService
|
||||
* incidentService: import("../business/incidentService.js").IncidentService
|
||||
* monitorsRepository: any
|
||||
* }}
|
||||
*/
|
||||
constructor({ db, logger, buffer, incidentService, monitorsRepository }) {
|
||||
this.db = db;
|
||||
this.logger = logger;
|
||||
|
||||
Reference in new issue
Block a user