mirror of
https://github.com/OneUptime/oneuptime.git
synced 2026-04-06 00:32:12 +02:00
Add new enum value and update description in
LayerPreview component
This commit is contained in:
@@ -23,6 +23,17 @@ export default class OneUptimeDate {
|
||||
return moment();
|
||||
}
|
||||
|
||||
public static keepTimeButMoveDay(keepTimeFor: Date, moveDayTo: Date){
|
||||
keepTimeFor = this.fromString(keepTimeFor);
|
||||
moveDayTo = this.fromString(moveDayTo);
|
||||
return moment(moveDayTo).set({
|
||||
hour: keepTimeFor.getHours(),
|
||||
minute: keepTimeFor.getMinutes(),
|
||||
second: keepTimeFor.getSeconds(),
|
||||
millisecond: keepTimeFor.getMilliseconds()
|
||||
}).toDate();
|
||||
}
|
||||
|
||||
public static getOneMinAgo(): Date {
|
||||
return this.getSomeMinutesAgo(new PositiveNumber(1));
|
||||
}
|
||||
@@ -42,6 +53,8 @@ export default class OneUptimeDate {
|
||||
return Math.abs(Seconds_from_T1_to_T2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static getSomeMinutesAgo(minutes: PositiveNumber | number): Date {
|
||||
if (!(minutes instanceof PositiveNumber)) {
|
||||
minutes = new PositiveNumber(minutes);
|
||||
@@ -87,6 +100,48 @@ export default class OneUptimeDate {
|
||||
};
|
||||
}
|
||||
|
||||
public static areOnTheSameDay(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'day');
|
||||
}
|
||||
|
||||
public static areOnTheSameMonth(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'month');
|
||||
}
|
||||
|
||||
public static areOnTheSameYear(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'year');
|
||||
}
|
||||
|
||||
public static areOnTheSameHour(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'hour');
|
||||
}
|
||||
|
||||
public static areOnTheSameMinute(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'minute');
|
||||
}
|
||||
|
||||
public static areOnTheSameSecond(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'second');
|
||||
}
|
||||
|
||||
public static areOnTheSameWeek(date1: Date, date2: Date): boolean {
|
||||
date1 = this.fromString(date1);
|
||||
date2 = this.fromString(date2);
|
||||
return moment(date1).isSame(date2, 'week');
|
||||
}
|
||||
|
||||
public static addRemoveMinutes(date: Date, minutes: number): Date {
|
||||
date = this.fromString(date);
|
||||
return moment(date).add(minutes, 'minutes').toDate();
|
||||
@@ -97,6 +152,26 @@ export default class OneUptimeDate {
|
||||
return moment(date).add(days, 'days').toDate();
|
||||
}
|
||||
|
||||
public static addRemoveHours(date: Date, hours: number): Date {
|
||||
date = this.fromString(date);
|
||||
return moment(date).add(hours, 'hours').toDate();
|
||||
}
|
||||
|
||||
public static addRemoveYears(date: Date, years: number): Date {
|
||||
date = this.fromString(date);
|
||||
return moment(date).add(years, 'years').toDate();
|
||||
}
|
||||
|
||||
public static addRemoveMonths(date: Date, months: number): Date {
|
||||
date = this.fromString(date);
|
||||
return moment(date).add(months, 'months').toDate();
|
||||
}
|
||||
|
||||
public static addRemoveWeeks(date: Date, weeks: number): Date {
|
||||
date = this.fromString(date);
|
||||
return moment(date).add(weeks, 'weeks').toDate();
|
||||
}
|
||||
|
||||
public static addRemoveSeconds(date: Date, seconds: number): Date {
|
||||
date = this.fromString(date);
|
||||
return moment(date).add(seconds, 'seconds').toDate();
|
||||
@@ -366,6 +441,18 @@ export default class OneUptimeDate {
|
||||
return moment(date).isAfter(startDate);
|
||||
}
|
||||
|
||||
public static isOnOrAfter(date: Date, startDate: Date): boolean {
|
||||
date = this.fromString(date);
|
||||
startDate = this.fromString(startDate);
|
||||
return moment(date).isSameOrAfter(startDate);
|
||||
}
|
||||
|
||||
public static isOnOrBefore(date: Date, endDate: Date): boolean {
|
||||
date = this.fromString(date);
|
||||
endDate = this.fromString(endDate);
|
||||
return moment(date).isSameOrBefore(endDate);
|
||||
}
|
||||
|
||||
public static isEqualBySeconds(date: Date, startDate: Date): boolean {
|
||||
date = this.fromString(date);
|
||||
startDate = this.fromString(startDate);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
enum EventInterval {
|
||||
Hour = 'Hour',
|
||||
Day = 'Day',
|
||||
Week = 'Week',
|
||||
Month = 'Month',
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import UserModel from '../../Models/UserModel';
|
||||
import Recurring from '../Events/Recurring';
|
||||
import CalendarEvent from '../Calendar/CalendarEvent';
|
||||
import RestrictionTimes from './RestrictionTimes';
|
||||
import RestrictionTimes, { RestrictionType } from './RestrictionTimes';
|
||||
import OneUptimeDate from '../Date';
|
||||
import EventInterval from '../Events/EventInterval';
|
||||
import StartAndEndTime from '../Time/StartAndEndTime';
|
||||
|
||||
export default class Layer {
|
||||
public static getEvents(_data: {
|
||||
export default class LayerUtil {
|
||||
public static getEvents(data: {
|
||||
users: Array<UserModel>;
|
||||
startDateTimeOfLayer: Date;
|
||||
calendarStartDate: Date;
|
||||
@@ -13,6 +16,247 @@ export default class Layer {
|
||||
handOffTime: Date;
|
||||
rotation: Recurring;
|
||||
}): Array<CalendarEvent> {
|
||||
|
||||
|
||||
const events: Array<CalendarEvent> = [];
|
||||
|
||||
|
||||
|
||||
let start: Date = data.calendarStartDate;
|
||||
let end: Date = data.calendarEndDate;
|
||||
|
||||
|
||||
// start time of the layer is after the start time of the calendar, so we need to update the start time of the calendar
|
||||
if (OneUptimeDate.isAfter(data.startDateTimeOfLayer, start)) {
|
||||
start = data.startDateTimeOfLayer;
|
||||
}
|
||||
|
||||
|
||||
// end time of the layer is before the end time of the calendar, so, we dont have any events and we can return empty array
|
||||
if (OneUptimeDate.isAfter(data.startDateTimeOfLayer, end)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// if users are empty, we dont have any events and we can return empty array
|
||||
if (data.users.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// split events by rotation.
|
||||
|
||||
const rotation: Recurring = data.rotation;
|
||||
|
||||
let hasReachedTheEndOfTheCalendar: boolean = false;
|
||||
|
||||
const handOffTime: Date = data.handOffTime;
|
||||
|
||||
|
||||
// Looop vars
|
||||
let currentEventStartTime: Date = start;
|
||||
let currentEventEndTime: Date = OneUptimeDate.getCurrentDate(); // temporary set to current time to avoid typescript error
|
||||
let currentUserIndex: number = 0;
|
||||
|
||||
while (!hasReachedTheEndOfTheCalendar) {
|
||||
|
||||
|
||||
if (rotation.intervalType === EventInterval.Day) {
|
||||
const daysToAdd = rotation.intervalCount.toNumber();
|
||||
currentEventEndTime = OneUptimeDate.addRemoveDays(currentEventStartTime, daysToAdd);
|
||||
} else if (rotation.intervalType === EventInterval.Week) {
|
||||
let weeksToAdd = rotation.intervalCount.toNumber();
|
||||
currentEventEndTime = OneUptimeDate.addRemoveWeeks(currentEventStartTime, weeksToAdd);
|
||||
} else if (rotation.intervalType === EventInterval.Month) {
|
||||
const monthsToAdd = rotation.intervalCount.toNumber();
|
||||
currentEventEndTime = OneUptimeDate.addRemoveMonths(currentEventStartTime, monthsToAdd);
|
||||
} else if (rotation.intervalType === EventInterval.Year) {
|
||||
const yearsToAdd = rotation.intervalCount.toNumber();
|
||||
currentEventEndTime = OneUptimeDate.addRemoveYears(currentEventStartTime, yearsToAdd);
|
||||
} else if (rotation.intervalType === EventInterval.Hour) {
|
||||
const hoursToAdd = rotation.intervalCount.toNumber();
|
||||
currentEventEndTime = OneUptimeDate.addRemoveHours(currentEventStartTime, hoursToAdd);
|
||||
}
|
||||
|
||||
// check calendar end time. if the end time of the event is after the end time of the calendar, we need to update the end time of the event
|
||||
if (OneUptimeDate.isAfter(currentEventEndTime, end)) {
|
||||
currentEventEndTime = end;
|
||||
hasReachedTheEndOfTheCalendar = true;
|
||||
}
|
||||
|
||||
|
||||
// check restriction times. if the end time of the event is after the end time of the restriction times, we need to update the end time of the event.
|
||||
|
||||
const trimmedStartAndEndTimes: Array<StartAndEndTime>
|
||||
= LayerUtil.trimStartAndEndTimesBasedOnRestrictionTimes({
|
||||
eventStartTime: currentEventStartTime,
|
||||
eventEndTime: currentEventEndTime,
|
||||
restrictionTimes: data.restrictionTImes,
|
||||
});
|
||||
|
||||
|
||||
|
||||
const userId = data.users[currentUserIndex]?.id?.toString() || '';
|
||||
|
||||
for (const trimmedStartAndEndTime of trimmedStartAndEndTimes) {
|
||||
const event: CalendarEvent = {
|
||||
id: 0,
|
||||
title: userId, // This will be changed to username in the UI or will bve kept the same if used on the server.
|
||||
allDay: false,
|
||||
start: trimmedStartAndEndTime.startTime,
|
||||
end: trimmedStartAndEndTime.endTime,
|
||||
};
|
||||
|
||||
events.push(event);
|
||||
}
|
||||
|
||||
// update the current event start time
|
||||
|
||||
currentEventStartTime = currentEventEndTime;
|
||||
|
||||
// update the current user index
|
||||
|
||||
currentUserIndex++;
|
||||
|
||||
|
||||
// if the current user index is greater than the length of the users array, we need to reset the current user index to 0
|
||||
if (currentUserIndex >= data.users.length) {
|
||||
currentUserIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// increment ids of all the events and return them, to make sure they are unique
|
||||
|
||||
let id = 1;
|
||||
|
||||
for (const event of events) {
|
||||
event.id = id;
|
||||
id++;
|
||||
}
|
||||
|
||||
return events;
|
||||
}
|
||||
|
||||
|
||||
public static trimStartAndEndTimesBasedOnRestrictionTimes(data: {
|
||||
eventStartTime: Date;
|
||||
eventEndTime: Date;
|
||||
restrictionTimes: RestrictionTimes;
|
||||
}): Array<StartAndEndTime> {
|
||||
|
||||
const restrictionTimes: RestrictionTimes = data.restrictionTimes;
|
||||
|
||||
if (restrictionTimes.restictionType === RestrictionType.None) {
|
||||
return [{
|
||||
startTime: data.eventStartTime,
|
||||
endTime: data.eventEndTime,
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
if (restrictionTimes.restictionType === RestrictionType.Daily) {
|
||||
const dayRestrictionTimes = restrictionTimes.dayRestrictionTimes;
|
||||
|
||||
|
||||
// if there are no day restriction times, we dont have any restrictions and we can return the event start and end times
|
||||
|
||||
if (!dayRestrictionTimes) {
|
||||
return [{
|
||||
startTime: data.eventStartTime,
|
||||
endTime: data.eventEndTime,
|
||||
}];
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
let restrictionStartTime: Date = dayRestrictionTimes.startTime;
|
||||
let restrictionEndTime: Date = dayRestrictionTimes.endTime;
|
||||
|
||||
|
||||
let currentStartTime = data.eventStartTime;
|
||||
let currentEndTime = data.eventEndTime;
|
||||
|
||||
const trimmedStartAndEndTimes: Array<StartAndEndTime> = [];
|
||||
|
||||
let reachedTheEndOfTheCurrentEvent = false;
|
||||
|
||||
while (!reachedTheEndOfTheCurrentEvent) {
|
||||
|
||||
// if current end time is equalto or before than the current start time, we need to return the current event and exit the loop
|
||||
|
||||
if (OneUptimeDate.isBefore(currentEndTime, currentStartTime)) {
|
||||
reachedTheEndOfTheCurrentEvent = true;
|
||||
}
|
||||
|
||||
// before this we need to make sure restrciton times are moved to the day of the event.
|
||||
restrictionStartTime = OneUptimeDate.keepTimeButMoveDay(restrictionStartTime, data.eventStartTime);
|
||||
restrictionEndTime = OneUptimeDate.keepTimeButMoveDay(restrictionEndTime, data.eventStartTime);
|
||||
|
||||
// if the restriction end time is before the restriction start time, we need to add one day to the restriction end time
|
||||
if (OneUptimeDate.isAfter(restrictionStartTime, restrictionEndTime)) {
|
||||
restrictionEndTime = OneUptimeDate.addRemoveDays(restrictionEndTime, 1);
|
||||
}
|
||||
|
||||
// 1 - if the current event falls within the restriction times, we need to return the current event.
|
||||
|
||||
if (OneUptimeDate.isOnOrAfter(currentStartTime, restrictionStartTime) && OneUptimeDate.isOnOrAfter(restrictionEndTime, currentEndTime)) {
|
||||
trimmedStartAndEndTimes.push({
|
||||
startTime: currentStartTime,
|
||||
endTime: currentEndTime,
|
||||
});
|
||||
reachedTheEndOfTheCurrentEvent = true;
|
||||
}
|
||||
|
||||
// 2 - Start Restriction: If the current event starts after the restriction start time and ends after the restriction end time, we need to return the current event with the start time of the current event and end time of the restriction
|
||||
|
||||
if (OneUptimeDate.isOnOrAfter(currentStartTime, restrictionStartTime) && OneUptimeDate.isOnOrAfter(currentEndTime, restrictionEndTime)) {
|
||||
trimmedStartAndEndTimes.push({
|
||||
startTime: currentStartTime,
|
||||
endTime: restrictionEndTime,
|
||||
});
|
||||
reachedTheEndOfTheCurrentEvent = true;
|
||||
}
|
||||
|
||||
// 3 - End Restriction - If the current event starts before the restriction start time and ends before the restriction end time, we need to return the current event with the start time of the restriction and end time of the current event.
|
||||
|
||||
if (OneUptimeDate.isBefore(currentStartTime, restrictionStartTime) && OneUptimeDate.isBefore(currentEndTime, restrictionEndTime)) {
|
||||
trimmedStartAndEndTimes.push({
|
||||
startTime: restrictionStartTime,
|
||||
endTime: currentEndTime,
|
||||
});
|
||||
reachedTheEndOfTheCurrentEvent = true;
|
||||
}
|
||||
|
||||
// 4 - If the current event starts before the restriction start time and ends after the restriction end time, we need to return the current event with the start time of the restriction and end time of the restriction.
|
||||
|
||||
if (OneUptimeDate.isBefore(currentStartTime, restrictionStartTime) && OneUptimeDate.isOnOrAfter(currentEndTime, restrictionEndTime)) {
|
||||
trimmedStartAndEndTimes.push({
|
||||
startTime: restrictionStartTime,
|
||||
endTime: restrictionEndTime,
|
||||
});
|
||||
reachedTheEndOfTheCurrentEvent = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (restrictionTimes.restictionType === RestrictionType.Weekly) {
|
||||
|
||||
const weeklyRestrictionTimes = restrictionTimes.weeklyRestrictionTimes;
|
||||
|
||||
// if there are no weekly restriction times, we dont have any restrictions and we can return the event start and end times
|
||||
|
||||
if (!weeklyRestrictionTimes || weeklyRestrictionTimes.length === 0) {
|
||||
return [{
|
||||
startTime: data.eventStartTime,
|
||||
endTime: data.eventEndTime,
|
||||
}];
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import OnCallDutyPolicyScheduleLayerUser from 'Model/Models/OnCallDutyPolicySche
|
||||
import React, { FunctionComponent, ReactElement } from 'react';
|
||||
import Calendar from 'CommonUI/src/Components/Calendar/Calendar';
|
||||
import FieldLabelElement from 'CommonUI/src/Components/Forms/Fields/FieldLabel';
|
||||
import OneUptimeDate from 'Common/Types/Date';
|
||||
|
||||
export interface ComponentProps {
|
||||
layer: OnCallDutyPolicyScheduleLayer;
|
||||
@@ -19,7 +20,7 @@ const LayerPreview: FunctionComponent<ComponentProps> = (
|
||||
<FieldLabelElement
|
||||
required={true}
|
||||
title="Layer Preview"
|
||||
description="Here is a preview of who is on call and when."
|
||||
description={"Here is a preview of who is on call and when. This is based on your local timezone - "+OneUptimeDate.getCurrentTimezoneString()}
|
||||
/>
|
||||
<Calendar
|
||||
events={[
|
||||
|
||||
Reference in New Issue
Block a user