This commit is contained in:
Simon Larsen
2023-05-02 17:50:16 +01:00
parent c48dca0925
commit 8b6ac3341a
25 changed files with 341 additions and 311 deletions

View File

@@ -266,7 +266,6 @@ export default class OneUptimeDate {
return b.diff(a, 'days');
}
public static getNumberOfMinutesBetweenDates(
startDate: Date,
endDate: Date
@@ -376,17 +375,15 @@ export default class OneUptimeDate {
}
public static fromString(date: string | JSONObject): Date {
if(typeof date === 'string') {
if (typeof date === 'string') {
return moment(date).toDate();
}
if(date && date['value'] && typeof date['value'] === 'string'){
if (date && date['value'] && typeof date['value'] === 'string') {
return moment(date['value']).toDate();
}
throw new BadDataException('Invalid date');
}
public static asDateForDatabaseQuery(date: string | Date): string {

View File

@@ -68,7 +68,6 @@ enum Permission {
CanEditScheduledMaintenanceCustomField = 'CanEditScheduledMaintenanceCustomField',
CanReadScheduledMaintenanceCustomField = 'CanReadScheduledMaintenanceCustomField',
CanCreateMonitorProbe = 'CanCreateMonitorProbe',
CanDeleteMonitorProbe = 'CanDeleteMonitorProbe',
CanEditMonitorProbe = 'CanEditMonitorProbe',
@@ -1629,7 +1628,6 @@ export class PermissionHelper {
isAccessControlPermission: false,
},
{
permission: Permission.CanCreateMonitorProbe,
title: 'Can Create Monitor Probe',

View File

@@ -13,15 +13,14 @@ import BaseAPI from './BaseAPI';
import LIMIT_MAX from 'Common/Types/Database/LimitMax';
import PositiveNumber from 'Common/Types/PositiveNumber';
export default class ProbeAPI extends BaseAPI<
Probe,
ProbeServiceType
> {
export default class ProbeAPI extends BaseAPI<Probe, ProbeServiceType> {
public constructor() {
super(Probe, ProbeService);
this.router.post(
`${new this.entityType().getCrudApiPath()?.toString()}/global-probes`,
`${new this.entityType()
.getCrudApiPath()
?.toString()}/global-probes`,
UserMiddleware.getUserMiddleware,
async (
req: ExpressRequest,
@@ -29,24 +28,30 @@ export default class ProbeAPI extends BaseAPI<
next: NextFunction
) => {
try {
const probes = await ProbeService.findBy({
const probes: Array<Probe> = await ProbeService.findBy({
query: {
isGlobalProbe: true,
},
select: {
name: true,
description: true,
description: true,
lastAlive: true,
iconFileId: true,
},
props: {
isRoot: true,
},
skip: 0,
limit: LIMIT_MAX
})
skip: 0,
limit: LIMIT_MAX,
});
return Response.sendEntityArrayResponse(req, res, probes, new PositiveNumber(probes.length), Probe);
return Response.sendEntityArrayResponse(
req,
res,
probes,
new PositiveNumber(probes.length),
Probe
);
} catch (err) {
next(err);
}

View File

@@ -10,12 +10,14 @@ export class Service extends DatabaseService<Model> {
super(Model, postgresDatabase);
}
protected override async onBeforeCreate(createBy: CreateBy<Model>): Promise<OnCreate<Model>> {
if(!createBy.data.key) {
protected override async onBeforeCreate(
createBy: CreateBy<Model>
): Promise<OnCreate<Model>> {
if (!createBy.data.key) {
createBy.data.key = ObjectID.generate().toString();
}
if(!createBy.data.probeVersion) {
if (!createBy.data.probeVersion) {
createBy.data.probeVersion = new Version('1.0.0');
}

View File

@@ -76,7 +76,7 @@ const Dropdown: FunctionComponent<ComponentProps> = (
props.onChange &&
props.onChange(
value.map(i => {
value.map((i: DropdownOption) => {
return i.value;
})
);

View File

@@ -110,7 +110,10 @@ const FilePicker: FunctionComponent<ComponentProps> = (
fileModel,
FileModel,
{
overrideRequestUrl: CommonURL.fromURL(FILE_URL).addRoute('/file')
overrideRequestUrl:
CommonURL.fromURL(FILE_URL).addRoute(
'/file'
),
}
)) as HTTPResponse<FileModel>;
filesResult.push(result.data as FileModel);

View File

@@ -284,9 +284,11 @@ const Icon: FunctionComponent<ComponentProps> = ({
);
} else if (icon === IconProp.Signal) {
return getSvgWrapper(
<path strokeLinecap="round" strokeLinejoin="round" d="M9.348 14.651a3.75 3.75 0 010-5.303m5.304 0a3.75 3.75 0 010 5.303m-7.425 2.122a6.75 6.75 0 010-9.546m9.546 0a6.75 6.75 0 010 9.546M5.106 18.894c-3.808-3.808-3.808-9.98 0-13.789m13.788 0c3.808 3.808 3.808 9.981 0 13.79M12 12h.008v.007H12V12zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z" />
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M9.348 14.651a3.75 3.75 0 010-5.303m5.304 0a3.75 3.75 0 010 5.303m-7.425 2.122a6.75 6.75 0 010-9.546m9.546 0a6.75 6.75 0 010 9.546M5.106 18.894c-3.808-3.808-3.808-9.98 0-13.789m13.788 0c3.808 3.808 3.808 9.981 0 13.79M12 12h.008v.007H12V12zm.375 0a.375.375 0 11-.75 0 .375.375 0 01.75 0z"
/>
);
} else if (icon === IconProp.Criteria) {
return getSvgWrapper(

View File

@@ -53,15 +53,11 @@ export default class ModelAPI {
public static async update<TBaseModel extends BaseModel>(
model: TBaseModel,
modelType: { new (): TBaseModel },
modelType: { new (): TBaseModel }
): Promise<
HTTPResponse<JSONObject | JSONArray | TBaseModel | Array<TBaseModel>>
> {
return await ModelAPI.createOrUpdate(
model,
modelType,
FormType.Update,
);
return await ModelAPI.createOrUpdate(model, modelType, FormType.Update);
}
public static async updateById<TBaseModel extends BaseModel>(
@@ -190,7 +186,7 @@ export default class ModelAPI {
.addRoute(apiPath)
.addRoute('/get-list');
if(requestOptions?.overrideRequestUrl){
if (requestOptions?.overrideRequestUrl) {
apiUrl = requestOptions.overrideRequestUrl;
}
@@ -261,9 +257,9 @@ export default class ModelAPI {
.addRoute(apiPath)
.addRoute('/count');
if(requestOptions?.overrideRequestUrl){
apiUrl = requestOptions.overrideRequestUrl;
}
if (requestOptions?.overrideRequestUrl) {
apiUrl = requestOptions.overrideRequestUrl;
}
if (!apiUrl) {
throw new BadDataException(
@@ -344,9 +340,9 @@ export default class ModelAPI {
.addRoute('/' + id.toString())
.addRoute('/get-item');
if(requestOptions?.overrideRequestUrl){
apiUrl = requestOptions.overrideRequestUrl;
}
if (requestOptions?.overrideRequestUrl) {
apiUrl = requestOptions.overrideRequestUrl;
}
if (!apiUrl) {
throw new BadDataException(

View File

@@ -300,7 +300,7 @@ const App: FunctionComponent = () => {
<NotOperationalMonitors
pageRoute={
RouteMap[
PageMap.HOME_NOT_OPERATIONAL_MONITORS
PageMap.HOME_NOT_OPERATIONAL_MONITORS
] as Route
}
currentProject={selectedProject}
@@ -320,8 +320,8 @@ const App: FunctionComponent = () => {
<OngoingScheduledEvents
pageRoute={
RouteMap[
PageMap
.HOME_ONGOING_SCHEDULED_MAINTENANCE_EVENTS
PageMap
.HOME_ONGOING_SCHEDULED_MAINTENANCE_EVENTS
] as Route
}
currentProject={selectedProject}
@@ -349,7 +349,7 @@ const App: FunctionComponent = () => {
<MonitorInoperational
pageRoute={
RouteMap[
PageMap.MONITORS_INOPERATIONAL
PageMap.MONITORS_INOPERATIONAL
] as Route
}
currentProject={selectedProject}
@@ -391,7 +391,7 @@ const App: FunctionComponent = () => {
<MonitorViewStatusTimeline
pageRoute={
RouteMap[
PageMap.MONITOR_VIEW_STATUS_TIMELINE
PageMap.MONITOR_VIEW_STATUS_TIMELINE
] as Route
}
currentProject={selectedProject}
@@ -423,7 +423,7 @@ const App: FunctionComponent = () => {
<MonitorIncidents
pageRoute={
RouteMap[
PageMap.MONITOR_VIEW_INCIDENTS
PageMap.MONITOR_VIEW_INCIDENTS
] as Route
}
currentProject={selectedProject}
@@ -441,7 +441,7 @@ const App: FunctionComponent = () => {
<MonitorViewCustomFields
pageRoute={
RouteMap[
PageMap.MONITOR_VIEW_CUSTOM_FIELDS
PageMap.MONITOR_VIEW_CUSTOM_FIELDS
] as Route
}
currentProject={selectedProject}
@@ -607,7 +607,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewDelete
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_DELETE
PageMap.STATUS_PAGE_VIEW_DELETE
] as Route
}
currentProject={selectedProject}
@@ -625,7 +625,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewBranding
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_BRANDING
PageMap.STATUS_PAGE_VIEW_BRANDING
] as Route
}
currentProject={selectedProject}
@@ -643,7 +643,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewCustomHtmlCss
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_CUSTOM_HTML_CSS
PageMap.STATUS_PAGE_VIEW_CUSTOM_HTML_CSS
] as Route
}
currentProject={selectedProject}
@@ -661,7 +661,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewAdvancedOptions
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_ADVANCED_OPTIONS
PageMap.STATUS_PAGE_VIEW_ADVANCED_OPTIONS
] as Route
}
currentProject={selectedProject}
@@ -679,7 +679,7 @@ const App: FunctionComponent = () => {
<StatusPageViewCustomFields
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_CUSTOM_FIELDS
PageMap.STATUS_PAGE_VIEW_CUSTOM_FIELDS
] as Route
}
currentProject={selectedProject}
@@ -711,7 +711,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewEmailSubscribers
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_EMAIL_SUBSCRIBERS
PageMap.STATUS_PAGE_VIEW_EMAIL_SUBSCRIBERS
] as Route
}
currentProject={selectedProject}
@@ -729,8 +729,8 @@ const App: FunctionComponent = () => {
<StatusPageViewAuthenticationSettings
pageRoute={
RouteMap[
PageMap
.STATUS_PAGE_VIEW_AUTHENTICATION_SETTINGS
PageMap
.STATUS_PAGE_VIEW_AUTHENTICATION_SETTINGS
] as Route
}
currentProject={selectedProject}
@@ -748,7 +748,7 @@ const App: FunctionComponent = () => {
<StatusPageViewCustomSMTP
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_CUSTOM_SMTP
PageMap.STATUS_PAGE_VIEW_CUSTOM_SMTP
] as Route
}
currentProject={selectedProject}
@@ -766,7 +766,7 @@ const App: FunctionComponent = () => {
<StatusPageViewPrivateUser
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_PRIVATE_USERS
PageMap.STATUS_PAGE_VIEW_PRIVATE_USERS
] as Route
}
currentProject={selectedProject}
@@ -784,7 +784,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewSMSSubscribers
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_SMS_SUBSCRIBERS
PageMap.STATUS_PAGE_VIEW_SMS_SUBSCRIBERS
] as Route
}
currentProject={selectedProject}
@@ -802,7 +802,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewHeaderStyle
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_HEADER_STYLE
PageMap.STATUS_PAGE_VIEW_HEADER_STYLE
] as Route
}
currentProject={selectedProject}
@@ -820,7 +820,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewFooterStyle
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_FOOTER_STYLE
PageMap.STATUS_PAGE_VIEW_FOOTER_STYLE
] as Route
}
currentProject={selectedProject}
@@ -838,7 +838,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewNavBarStyle
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_NAVBAR_STYLE
PageMap.STATUS_PAGE_VIEW_NAVBAR_STYLE
] as Route
}
currentProject={selectedProject}
@@ -856,7 +856,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewWebhookSubscribers
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_WEBHOOK_SUBSCRIBERS
PageMap.STATUS_PAGE_VIEW_WEBHOOK_SUBSCRIBERS
] as Route
}
currentProject={selectedProject}
@@ -874,7 +874,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewEmbedded
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_EMBEDDED
PageMap.STATUS_PAGE_VIEW_EMBEDDED
] as Route
}
currentProject={selectedProject}
@@ -892,7 +892,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewResources
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_RESOURCES
PageMap.STATUS_PAGE_VIEW_RESOURCES
] as Route
}
currentProject={selectedProject}
@@ -910,7 +910,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewDomains
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_DOMAINS
PageMap.STATUS_PAGE_VIEW_DOMAINS
] as Route
}
currentProject={selectedProject}
@@ -927,7 +927,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewGroups
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_GROUPS
PageMap.STATUS_PAGE_VIEW_GROUPS
] as Route
}
currentProject={selectedProject}
@@ -945,7 +945,7 @@ const App: FunctionComponent = () => {
<StatusPagesViewAnnouncement
pageRoute={
RouteMap[
PageMap.STATUS_PAGE_VIEW_ANNOUNCEMENTS
PageMap.STATUS_PAGE_VIEW_ANNOUNCEMENTS
] as Route
}
currentProject={selectedProject}
@@ -1013,7 +1013,7 @@ const App: FunctionComponent = () => {
<IncidentViewStateTimeline
pageRoute={
RouteMap[
PageMap.INCIDENT_VIEW_STATE_TIMELINE
PageMap.INCIDENT_VIEW_STATE_TIMELINE
] as Route
}
currentProject={selectedProject}
@@ -1030,7 +1030,7 @@ const App: FunctionComponent = () => {
<IncidentInternalNote
pageRoute={
RouteMap[
PageMap.INCIDENT_INTERNAL_NOTE
PageMap.INCIDENT_INTERNAL_NOTE
] as Route
}
currentProject={selectedProject}
@@ -1048,7 +1048,7 @@ const App: FunctionComponent = () => {
<IncidentViewCustomFields
pageRoute={
RouteMap[
PageMap.INCIDENT_VIEW_CUSTOM_FIELDS
PageMap.INCIDENT_VIEW_CUSTOM_FIELDS
] as Route
}
currentProject={selectedProject}
@@ -1082,7 +1082,7 @@ const App: FunctionComponent = () => {
<ScheduledMaintenanceEvents
pageRoute={
RouteMap[
PageMap.SCHEDULED_MAINTENANCE_EVENTS
PageMap.SCHEDULED_MAINTENANCE_EVENTS
] as Route
}
currentProject={selectedProject}
@@ -1100,7 +1100,7 @@ const App: FunctionComponent = () => {
<OngoingScheduledMaintenanceEvents
pageRoute={
RouteMap[
PageMap.ONGOING_SCHEDULED_MAINTENANCE_EVENTS
PageMap.ONGOING_SCHEDULED_MAINTENANCE_EVENTS
] as Route
}
currentProject={selectedProject}
@@ -1118,7 +1118,7 @@ const App: FunctionComponent = () => {
<ScheduledMaintenanceEventView
pageRoute={
RouteMap[
PageMap.SCHEDULED_MAINTENANCE_VIEW
PageMap.SCHEDULED_MAINTENANCE_VIEW
] as Route
}
currentProject={selectedProject}
@@ -1136,8 +1136,8 @@ const App: FunctionComponent = () => {
<ScheduledMaintenanceEventsViewCustomFields
pageRoute={
RouteMap[
PageMap
.SCHEDULED_MAINTENANCE_VIEW_CUSTOM_FIELDS
PageMap
.SCHEDULED_MAINTENANCE_VIEW_CUSTOM_FIELDS
] as Route
}
currentProject={selectedProject}
@@ -1155,7 +1155,7 @@ const App: FunctionComponent = () => {
<ScheduledMaintenanceEventViewDelete
pageRoute={
RouteMap[
PageMap.SCHEDULED_MAINTENANCE_VIEW_DELETE
PageMap.SCHEDULED_MAINTENANCE_VIEW_DELETE
] as Route
}
currentProject={selectedProject}
@@ -1173,8 +1173,8 @@ const App: FunctionComponent = () => {
<ScheduledMaintenanceEventViewStateTimeline
pageRoute={
RouteMap[
PageMap
.SCHEDULED_MAINTENANCE_VIEW_STATE_TIMELINE
PageMap
.SCHEDULED_MAINTENANCE_VIEW_STATE_TIMELINE
] as Route
}
currentProject={selectedProject}
@@ -1192,7 +1192,7 @@ const App: FunctionComponent = () => {
<ScheduledMaintenanceEventInternalNote
pageRoute={
RouteMap[
PageMap.SCHEDULED_MAINTENANCE_INTERNAL_NOTE
PageMap.SCHEDULED_MAINTENANCE_INTERNAL_NOTE
] as Route
}
currentProject={selectedProject}
@@ -1210,7 +1210,7 @@ const App: FunctionComponent = () => {
<ScheduledMaintenanceEventPublicNote
pageRoute={
RouteMap[
PageMap.SCHEDULED_MAINTENANCE_PUBLIC_NOTE
PageMap.SCHEDULED_MAINTENANCE_PUBLIC_NOTE
] as Route
}
currentProject={selectedProject}
@@ -1272,7 +1272,7 @@ const App: FunctionComponent = () => {
<SettingsMonitors
pageRoute={
RouteMap[
PageMap.SETTINGS_MONITORS_STATUS
PageMap.SETTINGS_MONITORS_STATUS
] as Route
}
currentProject={selectedProject}
@@ -1290,7 +1290,7 @@ const App: FunctionComponent = () => {
<SettingsIncidents
pageRoute={
RouteMap[
PageMap.SETTINGS_INCIDENTS_STATE
PageMap.SETTINGS_INCIDENTS_STATE
] as Route
}
currentProject={selectedProject}
@@ -1308,7 +1308,7 @@ const App: FunctionComponent = () => {
<SettingsScheduledMaintenanceState
pageRoute={
RouteMap[
PageMap.SETTINGS_SCHEDULED_MAINTENANCE_STATE
PageMap.SETTINGS_SCHEDULED_MAINTENANCE_STATE
] as Route
}
currentProject={selectedProject}
@@ -1336,7 +1336,7 @@ const App: FunctionComponent = () => {
<SettingsIncidentSeverity
pageRoute={
RouteMap[
PageMap.SETTINGS_INCIDENTS_SEVERITY
PageMap.SETTINGS_INCIDENTS_SEVERITY
] as Route
}
currentProject={selectedProject}
@@ -1406,7 +1406,7 @@ const App: FunctionComponent = () => {
<MonitorCustomFields
pageRoute={
RouteMap[
PageMap.SETTINGS_MONITOR_CUSTOM_FIELDS
PageMap.SETTINGS_MONITOR_CUSTOM_FIELDS
] as Route
}
currentProject={selectedProject}
@@ -1424,7 +1424,7 @@ const App: FunctionComponent = () => {
<StatusPageCustomFields
pageRoute={
RouteMap[
PageMap.SETTINGS_STATUS_PAGE_CUSTOM_FIELDS
PageMap.SETTINGS_STATUS_PAGE_CUSTOM_FIELDS
] as Route
}
currentProject={selectedProject}
@@ -1442,8 +1442,8 @@ const App: FunctionComponent = () => {
<ScheduledMaintenanceCustomFields
pageRoute={
RouteMap[
PageMap
.SETTINGS_SCHEDULED_MAINTENANCE_CUSTOM_FIELDS
PageMap
.SETTINGS_SCHEDULED_MAINTENANCE_CUSTOM_FIELDS
] as Route
}
currentProject={selectedProject}
@@ -1461,7 +1461,7 @@ const App: FunctionComponent = () => {
<IncidentCustomFields
pageRoute={
RouteMap[
PageMap.SETTINGS_INCIDENT_CUSTOM_FIELDS
PageMap.SETTINGS_INCIDENT_CUSTOM_FIELDS
] as Route
}
currentProject={selectedProject}
@@ -1491,7 +1491,7 @@ const App: FunctionComponent = () => {
<SettingsInvoices
pageRoute={
RouteMap[
PageMap.SETTINGS_BILLING_INVOICES
PageMap.SETTINGS_BILLING_INVOICES
] as Route
}
currentProject={selectedProject}

View File

@@ -84,7 +84,7 @@ const CriteriaFilterElement: FunctionComponent<ComponentProps> = (
if (
criteriaFilter?.checkOn === CheckOn.ResponseBody ||
criteriaFilter?.checkOn === CheckOn.ResponseHeader ||
criteriaFilter?.checkOn === CheckOn.ResponseHeader ||
criteriaFilter?.checkOn === CheckOn.ResponseHeaderValue
) {
options = options.filter((i: DropdownOption) => {

View File

@@ -28,7 +28,7 @@ const MonitorCriteriaIncidentForm: FunctionComponent<ComponentProps> = (
...props.initialValue,
incidentSeverityId:
props.incidentSeverityDropdownOptions.find(
(i) => {
(i: DropdownOption) => {
return (
i.value.toString() ===
props.initialValue?.incidentSeverityId?.toString()!

View File

@@ -327,9 +327,9 @@ const MonitorCriteriaInstanceElement: FunctionComponent<ComponentProps> = (
if (
(value &&
(!monitorCriteriaInstance.data?.incidents) ||
!monitorCriteriaInstance.data?.incidents) ||
monitorCriteriaInstance.data?.incidents?.length ===
0)
0
) {
monitorCriteriaInstance.setIncidents([
{
@@ -338,7 +338,8 @@ const MonitorCriteriaInstanceElement: FunctionComponent<ComponentProps> = (
incidentSeverityId: undefined,
},
]);
} if(!value) {
}
if (!value) {
monitorCriteriaInstance.setIncidents([]);
}

View File

@@ -30,29 +30,28 @@ const CriteriaFilterElement: FunctionComponent<ComponentProps> = (
props.criteriaFilter?.filterType &&
props.criteriaFilter?.checkOn !== CheckOn.IsOnline
) {
if(props.criteriaFilter?.filterType.toLowerCase().includes('contains')){
text += props.criteriaFilter?.filterType.toString().toLowerCase() +
' ';
}else{
if (
props.criteriaFilter?.filterType.toLowerCase().includes('contains')
) {
text +=
'is ' +
props.criteriaFilter?.filterType.toString().toLowerCase() +
' ';
props.criteriaFilter?.filterType.toString().toLowerCase() + ' ';
} else {
text +=
'is ' +
props.criteriaFilter?.filterType.toString().toLowerCase() +
' ';
}
}
if (props.criteriaFilter?.value !== undefined) {
text += props.criteriaFilter?.value.toString()+" ";
text += props.criteriaFilter?.value.toString() + ' ';
}
if(props.filterCondition === FilterCondition.All){
if (props.filterCondition === FilterCondition.All) {
text += 'and,';
}
if(props.filterCondition === FilterCondition.Any){
if (props.filterCondition === FilterCondition.Any) {
text += 'or,';
}

View File

@@ -1,4 +1,7 @@
import { CriteriaFilter, FilterCondition } from 'Common/Types/Monitor/CriteriaFilter';
import {
CriteriaFilter,
FilterCondition,
} from 'Common/Types/Monitor/CriteriaFilter';
import React, { FunctionComponent, ReactElement } from 'react';
import CriteriaFilterElement from './CriteriaFilter';
@@ -30,7 +33,11 @@ const CriteriaFilters: FunctionComponent<ComponentProps> = (
<CriteriaFilterElement
key={index}
criteriaFilter={i}
filterCondition={!isLastItem ? props.filterCondition : undefined}
filterCondition={
!isLastItem
? props.filterCondition
: undefined
}
/>{' '}
</li>
);

View File

@@ -57,73 +57,81 @@ const MonitorCriteriaInstanceElement: FunctionComponent<ComponentProps> = (
criteriaFilters={
props.monitorCriteriaInstance?.data?.filters || []
}
filterCondition={props.monitorCriteriaInstance?.data?.filterCondition || FilterCondition.Any}
filterCondition={
props.monitorCriteriaInstance?.data?.filterCondition ||
FilterCondition.Any
}
/>
</div>
{props.monitorCriteriaInstance.data?.monitorStatusId && <div className="mt-4">
<div className="flex">
<Icon
icon={IconProp.AltGlobe}
className="h-5 w-5 text-gray-900"
/>
<div className="ml-1 -mt-0.5 flex-auto py-0.5 text-sm leading-5 text-gray-500">
<span className="font-medium text-gray-900">
Change Monitor Status
</span>{' '}
when this criteria is met. Change monitor status to:
<div className="mt-3">
<Statusbubble
color={
(props.monitorStatusOptions.find(
(option: IncidentSeverity) => {
return (
option.id?.toString() ===
props.monitorCriteriaInstance.data?.monitorStatusId?.toString()
);
}
)?.color as Color) || Black
}
text={
(props.monitorStatusOptions.find(
(option: IncidentSeverity) => {
return (
option.id?.toString() ===
props.monitorCriteriaInstance.data?.monitorStatusId?.toString()
);
}
)?.name as string) || ''
}
/>
{props.monitorCriteriaInstance.data?.monitorStatusId && (
<div className="mt-4">
<div className="flex">
<Icon
icon={IconProp.AltGlobe}
className="h-5 w-5 text-gray-900"
/>
<div className="ml-1 -mt-0.5 flex-auto py-0.5 text-sm leading-5 text-gray-500">
<span className="font-medium text-gray-900">
Change Monitor Status
</span>{' '}
when this criteria is met. Change monitor status to:
<div className="mt-3">
<Statusbubble
color={
(props.monitorStatusOptions.find(
(option: IncidentSeverity) => {
return (
option.id?.toString() ===
props.monitorCriteriaInstance.data?.monitorStatusId?.toString()
);
}
)?.color as Color) || Black
}
text={
(props.monitorStatusOptions.find(
(option: IncidentSeverity) => {
return (
option.id?.toString() ===
props.monitorCriteriaInstance.data?.monitorStatusId?.toString()
);
}
)?.name as string) || ''
}
/>
</div>
</div>
</div>
</div>
</div>}
)}
{(props.monitorCriteriaInstance?.data?.incidents?.length || 0) > 0 && <div className="mt-4">
<div className="flex">
<Icon
icon={IconProp.Alert}
className="h-5 w-5 text-gray-900"
/>
<div className="ml-1 flex-auto py-0.5 text-sm leading-5 text-gray-500">
<span className="font-medium text-gray-900">
Create incident
</span>{' '}
when this criteria is met. These are the incident
details:{' '}
{(props.monitorCriteriaInstance?.data?.incidents?.length || 0) >
0 && (
<div className="mt-4">
<div className="flex">
<Icon
icon={IconProp.Alert}
className="h-5 w-5 text-gray-900"
/>
<div className="ml-1 flex-auto py-0.5 text-sm leading-5 text-gray-500">
<span className="font-medium text-gray-900">
Create incident
</span>{' '}
when this criteria is met. These are the incident
details:{' '}
</div>
</div>
<MonitorCriteriaIncidents
incidents={
props.monitorCriteriaInstance?.data?.incidents || []
}
incidentSeverityOptions={props.incidentSeverityOptions}
/>
</div>
<MonitorCriteriaIncidents
incidents={
props.monitorCriteriaInstance?.data?.incidents || []
}
incidentSeverityOptions={props.incidentSeverityOptions}
/>
</div>}
)}
<div className='mt-10'>
{!props.isLastCriteria && <HorizontalRule />}
<div className="mt-10">
{!props.isLastCriteria && <HorizontalRule />}
</div>
</div>
);

View File

@@ -127,12 +127,11 @@ const MonitorsTable: FunctionComponent<ComponentProps> = (
fieldType: FormFieldSchemaType.CustomComponent,
required: true,
customValidation: (values: FormValues<Monitor>) => {
const error = MonitorStepsType.getValidationError(
values.monitorSteps as MonitorStepsType,
values.monitorType as MonitorType
);
console.log(error);
const error: string | null =
MonitorStepsType.getValidationError(
values.monitorSteps as MonitorStepsType,
values.monitorType as MonitorType
);
return error;
},

View File

@@ -26,10 +26,7 @@ const ProbeElement: FunctionComponent<ComponentProps> = (
if (!probe) {
return (
<div className="flex">
<div className="bold">
No probe found.
</div>
<div className="bold">No probe found.</div>
</div>
);
}
@@ -47,20 +44,19 @@ const ProbeElement: FunctionComponent<ComponentProps> = (
/>
)}
{!props.probe?.iconFileId && (
<Icon icon={IconProp.Signal} className='text-gray-400 group-hover:text-gray-500 flex-shrink-0 -ml-0.5 mt-0.5 h-6 w-6'/>
<Icon
icon={IconProp.Signal}
className="text-gray-400 group-hover:text-gray-500 flex-shrink-0 -ml-0.5 mt-0.5 h-6 w-6"
/>
)}
</div>
<div className="mt-1 mr-1 ml-3">
<div>
<span
>{`${(probe['name']?.toString() as string) ||
''
}`}</span>{' '}
<span>{`${
(probe['name']?.toString() as string) || ''
}`}</span>{' '}
</div>
</div>
</div>
);
};

View File

@@ -25,9 +25,7 @@ import { DASHBOARD_API_URL } from 'CommonUI/src/Config';
const ProbePage: FunctionComponent<PageComponentProps> = (
_props: PageComponentProps
): ReactElement => {
const [showKeyModal, setShowKeyModal] =
useState<boolean>(false);
const [showKeyModal, setShowKeyModal] = useState<boolean>(false);
const [currentProbe, setCurrentProbe] = useState<JSONObject | null>(null);
@@ -56,10 +54,8 @@ const ProbePage: FunctionComponent<PageComponentProps> = (
]}
sideMenu={<DashboardSideMenu />}
>
<>
<ModelTable<Probe>
<ModelTable<Probe>
modelType={Probe}
id="probes-table"
name="Settings > Global Probes"
@@ -73,16 +69,14 @@ const ProbePage: FunctionComponent<PageComponentProps> = (
'Global Probes help you monitor external resources from different locations around the world.',
}}
fetchRequestOptions={{
overrideRequestUrl: URL.fromString(DASHBOARD_API_URL.toString()).addRoute('/probe/global-probes')
overrideRequestUrl: URL.fromString(
DASHBOARD_API_URL.toString()
).addRoute('/probe/global-probes'),
}}
noItemsMessage={'No probes found.'}
showRefreshButton={true}
showFilterButton={true}
columns={[
{
field: {
name: true,
@@ -91,9 +85,7 @@ const ProbePage: FunctionComponent<PageComponentProps> = (
type: FieldType.Text,
isFilterable: true,
getElement: (item: JSONObject): ReactElement => {
return (
<ProbeElement probe={item}/>
);
return <ProbeElement probe={item} />;
},
},
{
@@ -112,25 +104,40 @@ const ProbePage: FunctionComponent<PageComponentProps> = (
type: FieldType.Text,
isFilterable: false,
getElement: (item: JSONObject): ReactElement => {
if(item && item['lastAlive'] && OneUptimeDate.getNumberOfMinutesBetweenDates(OneUptimeDate.fromString(item['lastAlive'] as string), OneUptimeDate.getCurrentDate()) < 5){
return <Statusbubble text={'Connected'} color={Green}/>
if (
item &&
item['lastAlive'] &&
OneUptimeDate.getNumberOfMinutesBetweenDates(
OneUptimeDate.fromString(
item['lastAlive'] as string
),
OneUptimeDate.getCurrentDate()
) < 5
) {
return (
<Statusbubble
text={'Connected'}
color={Green}
/>
);
}
return (
<Statusbubble text={'Disconnected'} color={Red}/>
<Statusbubble
text={'Disconnected'}
color={Red}
/>
);
},
},
]}
/>
<ModelTable<Probe>
modelType={Probe}
query={{
projectId: DashboardNavigation.getProjectId()?.toString(),
projectId:
DashboardNavigation.getProjectId()?.toString(),
}}
id="probes-table"
name="Settings > Probes"
@@ -182,7 +189,6 @@ const ProbePage: FunctionComponent<PageComponentProps> = (
required: false,
placeholder: 'Upload logo',
},
]}
showRefreshButton={true}
showFilterButton={true}
@@ -208,7 +214,6 @@ const ProbePage: FunctionComponent<PageComponentProps> = (
},
]}
columns={[
{
field: {
name: true,
@@ -217,9 +222,7 @@ const ProbePage: FunctionComponent<PageComponentProps> = (
type: FieldType.Text,
isFilterable: true,
getElement: (item: JSONObject): ReactElement => {
return (
<ProbeElement probe={item}/>
);
return <ProbeElement probe={item} />;
},
},
{
@@ -238,41 +241,56 @@ const ProbePage: FunctionComponent<PageComponentProps> = (
type: FieldType.Text,
isFilterable: false,
getElement: (item: JSONObject): ReactElement => {
if(item && item['lastAlive'] && OneUptimeDate.getNumberOfMinutesBetweenDates(OneUptimeDate.fromString(item['lastAlive'] as string), OneUptimeDate.getCurrentDate()) < 5){
return <Statusbubble text={'Connected'} color={Green}/>
if (
item &&
item['lastAlive'] &&
OneUptimeDate.getNumberOfMinutesBetweenDates(
OneUptimeDate.fromString(
item['lastAlive'] as string
),
OneUptimeDate.getCurrentDate()
) < 5
) {
return (
<Statusbubble
text={'Connected'}
color={Green}
/>
);
}
return (
<Statusbubble text={'Disconnected'} color={Red}/>
<Statusbubble
text={'Disconnected'}
color={Red}
/>
);
},
},
]}
/>
{showKeyModal && currentProbe ? (
<ConfirmModal
title={`Probe Key`}
description={
<div>
<span>
Here is your probe key. Please keep this a secret.
Here is your probe key. Please keep this a
secret.
</span>
<br />
<br />
<span>
<b>Probe ID: </b> {currentProbe['_id']?.toString()}
<b>Probe ID: </b>{' '}
{currentProbe['_id']?.toString()}
</span>
<br />
<br />
<span>
<b>Probe Key: </b> {currentProbe['key']?.toString()}
<b>Probe Key: </b>{' '}
{currentProbe['key']?.toString()}
</span>
</div>
}
submitButtonText={'Close'}
@@ -285,7 +303,6 @@ const ProbePage: FunctionComponent<PageComponentProps> = (
<></>
)}
</>
</Page>
);
};

View File

@@ -69,7 +69,7 @@ const DashboardSideMenu: FunctionComponent = (): ReactElement => {
title: 'Custom Fields',
to: RouteUtil.populateRouteParams(
RouteMap[
PageMap.SETTINGS_MONITOR_CUSTOM_FIELDS
PageMap.SETTINGS_MONITOR_CUSTOM_FIELDS
] as Route
),
}}
@@ -82,7 +82,7 @@ const DashboardSideMenu: FunctionComponent = (): ReactElement => {
title: 'Custom Fields',
to: RouteUtil.populateRouteParams(
RouteMap[
PageMap.SETTINGS_STATUS_PAGE_CUSTOM_FIELDS
PageMap.SETTINGS_STATUS_PAGE_CUSTOM_FIELDS
] as Route
),
}}
@@ -104,7 +104,7 @@ const DashboardSideMenu: FunctionComponent = (): ReactElement => {
title: 'Incident Severity',
to: RouteUtil.populateRouteParams(
RouteMap[
PageMap.SETTINGS_INCIDENTS_SEVERITY
PageMap.SETTINGS_INCIDENTS_SEVERITY
] as Route
),
}}
@@ -115,7 +115,7 @@ const DashboardSideMenu: FunctionComponent = (): ReactElement => {
title: 'Custom Fields',
to: RouteUtil.populateRouteParams(
RouteMap[
PageMap.SETTINGS_INCIDENT_CUSTOM_FIELDS
PageMap.SETTINGS_INCIDENT_CUSTOM_FIELDS
] as Route
),
}}
@@ -135,7 +135,7 @@ const DashboardSideMenu: FunctionComponent = (): ReactElement => {
title: 'Event State',
to: RouteUtil.populateRouteParams(
RouteMap[
PageMap.SETTINGS_SCHEDULED_MAINTENANCE_STATE
PageMap.SETTINGS_SCHEDULED_MAINTENANCE_STATE
] as Route
),
}}
@@ -146,8 +146,8 @@ const DashboardSideMenu: FunctionComponent = (): ReactElement => {
title: 'Custom Fields',
to: RouteUtil.populateRouteParams(
RouteMap[
PageMap
.SETTINGS_SCHEDULED_MAINTENANCE_CUSTOM_FIELDS
PageMap
.SETTINGS_SCHEDULED_MAINTENANCE_CUSTOM_FIELDS
] as Route
),
}}
@@ -229,7 +229,7 @@ const DashboardSideMenu: FunctionComponent = (): ReactElement => {
title: 'Invoices',
to: RouteUtil.populateRouteParams(
RouteMap[
PageMap.SETTINGS_BILLING_INVOICES
PageMap.SETTINGS_BILLING_INVOICES
] as Route
),
}}

View File

@@ -45,7 +45,6 @@ import WorkflowVariableService, {
Service as WorkflowVariableServiceType,
} from 'CommonServer/Services/WorkflowVariableService';
import MonitorProbe from 'Model/Models/MonitorProbe';
import MonitorProbeService, {
Service as MonitorProbeServiceType,
@@ -252,13 +251,14 @@ app.use(
).getRouter()
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<MonitorProbe, MonitorProbeServiceType>(MonitorProbe, MonitorProbeService).getRouter()
new BaseAPI<MonitorProbe, MonitorProbeServiceType>(
MonitorProbe,
MonitorProbeService
).getRouter()
);
app.use(
`/${APP_NAME.toLocaleLowerCase()}`,
new BaseAPI<StatusPageAnnouncement, StatusPageAnnouncementServiceType>(

View File

@@ -129,7 +129,6 @@ export default class MonitorProbe extends AccessControlModel {
})
public projectId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
Permission.ProjectOwner,
@@ -149,8 +148,7 @@ export default class MonitorProbe extends AccessControlModel {
type: TableColumnType.Entity,
modelType: Probe,
title: 'Probe',
description:
'Relation to Probe Resource in which this object belongs',
description: 'Relation to Probe Resource in which this object belongs',
})
@ManyToOne(
(_type: string) => {
@@ -186,8 +184,7 @@ export default class MonitorProbe extends AccessControlModel {
required: true,
canReadOnPopulate: true,
title: 'Probe ID',
description:
'ID of your OneUptime Probe in which this object belongs',
description: 'ID of your OneUptime Probe in which this object belongs',
})
@Column({
type: ColumnType.ObjectID,
@@ -264,10 +261,12 @@ export default class MonitorProbe extends AccessControlModel {
@ColumnAccessControl({
create: [],
read: [Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CanReadMonitorProbe,],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CanReadMonitorProbe,
],
update: [],
})
@@ -281,10 +280,12 @@ export default class MonitorProbe extends AccessControlModel {
@ColumnAccessControl({
create: [],
read: [Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CanReadMonitorProbe],
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CanReadMonitorProbe,
],
update: [],
})
@TableColumn({ type: TableColumnType.Date })
@@ -430,7 +431,7 @@ export default class MonitorProbe extends AccessControlModel {
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CanEditMonitorProbe,
]
],
})
@TableColumn({
isDefaultValueColumn: true,
@@ -444,5 +445,4 @@ export default class MonitorProbe extends AccessControlModel {
default: true,
})
public isEnabled?: boolean = undefined;
}

View File

@@ -64,9 +64,7 @@ export default class Probe extends BaseModel {
Permission.ProjectMember,
Permission.CanCreateProjectProbe,
],
read: [Permission.ProjectOwner,
Permission.ProjectAdmin,
],
read: [Permission.ProjectOwner, Permission.ProjectAdmin],
update: [],
})
@TableColumn({
@@ -181,10 +179,12 @@ export default class Probe extends BaseModel {
Permission.ProjectMember,
Permission.CanCreateProjectProbe,
],
read: [Permission.ProjectOwner,
read: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.CanReadProjectProbe],
Permission.CanReadProjectProbe,
],
update: [],
})
@TableColumn({
@@ -410,17 +410,10 @@ export default class Probe extends BaseModel {
})
public createdByUserId?: ObjectID = undefined;
@ColumnAccessControl({
create: [
],
read: [
],
update: [
]
create: [],
read: [],
update: [],
})
@TableColumn({
isDefaultValueColumn: true,

View File

@@ -8,7 +8,6 @@ const init: Function = async (): Promise<void> => {
try {
// init the app
await App(APP_NAME);
} catch (err) {
logger.error('App Init Failed:');
logger.error(err);

View File

@@ -1,4 +1,3 @@
import Express, {
ExpressRequest,
ExpressResponse,
@@ -10,6 +9,8 @@ import Response from 'CommonServer/Utils/Response';
import BadDataException from 'Common/Types/Exception/BadDataException';
import ProbeService from 'CommonServer/Services/ProbeService';
import OneUptimeDate from 'Common/Types/Date';
import { JSONObject } from 'Common/Types/JSON';
import Probe from 'Model/Models/Probe';
const router: ExpressRouter = Express.getRouter();
@@ -21,52 +22,56 @@ router.post(
next: NextFunction
): Promise<void> => {
try {
const data = req.body;
const data: JSONObject = req.body;
if(!data.probeId || !data.probeKey) {
return Response.sendErrorResponse(req, res, new BadDataException("ProbeId or ProbeKey is missing"));
if (!data['probeId'] || !data['probeKey']) {
return Response.sendErrorResponse(
req,
res,
new BadDataException('ProbeId or ProbeKey is missing')
);
}
const probeId = new ObjectID(data.probeId);
const probeId: ObjectID = new ObjectID(data['probeId'] as string);
const probeKey = new ObjectID(data.probeKey);
const probeKey: string = data['probeKey'] as string;
const probe = await ProbeService.findOneBy({
const probe: Probe | null = await ProbeService.findOneBy({
query: {
_id: probeId.toString(),
key: probeKey
},
key: probeKey,
},
select: {
_id: true,
_id: true,
},
props: {
isRoot: true,
}
})
isRoot: true,
},
});
if(!probe){
return Response.sendErrorResponse(req, res, new BadDataException("Invalid Probe ID or Probe Key"));
if (!probe) {
return Response.sendErrorResponse(
req,
res,
new BadDataException('Invalid Probe ID or Probe Key')
);
}
await ProbeService.updateOneById({
id: probeId,
data: {
lastAlive: OneUptimeDate.getCurrentDate()
lastAlive: OneUptimeDate.getCurrentDate(),
},
props: {
isRoot: true
}
isRoot: true,
},
});
return Response.sendEmptyResponse(req, res);
} catch (err) {
return next(err);
}
}
);
export default router;

View File

@@ -1,4 +1,3 @@
import Express, {
ExpressRequest,
ExpressResponse,
@@ -10,11 +9,12 @@ import BadDataException from 'Common/Types/Exception/BadDataException';
import ProbeService from 'CommonServer/Services/ProbeService';
import OneUptimeDate from 'Common/Types/Date';
import ClusterKeyAuthorization from 'CommonServer/Middleware/ClusterKeyAuthorization';
import Probe from "Model/Models/Probe";
import Probe from 'Model/Models/Probe';
import { JSONObject } from 'Common/Types/JSON';
const router: ExpressRouter = Express.getRouter();
// Register Global Probe. Custom Probe can be registered via dashboard.
// Register Global Probe. Custom Probe can be registered via dashboard.
router.post(
'/register',
ClusterKeyAuthorization.isAuthorizedServiceMiddleware,
@@ -24,56 +24,59 @@ router.post(
next: NextFunction
): Promise<void> => {
try {
const data = req.body;
const data: JSONObject = req.body;
if(!data.probeKey) {
return Response.sendErrorResponse(req, res, new BadDataException("ProbeId or ProbeKey is missing"));
if (!data['probeKey']) {
return Response.sendErrorResponse(
req,
res,
new BadDataException('ProbeId or ProbeKey is missing')
);
}
const probeKey = data.probeKey;
const probeKey: string = data['probeKey'] as string;
const probe: Probe | null = await ProbeService.findOneBy({
query: {
key: probeKey,
isGlobalProbe: true
},
isGlobalProbe: true,
},
select: {
_id: true,
_id: true,
},
props: {
isRoot: true,
}
})
isRoot: true,
},
});
if(probe){
return Response.sendTextResponse(req, res, "Probe already registered");
if (probe) {
return Response.sendTextResponse(
req,
res,
'Probe already registered'
);
}
let newProbe: Probe = new Probe();
newProbe.isGlobalProbe = true;
newProbe.isGlobalProbe = true;
newProbe.key = probeKey;
newProbe.lastAlive = OneUptimeDate.getCurrentDate();
newProbe = await ProbeService.create({
data: newProbe,
props: {
isRoot: true
}
isRoot: true,
},
});
return Response.sendJsonObjectResponse(req, res, {
_id: newProbe._id?.toString(),
"message": "Probe registered successfully"
message: 'Probe registered successfully',
});
} catch (err) {
return next(err);
}
}
);
export default router;