@oneuptime/common 7.0.3567 → 7.0.3589

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.
Files changed (53) hide show
  1. package/Models/DatabaseModels/MonitorTest.ts +1 -0
  2. package/Models/DatabaseModels/StatusPageAnnouncement.ts +6 -1
  3. package/Server/Infrastructure/Postgres/SchemaMigrations/1737997557974-MigrationName.ts +17 -0
  4. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  5. package/Server/Services/AlertService.ts +106 -44
  6. package/Server/Services/IncidentService.ts +108 -44
  7. package/Server/Services/Index.ts +3 -0
  8. package/Server/Services/ScheduledMaintenanceService.ts +200 -19
  9. package/Types/Domain.ts +1 -1
  10. package/Types/Events/Recurring.ts +4 -0
  11. package/UI/Components/Forms/BasicForm.tsx +56 -2
  12. package/UI/Components/Forms/BasicModelForm.tsx +3 -0
  13. package/UI/Components/Forms/FormSummary.tsx +118 -0
  14. package/UI/Components/Forms/ModelForm.tsx +3 -1
  15. package/UI/Components/Forms/Types/Field.ts +2 -0
  16. package/UI/Components/Forms/Types/FormStep.ts +1 -0
  17. package/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.ts +84 -0
  18. package/UI/Components/ModelTable/BaseModelTable.tsx +3 -1
  19. package/UI/Components/ModelTable/ModelTable.tsx +1 -0
  20. package/build/dist/Models/DatabaseModels/MonitorTest.js +1 -0
  21. package/build/dist/Models/DatabaseModels/MonitorTest.js.map +1 -1
  22. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +6 -1
  23. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  24. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1737997557974-MigrationName.js +12 -0
  25. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1737997557974-MigrationName.js.map +1 -0
  26. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  27. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  28. package/build/dist/Server/Services/AlertService.js +85 -40
  29. package/build/dist/Server/Services/AlertService.js.map +1 -1
  30. package/build/dist/Server/Services/IncidentService.js +85 -40
  31. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  32. package/build/dist/Server/Services/Index.js +2 -0
  33. package/build/dist/Server/Services/Index.js.map +1 -1
  34. package/build/dist/Server/Services/ScheduledMaintenanceService.js +159 -16
  35. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  36. package/build/dist/Types/Domain.js +1 -1
  37. package/build/dist/Types/Domain.js.map +1 -1
  38. package/build/dist/Types/Events/Recurring.js +3 -0
  39. package/build/dist/Types/Events/Recurring.js.map +1 -1
  40. package/build/dist/UI/Components/Forms/BasicForm.js +51 -17
  41. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  42. package/build/dist/UI/Components/Forms/BasicModelForm.js +1 -1
  43. package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
  44. package/build/dist/UI/Components/Forms/FormSummary.js +64 -0
  45. package/build/dist/UI/Components/Forms/FormSummary.js.map +1 -0
  46. package/build/dist/UI/Components/Forms/ModelForm.js +1 -1
  47. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  48. package/build/dist/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.js +81 -0
  49. package/build/dist/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.js.map +1 -0
  50. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  51. package/build/dist/UI/Components/ModelTable/ModelTable.js +1 -0
  52. package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
  53. package/package.json +2 -2
@@ -442,6 +442,7 @@ export default class MonitorTest extends BaseModel {
442
442
  })
443
443
  public monitorStepProbeResponse?: MonitorStepProbeResponse = undefined;
444
444
 
