mirror of
https://github.com/OneUptime/oneuptime
synced 2024-11-22 15:24:55 +00:00
fix uptime graph
This commit is contained in:
parent
28f4a1f473
commit
d6788c138b
@ -359,6 +359,12 @@ export default class OneUptimeDate {
|
||||
return moment(date).isAfter(startDate);
|
||||
}
|
||||
|
||||
public static isEqualBySeconds(date: Date, startDate: Date): boolean {
|
||||
date = this.fromString(date);
|
||||
startDate = this.fromString(startDate);
|
||||
return moment(date).isSame(startDate, 'seconds');
|
||||
}
|
||||
|
||||
public static hasExpired(expirationDate: Date): boolean {
|
||||
expirationDate = this.fromString(expirationDate);
|
||||
return !moment(this.getCurrentDate()).isBefore(expirationDate);
|
||||
|
@ -46,9 +46,7 @@ export class Service extends DatabaseService<MonitorGroup> {
|
||||
limit: LIMIT_PER_PROJECT,
|
||||
skip: 0,
|
||||
select: {
|
||||
monitor: {
|
||||
currentMonitorStatusId: true,
|
||||
},
|
||||
monitorId: true,
|
||||
},
|
||||
props: {
|
||||
isRoot: true,
|
||||
@ -68,8 +66,8 @@ export class Service extends DatabaseService<MonitorGroup> {
|
||||
createdAt: QueryHelper.inBetween(startDate, endDate),
|
||||
},
|
||||
select: {
|
||||
monitorId: true,
|
||||
createdAt: true,
|
||||
monitorId: true,
|
||||
monitorStatus: {
|
||||
name: true,
|
||||
color: true,
|
||||
|
@ -12,6 +12,11 @@ import OneUptimeDate from 'Common/Types/Date';
|
||||
import DayUptimeGraph, { Event } from '../Graphs/DayUptimeGraph';
|
||||
import { Green } from 'Common/Types/BrandColors';
|
||||
import ErrorMessage from '../ErrorMessage/ErrorMessage';
|
||||
import ObjectID from 'Common/Types/ObjectID';
|
||||
|
||||
export interface MonitorEvent extends Event {
|
||||
monitorId: ObjectID;
|
||||
}
|
||||
|
||||
export interface ComponentProps {
|
||||
startDate: Date;
|
||||
@ -28,27 +33,144 @@ const MonitorUptimeGraph: FunctionComponent<ComponentProps> = (
|
||||
): ReactElement => {
|
||||
const [events, setEvents] = useState<Array<Event>>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const eventList: Array<Event> = [];
|
||||
// convert data to events.
|
||||
for (let i: number = 0; i < props.items.length; i++) {
|
||||
if (!props.items[i]) {
|
||||
break;
|
||||
/**
|
||||
* This function, `getMonitorEventsForId`, takes a `monitorId` as an argument and returns an array of `MonitorEvent` objects.
|
||||
* @param {ObjectID} monitorId - The ID of the monitor for which events are to be fetched.
|
||||
* @returns {Array<MonitorEvent>} - An array of `MonitorEvent` objects.
|
||||
*/
|
||||
const getMonitorEventsForId: (monitorId: ObjectID) => Array<MonitorEvent> = (monitorId: ObjectID): Array<MonitorEvent> => {
|
||||
// Initialize an empty array to store the monitor events.
|
||||
const eventList: Array<MonitorEvent> = [];
|
||||
|
||||
const monitorEvents = props.items.filter((item) => item.monitorId?.toString() === monitorId.toString());
|
||||
|
||||
// Loop through the items in the props object.
|
||||
for (let i: number = 0; i < monitorEvents.length; i++) {
|
||||
|
||||
// If the current item is null or undefined, skip to the next iteration.
|
||||
if (!monitorEvents[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Set the start date of the event to the creation date of the current item. If it doesn't exist, use the current date.
|
||||
const startDate: Date = monitorEvents[i]!.createdAt || OneUptimeDate.getCurrentDate();
|
||||
|
||||
// Initialize the end date as the current date.
|
||||
let endDate: Date = OneUptimeDate.getCurrentDate();
|
||||
|
||||
// If there is a next item and it has a creation date, use that as the end date.
|
||||
if (monitorEvents[i + 1] && monitorEvents[i + 1]!.createdAt) {
|
||||
endDate = monitorEvents[i + 1]!.createdAt!;
|
||||
}
|
||||
|
||||
// Push a new MonitorEvent object to the eventList array with properties from the current item and calculated dates.
|
||||
eventList.push({
|
||||
startDate:
|
||||
props.items[i]!.createdAt || OneUptimeDate.getCurrentDate(),
|
||||
endDate:
|
||||
props.items[i + 1] && props.items[i + 1]!.createdAt
|
||||
? (props.items[i + 1]?.createdAt as Date)
|
||||
: OneUptimeDate.getCurrentDate(),
|
||||
label: props.items[i]?.monitorStatus?.name || 'Operational',
|
||||
priority: props.items[i]?.monitorStatus?.priority || 0,
|
||||
color: props.items[i]?.monitorStatus?.color || Green,
|
||||
startDate: startDate,
|
||||
endDate: endDate,
|
||||
label: monitorEvents[i]?.monitorStatus?.name || 'Operational',
|
||||
priority: monitorEvents[i]?.monitorStatus?.priority || 0,
|
||||
color: monitorEvents[i]?.monitorStatus?.color || Green,
|
||||
monitorId: monitorEvents[i]?.monitorId!,
|
||||
});
|
||||
}
|
||||
|
||||
// Return the populated eventList array.
|
||||
return eventList;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const getMonitorEvents: () => Array<MonitorEvent> = (): Array<MonitorEvent> => {
|
||||
|
||||
|
||||
// get all distinct monitor ids.
|
||||
const monitorIds: Array<ObjectID> = [];
|
||||
|
||||
for (let i: number = 0; i < props.items.length; i++) {
|
||||
if (!props.items[i]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const monitorId: string | undefined = props.items[i]!.monitorId?.toString();
|
||||
|
||||
if (!monitorId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!monitorIds.find((item) => item.toString() === monitorId)) {
|
||||
monitorIds.push(new ObjectID(monitorId));
|
||||
}
|
||||
}
|
||||
|
||||
const eventList: Array<MonitorEvent> = [];
|
||||
// convert data to events.
|
||||
|
||||
for (const monitorId of monitorIds) {
|
||||
const monitorEvents: Array<MonitorEvent> = getMonitorEventsForId(monitorId);
|
||||
eventList.push(...monitorEvents);
|
||||
}
|
||||
|
||||
// sort event list by start date.
|
||||
eventList.sort((a: MonitorEvent, b: MonitorEvent) => {
|
||||
if (OneUptimeDate.isAfter(a.startDate, b.startDate)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (OneUptimeDate.isAfter(b.startDate, a.startDate)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
return [...eventList];
|
||||
}
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
let monitorEventList: Array<Event> = getMonitorEvents();
|
||||
|
||||
let eventList: Array<Event> = [];
|
||||
|
||||
for(const monitorEvent of monitorEventList) {
|
||||
|
||||
// if this event starts after the last event, then add it to the list directly.
|
||||
if(eventList.length === 0 || OneUptimeDate.isAfter(monitorEvent.startDate, eventList[eventList.length - 1]!.endDate) || OneUptimeDate.isEqualBySeconds(monitorEvent.startDate, eventList[eventList.length - 1]!.endDate)) {
|
||||
eventList.push(monitorEvent);
|
||||
continue;
|
||||
}
|
||||
|
||||
// if this event starts before the last event, then we need to check if it ends before the last event. If it does, then we can skip this event if the monitrEvent is of lower priority than the last event. If it is of higher priority, then we need to add it to the list and remove the last event from the list.
|
||||
if(OneUptimeDate.isBefore(monitorEvent.startDate, eventList[eventList.length - 1]!.endDate)) {
|
||||
|
||||
if(monitorEvent.priority > eventList[eventList.length - 1]!.priority) {
|
||||
// end the last event at the start of this event.
|
||||
|
||||
const tempLastEvent: Event = {...eventList[eventList.length - 1]} as any;
|
||||
|
||||
eventList[eventList.length - 1]!.endDate = monitorEvent.startDate;
|
||||
eventList.push(monitorEvent);
|
||||
|
||||
// if the monitorEvent endDate is before the end of the last event, then we need to add the end of the last event to the list.
|
||||
|
||||
if(OneUptimeDate.isBefore(monitorEvent.endDate, tempLastEvent.endDate)) {
|
||||
eventList.push({
|
||||
startDate: monitorEvent.endDate,
|
||||
endDate: tempLastEvent.endDate,
|
||||
label: tempLastEvent.label,
|
||||
priority: tempLastEvent.priority,
|
||||
color: tempLastEvent.color,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
setEvents(eventList);
|
||||
}, [props.items]);
|
||||
|
||||
|
@ -58,7 +58,7 @@ const MonitorGroupView: FunctionComponent<PageComponentProps> = (
|
||||
DASHBOARD_API_URL.toString()
|
||||
)
|
||||
.addRoute(new MonitorGroup().getCrudApiPath()!)
|
||||
.addRoute('/current-status/')
|
||||
.addRoute('/timeline/')
|
||||
.addRoute(`/${modelId.toString()}`),
|
||||
}
|
||||
);
|
||||
@ -116,7 +116,7 @@ const MonitorGroupView: FunctionComponent<PageComponentProps> = (
|
||||
},
|
||||
]}
|
||||
cardProps={{
|
||||
title: 'Monitor Group Hello',
|
||||
title: 'Monitor Group Details',
|
||||
description:
|
||||
'Here are more details for this monitor group.',
|
||||
}}
|
||||
@ -230,7 +230,7 @@ const MonitorGroupView: FunctionComponent<PageComponentProps> = (
|
||||
|
||||
<Card
|
||||
title="Uptime Graph"
|
||||
description="Here the 90 day uptime history of this monitor."
|
||||
description="Here the 90 day uptime history of this monitor group."
|
||||
>
|
||||
<MonitorUptimeGraph
|
||||
error={error}
|
||||
|
Loading…
Reference in New Issue
Block a user