@oneuptime/common 14.0.6 → 14.0.8
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/Incident.ts +267 -1
- package/Models/DatabaseModels/IncidentCustomField.ts +202 -0
- package/Models/DatabaseModels/IncidentEpisode.ts +30 -0
- package/Models/DatabaseModels/IncidentTemplate.ts +126 -1
- package/Models/DatabaseModels/InventoryItem.ts +23 -12
- package/Models/DatabaseModels/StatusPage.ts +55 -0
- package/Models/DatabaseModels/StatusPageSubscriber.ts +128 -0
- package/Server/API/IncidentAPI.ts +162 -0
- package/Server/API/StatusPageAPI.ts +487 -171
- package/Server/API/StatusPageSubscriberAPI.ts +63 -15
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795200000000-AddInventoryItemProjectEntityKeyIndex.ts +217 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications.ts +49 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795400000000-AddIncidentStatusPageScope.ts +108 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795500000000-AddIncidentTemplateStatusPageScopeFlag.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795600000000-AddStatusPageSubscriberUnsubscribeToken.ts +51 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795700000000-AddStatusPageSubscriberIsAddedByTeam.ts +33 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.ts +168 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1795900000000-AddSubscriberNotificationClaimedAt.ts +44 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +16 -0
- package/Server/Infrastructure/Semaphore.ts +10 -0
- package/Server/Middleware/IdentityRateLimit.ts +108 -3
- package/Server/Middleware/SubscriberNotificationPreviewRateLimit.ts +237 -0
- package/Server/Middleware/SubscriberNotificationTestSendRateLimit.ts +304 -0
- package/Server/Services/AlertService.ts +32 -36
- package/Server/Services/DatabaseService.ts +93 -10
- package/Server/Services/IncidentAlertService.ts +609 -2
- package/Server/Services/IncidentCustomFieldService.ts +276 -1
- package/Server/Services/IncidentEpisodePublicNoteService.ts +28 -0
- package/Server/Services/IncidentEpisodeService.ts +15 -0
- package/Server/Services/IncidentEpisodeStateTimelineService.ts +27 -1
- package/Server/Services/IncidentPublicNoteService.ts +30 -1
- package/Server/Services/IncidentService.ts +1663 -103
- package/Server/Services/IncidentStateTimelineService.ts +13 -0
- package/Server/Services/IncidentTemplateService.ts +109 -0
- package/Server/Services/InventoryItemService.ts +38 -0
- package/Server/Services/IoTDeviceCredentialService.ts +13 -4
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +30 -1
- package/Server/Services/ScheduledMaintenanceService.ts +118 -64
- package/Server/Services/SmsService.ts +10 -0
- package/Server/Services/StatusPageService.ts +65 -8
- package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +299 -37
- package/Server/Services/StatusPageSubscriberNotificationTemplateStatusPageService.ts +129 -0
- package/Server/Services/StatusPageSubscriberService.ts +1161 -64
- package/Server/Services/UserNotificationRuleService.ts +55 -53
- package/Server/Services/WorkspaceNotificationSummaryService.ts +38 -20
- package/Server/Types/Markdown.ts +153 -6
- package/Server/Types/Workflow/Components/Email.ts +61 -2
- package/Server/Utils/AffectedResources/LinkedAffectedResources.ts +576 -0
- package/Server/Utils/Alert/AlertStateChangeAuthorization.ts +129 -0
- package/Server/Utils/CustomField/CustomFieldRename.ts +378 -0
- package/Server/Utils/DataSource/EgressGuard.ts +66 -21
- package/Server/Utils/Inventory/InventoryOverviewAggregation.ts +111 -0
- package/Server/Utils/Mail/PinnedSmtpSocket.ts +130 -0
- package/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.ts +10 -0
- package/Server/Utils/Response.ts +31 -0
- package/Server/Utils/SSRFProtection.ts +76 -16
- package/Server/Utils/StatusPage/IncidentStatusPageScope.ts +948 -0
- package/Server/Utils/StatusPage/IncidentSubscriberAudienceBuilder.ts +656 -0
- package/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.ts +805 -0
- package/Server/Utils/StatusPage/StatusPageExclusion.ts +18 -0
- package/Server/Utils/StatusPage/StatusPageReadAccess.ts +125 -0
- package/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.ts +151 -0
- package/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.ts +70 -0
- package/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.ts +421 -0
- package/Server/Utils/StatusPage/SubscriberNotificationClaim.ts +107 -0
- package/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.ts +1049 -0
- package/Server/Utils/StatusPage/SubscriberNotificationFanOut.ts +180 -0
- package/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.ts +839 -0
- package/Server/Utils/StatusPage/SubscriberNotificationResendAccess.ts +393 -0
- package/Server/Utils/StatusPage/SubscriberNotificationRunLimit.ts +246 -0
- package/Server/Utils/StatusPage/SubscriberNotificationTiming.ts +133 -0
- package/Server/Utils/StatusPage/SubscriberTemplateIncidentRecordAccess.ts +215 -0
- package/Server/Utils/StatusPageResource.ts +51 -20
- package/Server/Utils/Topology/TopologyConcurrencyLimiter.ts +229 -0
- package/Server/Utils/Topology/TopologyQueries.ts +1350 -0
- package/Server/Utils/Topology/TopologyRequest.ts +463 -0
- package/Server/Utils/Topology/TopologyResponseCache.ts +183 -0
- package/Server/Utils/Topology/TopologySql.ts +1024 -0
- package/Server/Utils/VM/VMAPI.ts +1 -0
- package/Server/Utils/VM/VMRunner.ts +10 -0
- package/Server/Utils/Workflow/OAuth2TokenClient.ts +10 -0
- package/Server/Views/Partials/SensitiveUrlToken.ejs +8 -5
- package/Tests/App/Accounts/RegisterVerifyEmail.test.tsx +748 -0
- package/Tests/App/Accounts/ResendVerificationEmail.test.tsx +1222 -0
- package/Tests/App/Accounts/VerificationEmailResendUtils.test.ts +797 -0
- package/Tests/App/Accounts/VerifyEmailPending.test.tsx +538 -0
- package/Tests/App/Accounts/VerifyEmailResend.test.tsx +779 -0
- package/Tests/App/Dashboard/AcknowledgeAlertsOnDeclare.test.ts +369 -0
- package/Tests/App/Dashboard/AffectedResourcesSlo.test.tsx +1 -1
- package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +510 -123
- package/Tests/App/Dashboard/AlertsTableAffectedResources.test.tsx +490 -0
- package/Tests/App/Dashboard/ChangeAlertStateDeclareIncident.test.tsx +886 -0
- package/Tests/App/Dashboard/CreateReviewStepRoleSummary.test.tsx +1250 -0
- package/Tests/App/Dashboard/CreateReviewStepSelectionSummary.test.tsx +738 -0
- package/Tests/App/Dashboard/CustomFieldsSettingsIncidentOptions.test.tsx +357 -0
- package/Tests/App/Dashboard/DeclareIncidentFromAlert.test.ts +417 -0
- package/Tests/App/Dashboard/EntityDetailPanel.test.tsx +1948 -229
- package/Tests/App/Dashboard/EntityDetailPanelLifecycle.test.tsx +493 -0
- package/Tests/App/Dashboard/EntityDetailPanelNavigation.test.tsx +439 -0
- package/Tests/App/Dashboard/EventNotes.test.tsx +776 -0
- package/Tests/App/Dashboard/EventNotesPages.test.tsx +119 -0
- package/Tests/App/Dashboard/EventNotesUtil.test.ts +116 -17
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +534 -6
- package/Tests/App/Dashboard/EventStatusPanel.test.tsx +798 -2
- package/Tests/App/Dashboard/FetchStateAndSeverityElements.test.tsx +669 -0
- package/Tests/App/Dashboard/FetchUsers.test.tsx +230 -0
- package/Tests/App/Dashboard/IncidentChangeStateNotifyDefault.test.tsx +91 -1
- package/Tests/App/Dashboard/IncidentCreateAcknowledgeAlerts.test.tsx +1611 -0
- package/Tests/App/Dashboard/IncidentCreateDetailsStep.test.tsx +643 -0
- package/Tests/App/Dashboard/IncidentCreateFromAlerts.test.tsx +8 -1
- package/Tests/App/Dashboard/IncidentCreateStatusPageScope.test.tsx +601 -0
- package/Tests/App/Dashboard/IncidentCustomFieldTemplateVariables.test.tsx +386 -0
- package/Tests/App/Dashboard/IncidentNoteTemplatePlaceholders.test.tsx +124 -0
- package/Tests/App/Dashboard/IncidentNoteTemplateVariablesLoader.test.ts +305 -0
- package/Tests/App/Dashboard/IncidentOverviewNotifyDefault.test.tsx +112 -0
- package/Tests/App/Dashboard/IncidentSettingsRenotifyOnPublish.test.tsx +674 -0
- package/Tests/App/Dashboard/IncidentSettingsStatusPageScope.test.tsx +1051 -0
- package/Tests/App/Dashboard/IncidentTemplateCustomFields.test.tsx +384 -0
- package/Tests/App/Dashboard/IncidentTemplateStatusPageScopeCard.test.tsx +215 -0
- package/Tests/App/Dashboard/InfrastructureExplorer.test.tsx +1365 -57
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +964 -23
- package/Tests/App/Dashboard/InventoryRelationships.test.tsx +885 -0
- package/Tests/App/Dashboard/PublicNotePagesNotifyDefault.test.tsx +113 -1
- package/Tests/App/Dashboard/ServiceMapDatabaseLink.test.tsx +201 -15
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +508 -36
- package/Tests/App/Dashboard/SubscriberAudienceSummary.test.tsx +512 -0
- package/Tests/App/Dashboard/SubscriberNotificationPreviewModal.test.tsx +837 -0
- package/Tests/App/Dashboard/SubscriberNotificationStatusLabel.test.tsx +88 -0
- package/Tests/App/Dashboard/SubscriberNotificationStatusResend.test.tsx +473 -0
- package/Tests/App/Dashboard/SubscriberTemplateLivePreview.test.tsx +196 -0
- package/Tests/App/Dashboard/TeamAddedSubscribersUnsubscribedNotice.test.tsx +248 -0
- package/Tests/App/Dashboard/TopologyDataLifecycle.test.tsx +583 -0
- package/Tests/App/Dashboard/TopologyDataLoading.test.tsx +982 -218
- package/Tests/App/Dashboard/TopologyPageNavigation.test.tsx +818 -114
- package/Tests/App/SensitiveUrlTokenBootstrap.test.ts +64 -3
- package/Tests/App/StatusPage/StatusPageUnsubscribePage.test.tsx +412 -0
- package/Tests/Models/IncidentCustomFieldApiSchemaContract.test.ts +217 -0
- package/Tests/Models/IncidentCustomFieldCreateSettingsColumns.test.ts +252 -0
- package/Tests/Models/StatusPageSubscriberUnsubscribeColumns.test.ts +218 -0
- package/Tests/Server/API/ExpiredSessionRouteGuards.test.ts +7 -0
- package/Tests/Server/API/IncidentSubscriberAudienceAPI.test.ts +1408 -0
- package/Tests/Server/API/StatusPageIncidentScope.test.ts +1868 -0
- package/Tests/Server/API/StatusPageIncidentScopePostgres.test.ts +790 -0
- package/Tests/Server/API/StatusPageManageSubscriptionRecipient.test.ts +10 -1
- package/Tests/Server/API/StatusPageManageSubscriptionTemplateVariables.test.ts +206 -18
- package/Tests/Server/API/StatusPagePostmortemVisibility.test.ts +14 -2
- package/Tests/Server/API/StatusPageSubscriberCreateResponse.test.ts +217 -0
- package/Tests/Server/API/StatusPageSubscriberOwnership.test.ts +103 -2
- package/Tests/Server/API/StatusPageUnsubscribeAPI.test.ts +396 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentStatusPageScopeMigration.test.ts +395 -0
- package/Tests/Server/Infrastructure/Postgres/AddIncidentTemplateStatusPageScopeFlagMigration.test.ts +150 -0
- package/Tests/Server/Infrastructure/Postgres/AddSubscriberNotificationClaimedAtMigration.test.ts +156 -0
- package/Tests/Server/Infrastructure/Postgres/RenameInventoryItemMigration.test.ts +90 -21
- package/Tests/Server/Infrastructure/Postgres/SkipHiddenIncidentCreatedNotificationsMigration.test.ts +410 -0
- package/Tests/Server/Middleware/IdentityRateLimit.test.ts +551 -1
- package/Tests/Server/Middleware/SubscriberNotificationPreviewRateLimit.test.ts +238 -0
- package/Tests/Server/Middleware/SubscriberNotificationTestSendRateLimit.test.ts +245 -0
- package/Tests/Server/Services/AddStatusPageSubscriberUnsubscribeTokenMigration.test.ts +152 -0
- package/Tests/Server/Services/CrossProjectRelationWriteGuard.test.ts +221 -36
- package/Tests/Server/Services/DatabaseServiceCompareAndSetColumns.test.ts +191 -0
- package/Tests/Server/Services/DomainService.test.ts +525 -0
- package/Tests/Server/Services/IncidentAlertAcknowledgeOnDeclare.test.ts +2630 -0
- package/Tests/Server/Services/IncidentAlertPostgres.test.ts +1625 -1
- package/Tests/Server/Services/IncidentCreatedRenotifyOnPublish.test.ts +681 -0
- package/Tests/Server/Services/IncidentCreatedResend.test.ts +775 -0
- package/Tests/Server/Services/IncidentCustomFieldRenamePostgres.test.ts +713 -0
- package/Tests/Server/Services/IncidentCustomFieldService.test.ts +751 -0
- package/Tests/Server/Services/IncidentCustomFieldValueValidation.test.ts +556 -0
- package/Tests/Server/Services/IncidentDeclareAcknowledgeAlerts.test.ts +2189 -0
- package/Tests/Server/Services/IncidentStatusPageScope.test.ts +2971 -0
- package/Tests/Server/Services/IncidentStatusPageScopeFeed.test.ts +131 -0
- package/Tests/Server/Services/IncidentStatusPageScopePostgres.test.ts +625 -0
- package/Tests/Server/Services/IncidentTemplateCustomFieldsCopy.test.ts +311 -0
- package/Tests/Server/Services/IncidentTemplateStatusPageScope.test.ts +363 -0
- package/Tests/Server/Services/InventoryItemServiceOverviewCounts.test.ts +345 -0
- package/Tests/Server/Services/InventoryOverviewPostgres.test.ts +254 -0
- package/Tests/Server/Services/IoTDeviceCredentialService.test.ts +819 -0
- package/Tests/Server/Services/LinkedAffectedResourcesCreatedFeed.test.ts +420 -0
- package/Tests/Server/Services/PublicNoteEditFeedEventType.test.ts +213 -0
- package/Tests/Server/Services/PublicNoteResendAccess.test.ts +994 -0
- package/Tests/Server/Services/ScheduledMaintenanceSubscriberTemplateFormats.test.ts +289 -9
- package/Tests/Server/Services/SloAffectedResourceCreatedFeed.test.ts +92 -36
- package/Tests/Server/Services/SmsServiceFailIfNotSent.test.ts +67 -0
- package/Tests/Server/Services/StatusPageReportIncidentCounts.test.ts +610 -0
- package/Tests/Server/Services/StatusPageSubscriberAudienceCounts.test.ts +201 -0
- package/Tests/Server/Services/StatusPageSubscriberAudienceCountsPostgres.test.ts +271 -0
- package/Tests/Server/Services/StatusPageSubscriberConfirmationTemplateEscaping.test.ts +200 -0
- package/Tests/Server/Services/StatusPageSubscriberNotificationLogRedaction.test.ts +54 -0
- package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateCompile.test.ts +37 -0
- package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateIncidentRecordAccess.test.ts +772 -0
- package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateLookup.test.ts +506 -0
- package/Tests/Server/Services/StatusPageSubscriberNotificationTemplateLookupPostgres.test.ts +261 -0
- package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +21 -5
- package/Tests/Server/Services/StatusPageSubscriberUnsubscribe.test.ts +1618 -0
- package/Tests/Server/Services/StatusPageSubscriberUnsubscribeLinkSenders.test.ts +373 -0
- package/Tests/Server/Services/StatusPageSubscriberUnsubscribePostgres.test.ts +388 -0
- package/Tests/Server/Services/SubscriberNotificationInFlightRequeue.test.ts +500 -0
- package/Tests/Server/Types/MarkdownEmailLinks.test.ts +320 -0
- package/Tests/Server/Types/Workflow/Components/Email.test.ts +491 -1
- package/Tests/Server/Types/Workflow/Components/EmailSmtpPinning.test.ts +398 -0
- package/Tests/Server/Utils/AffectedResources/LinkedAffectedResources.test.ts +858 -0
- package/Tests/Server/Utils/Alert/AlertStateChangeAuthorization.test.ts +1172 -0
- package/Tests/Server/Utils/CustomField/CustomFieldRename.test.ts +586 -0
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +246 -10
- package/Tests/Server/Utils/DataSource/EgressGuardDeploymentConfig.test.ts +226 -0
- package/Tests/Server/Utils/DataSource/EgressGuardPinning.test.ts +131 -0
- package/Tests/Server/Utils/DataSource/HttpFetch.test.ts +4 -0
- package/Tests/Server/Utils/EgressPolicyEnvironment.ts +45 -0
- package/Tests/Server/Utils/Mail/PinnedSmtpSocket.test.ts +409 -0
- package/Tests/Server/Utils/Monitor/MonitorCriteriaObservationBuilderUnits.test.ts +23 -0
- package/Tests/Server/Utils/SSRFProtection.test.ts +4 -0
- package/Tests/Server/Utils/SSRFProtectionCloudServiceAddresses.test.ts +4 -0
- package/Tests/Server/Utils/SSRFProtectionPrivateNetwork.test.ts +4 -0
- package/Tests/Server/Utils/SSRFProtectionResolutionDetail.test.ts +314 -0
- package/Tests/Server/Utils/StatusPage/IncidentStatusPageScope.test.ts +1699 -0
- package/Tests/Server/Utils/StatusPage/IncidentStatusPageScopeQueriesPostgres.test.ts +508 -0
- package/Tests/Server/Utils/StatusPage/IncidentSubscriberAudienceCallerPermission.test.ts +246 -0
- package/Tests/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.test.ts +1348 -0
- package/Tests/Server/Utils/StatusPage/StatusPageReadAccess.test.ts +221 -0
- package/Tests/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.test.ts +132 -0
- package/Tests/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.test.ts +155 -0
- package/Tests/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.test.ts +708 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationClaim.test.ts +255 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationClaimPostgres.test.ts +528 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.test.ts +1238 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationFanOut.test.ts +472 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.test.ts +1168 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationRunLimit.test.ts +275 -0
- package/Tests/Server/Utils/StatusPage/SubscriberNotificationTiming.test.ts +131 -0
- package/Tests/Server/Utils/StatusPageResource.test.ts +98 -0
- package/Tests/Server/Utils/Topology/InventoryItemEntityKeyIndexMigration.test.ts +386 -0
- package/Tests/Server/Utils/Topology/InventoryItemEntityKeyIndexMigrationPostgres.test.ts +430 -0
- package/Tests/Server/Utils/Topology/TopologyActivityParityPostgres.test.ts +279 -0
- package/Tests/Server/Utils/Topology/TopologyConcurrencyLimiter.test.ts +534 -0
- package/Tests/Server/Utils/Topology/TopologyEstateGenerator.ts +624 -0
- package/Tests/Server/Utils/Topology/TopologyJsonResponse.test.ts +90 -0
- package/Tests/Server/Utils/Topology/TopologyQueries.test.ts +1634 -0
- package/Tests/Server/Utils/Topology/TopologyQueriesDifferentialPostgres.test.ts +683 -0
- package/Tests/Server/Utils/Topology/TopologyQueriesPostgres.test.ts +2624 -0
- package/Tests/Server/Utils/Topology/TopologyReference.ts +1018 -0
- package/Tests/Server/Utils/Topology/TopologyRequest.test.ts +643 -0
- package/Tests/Server/Utils/Topology/TopologyResponseCache.test.ts +305 -0
- package/Tests/Server/Utils/Topology/TopologySql.test.ts +973 -0
- package/Tests/Server/Utils/VM/VMRunnerPrivateNetworkWiring.test.ts +17 -0
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +75 -0
- package/Tests/Types/CustomField/CustomFieldSavedViews.test.ts +247 -0
- package/Tests/Types/CustomField/CustomFieldTemplateValues.test.ts +186 -0
- package/Tests/Types/CustomField/CustomFieldTypeCorrespondence.test.ts +48 -0
- package/Tests/Types/CustomField/CustomFieldValueFormat.test.ts +215 -0
- package/Tests/Types/CustomField/CustomFieldValueValidator.test.ts +343 -0
- package/Tests/Types/CustomField/CustomFieldVariableKey.test.ts +364 -0
- package/Tests/Types/SafeHtml.test.ts +102 -0
- package/Tests/Types/StatusPage/IncidentCreatedRenotify.test.ts +419 -0
- package/Tests/Types/StatusPage/IncidentCreatedResend.test.ts +118 -0
- package/Tests/Types/StatusPage/IncidentScopeAddedPagesNotification.test.ts +558 -0
- package/Tests/Types/StatusPage/IncidentSubscriberAudience.test.ts +284 -0
- package/Tests/Types/StatusPage/StatusPageSubscriberUnsubscribe.test.ts +341 -0
- package/Tests/Types/StatusPage/SubscriberNotificationPreview.test.ts +196 -0
- package/Tests/Types/StatusPage/SubscriberNotificationResend.test.ts +201 -0
- package/Tests/Types/StatusPage/SubscriberNotificationTemplateCompiler.test.ts +277 -0
- package/Tests/Types/StatusPage/SubscriberNotificationTemplatePreview.test.ts +179 -0
- package/Tests/Types/StatusPage/SubscriberNotificationTemplateVariables.test.ts +324 -0
- package/Tests/Types/StatusPage/SubscriberUpdateNotification.test.ts +60 -13
- package/Tests/Types/Topology/TopologyTypeRules.test.ts +176 -0
- package/Tests/UI/Components/CustomFields/CustomFieldFormFields.test.ts +432 -0
- package/Tests/UI/Components/CustomFields/CustomFieldModelFormFields.test.tsx +685 -0
- package/Tests/UI/Components/CustomFields/CustomFieldsDetailOrder.test.tsx +469 -0
- package/Tests/UI/Components/Forms/ModelFormCustomFieldInputs.test.tsx +325 -0
- package/Tests/UI/Components/Forms/ModelFormDropdownOptionsRefused.test.tsx +358 -0
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +22 -0
- package/Tests/UI/Monitor/NetworkPathView.test.tsx +289 -0
- package/Tests/Utils/Incident/IncidentFromAlerts.test.ts +302 -0
- package/Tests/Utils/Incident/IncidentNoteTemplateVariables.test.ts +623 -0
- package/Tests/Utils/Markdown/MarkdownEscape.test.ts +89 -0
- package/Tests/Utils/ProbeNetworkFailureUtil.test.ts +992 -0
- package/Tests/Utils/RequestFailedDetails.test.ts +575 -0
- package/Types/CustomField/CustomFieldOrder.ts +55 -0
- package/Types/CustomField/CustomFieldSavedViews.ts +225 -0
- package/Types/CustomField/CustomFieldTemplateMerge.ts +71 -0
- package/Types/CustomField/CustomFieldType.ts +14 -0
- package/Types/CustomField/CustomFieldValueFormat.ts +161 -0
- package/Types/CustomField/CustomFieldValueValidator.ts +488 -0
- package/Types/CustomField/CustomFieldVariableKey.ts +211 -0
- package/Types/Incident/IncidentAlertLink.ts +19 -0
- package/Types/SafeHtml.ts +93 -0
- package/Types/StatusPage/IncidentCreatedRenotify.ts +224 -0
- package/Types/StatusPage/IncidentCreatedResend.ts +108 -0
- package/Types/StatusPage/IncidentScopeAddedPagesNotification.ts +343 -0
- package/Types/StatusPage/IncidentSubscriberAudience.ts +332 -0
- package/Types/StatusPage/StatusPageSubscriberUnsubscribe.ts +405 -0
- package/Types/StatusPage/SubscriberNotificationInterruption.ts +32 -0
- package/Types/StatusPage/SubscriberNotificationPreview.ts +322 -0
- package/Types/StatusPage/SubscriberNotificationResend.ts +132 -0
- package/Types/StatusPage/SubscriberNotificationTemplateCompiler.ts +180 -0
- package/Types/StatusPage/SubscriberNotificationTemplatePreview.ts +301 -0
- package/Types/StatusPage/SubscriberNotificationTemplateVariables.ts +217 -4
- package/Types/StatusPage/SubscriberUpdateNotification.ts +32 -11
- package/Types/Telemetry/InventoryLiveness.ts +26 -0
- package/Types/Topology/TopologyApi.ts +428 -0
- package/Types/Topology/TopologyTypeRules.ts +191 -0
- package/UI/Components/CustomFields/CustomFieldFormFields.ts +317 -0
- package/UI/Components/CustomFields/CustomFieldModelFormFields.tsx +395 -0
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +95 -55
- package/UI/Components/Forms/ModelForm.tsx +70 -8
- package/UI/Components/Forms/Validation.ts +1 -1
- package/UI/Components/ModelFormModal/ModelFormModal.tsx +2 -4
- package/UI/Components/ModelTable/AnalyticsModelTable.tsx +2 -6
- package/UI/Components/ModelTable/BaseModelTable.tsx +9 -8
- package/UI/Components/ModelTable/CustomFieldColumns.tsx +14 -1
- package/UI/Components/ModelTable/ModelTable.tsx +6 -7
- package/UI/Utils/SensitiveUrlToken.ts +10 -5
- package/Utils/API.ts +247 -2
- package/Utils/Incident/IncidentFromAlerts.ts +78 -0
- package/Utils/Incident/IncidentNoteTemplateVariables.ts +304 -0
- package/Utils/Markdown/MarkdownEscape.ts +65 -0
- package/Utils/ProbeNetworkFailureUtil.ts +673 -0
- package/build/dist/Models/DatabaseModels/Incident.js +267 -1
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js +207 -1
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js +31 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js +124 -1
- package/build/dist/Models/DatabaseModels/IncidentTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/InventoryItem.js +20 -11
- package/build/dist/Models/DatabaseModels/InventoryItem.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +56 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js +131 -0
- package/build/dist/Models/DatabaseModels/StatusPageSubscriber.js.map +1 -1
- package/build/dist/Server/API/IncidentAPI.js +100 -1
- package/build/dist/Server/API/IncidentAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +417 -176
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageSubscriberAPI.js +52 -13
- package/build/dist/Server/API/StatusPageSubscriberAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795200000000-AddInventoryItemProjectEntityKeyIndex.js +165 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795200000000-AddInventoryItemProjectEntityKeyIndex.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications.js +41 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795300000000-SkipHiddenIncidentCreatedNotifications.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795400000000-AddIncidentStatusPageScope.js +57 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795400000000-AddIncidentStatusPageScope.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795500000000-AddIncidentTemplateStatusPageScopeFlag.js +23 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795500000000-AddIncidentTemplateStatusPageScopeFlag.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795600000000-AddStatusPageSubscriberUnsubscribeToken.js +40 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795600000000-AddStatusPageSubscriberUnsubscribeToken.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795700000000-AddStatusPageSubscriberIsAddedByTeam.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795700000000-AddStatusPageSubscriberIsAddedByTeam.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.js +89 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795800000000-AddIncidentCustomFieldCreateAndNotificationSettings.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795900000000-AddSubscriberNotificationClaimedAt.js +29 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1795900000000-AddSubscriberNotificationClaimedAt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +16 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Infrastructure/Semaphore.js +3 -0
- package/build/dist/Server/Infrastructure/Semaphore.js.map +1 -1
- package/build/dist/Server/Middleware/IdentityRateLimit.js +89 -3
- package/build/dist/Server/Middleware/IdentityRateLimit.js.map +1 -1
- package/build/dist/Server/Middleware/SubscriberNotificationPreviewRateLimit.js +149 -0
- package/build/dist/Server/Middleware/SubscriberNotificationPreviewRateLimit.js.map +1 -0
- package/build/dist/Server/Middleware/SubscriberNotificationTestSendRateLimit.js +190 -0
- package/build/dist/Server/Middleware/SubscriberNotificationTestSendRateLimit.js.map +1 -0
- package/build/dist/Server/Services/AlertService.js +21 -33
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +56 -7
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentAlertService.js +457 -3
- package/build/dist/Server/Services/IncidentAlertService.js.map +1 -1
- package/build/dist/Server/Services/IncidentCustomFieldService.js +204 -8
- package/build/dist/Server/Services/IncidentCustomFieldService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +24 -0
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeService.js +14 -0
- package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js +26 -0
- package/build/dist/Server/Services/IncidentEpisodeStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +26 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +1148 -42
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentStateTimelineService.js +12 -0
- package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/IncidentTemplateService.js +83 -0
- package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
- package/build/dist/Server/Services/InventoryItemService.js +31 -0
- package/build/dist/Server/Services/InventoryItemService.js.map +1 -1
- package/build/dist/Server/Services/IoTDeviceCredentialService.js +12 -5
- package/build/dist/Server/Services/IoTDeviceCredentialService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +26 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +84 -57
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/SmsService.js +2 -22
- package/build/dist/Server/Services/SmsService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageService.js +47 -9
- package/build/dist/Server/Services/StatusPageService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +237 -32
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateStatusPageService.js +109 -0
- package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateStatusPageService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageSubscriberService.js +925 -99
- package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
- package/build/dist/Server/Services/UserNotificationRuleService.js +55 -51
- package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js +42 -25
- package/build/dist/Server/Services/WorkspaceNotificationSummaryService.js.map +1 -1
- package/build/dist/Server/Types/Markdown.js +110 -6
- package/build/dist/Server/Types/Markdown.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Email.js +55 -6
- package/build/dist/Server/Types/Workflow/Components/Email.js.map +1 -1
- package/build/dist/Server/Utils/AffectedResources/LinkedAffectedResources.js +405 -0
- package/build/dist/Server/Utils/AffectedResources/LinkedAffectedResources.js.map +1 -0
- package/build/dist/Server/Utils/Alert/AlertStateChangeAuthorization.js +112 -0
- package/build/dist/Server/Utils/Alert/AlertStateChangeAuthorization.js.map +1 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldRename.js +211 -0
- package/build/dist/Server/Utils/CustomField/CustomFieldRename.js.map +1 -0
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +41 -12
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/Inventory/InventoryOverviewAggregation.js +81 -0
- package/build/dist/Server/Utils/Inventory/InventoryOverviewAggregation.js.map +1 -0
- package/build/dist/Server/Utils/Mail/PinnedSmtpSocket.js +101 -0
- package/build/dist/Server/Utils/Mail/PinnedSmtpSocket.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js +9 -0
- package/build/dist/Server/Utils/Monitor/MonitorCriteriaObservationBuilder.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +30 -0
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +48 -6
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/StatusPage/IncidentStatusPageScope.js +631 -0
- package/build/dist/Server/Utils/StatusPage/IncidentStatusPageScope.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/IncidentSubscriberAudienceBuilder.js +403 -0
- package/build/dist/Server/Utils/StatusPage/IncidentSubscriberAudienceBuilder.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.js +451 -0
- package/build/dist/Server/Utils/StatusPage/IncidentTemplateVariableBuilder.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageExclusion.js +13 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageExclusion.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageReadAccess.js +91 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageReadAccess.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.js +101 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeNotice.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.js +47 -0
- package/build/dist/Server/Utils/StatusPage/StatusPageSubscriberUnsubscribeToken.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.js +273 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberIncidentEmailBuilder.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationClaim.js +73 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationClaim.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.js +722 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationDeliveryRecord.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationFanOut.js +102 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationFanOut.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.js +527 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationPreviewBuilder.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationResendAccess.js +278 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationResendAccess.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationRunLimit.js +137 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationRunLimit.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationTiming.js +103 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberNotificationTiming.js.map +1 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberTemplateIncidentRecordAccess.js +114 -0
- package/build/dist/Server/Utils/StatusPage/SubscriberTemplateIncidentRecordAccess.js.map +1 -0
- package/build/dist/Server/Utils/StatusPageResource.js +39 -7
- package/build/dist/Server/Utils/StatusPageResource.js.map +1 -1
- package/build/dist/Server/Utils/Topology/TopologyConcurrencyLimiter.js +178 -0
- package/build/dist/Server/Utils/Topology/TopologyConcurrencyLimiter.js.map +1 -0
- package/build/dist/Server/Utils/Topology/TopologyQueries.js +884 -0
- package/build/dist/Server/Utils/Topology/TopologyQueries.js.map +1 -0
- package/build/dist/Server/Utils/Topology/TopologyRequest.js +275 -0
- package/build/dist/Server/Utils/Topology/TopologyRequest.js.map +1 -0
- package/build/dist/Server/Utils/Topology/TopologyResponseCache.js +146 -0
- package/build/dist/Server/Utils/Topology/TopologyResponseCache.js.map +1 -0
- package/build/dist/Server/Utils/Topology/TopologySql.js +688 -0
- package/build/dist/Server/Utils/Topology/TopologySql.js.map +1 -0
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +1 -0
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js +3 -0
- package/build/dist/Server/Utils/Workflow/OAuth2TokenClient.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldOrder.js +36 -0
- package/build/dist/Types/CustomField/CustomFieldOrder.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldSavedViews.js +135 -0
- package/build/dist/Types/CustomField/CustomFieldSavedViews.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldTemplateMerge.js +27 -0
- package/build/dist/Types/CustomField/CustomFieldTemplateMerge.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldType.js +12 -0
- package/build/dist/Types/CustomField/CustomFieldType.js.map +1 -1
- package/build/dist/Types/CustomField/CustomFieldValueFormat.js +126 -0
- package/build/dist/Types/CustomField/CustomFieldValueFormat.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldValueValidator.js +280 -0
- package/build/dist/Types/CustomField/CustomFieldValueValidator.js.map +1 -0
- package/build/dist/Types/CustomField/CustomFieldVariableKey.js +150 -0
- package/build/dist/Types/CustomField/CustomFieldVariableKey.js.map +1 -0
- package/build/dist/Types/Incident/IncidentAlertLink.js +17 -0
- package/build/dist/Types/Incident/IncidentAlertLink.js.map +1 -1
- package/build/dist/Types/SafeHtml.js +84 -0
- package/build/dist/Types/SafeHtml.js.map +1 -0
- package/build/dist/Types/StatusPage/IncidentCreatedRenotify.js +117 -0
- package/build/dist/Types/StatusPage/IncidentCreatedRenotify.js.map +1 -0
- package/build/dist/Types/StatusPage/IncidentCreatedResend.js +86 -0
- package/build/dist/Types/StatusPage/IncidentCreatedResend.js.map +1 -0
- package/build/dist/Types/StatusPage/IncidentScopeAddedPagesNotification.js +246 -0
- package/build/dist/Types/StatusPage/IncidentScopeAddedPagesNotification.js.map +1 -0
- package/build/dist/Types/StatusPage/IncidentSubscriberAudience.js +183 -0
- package/build/dist/Types/StatusPage/IncidentSubscriberAudience.js.map +1 -0
- package/build/dist/Types/StatusPage/StatusPageSubscriberUnsubscribe.js +277 -0
- package/build/dist/Types/StatusPage/StatusPageSubscriberUnsubscribe.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationInterruption.js +27 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationInterruption.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationPreview.js +190 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationPreview.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationResend.js +102 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationResend.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplateCompiler.js +97 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplateCompiler.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplatePreview.js +175 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplatePreview.js.map +1 -0
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js +144 -4
- package/build/dist/Types/StatusPage/SubscriberNotificationTemplateVariables.js.map +1 -1
- package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js +29 -9
- package/build/dist/Types/StatusPage/SubscriberUpdateNotification.js.map +1 -1
- package/build/dist/Types/Telemetry/InventoryLiveness.js +23 -0
- package/build/dist/Types/Telemetry/InventoryLiveness.js.map +1 -1
- package/build/dist/Types/Topology/TopologyApi.js +55 -0
- package/build/dist/Types/Topology/TopologyApi.js.map +1 -0
- package/build/dist/Types/Topology/TopologyTypeRules.js +165 -0
- package/build/dist/Types/Topology/TopologyTypeRules.js.map +1 -0
- package/build/dist/UI/Components/CustomFields/CustomFieldFormFields.js +169 -0
- package/build/dist/UI/Components/CustomFields/CustomFieldFormFields.js.map +1 -0
- package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js +212 -0
- package/build/dist/UI/Components/CustomFields/CustomFieldModelFormFields.js.map +1 -0
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +64 -49
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +39 -5
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Forms/Validation.js +1 -1
- package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
- package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/AnalyticsModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +2 -2
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +13 -1
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ModelTable.js +1 -1
- package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
- package/build/dist/UI/Utils/SensitiveUrlToken.js +10 -5
- package/build/dist/UI/Utils/SensitiveUrlToken.js.map +1 -1
- package/build/dist/Utils/API.js +177 -1
- package/build/dist/Utils/API.js.map +1 -1
- package/build/dist/Utils/Incident/IncidentFromAlerts.js +38 -0
- package/build/dist/Utils/Incident/IncidentFromAlerts.js.map +1 -1
- package/build/dist/Utils/Incident/IncidentNoteTemplateVariables.js +155 -0
- package/build/dist/Utils/Incident/IncidentNoteTemplateVariables.js.map +1 -0
- package/build/dist/Utils/Markdown/MarkdownEscape.js +48 -0
- package/build/dist/Utils/Markdown/MarkdownEscape.js.map +1 -1
- package/build/dist/Utils/ProbeNetworkFailureUtil.js +460 -0
- package/build/dist/Utils/ProbeNetworkFailureUtil.js.map +1 -0
- package/package.json +1 -1
|
@@ -17,21 +17,28 @@ import {
|
|
|
17
17
|
} from "@testing-library/react";
|
|
18
18
|
import * as React from "react";
|
|
19
19
|
import { MemoryRouter } from "react-router-dom";
|
|
20
|
-
import InventoryItem from "../../../Models/DatabaseModels/InventoryItem";
|
|
21
|
-
import InventoryItemRelationship from "../../../Models/DatabaseModels/InventoryItemRelationship";
|
|
22
20
|
import EntityType from "../../../Types/Telemetry/EntityType";
|
|
23
21
|
import EntityRelationshipType from "../../../Types/Telemetry/EntityRelationshipType";
|
|
24
22
|
import EntitySource from "../../../Types/Telemetry/EntitySource";
|
|
25
23
|
import TimeRange from "../../../Types/Time/TimeRange";
|
|
26
24
|
import { ServiceOperationalStatus } from "../../../../App/FeatureSet/Dashboard/src/Components/Topology/OperationalOverlay";
|
|
27
25
|
import ServiceMapGraph from "../../../../App/FeatureSet/Dashboard/src/Components/Topology/ServiceMapGraph";
|
|
26
|
+
import {
|
|
27
|
+
EntityDetailTarget,
|
|
28
|
+
TopologyEntity,
|
|
29
|
+
TopologyRelationship,
|
|
30
|
+
TopologyRunsOnCount,
|
|
31
|
+
TopologyRunsOnCounts,
|
|
32
|
+
} from "../../../../App/FeatureSet/Dashboard/src/Components/Topology/TopologyData";
|
|
28
33
|
import getJestMockFunction, { MockFunction } from "../../MockType";
|
|
29
34
|
|
|
30
35
|
/*
|
|
31
36
|
* The Service Map component: what a person sees first, how they narrow it
|
|
32
37
|
* down, and how they get to details. Graph drawing itself (React Flow) is
|
|
33
|
-
* replaced by a stand-in that renders nodes and edges as buttons,
|
|
34
|
-
*
|
|
38
|
+
* replaced by a stand-in that renders nodes and edges as buttons, and the
|
|
39
|
+
* detail drawer (which fetches its own connections) by a stand-in that
|
|
40
|
+
* records the props it was given, so these tests exercise the component's
|
|
41
|
+
* decisions, not the canvas or the drawer.
|
|
35
42
|
*/
|
|
36
43
|
|
|
37
44
|
const mockFitView: MockFunction = getJestMockFunction();
|
|
@@ -52,6 +59,14 @@ let mockStatuses: Map<string, ServiceOperationalStatus> = new Map<
|
|
|
52
59
|
string,
|
|
53
60
|
ServiceOperationalStatus
|
|
54
61
|
>();
|
|
62
|
+
/*
|
|
63
|
+
* Every drawer instance, by the entity it was mounted for. The map keeps one
|
|
64
|
+
* drawer while the user moves between entities (a remount would replay the
|
|
65
|
+
* slide-in and drop keyboard focus), so a new entry means a new drawer.
|
|
66
|
+
*/
|
|
67
|
+
const mockDrawerMounts: Array<string> = [];
|
|
68
|
+
/* The props of the drawer as last rendered. */
|
|
69
|
+
let mockDrawerProps: Record<string, unknown> | null = null;
|
|
55
70
|
|
|
56
71
|
jest.mock("../../../UI/Utils/Translation", () => {
|
|
57
72
|
return {
|
|
@@ -94,41 +109,143 @@ jest.mock(
|
|
|
94
109
|
};
|
|
95
110
|
},
|
|
96
111
|
);
|
|
112
|
+
/*
|
|
113
|
+
* The drawer's props contract: a preview of the entity (it fetches the rest
|
|
114
|
+
* itself), the server's range start, and callbacks. Its connection rows are
|
|
115
|
+
* stood in for by buttons that call back the way the real rows do: a
|
|
116
|
+
* "runs on" row opens the Infrastructure view when it can, every other row
|
|
117
|
+
* asks the map to select what it points at.
|
|
118
|
+
*/
|
|
97
119
|
jest.mock(
|
|
98
120
|
"../../../../App/FeatureSet/Dashboard/src/Components/Topology/EntityDetailPanel",
|
|
99
121
|
() => {
|
|
122
|
+
type Target = {
|
|
123
|
+
entityKey: string;
|
|
124
|
+
entityType?: string;
|
|
125
|
+
displayName?: string;
|
|
126
|
+
};
|
|
100
127
|
return {
|
|
101
128
|
__esModule: true,
|
|
102
129
|
default: (props: {
|
|
103
|
-
entity:
|
|
130
|
+
entity: Target;
|
|
131
|
+
rangeStart?: Date | null;
|
|
104
132
|
traffic?: { statusLabel: string; subtitle: string };
|
|
133
|
+
incidentStatus?: { activeIncidentCount: number } | null;
|
|
105
134
|
onClose: () => void;
|
|
106
|
-
onFocus
|
|
107
|
-
|
|
135
|
+
onFocus?: (key: string) => void;
|
|
136
|
+
focusButtonLabel?: string;
|
|
137
|
+
onSelectEntity?: (target: Target) => void;
|
|
138
|
+
onOpenInfrastructure?: (key: string) => void;
|
|
108
139
|
}) => {
|
|
140
|
+
mockDrawerProps = props as unknown as Record<string, unknown>;
|
|
141
|
+
const [mountedFor] = React.useState<string>(props.entity.entityKey);
|
|
142
|
+
React.useEffect(() => {
|
|
143
|
+
mockDrawerMounts.push(props.entity.entityKey);
|
|
144
|
+
}, []);
|
|
145
|
+
const select: (target: Target) => void = (target: Target): void => {
|
|
146
|
+
props.onSelectEntity?.(target);
|
|
147
|
+
};
|
|
109
148
|
return (
|
|
110
|
-
<div
|
|
111
|
-
|
|
149
|
+
<div
|
|
150
|
+
role="dialog"
|
|
151
|
+
aria-label="Service details"
|
|
152
|
+
data-mounted-for={mountedFor}
|
|
153
|
+
data-entity-key={props.entity.entityKey}
|
|
154
|
+
>
|
|
155
|
+
<p data-testid="drawer-name">
|
|
156
|
+
{props.entity.displayName || props.entity.entityKey}
|
|
157
|
+
</p>
|
|
158
|
+
<p data-testid="drawer-type">{props.entity.entityType || ""}</p>
|
|
112
159
|
<p data-testid="drawer-status">{props.traffic?.statusLabel}</p>
|
|
113
160
|
<p data-testid="drawer-subtitle">{props.traffic?.subtitle}</p>
|
|
161
|
+
<p data-testid="drawer-incidents">
|
|
162
|
+
{String(props.incidentStatus?.activeIncidentCount ?? "none")}
|
|
163
|
+
</p>
|
|
114
164
|
<button onClick={props.onClose}>Close service</button>
|
|
165
|
+
{props.onFocus ? (
|
|
166
|
+
<button
|
|
167
|
+
onClick={() => {
|
|
168
|
+
props.onFocus?.(props.entity.entityKey);
|
|
169
|
+
}}
|
|
170
|
+
>
|
|
171
|
+
{props.focusButtonLabel || "Focus"}
|
|
172
|
+
</button>
|
|
173
|
+
) : (
|
|
174
|
+
<></>
|
|
175
|
+
)}
|
|
115
176
|
<button
|
|
116
177
|
onClick={() => {
|
|
117
|
-
|
|
178
|
+
select({
|
|
179
|
+
entityKey: "postgres",
|
|
180
|
+
entityType: "database",
|
|
181
|
+
displayName: "postgres",
|
|
182
|
+
});
|
|
118
183
|
}}
|
|
119
184
|
>
|
|
120
|
-
|
|
185
|
+
View related dependency
|
|
121
186
|
</button>
|
|
122
187
|
<button
|
|
123
188
|
onClick={() => {
|
|
124
|
-
|
|
189
|
+
select({
|
|
190
|
+
entityKey: "web",
|
|
191
|
+
entityType: "service",
|
|
192
|
+
displayName: "web",
|
|
193
|
+
});
|
|
125
194
|
}}
|
|
126
195
|
>
|
|
127
|
-
View
|
|
196
|
+
View caller
|
|
197
|
+
</button>
|
|
198
|
+
<button
|
|
199
|
+
onClick={() => {
|
|
200
|
+
select({
|
|
201
|
+
entityKey: "legacy",
|
|
202
|
+
entityType: "service",
|
|
203
|
+
displayName: "legacy",
|
|
204
|
+
});
|
|
205
|
+
}}
|
|
206
|
+
>
|
|
207
|
+
View inactive caller
|
|
208
|
+
</button>
|
|
209
|
+
<button
|
|
210
|
+
onClick={() => {
|
|
211
|
+
select({
|
|
212
|
+
entityKey: "api-instance-1",
|
|
213
|
+
entityType: "service.instance",
|
|
214
|
+
displayName: "api-instance-1",
|
|
215
|
+
});
|
|
216
|
+
}}
|
|
217
|
+
>
|
|
218
|
+
View related instance
|
|
219
|
+
</button>
|
|
220
|
+
<button
|
|
221
|
+
onClick={() => {
|
|
222
|
+
select({ entityKey: "mystery-key" });
|
|
223
|
+
}}
|
|
224
|
+
>
|
|
225
|
+
View untyped resource
|
|
226
|
+
</button>
|
|
227
|
+
<button
|
|
228
|
+
onClick={() => {
|
|
229
|
+
select({
|
|
230
|
+
entityKey: "node-7",
|
|
231
|
+
entityType: "k8s.node",
|
|
232
|
+
displayName: "node-7",
|
|
233
|
+
});
|
|
234
|
+
}}
|
|
235
|
+
>
|
|
236
|
+
View related node
|
|
128
237
|
</button>
|
|
129
238
|
<button
|
|
130
239
|
onClick={() => {
|
|
131
|
-
props.
|
|
240
|
+
if (props.onOpenInfrastructure) {
|
|
241
|
+
props.onOpenInfrastructure("pod-1");
|
|
242
|
+
} else {
|
|
243
|
+
select({
|
|
244
|
+
entityKey: "pod-1",
|
|
245
|
+
entityType: "k8s.pod",
|
|
246
|
+
displayName: "pod-1",
|
|
247
|
+
});
|
|
248
|
+
}
|
|
132
249
|
}}
|
|
133
250
|
>
|
|
134
251
|
View placement
|
|
@@ -146,8 +263,8 @@ jest.mock(
|
|
|
146
263
|
__esModule: true,
|
|
147
264
|
default: (props: {
|
|
148
265
|
onClose: () => void;
|
|
149
|
-
fromEntity:
|
|
150
|
-
toEntity:
|
|
266
|
+
fromEntity: TopologyEntity;
|
|
267
|
+
toEntity: TopologyEntity;
|
|
151
268
|
}) => {
|
|
152
269
|
return (
|
|
153
270
|
<div role="dialog" aria-label="Connection details">
|
|
@@ -281,9 +398,9 @@ const RANGE_START: Date = new Date("2026-09-06T10:00:00Z");
|
|
|
281
398
|
|
|
282
399
|
function item(
|
|
283
400
|
key: string,
|
|
284
|
-
type: EntityType,
|
|
285
|
-
overrides: Partial<
|
|
286
|
-
):
|
|
401
|
+
type: EntityType | string,
|
|
402
|
+
overrides: Partial<TopologyEntity> = {},
|
|
403
|
+
): TopologyEntity {
|
|
287
404
|
return {
|
|
288
405
|
entityKey: key,
|
|
289
406
|
displayName: key,
|
|
@@ -291,7 +408,7 @@ function item(
|
|
|
291
408
|
source: EntitySource.Discovered,
|
|
292
409
|
lastSeenAt: NOW,
|
|
293
410
|
...overrides,
|
|
294
|
-
}
|
|
411
|
+
};
|
|
295
412
|
}
|
|
296
413
|
|
|
297
414
|
function edge(
|
|
@@ -300,7 +417,7 @@ function edge(
|
|
|
300
417
|
calls?: number,
|
|
301
418
|
errors?: number,
|
|
302
419
|
type: EntityRelationshipType = EntityRelationshipType.DependsOn,
|
|
303
|
-
):
|
|
420
|
+
): TopologyRelationship {
|
|
304
421
|
return {
|
|
305
422
|
fromEntityKey: from,
|
|
306
423
|
toEntityKey: to,
|
|
@@ -308,32 +425,54 @@ function edge(
|
|
|
308
425
|
callCount: calls,
|
|
309
426
|
errorCount: errors,
|
|
310
427
|
avgDurationMs: calls === undefined ? undefined : 25,
|
|
311
|
-
}
|
|
428
|
+
};
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function runsOn(
|
|
432
|
+
entityType: string,
|
|
433
|
+
active: number,
|
|
434
|
+
total: number,
|
|
435
|
+
): TopologyRunsOnCount {
|
|
436
|
+
return { entityType, active, total };
|
|
312
437
|
}
|
|
313
438
|
|
|
314
|
-
|
|
439
|
+
/*
|
|
440
|
+
* What the Service Map payload carries: services, what they call and the
|
|
441
|
+
* depends-on rows between them — no pods or hosts. Where services run comes
|
|
442
|
+
* as counts.
|
|
443
|
+
*/
|
|
444
|
+
const ENTITIES: Array<TopologyEntity> = [
|
|
315
445
|
item("web", EntityType.Service),
|
|
316
446
|
item("api", EntityType.Service),
|
|
317
447
|
item("worker", EntityType.Service),
|
|
318
448
|
item("postgres", EntityType.Database, {
|
|
319
449
|
descriptiveAttributes: { "db.system.name": "postgresql" },
|
|
320
450
|
}),
|
|
321
|
-
item("pod-1", EntityType.KubernetesPod),
|
|
322
451
|
item("legacy", EntityType.Service, {
|
|
323
452
|
lastSeenAt: new Date("2026-08-01T00:00:00Z"),
|
|
324
453
|
}),
|
|
325
454
|
];
|
|
326
455
|
|
|
327
|
-
const RELATIONSHIPS: Array<
|
|
456
|
+
const RELATIONSHIPS: Array<TopologyRelationship> = [
|
|
328
457
|
edge("web", "api", 600, 60),
|
|
329
458
|
edge("api", "postgres", 900, 0),
|
|
330
|
-
edge("api", "pod-1", undefined, undefined, EntityRelationshipType.RunsOn),
|
|
331
459
|
];
|
|
332
460
|
|
|
461
|
+
const RUNS_ON_COUNTS: TopologyRunsOnCounts = new Map<
|
|
462
|
+
string,
|
|
463
|
+
Array<TopologyRunsOnCount>
|
|
464
|
+
>([
|
|
465
|
+
["api", [runsOn(EntityType.KubernetesPod, 1, 3)]],
|
|
466
|
+
["worker", [runsOn(EntityType.Host, 0, 2)]],
|
|
467
|
+
["legacy", [runsOn(EntityType.Host, 0, 1)]],
|
|
468
|
+
]);
|
|
469
|
+
|
|
333
470
|
async function renderGraph(
|
|
334
471
|
options: {
|
|
335
|
-
entities?: Array<
|
|
336
|
-
relationships?: Array<
|
|
472
|
+
entities?: Array<TopologyEntity>;
|
|
473
|
+
relationships?: Array<TopologyRelationship>;
|
|
474
|
+
/* null renders without counts, the way full rows are fed. */
|
|
475
|
+
runsOnCounts?: TopologyRunsOnCounts | null;
|
|
337
476
|
includeInactive?: boolean;
|
|
338
477
|
onOpenInfrastructure?: (key: string) => void;
|
|
339
478
|
} = {},
|
|
@@ -344,6 +483,11 @@ async function renderGraph(
|
|
|
344
483
|
<ServiceMapGraph
|
|
345
484
|
entities={options.entities || ENTITIES}
|
|
346
485
|
relationships={options.relationships || RELATIONSHIPS}
|
|
486
|
+
runsOnCounts={
|
|
487
|
+
options.runsOnCounts === undefined
|
|
488
|
+
? RUNS_ON_COUNTS
|
|
489
|
+
: options.runsOnCounts || undefined
|
|
490
|
+
}
|
|
347
491
|
metricsWindowSeconds={60}
|
|
348
492
|
timeRange={{ range: TimeRange.PAST_ONE_DAY }}
|
|
349
493
|
rangeStart={RANGE_START}
|
|
@@ -355,11 +499,21 @@ async function renderGraph(
|
|
|
355
499
|
});
|
|
356
500
|
}
|
|
357
501
|
|
|
502
|
+
function drawer(): HTMLElement {
|
|
503
|
+
return screen.getByRole("dialog", { name: "Service details" });
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
function drawerTarget(): EntityDetailTarget {
|
|
507
|
+
return mockDrawerProps!["entity"] as EntityDetailTarget;
|
|
508
|
+
}
|
|
509
|
+
|
|
358
510
|
beforeEach(() => {
|
|
359
511
|
window.history.replaceState({}, "", "/");
|
|
360
512
|
mockStatuses = new Map<string, ServiceOperationalStatus>();
|
|
361
513
|
mockSetQuery.mockClear();
|
|
362
514
|
mockFitView.mockClear();
|
|
515
|
+
mockDrawerMounts.length = 0;
|
|
516
|
+
mockDrawerProps = null;
|
|
363
517
|
});
|
|
364
518
|
afterEach(() => {
|
|
365
519
|
cleanup();
|
|
@@ -430,8 +584,111 @@ describe("first impression", () => {
|
|
|
430
584
|
});
|
|
431
585
|
});
|
|
432
586
|
|
|
587
|
+
describe("where services run", () => {
|
|
588
|
+
test("comes from the server's counts of what reported in the range", async () => {
|
|
589
|
+
await renderGraph();
|
|
590
|
+
// api runs on 1 active pod of 3; web has no counts at all.
|
|
591
|
+
expect(screen.getByTestId("map-node-api")).toHaveAttribute(
|
|
592
|
+
"data-footer",
|
|
593
|
+
"Runs on 1 pod",
|
|
594
|
+
);
|
|
595
|
+
expect(screen.getByTestId("map-node-web")).toHaveAttribute(
|
|
596
|
+
"data-footer",
|
|
597
|
+
"",
|
|
598
|
+
);
|
|
599
|
+
// worker runs on 2 hosts, neither of which reported: nothing to say.
|
|
600
|
+
expect(
|
|
601
|
+
within(screen.getByTestId("service-map-unconnected")).getByRole(
|
|
602
|
+
"button",
|
|
603
|
+
{ name: /worker/ },
|
|
604
|
+
),
|
|
605
|
+
).toHaveTextContent(/^workerService$/);
|
|
606
|
+
});
|
|
607
|
+
|
|
608
|
+
test("counts every resource when inactive ones are shown", async () => {
|
|
609
|
+
await renderGraph({ includeInactive: true });
|
|
610
|
+
expect(screen.getByTestId("map-node-api")).toHaveAttribute(
|
|
611
|
+
"data-footer",
|
|
612
|
+
"Runs on 3 pods",
|
|
613
|
+
);
|
|
614
|
+
const tray: HTMLElement = screen.getByTestId("service-map-unconnected");
|
|
615
|
+
expect(
|
|
616
|
+
within(tray).getByRole("button", { name: /worker/ }),
|
|
617
|
+
).toHaveTextContent("Service · 2 hosts");
|
|
618
|
+
expect(
|
|
619
|
+
within(tray).getByRole("button", { name: /legacy/ }),
|
|
620
|
+
).toHaveTextContent("Service · 1 host");
|
|
621
|
+
});
|
|
622
|
+
|
|
623
|
+
test("reads several types most first, in the table too", async () => {
|
|
624
|
+
await renderGraph({
|
|
625
|
+
runsOnCounts: new Map<string, Array<TopologyRunsOnCount>>([
|
|
626
|
+
[
|
|
627
|
+
"api",
|
|
628
|
+
[
|
|
629
|
+
runsOn(EntityType.Host, 2, 2),
|
|
630
|
+
runsOn(EntityType.KubernetesPod, 12, 12),
|
|
631
|
+
],
|
|
632
|
+
],
|
|
633
|
+
]),
|
|
634
|
+
});
|
|
635
|
+
expect(screen.getByTestId("map-node-api")).toHaveAttribute(
|
|
636
|
+
"data-footer",
|
|
637
|
+
"Runs on 12 pods · 2 hosts",
|
|
638
|
+
);
|
|
639
|
+
fireEvent.click(screen.getByTestId("service-map-view-list"));
|
|
640
|
+
expect(
|
|
641
|
+
screen.getByRole("button", { name: "api", exact: true }).closest("tr"),
|
|
642
|
+
).toHaveTextContent("Service · 12 pods · 2 hosts");
|
|
643
|
+
});
|
|
644
|
+
|
|
645
|
+
test("without counts, is counted from runs-on rows to resources it was given", async () => {
|
|
646
|
+
await renderGraph({
|
|
647
|
+
entities: [
|
|
648
|
+
...ENTITIES,
|
|
649
|
+
item("pod-1", EntityType.KubernetesPod),
|
|
650
|
+
item("pod-2", EntityType.KubernetesPod),
|
|
651
|
+
item("old-host", EntityType.Host, {
|
|
652
|
+
lastSeenAt: new Date("2026-08-01T00:00:00Z"),
|
|
653
|
+
}),
|
|
654
|
+
],
|
|
655
|
+
relationships: [
|
|
656
|
+
...RELATIONSHIPS,
|
|
657
|
+
edge(
|
|
658
|
+
"api",
|
|
659
|
+
"pod-1",
|
|
660
|
+
undefined,
|
|
661
|
+
undefined,
|
|
662
|
+
EntityRelationshipType.RunsOn,
|
|
663
|
+
),
|
|
664
|
+
edge(
|
|
665
|
+
"api",
|
|
666
|
+
"pod-2",
|
|
667
|
+
undefined,
|
|
668
|
+
undefined,
|
|
669
|
+
EntityRelationshipType.RunsOn,
|
|
670
|
+
),
|
|
671
|
+
edge(
|
|
672
|
+
"api",
|
|
673
|
+
"old-host",
|
|
674
|
+
undefined,
|
|
675
|
+
undefined,
|
|
676
|
+
EntityRelationshipType.HostedOn,
|
|
677
|
+
),
|
|
678
|
+
],
|
|
679
|
+
runsOnCounts: null,
|
|
680
|
+
});
|
|
681
|
+
expect(screen.getByTestId("map-node-api")).toHaveAttribute(
|
|
682
|
+
"data-footer",
|
|
683
|
+
"Runs on 2 pods",
|
|
684
|
+
);
|
|
685
|
+
// Infrastructure is never a node of the Service Map.
|
|
686
|
+
expect(screen.queryByTestId("map-node-pod-1")).not.toBeInTheDocument();
|
|
687
|
+
});
|
|
688
|
+
});
|
|
689
|
+
|
|
433
690
|
describe("a project with services but no observed calls", () => {
|
|
434
|
-
const entities: Array<
|
|
691
|
+
const entities: Array<TopologyEntity> = [
|
|
435
692
|
item("dashboard", EntityType.Service),
|
|
436
693
|
item("probe", EntityType.Service),
|
|
437
694
|
];
|
|
@@ -681,32 +938,215 @@ describe("connections", () => {
|
|
|
681
938
|
});
|
|
682
939
|
|
|
683
940
|
describe("details", () => {
|
|
684
|
-
test("the drawer
|
|
941
|
+
test("the drawer opens on a preview of the node and the server's range start", async () => {
|
|
942
|
+
await renderGraph();
|
|
943
|
+
fireEvent.click(screen.getByTestId("map-node-api"));
|
|
944
|
+
expect(drawer()).toHaveAttribute("data-entity-key", "api");
|
|
945
|
+
expect(drawerTarget()).toEqual({
|
|
946
|
+
entityKey: "api",
|
|
947
|
+
entityType: EntityType.Service,
|
|
948
|
+
displayName: "api",
|
|
949
|
+
});
|
|
950
|
+
expect(mockDrawerProps!["rangeStart"]).toBe(RANGE_START);
|
|
951
|
+
expect(mockDrawerProps!["metricsWindowSeconds"]).toBe(60);
|
|
952
|
+
expect(mockDrawerProps!["focusButtonLabel"]).toBe("Show its connections");
|
|
953
|
+
expect(screen.getByTestId("drawer-subtitle")).toHaveTextContent("Service");
|
|
954
|
+
expect(screen.getByTestId("drawer-status")).toHaveTextContent(
|
|
955
|
+
"High error rate",
|
|
956
|
+
);
|
|
957
|
+
// The drawer fetches connections itself: the map hands it no rows.
|
|
958
|
+
expect(mockDrawerProps).not.toHaveProperty("relationships");
|
|
959
|
+
expect(mockDrawerProps).not.toHaveProperty("entityByKey");
|
|
960
|
+
});
|
|
961
|
+
|
|
962
|
+
test("an unnamed node's preview leaves naming to the drawer", async () => {
|
|
963
|
+
await renderGraph({
|
|
964
|
+
entities: [
|
|
965
|
+
item("svc", EntityType.Service, { displayName: undefined }),
|
|
966
|
+
item("db", EntityType.Database, { displayName: undefined }),
|
|
967
|
+
],
|
|
968
|
+
relationships: [edge("svc", "db", 5, 0)],
|
|
969
|
+
});
|
|
970
|
+
fireEvent.click(screen.getByTestId("map-node-db"));
|
|
971
|
+
expect(drawerTarget()).toEqual({
|
|
972
|
+
entityKey: "db",
|
|
973
|
+
entityType: EntityType.Database,
|
|
974
|
+
displayName: undefined,
|
|
975
|
+
});
|
|
976
|
+
});
|
|
977
|
+
|
|
978
|
+
test("a row pointing at a node of the map selects that node", async () => {
|
|
685
979
|
const onOpenInfrastructure: MockFunction = getJestMockFunction();
|
|
686
980
|
await renderGraph({ onOpenInfrastructure });
|
|
687
981
|
fireEvent.click(screen.getByTestId("map-node-api"));
|
|
688
|
-
expect(screen.getByTestId("drawer-subtitle")).toHaveTextContent("Service");
|
|
689
982
|
fireEvent.click(
|
|
690
983
|
screen.getByRole("button", { name: "View related dependency" }),
|
|
691
984
|
);
|
|
692
|
-
expect(
|
|
693
|
-
|
|
694
|
-
).toHaveTextContent("postgres");
|
|
985
|
+
expect(drawer()).toHaveAttribute("data-entity-key", "postgres");
|
|
986
|
+
expect(screen.getByTestId("drawer-name")).toHaveTextContent("postgres");
|
|
695
987
|
expect(screen.getByTestId("drawer-subtitle")).toHaveTextContent(
|
|
696
988
|
"Database · PostgreSQL",
|
|
697
989
|
);
|
|
990
|
+
// The open drawer carries on to the new node: never a remount.
|
|
991
|
+
expect(mockDrawerMounts).toEqual(["api"]);
|
|
992
|
+
expect(drawer()).toHaveAttribute("data-mounted-for", "api");
|
|
993
|
+
expect(onOpenInfrastructure).not.toHaveBeenCalled();
|
|
994
|
+
fireEvent.click(screen.getByRole("button", { name: "View caller" }));
|
|
995
|
+
expect(screen.getByTestId("drawer-name")).toHaveTextContent("web");
|
|
996
|
+
expect(screen.getByTestId("drawer-status")).toHaveTextContent(
|
|
997
|
+
"Entry point",
|
|
998
|
+
);
|
|
999
|
+
expect(mockDrawerMounts).toEqual(["api"]);
|
|
1000
|
+
});
|
|
1001
|
+
|
|
1002
|
+
test("a runs-on row opens the Infrastructure view and closes the drawer", async () => {
|
|
1003
|
+
const onOpenInfrastructure: MockFunction = getJestMockFunction();
|
|
1004
|
+
await renderGraph({ onOpenInfrastructure });
|
|
1005
|
+
fireEvent.click(screen.getByTestId("map-node-api"));
|
|
698
1006
|
fireEvent.click(screen.getByRole("button", { name: "View placement" }));
|
|
1007
|
+
expect(onOpenInfrastructure).toHaveBeenCalledTimes(1);
|
|
699
1008
|
expect(onOpenInfrastructure).toHaveBeenCalledWith("pod-1");
|
|
700
1009
|
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
|
701
1010
|
});
|
|
702
1011
|
|
|
1012
|
+
test("any other infrastructure a row points at opens in the Infrastructure view", async () => {
|
|
1013
|
+
const onOpenInfrastructure: MockFunction = getJestMockFunction();
|
|
1014
|
+
await renderGraph({ onOpenInfrastructure });
|
|
1015
|
+
fireEvent.click(screen.getByTestId("map-node-api"));
|
|
1016
|
+
fireEvent.click(screen.getByRole("button", { name: "View related node" }));
|
|
1017
|
+
expect(onOpenInfrastructure).toHaveBeenCalledWith("node-7");
|
|
1018
|
+
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
|
1019
|
+
});
|
|
1020
|
+
|
|
1021
|
+
test("without an Infrastructure view, infrastructure opens in the drawer", async () => {
|
|
1022
|
+
await renderGraph();
|
|
1023
|
+
fireEvent.click(screen.getByTestId("map-node-api"));
|
|
1024
|
+
fireEvent.click(screen.getByRole("button", { name: "View placement" }));
|
|
1025
|
+
expect(drawer()).toHaveAttribute("data-entity-key", "pod-1");
|
|
1026
|
+
expect(drawerTarget()).toEqual({
|
|
1027
|
+
entityKey: "pod-1",
|
|
1028
|
+
entityType: EntityType.KubernetesPod,
|
|
1029
|
+
displayName: "pod-1",
|
|
1030
|
+
});
|
|
1031
|
+
// Not a node of this map: no traffic, and nothing to focus on.
|
|
1032
|
+
expect(screen.getByTestId("drawer-status")).toBeEmptyDOMElement();
|
|
1033
|
+
expect(mockDrawerProps!["onFocus"]).toBeUndefined();
|
|
1034
|
+
expect(mockDrawerProps!["onOpenInfrastructure"]).toBeUndefined();
|
|
1035
|
+
expect(
|
|
1036
|
+
screen.queryByRole("button", { name: "Show its connections" }),
|
|
1037
|
+
).not.toBeInTheDocument();
|
|
1038
|
+
});
|
|
1039
|
+
|
|
1040
|
+
test("a service that is not on the map opens in the drawer, not elsewhere", async () => {
|
|
1041
|
+
const onOpenInfrastructure: MockFunction = getJestMockFunction();
|
|
1042
|
+
await renderGraph({ onOpenInfrastructure });
|
|
1043
|
+
fireEvent.click(screen.getByTestId("map-node-api"));
|
|
1044
|
+
fireEvent.click(
|
|
1045
|
+
screen.getByRole("button", { name: "View inactive caller" }),
|
|
1046
|
+
);
|
|
1047
|
+
expect(onOpenInfrastructure).not.toHaveBeenCalled();
|
|
1048
|
+
expect(drawer()).toHaveAttribute("data-entity-key", "legacy");
|
|
1049
|
+
expect(drawerTarget()).toEqual({
|
|
1050
|
+
entityKey: "legacy",
|
|
1051
|
+
entityType: EntityType.Service,
|
|
1052
|
+
displayName: "legacy",
|
|
1053
|
+
});
|
|
1054
|
+
expect(screen.getByTestId("drawer-status")).toBeEmptyDOMElement();
|
|
1055
|
+
expect(screen.getByTestId("drawer-incidents")).toHaveTextContent("none");
|
|
1056
|
+
expect(
|
|
1057
|
+
screen.queryByRole("button", { name: "Show its connections" }),
|
|
1058
|
+
).not.toBeInTheDocument();
|
|
1059
|
+
});
|
|
1060
|
+
|
|
1061
|
+
test("application types and untyped resources open in the drawer", async () => {
|
|
1062
|
+
const onOpenInfrastructure: MockFunction = getJestMockFunction();
|
|
1063
|
+
await renderGraph({ onOpenInfrastructure });
|
|
1064
|
+
fireEvent.click(screen.getByTestId("map-node-api"));
|
|
1065
|
+
fireEvent.click(
|
|
1066
|
+
screen.getByRole("button", { name: "View related instance" }),
|
|
1067
|
+
);
|
|
1068
|
+
expect(drawer()).toHaveAttribute("data-entity-key", "api-instance-1");
|
|
1069
|
+
fireEvent.click(
|
|
1070
|
+
screen.getByRole("button", { name: "View untyped resource" }),
|
|
1071
|
+
);
|
|
1072
|
+
expect(drawer()).toHaveAttribute("data-entity-key", "mystery-key");
|
|
1073
|
+
expect(drawerTarget()).toEqual({ entityKey: "mystery-key" });
|
|
1074
|
+
expect(onOpenInfrastructure).not.toHaveBeenCalled();
|
|
1075
|
+
});
|
|
1076
|
+
|
|
1077
|
+
test("from a drawer off the map, rows and the map lead back onto it", async () => {
|
|
1078
|
+
await renderGraph();
|
|
1079
|
+
fireEvent.click(screen.getByTestId("map-node-api"));
|
|
1080
|
+
fireEvent.click(
|
|
1081
|
+
screen.getByRole("button", { name: "View inactive caller" }),
|
|
1082
|
+
);
|
|
1083
|
+
fireEvent.click(
|
|
1084
|
+
screen.getByRole("button", { name: "View related dependency" }),
|
|
1085
|
+
);
|
|
1086
|
+
expect(drawer()).toHaveAttribute("data-entity-key", "postgres");
|
|
1087
|
+
expect(
|
|
1088
|
+
screen.getByRole("button", { name: "Show its connections" }),
|
|
1089
|
+
).toBeInTheDocument();
|
|
1090
|
+
fireEvent.click(
|
|
1091
|
+
screen.getByRole("button", { name: "View inactive caller" }),
|
|
1092
|
+
);
|
|
1093
|
+
fireEvent.click(screen.getByTestId("map-node-web"));
|
|
1094
|
+
expect(drawer()).toHaveAttribute("data-entity-key", "web");
|
|
1095
|
+
expect(screen.getByTestId("drawer-status")).toHaveTextContent(
|
|
1096
|
+
"Entry point",
|
|
1097
|
+
);
|
|
1098
|
+
/* Rows and map clicks alike moved the one open drawer along. */
|
|
1099
|
+
expect(mockDrawerMounts).toEqual(["api"]);
|
|
1100
|
+
});
|
|
1101
|
+
|
|
1102
|
+
test("a connection closes a drawer that is open off the map", async () => {
|
|
1103
|
+
await renderGraph();
|
|
1104
|
+
fireEvent.click(screen.getByTestId("map-node-api"));
|
|
1105
|
+
fireEvent.click(
|
|
1106
|
+
screen.getByRole("button", { name: "View inactive caller" }),
|
|
1107
|
+
);
|
|
1108
|
+
fireEvent.click(screen.getByTestId("map-edge-api->postgres"));
|
|
1109
|
+
expect(
|
|
1110
|
+
screen.queryByRole("dialog", { name: "Service details" }),
|
|
1111
|
+
).not.toBeInTheDocument();
|
|
1112
|
+
expect(
|
|
1113
|
+
screen.getByRole("dialog", { name: "Connection details" }),
|
|
1114
|
+
).toBeInTheDocument();
|
|
1115
|
+
});
|
|
1116
|
+
|
|
1117
|
+
test("with inactive services shown, the same service is a node again", async () => {
|
|
1118
|
+
await renderGraph({ includeInactive: true });
|
|
1119
|
+
fireEvent.click(screen.getByTestId("map-node-api"));
|
|
1120
|
+
fireEvent.click(
|
|
1121
|
+
screen.getByRole("button", { name: "View inactive caller" }),
|
|
1122
|
+
);
|
|
1123
|
+
expect(drawer()).toHaveAttribute("data-entity-key", "legacy");
|
|
1124
|
+
expect(screen.getByTestId("drawer-status")).toHaveTextContent(
|
|
1125
|
+
"No calls observed",
|
|
1126
|
+
);
|
|
1127
|
+
expect(
|
|
1128
|
+
screen.getByRole("button", { name: "Show its connections" }),
|
|
1129
|
+
).toBeInTheDocument();
|
|
1130
|
+
});
|
|
1131
|
+
|
|
1132
|
+
test("closing the drawer clears the selection", async () => {
|
|
1133
|
+
await renderGraph();
|
|
1134
|
+
fireEvent.click(screen.getByTestId("map-node-api"));
|
|
1135
|
+
fireEvent.click(screen.getByRole("button", { name: "Close service" }));
|
|
1136
|
+
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
|
1137
|
+
fireEvent.click(screen.getByTestId("map-node-api"));
|
|
1138
|
+
expect(mockDrawerMounts).toEqual(["api", "api"]);
|
|
1139
|
+
});
|
|
1140
|
+
|
|
703
1141
|
test("focusing from the drawer opens that node's connections on the map", async () => {
|
|
704
1142
|
await renderGraph();
|
|
705
1143
|
fireEvent.click(screen.getByTestId("service-map-view-list"));
|
|
706
1144
|
fireEvent.click(
|
|
707
1145
|
screen.getByRole("button", { name: "postgres", exact: true }),
|
|
708
1146
|
);
|
|
709
|
-
fireEvent.click(
|
|
1147
|
+
fireEvent.click(
|
|
1148
|
+
screen.getByRole("button", { name: "Show its connections" }),
|
|
1149
|
+
);
|
|
710
1150
|
expect(screen.queryByRole("dialog")).not.toBeInTheDocument();
|
|
711
1151
|
expect(screen.getByTestId("service-map-view-map")).toHaveAttribute(
|
|
712
1152
|
"aria-pressed",
|
|
@@ -716,6 +1156,38 @@ describe("details", () => {
|
|
|
716
1156
|
expect(screen.queryByTestId("map-node-web")).not.toBeInTheDocument();
|
|
717
1157
|
});
|
|
718
1158
|
|
|
1159
|
+
test("a service's incidents reach its drawer; a dependency's never do", async () => {
|
|
1160
|
+
mockStatuses.set("api", {
|
|
1161
|
+
serviceId: "api-id",
|
|
1162
|
+
activeIncidentCount: 2,
|
|
1163
|
+
worstIncidentSeverityName: "Critical",
|
|
1164
|
+
worstIncidentSeverityColor: "#dc2626",
|
|
1165
|
+
incidents: [],
|
|
1166
|
+
activeAlertCount: 0,
|
|
1167
|
+
worstAlertSeverityName: null,
|
|
1168
|
+
worstAlertSeverityColor: null,
|
|
1169
|
+
alerts: [],
|
|
1170
|
+
});
|
|
1171
|
+
mockStatuses.set("postgres", {
|
|
1172
|
+
serviceId: "postgres-id",
|
|
1173
|
+
activeIncidentCount: 5,
|
|
1174
|
+
worstIncidentSeverityName: "Critical",
|
|
1175
|
+
worstIncidentSeverityColor: "#dc2626",
|
|
1176
|
+
incidents: [],
|
|
1177
|
+
activeAlertCount: 0,
|
|
1178
|
+
worstAlertSeverityName: null,
|
|
1179
|
+
worstAlertSeverityColor: null,
|
|
1180
|
+
alerts: [],
|
|
1181
|
+
});
|
|
1182
|
+
await renderGraph();
|
|
1183
|
+
fireEvent.click(screen.getByTestId("map-node-api"));
|
|
1184
|
+
expect(screen.getByTestId("drawer-incidents")).toHaveTextContent("2");
|
|
1185
|
+
fireEvent.click(
|
|
1186
|
+
screen.getByRole("button", { name: "View related dependency" }),
|
|
1187
|
+
);
|
|
1188
|
+
expect(screen.getByTestId("drawer-incidents")).toHaveTextContent("none");
|
|
1189
|
+
});
|
|
1190
|
+
|
|
719
1191
|
test("incidents take precedence over traffic in status", async () => {
|
|
720
1192
|
mockStatuses.set("worker", {
|
|
721
1193
|
serviceId: "worker-id",
|
|
@@ -755,7 +1227,7 @@ describe("table", () => {
|
|
|
755
1227
|
});
|
|
756
1228
|
|
|
757
1229
|
test("a large catalog opens as a paged table with a hint to narrow it", async () => {
|
|
758
|
-
const many: Array<
|
|
1230
|
+
const many: Array<TopologyEntity> = Array.from(
|
|
759
1231
|
{ length: 130 },
|
|
760
1232
|
(_value: unknown, index: number) => {
|
|
761
1233
|
return item(
|