445
+ @Index()
445
446
  @ColumnAccessControl({
446
447
  create: [
447
448
  Permission.ProjectOwner,
@@ -164,7 +164,12 @@ export default class StatusPageAnnouncement extends BaseModel {
164
164
  Permission.ProjectMember,
165
165
  Permission.ReadStatusPageAnnouncement,
166
166
  ],
167
- update: [],
167
+ update: [
168
+ Permission.ProjectOwner,
169
+ Permission.ProjectAdmin,
170
+ Permission.ProjectMember,
171
+ Permission.EditStatusPageAnnouncement,
172
+ ],
168
173
  })
169
174
  @TableColumn({
170
175
  required: false,
@@ -0,0 +1,17 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1737997557974 implements MigrationInterface {
4
+ public name = "MigrationName1737997557974";
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(
8
+ `CREATE INDEX "IDX_4d5e62631b2b63aaecb00950ef" ON "MonitorTest" ("isInQueue") `,
9
+ );
10
+ }
11
+
12
+ public async down(queryRunner: QueryRunner): Promise<void> {
13
+ await queryRunner.query(
14
+ `DROP INDEX "public"."IDX_4d5e62631b2b63aaecb00950ef"`,
15
+ );
16
+ }
17
+ }
@@ -98,6 +98,7 @@ import { MigrationName1736856662868 } from "./1736856662868-MigrationName";
98
98
  import { MigrationName1737141420441 } from "./1737141420441-MigrationName";
99
99
  import { MigrationName1737713529424 } from "./1737713529424-MigrationName";
100
100
  import { MigrationName1737715240684 } from "./1737715240684-MigrationName";
101
+ import { MigrationName1737997557974 } from "./1737997557974-MigrationName";
101
102
 
102
103
  export default [
103
104
  InitialMigration,
@@ -200,4 +201,5 @@ export default [
200
201
  MigrationName1737141420441,
201
202
  MigrationName1737713529424,
202
203
  MigrationName1737715240684,
204
+ MigrationName1737997557974,
203
205
  ];
@@ -41,6 +41,10 @@ import AlertMetricType from "../../Types/Alerts/AlertMetricType";
41
41
  import AlertFeedService from "./AlertFeedService";
42
42
  import { AlertFeedEventType } from "../../Models/DatabaseModels/AlertFeed";
43
43
  import { Gray500, Red500 } from "../../Types/BrandColors";
44
+ import Label from "../../Models/DatabaseModels/Label";
45
+ import LabelService from "./LabelService";
46
+ import AlertSeverity from "../../Models/DatabaseModels/AlertSeverity";
47
+ import AlertSeverityService from "./AlertSeverityService";
44
48
 
45
49
  export class Service extends DatabaseService<Model> {
46
50
  public constructor() {
@@ -492,74 +496,132 @@ ${createdItem.remediationNotes || "No remediation notes provided."}`,
492
496
 
493
497
  if (updatedItemIds.length > 0) {
494
498
  for (const alertId of updatedItemIds) {
499
+ let shouldAddAlertFeed: boolean = false;
500
+ let feedInfoInMarkdown: string = "**Alert was updated.**";
501
+
502
+ const createdByUserId: ObjectID | undefined | null =
503
+ onUpdate.updateBy.props.userId;
504
+
495
505
  if (onUpdate.updateBy.data.title) {
496
506
  // add alert feed.
497
- const createdByUserId: ObjectID | undefined | null =
498
- onUpdate.updateBy.props.userId;
499
507
 
500
- await AlertFeedService.createAlertFeed({
501
- alertId: alertId,
502
- projectId: onUpdate.updateBy.props.tenantId as ObjectID,
503
- alertFeedEventType: AlertFeedEventType.AlertUpdated,
504
- displayColor: Gray500,
505
- feedInfoInMarkdown: `**Alert title was updated.** Here's the new title.
506
-
508
+ feedInfoInMarkdown += `\n\n**Title**:
507
509
  ${onUpdate.updateBy.data.title || "No title provided."}
508
- `,
509
- userId: createdByUserId || undefined,
510
- });
510
+ `;
511
+ shouldAddAlertFeed = true;
511
512
  }
512
513
 
513
514
  if (onUpdate.updateBy.data.rootCause) {
514
- // add alert feed.
515
- const createdByUserId: ObjectID | undefined | null =
516
- onUpdate.updateBy.props.userId;
515
+ if (onUpdate.updateBy.data.title) {
516
+ // add alert feed.
517
517
 
518
- await AlertFeedService.createAlertFeed({
519
- alertId: alertId,
520
- projectId: onUpdate.updateBy.props.tenantId as ObjectID,
521
- alertFeedEventType: AlertFeedEventType.AlertUpdated,
522
- displayColor: Gray500,
523
- feedInfoInMarkdown: `**Alert root cause was updated.** Here's the new root cause.
524
-
518
+ feedInfoInMarkdown += `\n\n**Root Cause**:
525
519
  ${onUpdate.updateBy.data.rootCause || "No root cause provided."}
526
- `,
527
- userId: createdByUserId || undefined,
528
- });
520
+ `;
521
+ shouldAddAlertFeed = true;
522
+ }
529
523
  }
530
524
 
531
525
  if (onUpdate.updateBy.data.description) {
532
526
  // add alert feed.
533
- const createdByUserId: ObjectID | undefined | null =
534
- onUpdate.updateBy.props.userId;
535
527
 
536
- await AlertFeedService.createAlertFeed({
537
- alertId: alertId,
538
- projectId: onUpdate.updateBy.props.tenantId as ObjectID,
539
- alertFeedEventType: AlertFeedEventType.AlertUpdated,
540
- displayColor: Gray500,
541
- feedInfoInMarkdown: `**Alert description was updated.** Here's the new description.
542
-
543
- ${onUpdate.updateBy.data.description || "No description provided."}
544
- `,
545
- userId: createdByUserId || undefined,
546
- });
528
+ feedInfoInMarkdown += `\n\n**Alert Description**:
529
+ ${onUpdate.updateBy.data.description || "No description provided."}
530
+ `;
531
+ shouldAddAlertFeed = true;
547
532
  }
548
533
 
549
534
  if (onUpdate.updateBy.data.remediationNotes) {
550
535
  // add alert feed.
551
- const createdByUserId: ObjectID | undefined | null =
552
- onUpdate.updateBy.props.userId;
553
536
 
537
+ feedInfoInMarkdown += `\n\n**Remediation Notes**:
538
+ ${onUpdate.updateBy.data.remediationNotes || "No remediation notes provided."}
539
+ `;
540
+ shouldAddAlertFeed = true;
541
+ }
542
+
543
+ if (
544
+ onUpdate.updateBy.data.labels &&
545
+ onUpdate.updateBy.data.labels.length > 0 &&
546
+ Array.isArray(onUpdate.updateBy.data.labels)
547
+ ) {
548
+ const labelIds: Array<ObjectID> = (
549
+ onUpdate.updateBy.data.labels as any
550
+ )
551
+ .map((label: Label) => {
552
+ if (label._id) {
553
+ return new ObjectID(label._id?.toString());
554
+ }
555
+
556
+ return null;
557
+ })
558
+ .filter((labelId: ObjectID | null) => {
559
+ return labelId !== null;
560
+ });
561
+
562
+ const labels: Array<Label> = await LabelService.findBy({
563
+ query: {
564
+ _id: QueryHelper.any(labelIds),
565
+ },
566
+ select: {
567
+ name: true,
568
+ },
569
+ limit: LIMIT_PER_PROJECT,
570
+ skip: 0,
571
+ props: {
572
+ isRoot: true,
573
+ },
574
+ });
575
+
576
+ if (labels.length > 0) {
577
+ feedInfoInMarkdown += `\n\n**Labels**:
578
+
579
+ ${labels
580
+ .map((label: Label) => {
581
+ return `- ${label.name}`;
582
+ })
583
+ .join("\n")}
584
+ `;
585
+
586
+ shouldAddAlertFeed = true;
587
+ }
588
+ }
589
+
590
+ if (
591
+ onUpdate.updateBy.data.alertSeverity &&
592
+ (onUpdate.updateBy.data.alertSeverity as any)._id
593
+ ) {
594
+ const alertSeverity: AlertSeverity | null =
595
+ await AlertSeverityService.findOneBy({
596
+ query: {
597
+ _id: new ObjectID(
598
+ (onUpdate.updateBy.data.alertSeverity as any)?._id.toString(),
599
+ ),
600
+ },
601
+ select: {
602
+ name: true,
603
+ },
604
+ props: {
605
+ isRoot: true,
606
+ },
607
+ });
608
+
609
+ if (alertSeverity) {
610
+ feedInfoInMarkdown += `\n\n**Alert Severity**:
611
+ ${alertSeverity.name}
612
+ `;
613
+
614
+ shouldAddAlertFeed = true;
615
+ }
616
+ }
617
+
618
+ if (shouldAddAlertFeed) {
554
619
  await AlertFeedService.createAlertFeed({
555
620
  alertId: alertId,
556
621
  projectId: onUpdate.updateBy.props.tenantId as ObjectID,
557
622
  alertFeedEventType: AlertFeedEventType.AlertUpdated,
558
623
  displayColor: Gray500,
559
- feedInfoInMarkdown: `**Remediation notes were updated.** Here are the new notes.
560
-
561
- ${onUpdate.updateBy.data.remediationNotes || "No remediation notes provided."}
562
- `,
624
+ feedInfoInMarkdown: feedInfoInMarkdown,
563
625
  userId: createdByUserId || undefined,
564
626
  });
565
627
  }
@@ -50,6 +50,10 @@ import Semaphore, {
50
50
  import IncidentFeedService from "./IncidentFeedService";
51
51
  import { IncidentFeedEventType } from "../../Models/DatabaseModels/IncidentFeed";
52
52
  import { Gray500, Red500 } from "../../Types/BrandColors";
53
+ import Label from "../../Models/DatabaseModels/Label";
54
+ import LabelService from "./LabelService";
55
+ import IncidentSeverity from "../../Models/DatabaseModels/IncidentSeverity";
56
+ import IncidentSeverityService from "./IncidentSeverityService";
53
57
 
54
58
  export class Service extends DatabaseService<Model> {
55
59
  public constructor() {
@@ -644,74 +648,134 @@ ${createdItem.remediationNotes || "No remediation notes provided."}`,
644
648
 
645
649
  if (updatedItemIds.length > 0) {
646
650
  for (const incidentId of updatedItemIds) {
651
+ let shouldAddIncidentFeed: boolean = false;
652
+ let feedInfoInMarkdown: string = "**Incident was updated.**";
653
+
654
+ const createdByUserId: ObjectID | undefined | null =
655
+ onUpdate.updateBy.props.userId;
656
+
647
657
  if (onUpdate.updateBy.data.title) {
648
658
  // add incident feed.
649
- const createdByUserId: ObjectID | undefined | null =
650
- onUpdate.updateBy.props.userId;
651
-
652
- await IncidentFeedService.createIncidentFeed({
653
- incidentId: incidentId,
654
- projectId: onUpdate.updateBy.props.tenantId as ObjectID,
655
- incidentFeedEventType: IncidentFeedEventType.IncidentUpdated,
656
- displayColor: Gray500,
657
- feedInfoInMarkdown: `**Incident title was updated.** Here's the new title.
658
659
 
660
+ feedInfoInMarkdown += `\n\n**Title**:
659
661
  ${onUpdate.updateBy.data.title || "No title provided."}
660
- `,
661
- userId: createdByUserId || undefined,
662
- });
662
+ `;
663
+ shouldAddIncidentFeed = true;
663
664
  }
664
665
 
665
666
  if (onUpdate.updateBy.data.rootCause) {
666
- // add incident feed.
667
- const createdByUserId: ObjectID | undefined | null =
668
- onUpdate.updateBy.props.userId;
667
+ if (onUpdate.updateBy.data.title) {
668
+ // add incident feed.
669
669
 
670
- await IncidentFeedService.createIncidentFeed({
671
- incidentId: incidentId,
672
- projectId: onUpdate.updateBy.props.tenantId as ObjectID,
673
- incidentFeedEventType: IncidentFeedEventType.IncidentUpdated,
674
- displayColor: Gray500,
675
- feedInfoInMarkdown: `**Incident root cause was updated.** Here's the new root cause.
676
-
670
+ feedInfoInMarkdown += `\n\n**Root Cause**:
677
671
  ${onUpdate.updateBy.data.rootCause || "No root cause provided."}
678
- `,
679
- userId: createdByUserId || undefined,
680
- });
672
+ `;
673
+ shouldAddIncidentFeed = true;
674
+ }
681
675
  }
682
676
 
683
677
  if (onUpdate.updateBy.data.description) {
684
678
  // add incident feed.
685
- const createdByUserId: ObjectID | undefined | null =
686
- onUpdate.updateBy.props.userId;
687
679
 
688
- await IncidentFeedService.createIncidentFeed({
689
- incidentId: incidentId,
690
- projectId: onUpdate.updateBy.props.tenantId as ObjectID,
691
- incidentFeedEventType: IncidentFeedEventType.IncidentUpdated,
692
- displayColor: Gray500,
693
- feedInfoInMarkdown: `**Incident description was updated.** Here's the new description.
694
-
695
- ${onUpdate.updateBy.data.description || "No description provided."}
696
- `,
697
- userId: createdByUserId || undefined,
698
- });
680
+ feedInfoInMarkdown += `\n\n**Incident Description**:
681
+ ${onUpdate.updateBy.data.description || "No description provided."}
682
+ `;
683
+ shouldAddIncidentFeed = true;
699
684
  }
700
685
 
701
686
  if (onUpdate.updateBy.data.remediationNotes) {
702
687
  // add incident feed.
703
- const createdByUserId: ObjectID | undefined | null =
704
- onUpdate.updateBy.props.userId;
705
688
 
689
+ feedInfoInMarkdown += `\n\n**Remediation Notes**:
690
+ ${onUpdate.updateBy.data.remediationNotes || "No remediation notes provided."}
691
+ `;
692
+ shouldAddIncidentFeed = true;
693
+ }
694
+
695
+ if (
696
+ onUpdate.updateBy.data.labels &&
697
+ onUpdate.updateBy.data.labels.length > 0 &&
698
+ Array.isArray(onUpdate.updateBy.data.labels)
699
+ ) {
700
+ const labelIds: Array<ObjectID> = (
701
+ onUpdate.updateBy.data.labels as any
702
+ )
703
+ .map((label: Label) => {
704
+ if (label._id) {
705
+ return new ObjectID(label._id?.toString());
706
+ }
707
+
708
+ return null;
709
+ })
710
+ .filter((labelId: ObjectID | null) => {
711
+ return labelId !== null;
712
+ });
713
+
714
+ const labels: Array<Label> = await LabelService.findBy({
715
+ query: {
716
+ _id: QueryHelper.any(labelIds),
717
+ },
718
+ select: {
719
+ name: true,
720
+ },
721
+ limit: LIMIT_PER_PROJECT,
722
+ skip: 0,
723
+ props: {
724
+ isRoot: true,
725
+ },
726
+ });
727
+
728
+ if (labels.length > 0) {
729
+ feedInfoInMarkdown += `\n\n**Labels**:
730
+
731
+ ${labels
732
+ .map((label: Label) => {
733
+ return `- ${label.name}`;
734
+ })
735
+ .join("\n")}
736
+ `;
737
+
738
+ shouldAddIncidentFeed = true;
739
+ }
740
+ }
741
+
742
+ if (
743
+ onUpdate.updateBy.data.incidentSeverity &&
744
+ (onUpdate.updateBy.data.incidentSeverity as any)._id
745
+ ) {
746
+ const incidentSeverity: IncidentSeverity | null =
747
+ await IncidentSeverityService.findOneBy({
748
+ query: {
749
+ _id: new ObjectID(
750
+ (
751
+ onUpdate.updateBy.data.incidentSeverity as any
752
+ )?._id.toString(),
753
+ ),
754
+ },
755
+ select: {
756
+ name: true,
757
+ },
758
+ props: {
759
+ isRoot: true,
760
+ },
761
+ });
762
+
763
+ if (incidentSeverity) {
764
+ feedInfoInMarkdown += `\n\n**Incident Severity**:
765
+ ${incidentSeverity.name}
766
+ `;
767
+
768
+ shouldAddIncidentFeed = true;
769
+ }
770
+ }
771
+
772
+ if (shouldAddIncidentFeed) {
706
773
  await IncidentFeedService.createIncidentFeed({
707
774
  incidentId: incidentId,
708
775
  projectId: onUpdate.updateBy.props.tenantId as ObjectID,
709
776
  incidentFeedEventType: IncidentFeedEventType.IncidentUpdated,
710
777
  displayColor: Gray500,
711
- feedInfoInMarkdown: `**Remediation notes were updated.** Here are the new notes.
712
-
713
- ${onUpdate.updateBy.data.remediationNotes || "No remediation notes provided."}
714
- `,
778
+ feedInfoInMarkdown: feedInfoInMarkdown,
715
779
  userId: createdByUserId || undefined,
716
780
  });
717
781
  }
@@ -151,6 +151,8 @@ import ScheduledMaintenanceFeedService from "./ScheduledMaintenanceFeedService";
151
151
  import AlertFeedService from "./AlertFeedService";
152
152
  import IncidentFeedService from "./IncidentFeedService";
153
153
 
154
+ import MonitorTestService from "./MonitorTestService";
155
+
154
156
  const services: Array<BaseService> = [
155
157
  AcmeCertificateService,
156
158
  PromoCodeService,
@@ -314,6 +316,7 @@ const services: Array<BaseService> = [
314
316
  AlertFeedService,
315
317
 
316
318
  TableViewService,
319
+ MonitorTestService,
317
320
  ];
318
321
 
319
322
  export const AnalyticsServices: Array<