@oneuptime/common 7.0.2972 → 7.0.2976
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/StatusPage.ts +71 -0
- package/Models/DatabaseModels/StatusPageResource.ts +1 -7
- package/Server/API/StatusPageAPI.ts +2 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1723825511054-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1723828588502-MigrationName.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Services/StatusPageService.ts +11 -3
- package/Types/Domain.ts +1 -1
- package/Types/Monitor/MonitorSteps.ts +1 -1
- package/Types/StatusPage/UptimePrecision.ts +8 -0
- package/UI/Components/Alerts/Alert.tsx +18 -7
- package/UI/Components/Link/Link.tsx +14 -0
- package/Utils/Uptime/UptimeUtil.ts +119 -6
- package/build/dist/Models/DatabaseModels/StatusPage.js +75 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageResource.js +1 -7
- package/build/dist/Models/DatabaseModels/StatusPageResource.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +2 -0
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1723825511054-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1723825511054-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1723828588502-MigrationName.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1723828588502-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +6 -1
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Types/Domain.js +1 -1
- package/build/dist/Types/Domain.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorSteps.js +1 -1
- package/build/dist/Types/Monitor/MonitorSteps.js.map +1 -1
- package/build/dist/Types/StatusPage/UptimePrecision.js +9 -0
- package/build/dist/Types/StatusPage/UptimePrecision.js.map +1 -0
- package/build/dist/UI/Components/Alerts/Alert.js +11 -8
- package/build/dist/UI/Components/Alerts/Alert.js.map +1 -1
- package/build/dist/UI/Components/Link/Link.js +13 -1
- package/build/dist/UI/Components/Link/Link.js.map +1 -1
- package/build/dist/Utils/Uptime/UptimeUtil.js +72 -5
- package/build/dist/Utils/Uptime/UptimeUtil.js.map +1 -1
- package/package.json +2 -2
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
ManyToMany,
|
|
40
40
|
ManyToOne,
|
|
41
41
|
} from "typeorm";
|
|
42
|
+
import UptimePrecision from "../../Types/StatusPage/UptimePrecision";
|
|
42
43
|
|
|
43
44
|
@EnableDocumentation()
|
|
44
45
|
@AccessControlColumn("labels")
|
|
@@ -1864,4 +1865,74 @@ export default class StatusPage extends BaseModel {
|
|
|
1864
1865
|
create: PlanType.Free,
|
|
1865
1866
|
})
|
|
1866
1867
|
public reportDataInDays?: number = undefined;
|
|
1868
|
+
|
|
1869
|
+
@ColumnAccessControl({
|
|
1870
|
+
create: [
|
|
1871
|
+
Permission.ProjectOwner,
|
|
1872
|
+
Permission.ProjectAdmin,
|
|
1873
|
+
Permission.ProjectMember,
|
|
1874
|
+
Permission.CreateProjectStatusPage,
|
|
1875
|
+
],
|
|
1876
|
+
read: [
|
|
1877
|
+
Permission.ProjectOwner,
|
|
1878
|
+
Permission.ProjectAdmin,
|
|
1879
|
+
Permission.ProjectMember,
|
|
1880
|
+
Permission.ReadProjectStatusPage,
|
|
1881
|
+
],
|
|
1882
|
+
update: [
|
|
1883
|
+
Permission.ProjectOwner,
|
|
1884
|
+
Permission.ProjectAdmin,
|
|
1885
|
+
Permission.ProjectMember,
|
|
1886
|
+
Permission.EditProjectStatusPage,
|
|
1887
|
+
],
|
|
1888
|
+
})
|
|
1889
|
+
@TableColumn({
|
|
1890
|
+
isDefaultValueColumn: true,
|
|
1891
|
+
type: TableColumnType.Boolean,
|
|
1892
|
+
title: "Show Overall Uptime Percent on Status Page",
|
|
1893
|
+
description: "Show Overall Uptime Percent on Status Page?",
|
|
1894
|
+
})
|
|
1895
|
+
@Column({
|
|
1896
|
+
type: ColumnType.Boolean,
|
|
1897
|
+
default: false,
|
|
1898
|
+
})
|
|
1899
|
+
@ColumnBillingAccessControl({
|
|
1900
|
+
read: PlanType.Free,
|
|
1901
|
+
update: PlanType.Scale,
|
|
1902
|
+
create: PlanType.Free,
|
|
1903
|
+
})
|
|
1904
|
+
public showOverallUptimePercentOnStatusPage?: boolean = undefined;
|
|
1905
|
+
|
|
1906
|
+
@ColumnAccessControl({
|
|
1907
|
+
create: [
|
|
1908
|
+
Permission.ProjectOwner,
|
|
1909
|
+
Permission.ProjectAdmin,
|
|
1910
|
+
Permission.ProjectMember,
|
|
1911
|
+
Permission.CreateProjectStatusPage,
|
|
1912
|
+
],
|
|
1913
|
+
read: [
|
|
1914
|
+
Permission.ProjectOwner,
|
|
1915
|
+
Permission.ProjectAdmin,
|
|
1916
|
+
Permission.ProjectMember,
|
|
1917
|
+
Permission.ReadProjectStatusPage,
|
|
1918
|
+
],
|
|
1919
|
+
update: [
|
|
1920
|
+
Permission.ProjectOwner,
|
|
1921
|
+
Permission.ProjectAdmin,
|
|
1922
|
+
Permission.ProjectMember,
|
|
1923
|
+
Permission.EditProjectStatusPage,
|
|
1924
|
+
],
|
|
1925
|
+
})
|
|
1926
|
+
@TableColumn({
|
|
1927
|
+
type: TableColumnType.ShortText,
|
|
1928
|
+
title: "Overall Uptime Percent Precision",
|
|
1929
|
+
required: false,
|
|
1930
|
+
description: "Overall Precision of uptime percent for this status page.",
|
|
1931
|
+
})
|
|
1932
|
+
@Column({
|
|
1933
|
+
type: ColumnType.ShortText,
|
|
1934
|
+
nullable: true,
|
|
1935
|
+
default: UptimePrecision.TWO_DECIMAL,
|
|
1936
|
+
})
|
|
1937
|
+
public overallUptimePercentPrecision?: UptimePrecision = undefined;
|
|
1867
1938
|
}
|
|
@@ -23,13 +23,7 @@ import IconProp from "../../Types/Icon/IconProp";
|
|
|
23
23
|
import ObjectID from "../../Types/ObjectID";
|
|
24
24
|
import Permission from "../../Types/Permission";
|
|
25
25
|
import { Column, Entity, Index, JoinColumn, ManyToOne } from "typeorm";
|
|
26
|
-
|
|
27
|
-
export enum UptimePrecision {
|
|
28
|
-
NO_DECIMAL = "99% (No Decimal)",
|
|
29
|
-
ONE_DECIMAL = "99.9% (One Decimal)",
|
|
30
|
-
TWO_DECIMAL = "99.99% (Two Decimal)",
|
|
31
|
-
THREE_DECIMAL = "99.999% (Three Decimal)",
|
|
32
|
-
}
|
|
26
|
+
import UptimePrecision from "../../Types/StatusPage/UptimePrecision";
|
|
33
27
|
|
|
34
28
|
@EnableDocumentation()
|
|
35
29
|
@CanAccessIfCanReadOn("statusPage")
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1723825511054 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1723825511054";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`ALTER TABLE "StatusPage" ADD "showOverallUptimePercentOnStatusPage" boolean NOT NULL DEFAULT false`,
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`ALTER TABLE "StatusPage" DROP COLUMN "showOverallUptimePercentOnStatusPage"`,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1723828588502 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1723828588502";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`ALTER TABLE "StatusPage" ADD "overallUptimePercentPrecision" character varying DEFAULT '99.99% (Two Decimal)'`,
|
|
9
|
+
);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`ALTER TABLE "StatusPage" DROP COLUMN "overallUptimePercentPrecision"`,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -38,6 +38,8 @@ import { MigrationName1721779190475 } from "./1721779190475-MigrationName";
|
|
|
38
38
|
import { MigrationName1722031205897 } from "./1722031205897-MigrationName";
|
|
39
39
|
import { MigrationName1722543640526 } from "./1722543640526-MigrationName";
|
|
40
40
|
import { MigrationName1722892318363 } from "./1722892318363-MigrationName";
|
|
41
|
+
import { MigrationName1723825511054 } from "./1723825511054-MigrationName";
|
|
42
|
+
import { MigrationName1723828588502 } from "./1723828588502-MigrationName";
|
|
41
43
|
|
|
42
44
|
export default [
|
|
43
45
|
InitialMigration,
|
|
@@ -80,4 +82,6 @@ export default [
|
|
|
80
82
|
MigrationName1722031205897,
|
|
81
83
|
MigrationName1722543640526,
|
|
82
84
|
MigrationName1722892318363,
|
|
85
|
+
MigrationName1723825511054,
|
|
86
|
+
MigrationName1723828588502,
|
|
83
87
|
];
|
|
@@ -43,9 +43,7 @@ import MailService from "./MailService";
|
|
|
43
43
|
import EmailTemplateType from "../../Types/Email/EmailTemplateType";
|
|
44
44
|
import { FileRoute } from "Common/ServiceRoute";
|
|
45
45
|
import ProjectSMTPConfigService from "./ProjectSmtpConfigService";
|
|
46
|
-
import StatusPageResource
|
|
47
|
-
UptimePrecision,
|
|
48
|
-
} from "Common/Models/DatabaseModels/StatusPageResource";
|
|
46
|
+
import StatusPageResource from "Common/Models/DatabaseModels/StatusPageResource";
|
|
49
47
|
import StatusPageResourceService from "./StatusPageResourceService";
|
|
50
48
|
import Dictionary from "../../Types/Dictionary";
|
|
51
49
|
import MonitorGroupResource from "Common/Models/DatabaseModels/MonitorGroupResource";
|
|
@@ -57,6 +55,7 @@ import MonitorStatusTimeline from "Common/Models/DatabaseModels/MonitorStatusTim
|
|
|
57
55
|
import MonitorStatusTimelineService from "./MonitorStatusTimelineService";
|
|
58
56
|
import SortOrder from "../../Types/BaseDatabase/SortOrder";
|
|
59
57
|
import UptimeUtil from "Common/Utils/Uptime/UptimeUtil";
|
|
58
|
+
import UptimePrecision from "../../Types/StatusPage/UptimePrecision";
|
|
60
59
|
|
|
61
60
|
export interface StatusPageReportItem {
|
|
62
61
|
resourceName: string;
|
|
@@ -67,6 +66,7 @@ export interface StatusPageReportItem {
|
|
|
67
66
|
}
|
|
68
67
|
|
|
69
68
|
export interface StatusPageReport {
|
|
69
|
+
reportDates: string; // start date and end date in string. e.g. "01 July 2021 - 14 July 2021"
|
|
70
70
|
totalResources: number;
|
|
71
71
|
totalIncidents: number;
|
|
72
72
|
averageUptimePercent: string;
|
|
@@ -755,8 +755,15 @@ export class Service extends DatabaseService<StatusPage> {
|
|
|
755
755
|
statusPageId: data.statusPageId,
|
|
756
756
|
});
|
|
757
757
|
|
|
758
|
+
const currentDate: Date = OneUptimeDate.getCurrentDate();
|
|
759
|
+
const startDate: Date = OneUptimeDate.getSomeDaysAgo(
|
|
760
|
+
data.historyDays || 14,
|
|
761
|
+
);
|
|
762
|
+
const startAndEndDate: string = `${OneUptimeDate.getDateAsLocalFormattedString(startDate, true)} - ${OneUptimeDate.getDateAsLocalFormattedString(currentDate, true)}`;
|
|
763
|
+
|
|
758
764
|
if (statusPageResources.length === 0) {
|
|
759
765
|
return {
|
|
766
|
+
reportDates: startAndEndDate,
|
|
760
767
|
totalResources: 0,
|
|
761
768
|
totalIncidents: 0,
|
|
762
769
|
averageUptimePercent: "0%",
|
|
@@ -854,6 +861,7 @@ export class Service extends DatabaseService<StatusPage> {
|
|
|
854
861
|
);
|
|
855
862
|
|
|
856
863
|
return {
|
|
864
|
+
reportDates: startAndEndDate,
|
|
857
865
|
totalResources: statusPageResources.length,
|
|
858
866
|
totalIncidents: incidentCount,
|
|
859
867
|
averageUptimePercent: avgUptimePercentString,
|
package/Types/Domain.ts
CHANGED
|
@@ -26,7 +26,7 @@ export default class Domain extends DatabaseProperty {
|
|
|
26
26
|
"|",
|
|
27
27
|
);
|
|
28
28
|
const secondTLDs: Array<string> =
|
|
29
|
-
"ac|academy|accountant|accountants|actor|adult|aero|ag|agency|ai|airforce|am|amsterdam|apartments|app|archi|army|art|asia|associates|at|attorney|au|auction|auto|autos|baby|band|bar|barcelona|bargains|basketball|bayern|be|beauty|beer|berlin|best|bet|bid|bike|bingo|bio|biz|biz.pl|black|blog|blue|boats|boston|boutique|broker|build|builders|business|buzz|bz|ca|cab|cafe|camera|camp|capital|car|cards|care|careers|cars|casa|cash|casino|catering|cc|center|ceo|ch|charity|chat|cheap|church|city|cl|claims|cleaning|clinic|clothing|cloud|club|cn|co|co.in|co.jp|co.kr|co.nz|co.uk|co.za|coach|codes|coffee|college|com|com.ag|com.au|com.br|com.bz|com.cn|com.co|com.es|com.ky|com.mx|com.pe|com.ph|com.pl|com.ru|com.tw|community|company|computer|condos|construction|consulting|contact|contractors|cooking|cool|country|coupons|courses|credit|creditcard|cricket|cruises|cymru|cz|dance|date|dating|de|deals|degree|delivery|democrat|dental|dentist|design|dev|diamonds|digital|direct|directory|discount|dk|doctor|dog|domains|download|earth|education|email|energy|engineer|engineering|enterprises|equipment|es|estate|eu|events|exchange|expert|exposed|express|fail|faith|family|fan|fans|farm|fashion|film|finance|financial|firm.in|fish|fishing|fit|fitness|flights|florist|fm|football|forsale|foundation|fr|fun|fund|furniture|futbol|fyi|gallery|games|garden|gay|gen.in|gg|gifts|gives|giving|glass|global|gmbh|gold|golf|graphics|gratis|green|gripe|group|gs|guide|guru|hair|haus|health|healthcare|hockey|holdings|holiday|homes|horse|hospital|host|house|idv.tw|immo|immobilien|in|inc|ind.in|industries|info|info.pl|ink|institute|insure|international|investments|io|irish|ist|istanbul|it|jetzt|jewelry|jobs|jp|kaufen|kids|kim|kitchen|kiwi|kr|ky|la|land|lat|law|lawyer|lease|legal|lgbt|life|lighting|limited|limo|live|llc|llp|loan|loans|london|love|ltd|ltda|luxury|maison|makeup|management|market|marketing|mba|me|me.uk|media|melbourne|memorial|men|menu|miami|mobi|moda|moe|money|monster|mortgage|motorcycles|movie|ms|music|mx|nagoya|name|navy|ne.kr|net|net.ag|net.au|net.br|net.bz|net.cn|net.co|net.in|net.ky|net.nz|net.pe|net.ph|net.pl|net.ru|network|news|ninja|nl|no|nom.co|nom.es|nom.pe|nrw|nyc|okinawa|one|onl|online|org|org.ag|org.au|org.cn|org.es|org.in|org.ky|org.nz|org.pe|org.ph|org.pl|org.ru|org.uk|organic|page|paris|partners|parts|party|pe|pet|ph|photography|photos|pictures|pink|pizza|pl|place|plumbing|plus|poker|porn|press|pro|productions|promo|properties|protection|pub|pw|quebec|quest|racing|re.kr|realestate|recipes|red|rehab|reise|reisen|rent|rentals|repair|report|republican|rest|restaurant|review|reviews|rich|rip|rocks|rodeo|rugby|run|ryukyu|sale|salon|sarl|school|schule|science|se|security|services|sex|sg|sh|shiksha|shoes|shop|shopping|show|singles|site|ski|skin|soccer|social|software|solar|solutions|space|storage|store|stream|studio|study|style|supplies|supply|support|surf|surgery|sydney|systems|tax|taxi|team|tech|technology|tel|tennis|theater|theatre|tickets|tienda|tips|tires|today|tokyo|tools|tours|town|toys|trade|trading|training|travel|tube|tv|tw|uk|university|uno|us|vacations|vc|vegas|ventures|vet|viajes|video|villas|vin|vip|vision|vodka|vote|voto|voyage|wales|watch|web|webcam|website|wedding|wiki|win|wine|work|works|world|ws|wtf|xxx|xyz|yachts|yoga|yokohama|zone|移动|dev|com|edu|gov|net|mil|org|nom|sch|sbs|caa|res|off|gob|int|tur|ip6|uri|urn|asn|act|nsw|qld|tas|vic|pro|biz|adm|adv|agr|arq|art|ato|bio|bmd|cim|cng|cnt|ecn|eco|emp|eng|esp|etc|eti|far|fnd|fot|fst|g12|ggf|imb|ind|inf|jor|jus|leg|lel|mat|med|mus|not|ntr|odo|ppg|psc|psi|qsl|rec|slg|srv|teo|tmp|trd|vet|zlg|web|ltd|sld|pol|fin|k12|lib|pri|aip|fie|eun|sci|prd|cci|pvt|mod|idv|rel|sex|gen|nic|abr|bas|cal|cam|emr|fvg|laz|lig|lom|mar|mol|pmn|pug|sar|sic|taa|tos|umb|vao|vda|ven|mie|北海道|和歌山|神奈川|鹿児島|ass|rep|tra|per|ngo|soc|grp|plc|its|air|and|bus|can|ddr|jfk|mad|nrw|nyc|ski|spy|tcm|ulm|usa|war|fhs|vgs|dep|eid|fet|fla|flå|gol|hof|hol|sel|vik|cri|iwi|ing|abo|fam|gok|gon|gop|gos|aid|atm|gsm|sos|elk|waw|est|aca|bar|cpa|jur|law|sec|plo|www|bir|cbg|jar|khv|msk|nov|nsk|ptz|rnd|spb|stv|tom|tsk|udm|vrn|cmw|kms|nkz|snz|pub|fhv|red|ens|nat|rns|rnu|bbs|tel|bel|kep|nhs|dni|fed|isa|nsn|gub|e12|tec|орг|обр|упр|alt|nis|jpn|mex|ath|iki|nid|gda|inc|za|ovh".split(
|
|
29
|
+
"ac|academy|accountant|accountants|actor|adult|aero|ag|agency|ai|airforce|am|amsterdam|apartments|app|archi|army|art|asia|associates|at|attorney|au|auction|auto|autos|baby|band|bar|barcelona|bargains|basketball|bayern|be|beauty|beer|berlin|best|bet|bid|bike|bingo|bio|biz|biz.pl|black|blog|blue|boats|boston|boutique|broker|build|builders|business|buzz|bz|ca|cab|cafe|camera|camp|capital|car|cards|care|careers|cars|casa|cash|casino|catering|cc|center|ceo|ch|charity|chat|cheap|church|city|cl|claims|cleaning|clinic|clothing|cloud|club|cn|co|co.in|co.jp|co.kr|co.nz|co.uk|co.za|coach|codes|coffee|college|com|com.ag|com.au|com.br|com.bz|com.cn|com.co|com.es|com.ky|com.mx|com.pe|com.ph|com.pl|com.ru|com.tw|community|company|computer|condos|construction|consulting|contact|contractors|cooking|cool|country|coupons|courses|credit|creditcard|cricket|cruises|cymru|cz|dance|date|dating|de|deals|degree|delivery|democrat|dental|dentist|design|dev|diamonds|digital|direct|directory|discount|dk|doctor|dog|domains|download|earth|education|email|energy|engineer|engineering|enterprises|equipment|es|estate|eu|events|exchange|expert|exposed|express|fail|faith|family|fan|fans|farm|fashion|film|finance|financial|firm.in|fish|fishing|fit|fitness|flights|florist|fm|football|forsale|foundation|fr|fun|fund|furniture|futbol|fyi|gallery|games|garden|gay|gen.in|gg|gifts|gives|giving|glass|global|gmbh|gold|golf|graphics|gratis|green|gripe|group|gs|guide|guru|hair|haus|health|healthcare|hockey|holdings|holiday|homes|horse|hospital|host|house|idv.tw|immo|immobilien|in|inc|ind.in|industries|info|info.pl|ink|institute|insure|international|investments|io|irish|ist|istanbul|it|jetzt|jewelry|jobs|jp|kaufen|kids|kim|kitchen|kiwi|kr|ky|la|land|lat|law|lawyer|lease|legal|lgbt|life|lighting|limited|limo|live|llc|llp|loan|loans|london|love|ltd|ltda|luxury|maison|makeup|management|market|marketing|mba|me|me.uk|media|melbourne|memorial|men|menu|miami|mobi|moda|moe|money|monster|mortgage|motorcycles|movie|ms|music|mx|nagoya|name|navy|ne.kr|net|net.ag|net.au|net.br|net.bz|net.cn|net.co|net.in|net.ky|net.nz|net.pe|net.ph|net.pl|net.ru|network|news|ninja|nl|no|nom.co|nom.es|nom.pe|nrw|nyc|okinawa|one|onl|online|org|org.ag|org.au|org.cn|org.es|org.in|org.ky|org.nz|org.pe|org.ph|org.pl|org.ru|org.uk|organic|page|paris|partners|parts|party|pe|pet|ph|photography|photos|pictures|pink|pizza|pl|place|plumbing|plus|poker|porn|press|pro|productions|promo|properties|protection|pub|pw|quebec|quest|racing|re.kr|realestate|recipes|red|rehab|reise|reisen|rent|rentals|repair|report|republican|rest|restaurant|review|reviews|rich|rip|rocks|rodeo|rugby|run|ryukyu|sale|salon|sarl|school|schule|science|se|security|services|sex|sg|sh|shiksha|shoes|shop|shopping|show|singles|site|ski|skin|soccer|social|software|solar|solutions|space|storage|store|stream|studio|study|style|supplies|supply|support|surf|surgery|sydney|systems|tax|taxi|team|tech|technology|tel|tennis|theater|theatre|tickets|tienda|tips|tires|today|tokyo|tools|tours|town|toys|trade|trading|training|travel|tube|tv|tw|uk|university|uno|us|vacations|vc|vegas|ventures|vet|viajes|video|villas|vin|vip|vision|vodka|vote|voto|voyage|wales|watch|web|webcam|website|wedding|wiki|win|wine|work|works|world|ws|wtf|xxx|xyz|yachts|yoga|yokohama|zone|移动|dev|com|edu|gov|net|mil|org|nom|sch|sbs|caa|res|off|gob|int|tur|ip6|uri|urn|asn|act|nsw|qld|tas|vic|pro|biz|adm|adv|agr|arq|art|ato|bio|bmd|cim|cng|cnt|ecn|eco|emp|eng|esp|etc|eti|far|fnd|fot|fst|g12|ggf|imb|ind|inf|jor|jus|leg|lel|mat|med|mus|not|ntr|odo|ppg|psc|psi|qsl|rec|slg|srv|teo|tmp|trd|vet|zlg|web|ltd|sld|pol|fin|k12|lib|pri|aip|fie|eun|sci|prd|cci|pvt|mod|idv|rel|sex|gen|nic|abr|bas|cal|cam|emr|fvg|laz|lig|lom|mar|mol|pmn|pug|sar|sic|taa|tos|umb|vao|vda|ven|mie|北海道|和歌山|神奈川|鹿児島|ass|rep|tra|per|ngo|soc|grp|plc|its|air|and|bus|can|ddr|jfk|mad|nrw|nyc|ski|spy|tcm|ulm|usa|war|fhs|vgs|dep|eid|fet|fla|flå|gol|hof|hol|sel|vik|cri|iwi|ing|abo|fam|gok|gon|gop|gos|aid|atm|gsm|sos|elk|waw|est|aca|bar|cpa|jur|law|sec|plo|www|bir|cbg|jar|khv|msk|nov|nsk|ptz|rnd|spb|stv|tom|tsk|udm|vrn|cmw|kms|nkz|snz|pub|fhv|red|ens|nat|rns|rnu|bbs|tel|bel|kep|nhs|dni|fed|isa|nsn|gub|e12|tec|орг|обр|упр|alt|nis|jpn|mex|ath|iki|nid|gda|inc|za|ovh|lol".split(
|
|
30
30
|
"|",
|
|
31
31
|
);
|
|
32
32
|
|
|
@@ -27,6 +27,7 @@ export interface ComponentProps {
|
|
|
27
27
|
className?: string | undefined;
|
|
28
28
|
color?: Color | undefined;
|
|
29
29
|
id?: string | undefined;
|
|
30
|
+
textOnRight?: string | undefined;
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
const Alert: FunctionComponent<ComponentProps> = (
|
|
@@ -93,14 +94,24 @@ const Alert: FunctionComponent<ComponentProps> = (
|
|
|
93
94
|
</div>
|
|
94
95
|
)}
|
|
95
96
|
<div
|
|
96
|
-
className={`ml-3 flex-1 md:flex md:justify-between ${props.className}`}
|
|
97
|
+
className={`ml-3 mr-3 flex-1 md:flex md:justify-between ${props.className}`}
|
|
97
98
|
>
|
|
98
|
-
<
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
99
|
+
<div
|
|
100
|
+
className={
|
|
101
|
+
props.textClassName ||
|
|
102
|
+
`text-sm flex justify-between ${className}-200`
|
|
103
|
+
}
|
|
104
|
+
>
|
|
105
|
+
<div>
|
|
106
|
+
<span className="font-medium">
|
|
107
|
+
{props.strongTitle}{" "}
|
|
108
|
+
{props.title && props.strongTitle ? "-" : ""}{" "}
|
|
109
|
+
</span>
|
|
110
|
+
{props.title}
|
|
111
|
+
</div>
|
|
112
|
+
{props.textOnRight && <div>{props.textOnRight}</div>}
|
|
113
|
+
</div>
|
|
114
|
+
|
|
104
115
|
{props.onClose && (
|
|
105
116
|
<p className="mt-3 text-sm md:mt-0 md:ml-6">
|
|
106
117
|
<button
|
|
@@ -48,6 +48,20 @@ const Link: FunctionComponent<ComponentProps> = (
|
|
|
48
48
|
onMouseOut={props.onMouseOut}
|
|
49
49
|
onMouseLeave={props.onMouseLeave}
|
|
50
50
|
style={props.style}
|
|
51
|
+
onAuxClick={(event: React.MouseEvent<HTMLAnchorElement>) => {
|
|
52
|
+
// middle click
|
|
53
|
+
if (event.button === 1) {
|
|
54
|
+
if (props.to) {
|
|
55
|
+
Navigation.navigate(props.to, {
|
|
56
|
+
openInNewTab: true,
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
if (props.onNavigateComplete) {
|
|
60
|
+
props.onNavigateComplete();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}}
|
|
51
65
|
onClick={() => {
|
|
52
66
|
if (props.onClick) {
|
|
53
67
|
props.onClick();
|
|
@@ -5,7 +5,9 @@ import OneUptimeDate from "../../Types/Date";
|
|
|
5
5
|
import ObjectID from "../../Types/ObjectID";
|
|
6
6
|
import MonitorStatus from "../../Models/DatabaseModels/MonitorStatus";
|
|
7
7
|
import MonitorStatusTimeline from "../../Models/DatabaseModels/MonitorStatusTimeline";
|
|
8
|
-
import
|
|
8
|
+
import StatusPageResource from "../../Models/DatabaseModels/StatusPageResource";
|
|
9
|
+
import Dictionary from "../../Types/Dictionary";
|
|
10
|
+
import UptimePrecision from "../../Types/StatusPage/UptimePrecision";
|
|
9
11
|
|
|
10
12
|
export default class UptimeUtil {
|
|
11
13
|
/**
|
|
@@ -221,14 +223,15 @@ export default class UptimeUtil {
|
|
|
221
223
|
}
|
|
222
224
|
|
|
223
225
|
public static getTotalDowntimeInSeconds(
|
|
224
|
-
|
|
226
|
+
monitorStatusTimelines: Array<MonitorStatusTimeline>,
|
|
225
227
|
downtimeMonitorStatuses: Array<MonitorStatus>,
|
|
226
228
|
): {
|
|
227
229
|
totalDowntimeInSeconds: number;
|
|
228
230
|
totalSecondsInTimePeriod: number;
|
|
229
231
|
} {
|
|
230
|
-
const monitorEvents: Array<Event> =
|
|
231
|
-
|
|
232
|
+
const monitorEvents: Array<Event> = this.getNonOverlappingMonitorEvents(
|
|
233
|
+
monitorStatusTimelines,
|
|
234
|
+
);
|
|
232
235
|
|
|
233
236
|
// sort these by start date,
|
|
234
237
|
monitorEvents.sort((a: Event, b: Event) => {
|
|
@@ -298,15 +301,125 @@ export default class UptimeUtil {
|
|
|
298
301
|
};
|
|
299
302
|
}
|
|
300
303
|
|
|
304
|
+
public static calculateAvgUptimePercentageOfAllResources(data: {
|
|
305
|
+
monitorStatusTimelines: Array<MonitorStatusTimeline>;
|
|
306
|
+
precision: UptimePrecision;
|
|
307
|
+
downtimeMonitorStatuses: Array<MonitorStatus>;
|
|
308
|
+
statusPageResources: Array<StatusPageResource>;
|
|
309
|
+
monitorsInGroup: Dictionary<Array<ObjectID>>;
|
|
310
|
+
}): number | null {
|
|
311
|
+
const showUptimePercentage: boolean = Boolean(
|
|
312
|
+
data.statusPageResources.find((item: StatusPageResource) => {
|
|
313
|
+
return item.showUptimePercent || item.showStatusHistoryChart;
|
|
314
|
+
}),
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
if (!showUptimePercentage) {
|
|
318
|
+
return null;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
const uptimePercentPerResource: Array<number> = [];
|
|
322
|
+
|
|
323
|
+
for (const resource of data.statusPageResources) {
|
|
324
|
+
if (!resource.showUptimePercent && !resource.showStatusHistoryChart) {
|
|
325
|
+
continue;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
let timelinesForThisResource: Array<MonitorStatusTimeline> = [];
|
|
329
|
+
|
|
330
|
+
if (resource.monitorGroupId) {
|
|
331
|
+
timelinesForThisResource = [...data.monitorStatusTimelines].filter(
|
|
332
|
+
(timeline: MonitorStatusTimeline) => {
|
|
333
|
+
const monitorsInThisGroup: Array<ObjectID> | undefined =
|
|
334
|
+
data.monitorsInGroup[resource.monitorGroupId?.toString() || ""];
|
|
335
|
+
|
|
336
|
+
if (!monitorsInThisGroup) {
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
return monitorsInThisGroup.find((monitorId: ObjectID) => {
|
|
341
|
+
return monitorId.toString() === timeline.monitorId?.toString();
|
|
342
|
+
});
|
|
343
|
+
},
|
|
344
|
+
);
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (resource.monitorId || resource.monitor?.id) {
|
|
348
|
+
const monitorId: ObjectID | null | undefined =
|
|
349
|
+
resource.monitorId || resource.monitor?.id;
|
|
350
|
+
|
|
351
|
+
if (!monitorId) {
|
|
352
|
+
// this should never happen.
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
timelinesForThisResource = [...data.monitorStatusTimelines].filter(
|
|
357
|
+
(timeline: MonitorStatusTimeline) => {
|
|
358
|
+
return (
|
|
359
|
+
timeline.monitorId?.toString() === resource.monitorId?.toString()
|
|
360
|
+
);
|
|
361
|
+
},
|
|
362
|
+
);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
const uptimePercent: number = this.calculateUptimePercentage(
|
|
366
|
+
timelinesForThisResource,
|
|
367
|
+
data.precision,
|
|
368
|
+
data.downtimeMonitorStatuses,
|
|
369
|
+
);
|
|
370
|
+
|
|
371
|
+
uptimePercentPerResource.push(uptimePercent);
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
// calculate avg
|
|
375
|
+
|
|
376
|
+
if (uptimePercentPerResource.length === 0) {
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
const averageUptimePercentage: number =
|
|
381
|
+
uptimePercentPerResource.reduce((a: number, b: number) => {
|
|
382
|
+
return a + b;
|
|
383
|
+
}) / uptimePercentPerResource.length;
|
|
384
|
+
|
|
385
|
+
//round this to precision.
|
|
386
|
+
|
|
387
|
+
if (data.precision === UptimePrecision.NO_DECIMAL) {
|
|
388
|
+
const percent: number = Math.round(averageUptimePercentage);
|
|
389
|
+
|
|
390
|
+
return percent;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
if (data.precision === UptimePrecision.ONE_DECIMAL) {
|
|
394
|
+
const percent: number = Math.round(averageUptimePercentage * 10) / 10;
|
|
395
|
+
return percent;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (data.precision === UptimePrecision.TWO_DECIMAL) {
|
|
399
|
+
const percent: number = Math.round(averageUptimePercentage * 100) / 100;
|
|
400
|
+
return percent;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
if (data.precision === UptimePrecision.THREE_DECIMAL) {
|
|
404
|
+
const percent: number = Math.round(averageUptimePercentage * 1000) / 1000;
|
|
405
|
+
return percent;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
return averageUptimePercentage;
|
|
409
|
+
}
|
|
410
|
+
|
|
301
411
|
public static calculateUptimePercentage(
|
|
302
|
-
|
|
412
|
+
monitorStatusTimelines: Array<MonitorStatusTimeline>,
|
|
303
413
|
precision: UptimePrecision,
|
|
304
414
|
downtimeMonitorStatuses: Array<MonitorStatus>,
|
|
305
415
|
): number {
|
|
306
416
|
// calculate percentage.
|
|
307
417
|
|
|
308
418
|
const { totalDowntimeInSeconds, totalSecondsInTimePeriod } =
|
|
309
|
-
this.getTotalDowntimeInSeconds(
|
|
419
|
+
this.getTotalDowntimeInSeconds(
|
|
420
|
+
monitorStatusTimelines,
|
|
421
|
+
downtimeMonitorStatuses,
|
|
422
|
+
);
|
|
310
423
|
|
|
311
424
|
if (totalSecondsInTimePeriod === 0) {
|
|
312
425
|
return 100;
|
|
@@ -38,6 +38,7 @@ import IconProp from "../../Types/Icon/IconProp";
|
|
|
38
38
|
import ObjectID from "../../Types/ObjectID";
|
|
39
39
|
import Permission from "../../Types/Permission";
|
|
40
40
|
import { Column, Entity, Index, JoinColumn, JoinTable, ManyToMany, ManyToOne, } from "typeorm";
|
|
41
|
+
import UptimePrecision from "../../Types/StatusPage/UptimePrecision";
|
|
41
42
|
let StatusPage = class StatusPage extends BaseModel {
|
|
42
43
|
constructor() {
|
|
43
44
|
super(...arguments);
|
|
@@ -94,6 +95,8 @@ let StatusPage = class StatusPage extends BaseModel {
|
|
|
94
95
|
this.reportRecurringInterval = undefined;
|
|
95
96
|
this.sendNextReportBy = undefined;
|
|
96
97
|
this.reportDataInDays = undefined;
|
|
98
|
+
this.showOverallUptimePercentOnStatusPage = undefined;
|
|
99
|
+
this.overallUptimePercentPrecision = undefined;
|
|
97
100
|
}
|
|
98
101
|
};
|
|
99
102
|
__decorate([
|
|
@@ -1874,6 +1877,78 @@ __decorate([
|
|
|
1874
1877
|
}),
|
|
1875
1878
|
__metadata("design:type", Number)
|
|
1876
1879
|
], StatusPage.prototype, "reportDataInDays", void 0);
|
|
1880
|
+
__decorate([
|
|
1881
|
+
ColumnAccessControl({
|
|
1882
|
+
create: [
|
|
1883
|
+
Permission.ProjectOwner,
|
|
1884
|
+
Permission.ProjectAdmin,
|
|
1885
|
+
Permission.ProjectMember,
|
|
1886
|
+
Permission.CreateProjectStatusPage,
|
|
1887
|
+
],
|
|
1888
|
+
read: [
|
|
1889
|
+
Permission.ProjectOwner,
|
|
1890
|
+
Permission.ProjectAdmin,
|
|
1891
|
+
Permission.ProjectMember,
|
|
1892
|
+
Permission.ReadProjectStatusPage,
|
|
1893
|
+
],
|
|
1894
|
+
update: [
|
|
1895
|
+
Permission.ProjectOwner,
|
|
1896
|
+
Permission.ProjectAdmin,
|
|
1897
|
+
Permission.ProjectMember,
|
|
1898
|
+
Permission.EditProjectStatusPage,
|
|
1899
|
+
],
|
|
1900
|
+
}),
|
|
1901
|
+
TableColumn({
|
|
1902
|
+
isDefaultValueColumn: true,
|
|
1903
|
+
type: TableColumnType.Boolean,
|
|
1904
|
+
title: "Show Overall Uptime Percent on Status Page",
|
|
1905
|
+
description: "Show Overall Uptime Percent on Status Page?",
|
|
1906
|
+
}),
|
|
1907
|
+
Column({
|
|
1908
|
+
type: ColumnType.Boolean,
|
|
1909
|
+
default: false,
|
|
1910
|
+
}),
|
|
1911
|
+
ColumnBillingAccessControl({
|
|
1912
|
+
read: PlanType.Free,
|
|
1913
|
+
update: PlanType.Scale,
|
|
1914
|
+
create: PlanType.Free,
|
|
1915
|
+
}),
|
|
1916
|
+
__metadata("design:type", Boolean)
|
|
1917
|
+
], StatusPage.prototype, "showOverallUptimePercentOnStatusPage", void 0);
|
|
1918
|
+
__decorate([
|
|
1919
|
+
ColumnAccessControl({
|
|
1920
|
+
create: [
|
|
1921
|
+
Permission.ProjectOwner,
|
|
1922
|
+
Permission.ProjectAdmin,
|
|
1923
|
+
Permission.ProjectMember,
|
|
1924
|
+
Permission.CreateProjectStatusPage,
|
|
1925
|
+
],
|
|
1926
|
+
read: [
|
|
1927
|
+
Permission.ProjectOwner,
|
|
1928
|
+
Permission.ProjectAdmin,
|
|
1929
|
+
Permission.ProjectMember,
|
|
1930
|
+
Permission.ReadProjectStatusPage,
|
|
1931
|
+
],
|
|
1932
|
+
update: [
|
|
1933
|
+
Permission.ProjectOwner,
|
|
1934
|
+
Permission.ProjectAdmin,
|
|
1935
|
+
Permission.ProjectMember,
|
|
1936
|
+
Permission.EditProjectStatusPage,
|
|
1937
|
+
],
|
|
1938
|
+
}),
|
|
1939
|
+
TableColumn({
|
|
1940
|
+
type: TableColumnType.ShortText,
|
|
1941
|
+
title: "Overall Uptime Percent Precision",
|
|
1942
|
+
required: false,
|
|
1943
|
+
description: "Overall Precision of uptime percent for this status page.",
|
|
1944
|
+
}),
|
|
1945
|
+
Column({
|
|
1946
|
+
type: ColumnType.ShortText,
|
|
1947
|
+
nullable: true,
|
|
1948
|
+
default: UptimePrecision.TWO_DECIMAL,
|
|
1949
|
+
}),
|
|
1950
|
+
__metadata("design:type", String)
|
|
1951
|
+
], StatusPage.prototype, "overallUptimePercentPrecision", void 0);
|
|
1877
1952
|
StatusPage = __decorate([
|
|
1878
1953
|
EnableDocumentation(),
|
|
1879
1954
|
AccessControlColumn("labels"),
|