@oneuptime/common 12.0.6 → 12.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/AIInsight.ts +1 -1
- package/Models/DatabaseModels/DatabaseBaseModel/FileModel.ts +2 -3
- package/Models/DatabaseModels/DeletedProject.ts +595 -0
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/Monitor.ts +111 -0
- package/Models/DatabaseModels/Project.ts +3 -3
- package/Models/DatabaseModels/TelemetryEntity.ts +45 -0
- package/Models/DatabaseModels/TelemetryEntityRelationship.ts +26 -0
- package/Models/DatabaseModels/WorkflowLog.ts +38 -0
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -1
- package/Server/API/FileAPI.ts +15 -2
- package/Server/API/MicrosoftTeamsAPI.ts +6 -1
- package/Server/API/ProjectAPI.ts +214 -0
- package/Server/API/StatusPageAPI.ts +39 -6
- package/Server/API/UserAPI.ts +16 -1
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.ts +50 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.ts +67 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.ts +39 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.ts +41 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.ts +17 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Middleware/MasterAdminAuthorization.ts +11 -6
- package/Server/Services/AIAgentService.ts +20 -0
- package/Server/Services/DashboardDomainService.ts +73 -28
- package/Server/Services/DatabaseService.ts +1 -0
- package/Server/Services/DeletedProjectService.ts +138 -0
- package/Server/Services/FileService.ts +61 -0
- package/Server/Services/IncidentEpisodePublicNoteService.ts +18 -0
- package/Server/Services/IncidentPublicNoteService.ts +18 -0
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/MonitorService.ts +311 -0
- package/Server/Services/ProbeService.ts +20 -0
- package/Server/Services/ProjectService.ts +297 -1
- package/Server/Services/PushNotificationService.ts +71 -0
- package/Server/Services/ScheduledMaintenancePublicNoteService.ts +18 -0
- package/Server/Services/StatusPageAnnouncementService.ts +53 -0
- package/Server/Services/StatusPageDomainService.ts +73 -28
- package/Server/Services/TeamMemberService.ts +117 -12
- package/Server/Services/TelemetryEntityRelationshipService.ts +3 -0
- package/Server/Services/TelemetryEntityService.ts +114 -1
- package/Server/Services/TelemetryIngestionKeyService.ts +1 -0
- package/Server/Services/UserWebhookService.ts +34 -109
- package/Server/Services/WorkspaceNotificationRuleService.ts +69 -0
- package/Server/Services/WorkspaceProjectAuthTokenService.ts +37 -1
- package/Server/Types/Database/DeleteById.ts +2 -0
- package/Server/Types/Database/DeleteOneBy.ts +6 -0
- package/Server/Types/Domain.ts +41 -0
- package/Server/Types/Workflow/Components/API/Delete.ts +2 -1
- package/Server/Types/Workflow/Components/API/Get.ts +2 -1
- package/Server/Types/Workflow/Components/API/Patch.ts +2 -1
- package/Server/Types/Workflow/Components/API/Post.ts +2 -1
- package/Server/Types/Workflow/Components/API/Put.ts +2 -1
- package/Server/Types/Workflow/Components/API/Utils.ts +85 -3
- package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +25 -19
- package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +6 -5
- package/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.ts +32 -14
- package/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.ts +31 -13
- package/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.ts +29 -20
- package/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.ts +28 -21
- package/Server/Types/Workflow/Components/BaseModel/LogComponentError.ts +89 -0
- package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +208 -0
- package/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.ts +11 -0
- package/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.ts +41 -18
- package/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.ts +45 -19
- package/Server/Types/Workflow/Components/Discord/SendMessageToChannel.ts +16 -9
- package/Server/Types/Workflow/Components/IncomingWebhookUtils.ts +66 -0
- package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +15 -9
- package/Server/Types/Workflow/Components/Slack/SendMessageToChannel.ts +17 -0
- package/Server/Types/Workflow/TriggerCode.ts +12 -0
- package/Server/Types/Workflow/Workflow.ts +5 -0
- package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
- package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +171 -0
- package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +3 -3
- package/Server/Utils/AI/SRE/Insights/FixRouting.ts +3 -2
- package/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.ts +1 -1
- package/Server/Utils/AI/Toolbox/CodeWriteTools.ts +6 -6
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +43 -5
- package/Server/Utils/DataSource/EgressGuard.ts +176 -16
- package/Server/Utils/DataSource/HttpFetch.ts +6 -45
- package/Server/Utils/Execute.ts +8 -0
- package/Server/Utils/InlineImageAccessTokenSync.ts +23 -0
- package/Server/Utils/LLM/LLMService.ts +57 -12
- package/Server/Utils/Monitor/MonitorAlert.ts +40 -0
- package/Server/Utils/Monitor/MonitorDependencySuppression.ts +192 -0
- package/Server/Utils/Monitor/MonitorIncident.ts +40 -0
- package/Server/Utils/Monitor/MonitorResource.ts +36 -0
- package/Server/Utils/Response.ts +142 -6
- package/Server/Utils/SSRFProtection.ts +273 -60
- package/Server/Utils/StartServer.ts +8 -0
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +689 -0
- package/Server/Utils/VM/VMAPI.ts +56 -8
- package/Server/Utils/VM/VMRunner.ts +88 -1
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +555 -49
- package/Server/Utils/Workspace/Slack/Slack.ts +25 -2
- package/Server/Utils/Workspace/WorkspaceBase.ts +6 -0
- package/Tests/App/Dashboard/DangerZone.test.tsx +334 -0
- package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +539 -0
- package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +678 -0
- package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +706 -0
- package/Tests/App/Dashboard/DashboardVariablesModal.test.tsx +508 -0
- package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +574 -0
- package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +470 -0
- package/Tests/App/StatusPage/StatusPageDetailPagesNotFound.test.tsx +308 -0
- package/Tests/Models/DatabaseModels/DeletedProjectModel.test.ts +251 -0
- package/Tests/Models/DatabaseModels/SavedViewJSONColumnTuples.test.ts +115 -0
- package/Tests/Server/API/FileAPIAccessControl.test.ts +316 -0
- package/Tests/Server/API/ProjectAPI.test.ts +299 -1
- package/Tests/Server/API/ProjectAPIAdjustBalance.test.ts +459 -0
- package/Tests/Server/API/ProjectAPIAdjustBalanceBillingDisabled.test.ts +177 -0
- package/Tests/Server/API/UserProjectsAPI.test.ts +478 -4
- package/Tests/Server/Services/DatabaseServiceDeletionReason.test.ts +123 -0
- package/Tests/Server/Services/DeletedProjectService.test.ts +415 -0
- package/Tests/Server/Services/DeletedProjectServiceSelfHosted.test.ts +70 -0
- package/Tests/Server/Services/DomainSubdomainHooks.test.ts +94 -0
- package/Tests/Server/Services/FileIsPublicBooleanMigration.test.ts +244 -0
- package/Tests/Server/Services/FileServiceMimeType.test.ts +89 -0
- package/Tests/Server/Services/MonitorServiceDependencyValidation.test.ts +702 -0
- package/Tests/Server/Services/ProjectServiceAdjustBalance.test.ts +615 -0
- package/Tests/Server/Services/ProjectServiceDeleteAudit.test.ts +406 -0
- package/Tests/Server/Services/PublishTimeImageVisibility.test.ts +450 -0
- package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +669 -0
- package/Tests/Server/Services/TelemetryEntityManualCreate.test.ts +248 -0
- package/Tests/Server/Services/UserWebhookSSRF.test.ts +174 -0
- package/Tests/Server/Services/WebPushEndpointAllowlist.test.ts +133 -0
- package/Tests/Server/Services/WorkspaceProjectAuthTokenRepoint.test.ts +618 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +26 -1
- package/Tests/Server/Types/Workflow/Components/ApiComponentHeaders.test.ts +192 -0
- package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +215 -0
- package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +742 -0
- package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +256 -0
- package/Tests/Server/Types/Workflow/Components/ModelArguments.test.ts +371 -0
- package/Tests/Server/Utils/AI/CodeAgentCommandGuard.test.ts +204 -0
- package/Tests/Server/Utils/AI/CodeAgentWriteLimits.test.ts +213 -0
- package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +52 -5
- package/Tests/Server/Utils/AI/LLMServiceBaseUrl.test.ts +3 -0
- package/Tests/Server/Utils/AI/LLMServiceEgressGuard.test.ts +315 -0
- package/Tests/Server/Utils/AI/LLMServiceModelCompatibility.test.ts +3 -0
- package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +17 -5
- package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +14 -1
- package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +35 -0
- package/Tests/Server/Utils/AI/StubLLMEgressGuard.ts +25 -0
- package/Tests/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.test.ts +152 -0
- package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +62 -7
- package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +69 -0
- package/Tests/Server/Utils/DataSource/EgressGuardPinning.test.ts +330 -0
- package/Tests/Server/Utils/GitHubCreatePullRequestWithToken.test.ts +393 -0
- package/Tests/Server/Utils/InlineImageAccessTokenSync.test.ts +202 -0
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppression.test.ts +811 -0
- package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +604 -0
- package/Tests/Server/Utils/ResponseSendFileResponse.test.ts +192 -0
- package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +406 -0
- package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +322 -0
- package/Tests/Server/Utils/VM/VMAPISubstitution.test.ts +243 -0
- package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +194 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +1169 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelsList.test.ts +2 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +1605 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsTenantResolution.test.ts +1218 -0
- package/Tests/Types/AI/AIChatMessageStatus.test.ts +79 -0
- package/Tests/Types/AI/AIInsightStatus.test.ts +40 -0
- package/Tests/Types/API/HostnameAuthorityParsing.test.ts +157 -0
- package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +27 -0
- package/Tests/Types/DataSource/DataSourceLimits.test.ts +71 -0
- package/Tests/Types/DataSource/DataSourceType.test.ts +181 -0
- package/Tests/Types/DomainSubdomainValidation.test.ts +90 -0
- package/Tests/Types/JSONFunctions.test.ts +252 -1
- package/Tests/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.test.ts +61 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.test.ts +62 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.test.ts +68 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpVersion.test.ts +51 -0
- package/Tests/Types/SerializableObjectDictionaryImportCycle.test.ts +197 -0
- package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +140 -0
- package/Tests/Types/Workflow/StepTrace.test.ts +235 -0
- package/Tests/Types/Workflow/TemplateSyntax.test.ts +379 -0
- package/Tests/Types/Workflow/Templates.test.ts +403 -0
- package/Tests/UI/Components/404.test.tsx +1 -1
- package/Tests/UI/Components/Alert.test.tsx +1 -1
- package/Tests/UI/Components/Badge.test.tsx +1 -1
- package/Tests/UI/Components/BasicForm.test.tsx +39 -10
- package/Tests/UI/Components/Button.test.tsx +1 -1
- package/Tests/UI/Components/Card.test.tsx +1 -1
- package/Tests/UI/Components/Charts/AxisTickColor.test.tsx +1 -1
- package/Tests/UI/Components/ColorViewer.test.tsx +1 -1
- package/Tests/UI/Components/ComponentsModal.test.tsx +7 -1
- package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +459 -0
- package/Tests/UI/Components/DictionaryAttributeFilterRow.test.tsx +477 -0
- package/Tests/UI/Components/DictionaryOfStrings.test.tsx +1 -1
- package/Tests/UI/Components/Dropdown.test.tsx +1 -1
- package/Tests/UI/Components/FilePicker.test.tsx +1 -1
- package/Tests/UI/Components/Forms/AnchoredFieldPopupKeyboard.test.tsx +382 -0
- package/Tests/UI/Components/Forms/ColorPickerPicking.test.tsx +569 -0
- package/Tests/UI/Components/Forms/ValidationJSON.test.ts +241 -0
- package/Tests/UI/Components/HiddenText.test.tsx +1 -1
- package/Tests/UI/Components/Input.test.tsx +1 -1
- package/Tests/UI/Components/Loader.test.tsx +1 -1
- package/Tests/UI/Components/LogTimeRangePicker.test.tsx +43 -1
- package/Tests/UI/Components/MasterPage.test.tsx +1 -1
- package/Tests/UI/Components/ModalPortalDismissal.test.tsx +579 -0
- package/Tests/UI/Components/ModelDelete.test.tsx +214 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkSelectAll.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1 -1
- package/Tests/UI/Components/NavBar.test.tsx +1 -1
- package/Tests/UI/Components/OperatorSelectorKeyboard.test.tsx +1 -1
- package/Tests/UI/Components/Pagination.test.tsx +1 -1
- package/Tests/UI/Components/Pill.test.tsx +1 -1
- package/Tests/UI/Components/Probe.test.tsx +1 -1
- package/Tests/UI/Components/ProgressBar.test.tsx +1 -1
- package/Tests/UI/Components/RadioButtons.test.tsx +1 -1
- package/Tests/UI/Components/SideMenuItem.test.tsx +1 -1
- package/Tests/UI/Components/SideOver.test.tsx +500 -6
- package/Tests/UI/Components/Tabs.test.tsx +1 -1
- package/Tests/UI/Components/TelemetrySearchBar.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +50 -8
- package/Tests/UI/Components/TextArea.test.tsx +1 -1
- package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +325 -0
- package/Tests/UI/Components/Toast.test.tsx +1 -1
- package/Tests/UI/Components/Toggle.test.tsx +1 -1
- package/Tests/UI/Components/TopSection.test.tsx +1 -1
- package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +1 -1
- package/Tests/UI/Components/Workflow/GraphLint.test.ts +821 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +287 -0
- package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +185 -0
- package/Tests/UI/Components/Workflow/ModelSchema.test.ts +174 -0
- package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +152 -0
- package/Tests/UI/Components/Workflow/Utils.test.ts +192 -0
- package/Tests/UI/Monitor/MonitorStepCriteriaView.test.tsx +432 -0
- package/Tests/UI/Rum/ReplayScrubber.test.tsx +1 -1
- package/Tests/UI/Rum/ReplayStage.test.tsx +1 -1
- package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +1 -1
- package/Tests/UI/Utils/LocalStorageArrayRoundTrip.test.ts +72 -0
- package/Tests/Utils/Dashboard/HtmlWidgetDocument.test.ts +19 -2
- package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +44 -0
- package/Tests/Utils/Dashboard/VariableInterpolation.test.ts +288 -5
- package/Tests/Utils/Dashboard/VariableUrlState.test.ts +42 -0
- package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +27 -0
- package/Tests/Utils/LegacySerializedArray.test.ts +139 -0
- package/Tests/Utils/Monitor/MonitorDependencyRule.test.ts +190 -0
- package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +514 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +240 -0
- package/Tests/Utils/Realtime.test.ts +78 -0
- package/Tests/Utils/Schema/AnalyticsModelSchema.test.ts +469 -0
- package/Tests/Utils/Schema/ModelSchema.test.ts +268 -0
- package/Tests/Utils/Telemetry/EntityKeyNonTelemetry.test.ts +193 -0
- package/Tests/Utils/Telemetry/SavedViewFilters.test.ts +246 -0
- package/Tests/__mocks__/i18next-browser-languagedetector.js +21 -0
- package/Types/AI/FixPullRequestCiStatus.ts +1 -1
- package/Types/AI/FixVerificationStatus.ts +2 -2
- package/Types/API/Hostname.ts +92 -4
- package/Types/API/URL.ts +43 -25
- package/Types/Billing/BalanceAdjustmentType.ts +14 -0
- package/Types/Billing/ProjectBalanceType.ts +13 -0
- package/Types/Domain.ts +26 -0
- package/Types/File/MimeType.ts +11 -0
- package/Types/JSONFunctions.ts +15 -0
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -0
- package/Types/SerializableObjectDictionary.ts +133 -39
- package/Types/Telemetry/EntitySource.ts +40 -0
- package/Types/Telemetry/EntityType.ts +27 -0
- package/Types/Telemetry/EntityTypeGroups.ts +65 -0
- package/Types/Telemetry/TelemetrySavedViewState.ts +9 -1
- package/Types/Workflow/Component.ts +29 -0
- package/Types/Workflow/Components/API.ts +35 -0
- package/Types/Workflow/Components/BaseModel.ts +96 -28
- package/Types/Workflow/StepTrace.ts +181 -0
- package/Types/Workflow/TemplateSyntax.ts +499 -0
- package/Types/Workflow/Templates.ts +316 -0
- package/Typings/Index.d.ts +12 -0
- package/UI/Components/Date/CustomTimeRangeModal.tsx +278 -0
- package/UI/Components/Date/TimeRangePickerDropdown.tsx +250 -0
- package/UI/Components/Dictionary/Dictionary.tsx +23 -6
- package/UI/Components/Forms/Fields/ColorPicker.tsx +66 -10
- package/UI/Components/Forms/Fields/IconPicker.tsx +48 -10
- package/UI/Components/Forms/Types/Field.ts +7 -0
- package/UI/Components/Forms/Validation.ts +63 -1
- package/UI/Components/GanttChart/ChartContainer.tsx +4 -3
- package/UI/Components/Input/Input.tsx +31 -3
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +11 -216
- package/UI/Components/Modal/ConfirmModal.tsx +10 -5
- package/UI/Components/Modal/Modal.tsx +64 -51
- package/UI/Components/ModelDelete/ModelDelete.tsx +23 -6
- package/UI/Components/SideOver/SideOver.tsx +195 -68
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +11 -210
- package/UI/Components/Workflow/ArgumentsForm.tsx +194 -7
- package/UI/Components/Workflow/Component.tsx +28 -26
- package/UI/Components/Workflow/ComponentSettingsModal.tsx +69 -8
- package/UI/Components/Workflow/GraphLint.ts +591 -0
- package/UI/Components/Workflow/ModelColumnEditor.tsx +396 -0
- package/UI/Components/Workflow/ModelSchema.ts +196 -0
- package/UI/Components/Workflow/RunForm.tsx +41 -7
- package/UI/Components/Workflow/RunStatusWatcher.ts +122 -0
- package/UI/Components/Workflow/StepTraceViewer.tsx +186 -0
- package/UI/Components/Workflow/Utils.ts +93 -1
- package/UI/Components/Workflow/Workflow.tsx +77 -4
- package/UI/Types/LayeredDismissal.ts +31 -0
- package/UI/Types/UseAnchoredFieldPopup.ts +99 -0
- package/UI/Utils/PageScrollLock.ts +66 -0
- package/Utils/Dashboard/HtmlWidgetDocument.ts +4 -2
- package/Utils/Dashboard/VariableInterpolation.ts +19 -1
- package/Utils/LegacySerializedArray.ts +60 -0
- package/Utils/Monitor/MonitorDependencyRule.ts +88 -0
- package/Utils/Monitor/NetworkDeviceRoleUtil.ts +533 -0
- package/Utils/Monitor/NetworkTopologyUtil.ts +45 -7
- package/Utils/Telemetry/EntityKey.ts +66 -0
- package/Utils/Telemetry/SavedViewFilters.ts +88 -0
- package/build/dist/Models/DatabaseModels/AIInsight.js +1 -1
- package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js +2 -3
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DeletedProject.js +640 -0
- package/build/dist/Models/DatabaseModels/DeletedProject.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Monitor.js +106 -0
- package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +3 -3
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntity.js +47 -0
- package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js +27 -0
- package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkflowLog.js +39 -0
- package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/FileAPI.js +14 -2
- package/build/dist/Server/API/FileAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +6 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/ProjectAPI.js +157 -4
- package/build/dist/Server/API/ProjectAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +27 -3
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/UserAPI.js +16 -1
- package/build/dist/Server/API/UserAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js +34 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -6
- package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
- package/build/dist/Server/Services/AIAgentService.js +17 -0
- package/build/dist/Server/Services/AIAgentService.js.map +1 -1
- package/build/dist/Server/Services/DashboardDomainService.js +55 -18
- package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +1 -0
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/DeletedProjectService.js +124 -0
- package/build/dist/Server/Services/DeletedProjectService.js.map +1 -0
- package/build/dist/Server/Services/FileService.js +52 -0
- package/build/dist/Server/Services/FileService.js.map +1 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +10 -1
- package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js +10 -1
- package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +232 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/ProbeService.js +17 -0
- package/build/dist/Server/Services/ProbeService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +228 -6
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/PushNotificationService.js +56 -0
- package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +10 -1
- package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageAnnouncementService.js +54 -0
- package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
- package/build/dist/Server/Services/StatusPageDomainService.js +55 -18
- package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
- package/build/dist/Server/Services/TeamMemberService.js +97 -6
- package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +3 -0
- package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryEntityService.js +91 -1
- package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js +1 -0
- package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
- package/build/dist/Server/Services/UserWebhookService.js +31 -87
- package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +65 -0
- package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +23 -0
- package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
- package/build/dist/Server/Types/Domain.js +37 -0
- package/build/dist/Server/Types/Domain.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js +2 -1
- package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js +63 -2
- package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +15 -11
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +2 -3
- package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js +21 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js +21 -10
- package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js +18 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js +18 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js +43 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +116 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js +7 -0
- package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js +24 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js +27 -13
- package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js +14 -6
- package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js +42 -0
- package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js.map +1 -0
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +15 -6
- package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js +10 -2
- package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js.map +1 -1
- package/build/dist/Server/Types/Workflow/TriggerCode.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +141 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.js +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js +6 -6
- package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +39 -5
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/EgressGuard.js +94 -10
- package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
- package/build/dist/Server/Utils/DataSource/HttpFetch.js +1 -19
- package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
- package/build/dist/Server/Utils/Execute.js +2 -2
- package/build/dist/Server/Utils/Execute.js.map +1 -1
- package/build/dist/Server/Utils/InlineImageAccessTokenSync.js +13 -0
- package/build/dist/Server/Utils/InlineImageAccessTokenSync.js.map +1 -1
- package/build/dist/Server/Utils/LLM/LLMService.js +43 -12
- package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js +44 -24
- package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js +158 -0
- package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js +50 -30
- package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +32 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +112 -5
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/SSRFProtection.js +219 -53
- package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
- package/build/dist/Server/Utils/StartServer.js +7 -0
- package/build/dist/Server/Utils/StartServer.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +507 -0
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -0
- package/build/dist/Server/Utils/VM/VMAPI.js +51 -4
- package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
- package/build/dist/Server/Utils/VM/VMRunner.js +73 -1
- package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +445 -43
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +18 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
- package/build/dist/Types/AI/FixPullRequestCiStatus.js +1 -1
- package/build/dist/Types/AI/FixVerificationStatus.js +2 -2
- package/build/dist/Types/API/Hostname.js +73 -4
- package/build/dist/Types/API/Hostname.js.map +1 -1
- package/build/dist/Types/API/URL.js +42 -24
- package/build/dist/Types/API/URL.js.map +1 -1
- package/build/dist/Types/Billing/BalanceAdjustmentType.js +15 -0
- package/build/dist/Types/Billing/BalanceAdjustmentType.js.map +1 -0
- package/build/dist/Types/Billing/ProjectBalanceType.js +14 -0
- package/build/dist/Types/Billing/ProjectBalanceType.js.map +1 -0
- package/build/dist/Types/Domain.js +22 -0
- package/build/dist/Types/Domain.js.map +1 -1
- package/build/dist/Types/File/MimeType.js +11 -0
- package/build/dist/Types/File/MimeType.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +14 -0
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/SerializableObjectDictionary.js +133 -39
- package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
- package/build/dist/Types/Telemetry/EntitySource.js +39 -0
- package/build/dist/Types/Telemetry/EntitySource.js.map +1 -0
- package/build/dist/Types/Telemetry/EntityType.js +27 -0
- package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
- package/build/dist/Types/Telemetry/EntityTypeGroups.js +57 -0
- package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -0
- package/build/dist/Types/Workflow/Component.js +21 -0
- package/build/dist/Types/Workflow/Component.js.map +1 -1
- package/build/dist/Types/Workflow/Components/API.js +35 -0
- package/build/dist/Types/Workflow/Components/API.js.map +1 -1
- package/build/dist/Types/Workflow/Components/BaseModel.js +87 -28
- package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
- package/build/dist/Types/Workflow/StepTrace.js +104 -0
- package/build/dist/Types/Workflow/StepTrace.js.map +1 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js +326 -0
- package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -0
- package/build/dist/Types/Workflow/Templates.js +218 -0
- package/build/dist/Types/Workflow/Templates.js.map +1 -0
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +126 -0
- package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -0
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +123 -0
- package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -0
- package/build/dist/UI/Components/Dictionary/Dictionary.js +22 -6
- package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +52 -13
- package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js +28 -12
- package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Validation.js +44 -0
- package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
- package/build/dist/UI/Components/GanttChart/ChartContainer.js +4 -3
- package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +12 -4
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +5 -108
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js +3 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +55 -39
- package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
- package/build/dist/UI/Components/ModelDelete/ModelDelete.js +11 -6
- package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
- package/build/dist/UI/Components/SideOver/SideOver.js +105 -30
- package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +5 -105
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js +140 -11
- package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Component.js +20 -19
- package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +31 -3
- package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
- package/build/dist/UI/Components/Workflow/GraphLint.js +396 -0
- package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +225 -0
- package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -0
- package/build/dist/UI/Components/Workflow/ModelSchema.js +118 -0
- package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -0
- package/build/dist/UI/Components/Workflow/RunForm.js +22 -6
- package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +76 -0
- package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -0
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js +76 -0
- package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -0
- package/build/dist/UI/Components/Workflow/Utils.js +73 -1
- package/build/dist/UI/Components/Workflow/Utils.js.map +1 -1
- package/build/dist/UI/Components/Workflow/Workflow.js +51 -6
- package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
- package/build/dist/UI/Types/LayeredDismissal.js +21 -0
- package/build/dist/UI/Types/LayeredDismissal.js.map +1 -0
- package/build/dist/UI/Types/UseAnchoredFieldPopup.js +74 -1
- package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
- package/build/dist/UI/Utils/PageScrollLock.js +52 -0
- package/build/dist/UI/Utils/PageScrollLock.js.map +1 -0
- package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js +4 -2
- package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js.map +1 -1
- package/build/dist/Utils/Dashboard/VariableInterpolation.js +19 -1
- package/build/dist/Utils/Dashboard/VariableInterpolation.js.map +1 -1
- package/build/dist/Utils/LegacySerializedArray.js +51 -0
- package/build/dist/Utils/LegacySerializedArray.js.map +1 -0
- package/build/dist/Utils/Monitor/MonitorDependencyRule.js +47 -0
- package/build/dist/Utils/Monitor/MonitorDependencyRule.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +386 -0
- package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +35 -6
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/Telemetry/EntityKey.js +52 -0
- package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
- package/build/dist/Utils/Telemetry/SavedViewFilters.js +52 -0
- package/build/dist/Utils/Telemetry/SavedViewFilters.js.map +1 -0
- package/jest.config.json +3 -0
- package/package.json +1 -1
- package/tsconfig.json +3 -1
|
@@ -0,0 +1,706 @@
|
|
|
1
|
+
import {
|
|
2
|
+
cleanup,
|
|
3
|
+
fireEvent,
|
|
4
|
+
render,
|
|
5
|
+
screen,
|
|
6
|
+
waitFor,
|
|
7
|
+
} from "@testing-library/react";
|
|
8
|
+
import "@testing-library/jest-dom";
|
|
9
|
+
import {
|
|
10
|
+
afterEach,
|
|
11
|
+
beforeEach,
|
|
12
|
+
describe,
|
|
13
|
+
expect,
|
|
14
|
+
jest,
|
|
15
|
+
test,
|
|
16
|
+
} from "@jest/globals";
|
|
17
|
+
import React, { act } from "react";
|
|
18
|
+
import { JSONObject, ObjectType } from "../../../Types/JSON";
|
|
19
|
+
import ObjectID from "../../../Types/ObjectID";
|
|
20
|
+
import DashboardVariable, {
|
|
21
|
+
DashboardVariableType,
|
|
22
|
+
} from "../../../Types/Dashboard/DashboardVariable";
|
|
23
|
+
import DashboardViewConfig from "../../../Types/Dashboard/DashboardViewConfig";
|
|
24
|
+
import DefaultDashboardSize from "../../../Types/Dashboard/DashboardSize";
|
|
25
|
+
import DashboardTextComponentUtil from "../../../Utils/Dashboard/Components/DashboardTextComponent";
|
|
26
|
+
|
|
27
|
+
/*
|
|
28
|
+
* "Discard Changes" on a dashboard has to put the board back exactly as the
|
|
29
|
+
* server has it, and dashboard variables were the one part of it that survived
|
|
30
|
+
* the discard.
|
|
31
|
+
*
|
|
32
|
+
* The restore lived behind `if (config.variables)`. A dashboard that had never
|
|
33
|
+
* saved a variable therefore hit no branch at all on discard: a variable added
|
|
34
|
+
* in edit mode stayed in React state, kept its selector on the toolbar, kept
|
|
35
|
+
* being handed to every widget as a filter, kept its `var-` param in the URL,
|
|
36
|
+
* and — because the Variables modal seeds itself from the live list — came
|
|
37
|
+
* back the next time the modal was opened. Only a page reload cleared it, and
|
|
38
|
+
* in the meantime the board was scoped by a variable that did not exist
|
|
39
|
+
* server-side.
|
|
40
|
+
*
|
|
41
|
+
* These tests drive the real DashboardViewer against a fake dashboard API, so
|
|
42
|
+
* they assert what a person actually ends up with after the discard: what the
|
|
43
|
+
* canvas is filtered by, what the toolbar renders, what the URL says, and what
|
|
44
|
+
* the Variables modal shows when it is opened again.
|
|
45
|
+
*
|
|
46
|
+
* The canvas is stubbed — it is ~60 widget implementations deep and none of
|
|
47
|
+
* them are under test here — but it publishes the `variables` prop it received
|
|
48
|
+
* so the runtime list is directly observable.
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/*
|
|
52
|
+
* Mounting the real DashboardViewer costs a few hundred milliseconds of module
|
|
53
|
+
* work per test on an idle machine and several seconds on a loaded CI box. The
|
|
54
|
+
* default 5s budget is a machine-speed check, not an assertion about the code.
|
|
55
|
+
*/
|
|
56
|
+
jest.setTimeout(120000);
|
|
57
|
+
|
|
58
|
+
const DASHBOARD_ID: string = "22222222-2222-4222-8222-222222222222";
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* The fake server's copy of the dashboard. `updateById` writes to it and
|
|
62
|
+
* `getItem` reads from it, so a save followed by a re-fetch behaves the way
|
|
63
|
+
* the real API does.
|
|
64
|
+
*/
|
|
65
|
+
const serverState: { dashboardViewConfig: JSONObject | null } = {
|
|
66
|
+
dashboardViewConfig: null,
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
const getItemMock: jest.Mock<any, any> = jest.fn() as jest.Mock<any, any>;
|
|
70
|
+
const updateByIdMock: jest.Mock<any, any> = jest.fn() as jest.Mock<any, any>;
|
|
71
|
+
|
|
72
|
+
jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
|
|
73
|
+
return {
|
|
74
|
+
__esModule: true,
|
|
75
|
+
default: {
|
|
76
|
+
getItem: (...args: Array<any>) => {
|
|
77
|
+
return getItemMock(...args);
|
|
78
|
+
},
|
|
79
|
+
updateById: (...args: Array<any>) => {
|
|
80
|
+
return updateByIdMock(...args);
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
jest.mock("../../../UI/Utils/API/API", () => {
|
|
87
|
+
return {
|
|
88
|
+
__esModule: true,
|
|
89
|
+
default: {
|
|
90
|
+
getFriendlyErrorMessage: (err: Error) => {
|
|
91
|
+
return err.message;
|
|
92
|
+
},
|
|
93
|
+
getFriendlyMessage: (err: Error) => {
|
|
94
|
+
return err.message;
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
/*
|
|
101
|
+
* The attribute values the telemetry-backed selector offers. Fixed here so a
|
|
102
|
+
* <select> in the toolbar has real options to choose between.
|
|
103
|
+
*/
|
|
104
|
+
const ATTRIBUTE_VALUE: string = "prod";
|
|
105
|
+
|
|
106
|
+
jest.mock(
|
|
107
|
+
"../../../../App/FeatureSet/Dashboard/src/Components/Metrics/Utils/Metrics",
|
|
108
|
+
() => {
|
|
109
|
+
return {
|
|
110
|
+
__esModule: true,
|
|
111
|
+
default: {
|
|
112
|
+
loadAllMetricsTypes: () => {
|
|
113
|
+
return Promise.resolve({ metricTypes: [], telemetryAttributes: [] });
|
|
114
|
+
},
|
|
115
|
+
getTelemetryAttributes: () => {
|
|
116
|
+
return Promise.resolve([]);
|
|
117
|
+
},
|
|
118
|
+
getTelemetryAttributeValues: () => {
|
|
119
|
+
return Promise.resolve(["prod", "staging"]);
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
};
|
|
123
|
+
},
|
|
124
|
+
);
|
|
125
|
+
|
|
126
|
+
/*
|
|
127
|
+
* The canvas stub. It renders nothing visible and publishes the variable names
|
|
128
|
+
* it was handed on a data attribute, so asserting on it never collides with
|
|
129
|
+
* the same name rendered by the toolbar selector.
|
|
130
|
+
*/
|
|
131
|
+
jest.mock(
|
|
132
|
+
"../../../../App/FeatureSet/Dashboard/src/Components/Dashboard/Canvas/Index",
|
|
133
|
+
() => {
|
|
134
|
+
const reactModule: typeof React = jest.requireActual(
|
|
135
|
+
"react",
|
|
136
|
+
) as typeof React;
|
|
137
|
+
return {
|
|
138
|
+
__esModule: true,
|
|
139
|
+
default: (props: {
|
|
140
|
+
variables?: Array<DashboardVariable> | undefined;
|
|
141
|
+
}) => {
|
|
142
|
+
return reactModule.createElement("div", {
|
|
143
|
+
"data-testid": "canvas-stub",
|
|
144
|
+
"data-variable-names": (props.variables || [])
|
|
145
|
+
.map((variable: DashboardVariable) => {
|
|
146
|
+
return variable.name;
|
|
147
|
+
})
|
|
148
|
+
.join(","),
|
|
149
|
+
"data-variable-selections": (props.variables || [])
|
|
150
|
+
.map((variable: DashboardVariable) => {
|
|
151
|
+
return `${variable.name}=${
|
|
152
|
+
variable.selectedValues
|
|
153
|
+
? variable.selectedValues.join("|")
|
|
154
|
+
: variable.selectedValue || ""
|
|
155
|
+
}`;
|
|
156
|
+
})
|
|
157
|
+
.join(","),
|
|
158
|
+
});
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
);
|
|
163
|
+
|
|
164
|
+
import DashboardViewer from "../../../../App/FeatureSet/Dashboard/src/Components/Dashboard/DashboardView";
|
|
165
|
+
|
|
166
|
+
type MakeVariableFunction = (
|
|
167
|
+
data: Partial<DashboardVariable>,
|
|
168
|
+
) => DashboardVariable;
|
|
169
|
+
|
|
170
|
+
const makeVariable: MakeVariableFunction = (
|
|
171
|
+
data: Partial<DashboardVariable>,
|
|
172
|
+
): DashboardVariable => {
|
|
173
|
+
return {
|
|
174
|
+
id: data.id || `var-id-${data.name || "unnamed"}`,
|
|
175
|
+
name: data.name || "cluster",
|
|
176
|
+
type: data.type || DashboardVariableType.TelemetryAttribute,
|
|
177
|
+
attributeKey: data.attributeKey || "k8s.cluster.name",
|
|
178
|
+
...data,
|
|
179
|
+
};
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
type MakeConfigFunction = (
|
|
183
|
+
variables?: Array<DashboardVariable> | undefined,
|
|
184
|
+
) => DashboardViewConfig;
|
|
185
|
+
|
|
186
|
+
/**
|
|
187
|
+
* A saved dashboard with exactly one widget on it. The widget matters: the
|
|
188
|
+
* toolbar only renders variable selectors for a board that has components.
|
|
189
|
+
*/
|
|
190
|
+
const makeConfig: MakeConfigFunction = (
|
|
191
|
+
variables?: Array<DashboardVariable> | undefined,
|
|
192
|
+
): DashboardViewConfig => {
|
|
193
|
+
const config: DashboardViewConfig = {
|
|
194
|
+
_type: ObjectType.DashboardViewConfig,
|
|
195
|
+
components: [DashboardTextComponentUtil.getDefaultComponent()],
|
|
196
|
+
heightInDashboardUnits: DefaultDashboardSize.heightInDashboardUnits,
|
|
197
|
+
};
|
|
198
|
+
|
|
199
|
+
if (variables) {
|
|
200
|
+
config.variables = variables;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return config;
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
type SeedServerFunction = (config: DashboardViewConfig) => void;
|
|
207
|
+
|
|
208
|
+
const seedServer: SeedServerFunction = (config: DashboardViewConfig): void => {
|
|
209
|
+
serverState.dashboardViewConfig = config as unknown as JSONObject;
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
type SetUrlFunction = (search: string) => void;
|
|
213
|
+
|
|
214
|
+
const setUrl: SetUrlFunction = (search: string): void => {
|
|
215
|
+
window.history.replaceState({}, "", `/dashboard/${DASHBOARD_ID}${search}`);
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
type CurrentVarParamsFunction = () => Record<string, string>;
|
|
219
|
+
|
|
220
|
+
/** Every `var-*` param currently in the browser URL. */
|
|
221
|
+
const currentVarParams: CurrentVarParamsFunction = (): Record<
|
|
222
|
+
string,
|
|
223
|
+
string
|
|
224
|
+
> => {
|
|
225
|
+
const params: URLSearchParams = new URLSearchParams(window.location.search);
|
|
226
|
+
const out: Record<string, string> = {};
|
|
227
|
+
params.forEach((value: string, key: string) => {
|
|
228
|
+
if (key.startsWith("var-")) {
|
|
229
|
+
out[key] = value;
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
return out;
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
type CanvasVariableNamesFunction = () => Array<string>;
|
|
236
|
+
|
|
237
|
+
/** The variable names the canvas — i.e. every widget — is scoped by. */
|
|
238
|
+
const canvasVariableNames: CanvasVariableNamesFunction = (): Array<string> => {
|
|
239
|
+
const raw: string =
|
|
240
|
+
screen.getByTestId("canvas-stub").getAttribute("data-variable-names") || "";
|
|
241
|
+
return raw === "" ? [] : raw.split(",");
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
type CanvasVariableSelectionsFunction = () => Array<string>;
|
|
245
|
+
|
|
246
|
+
const canvasVariableSelections: CanvasVariableSelectionsFunction =
|
|
247
|
+
(): Array<string> => {
|
|
248
|
+
const raw: string =
|
|
249
|
+
screen
|
|
250
|
+
.getByTestId("canvas-stub")
|
|
251
|
+
.getAttribute("data-variable-selections") || "";
|
|
252
|
+
return raw === "" ? [] : raw.split(",");
|
|
253
|
+
};
|
|
254
|
+
|
|
255
|
+
type SettleFunction = () => Promise<void>;
|
|
256
|
+
|
|
257
|
+
/*
|
|
258
|
+
* Drain the promise chain a fetch kicked off and flush the React updates it
|
|
259
|
+
* schedules. A bare `act` only drains the microtasks queued at the moment it
|
|
260
|
+
* runs, which is not enough for `loadPage` — it awaits `Promise.all` and then
|
|
261
|
+
* sets state, so the updates land several turns later. Awaiting real macrotask
|
|
262
|
+
* turns is what makes that deterministic instead of a race the test wins only
|
|
263
|
+
* on an idle machine.
|
|
264
|
+
*/
|
|
265
|
+
const settle: SettleFunction = async (): Promise<void> => {
|
|
266
|
+
await act(async () => {
|
|
267
|
+
for (let turn: number = 0; turn < 5; turn++) {
|
|
268
|
+
await new Promise<void>((resolve: () => void) => {
|
|
269
|
+
setTimeout(resolve, 0);
|
|
270
|
+
});
|
|
271
|
+
}
|
|
272
|
+
});
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
type RenderDashboardFunction = () => Promise<void>;
|
|
276
|
+
|
|
277
|
+
const renderDashboard: RenderDashboardFunction = async (): Promise<void> => {
|
|
278
|
+
render(<DashboardViewer dashboardId={new ObjectID(DASHBOARD_ID)} />);
|
|
279
|
+
/*
|
|
280
|
+
* The canvas only mounts once `isLoading` flips false, which happens after
|
|
281
|
+
* the whole load chain — including the variable restore — has run. Waiting
|
|
282
|
+
* for it is therefore the gate for "the dashboard is ready to assert on".
|
|
283
|
+
*/
|
|
284
|
+
await waitFor(() => {
|
|
285
|
+
expect(screen.getByTestId("canvas-stub")).toBeInTheDocument();
|
|
286
|
+
});
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
type EnterEditModeFunction = () => Promise<void>;
|
|
290
|
+
|
|
291
|
+
const enterEditMode: EnterEditModeFunction = async (): Promise<void> => {
|
|
292
|
+
await act(async () => {
|
|
293
|
+
fireEvent.click(screen.getByLabelText("More dashboard options"));
|
|
294
|
+
});
|
|
295
|
+
await act(async () => {
|
|
296
|
+
fireEvent.click(screen.getByText("Edit Dashboard"));
|
|
297
|
+
});
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
type OpenVariablesModalFunction = () => Promise<void>;
|
|
301
|
+
|
|
302
|
+
const openVariablesModal: OpenVariablesModalFunction =
|
|
303
|
+
async (): Promise<void> => {
|
|
304
|
+
await act(async () => {
|
|
305
|
+
fireEvent.click(screen.getByTitle("Variables"));
|
|
306
|
+
});
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
type VariableNameInputsFunction = () => Array<HTMLInputElement>;
|
|
310
|
+
|
|
311
|
+
/** The Name field of every row in the open Variables modal, in DOM order. */
|
|
312
|
+
const variableNameInputs: VariableNameInputsFunction =
|
|
313
|
+
(): Array<HTMLInputElement> => {
|
|
314
|
+
return screen.queryAllByPlaceholderText(
|
|
315
|
+
"cluster",
|
|
316
|
+
) as Array<HTMLInputElement>;
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
type AddVariableInModalFunction = (name: string) => Promise<void>;
|
|
320
|
+
|
|
321
|
+
const addVariableInModal: AddVariableInModalFunction = async (
|
|
322
|
+
name: string,
|
|
323
|
+
): Promise<void> => {
|
|
324
|
+
await act(async () => {
|
|
325
|
+
fireEvent.click(screen.getByText("Add Variable"));
|
|
326
|
+
});
|
|
327
|
+
const inputs: Array<HTMLInputElement> = variableNameInputs();
|
|
328
|
+
const newRow: HTMLInputElement = inputs[
|
|
329
|
+
inputs.length - 1
|
|
330
|
+
] as HTMLInputElement;
|
|
331
|
+
await act(async () => {
|
|
332
|
+
fireEvent.change(newRow, { target: { value: name } });
|
|
333
|
+
});
|
|
334
|
+
};
|
|
335
|
+
|
|
336
|
+
type SaveVariablesModalFunction = () => Promise<void>;
|
|
337
|
+
|
|
338
|
+
const saveVariablesModal: SaveVariablesModalFunction =
|
|
339
|
+
async (): Promise<void> => {
|
|
340
|
+
await act(async () => {
|
|
341
|
+
fireEvent.click(screen.getByText("Save Variables"));
|
|
342
|
+
});
|
|
343
|
+
};
|
|
344
|
+
|
|
345
|
+
type DiscardEditsFunction = () => Promise<void>;
|
|
346
|
+
|
|
347
|
+
const discardEdits: DiscardEditsFunction = async (): Promise<void> => {
|
|
348
|
+
await act(async () => {
|
|
349
|
+
fireEvent.click(screen.getByTitle("Cancel"));
|
|
350
|
+
});
|
|
351
|
+
await act(async () => {
|
|
352
|
+
fireEvent.click(screen.getByText("Discard Changes"));
|
|
353
|
+
});
|
|
354
|
+
/*
|
|
355
|
+
* `onCancelEditClick` re-fetches and applies the result asynchronously, and
|
|
356
|
+
* nothing visible flips once it lands, so there is no element to wait on.
|
|
357
|
+
*/
|
|
358
|
+
await settle();
|
|
359
|
+
};
|
|
360
|
+
|
|
361
|
+
type KeepEditingFunction = () => Promise<void>;
|
|
362
|
+
|
|
363
|
+
/** Open the cancel confirmation and then back out of it. */
|
|
364
|
+
const keepEditing: KeepEditingFunction = async (): Promise<void> => {
|
|
365
|
+
await act(async () => {
|
|
366
|
+
fireEvent.click(screen.getByTitle("Cancel"));
|
|
367
|
+
});
|
|
368
|
+
await act(async () => {
|
|
369
|
+
fireEvent.click(screen.getByText("Keep Editing"));
|
|
370
|
+
});
|
|
371
|
+
};
|
|
372
|
+
|
|
373
|
+
type SaveDashboardFunction = () => Promise<void>;
|
|
374
|
+
|
|
375
|
+
const saveDashboard: SaveDashboardFunction = async (): Promise<void> => {
|
|
376
|
+
await act(async () => {
|
|
377
|
+
fireEvent.click(screen.getByText("Save Changes"));
|
|
378
|
+
});
|
|
379
|
+
await settle();
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
beforeEach(() => {
|
|
383
|
+
serverState.dashboardViewConfig = null;
|
|
384
|
+
setUrl("");
|
|
385
|
+
|
|
386
|
+
getItemMock.mockImplementation(() => {
|
|
387
|
+
return Promise.resolve({
|
|
388
|
+
dashboardViewConfig: serverState.dashboardViewConfig,
|
|
389
|
+
name: "Test Dashboard",
|
|
390
|
+
description: "A dashboard",
|
|
391
|
+
pageTitle: null,
|
|
392
|
+
pageDescription: null,
|
|
393
|
+
});
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
updateByIdMock.mockImplementation((args: any) => {
|
|
397
|
+
serverState.dashboardViewConfig = args.data
|
|
398
|
+
.dashboardViewConfig as JSONObject;
|
|
399
|
+
return Promise.resolve();
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
afterEach(() => {
|
|
404
|
+
cleanup();
|
|
405
|
+
jest.clearAllMocks();
|
|
406
|
+
});
|
|
407
|
+
|
|
408
|
+
describe("DashboardView — discarding edits reconciles dashboard variables", () => {
|
|
409
|
+
describe("a dashboard that saved no variables", () => {
|
|
410
|
+
beforeEach(() => {
|
|
411
|
+
seedServer(makeConfig());
|
|
412
|
+
});
|
|
413
|
+
|
|
414
|
+
test("drops a variable that was added and then discarded", async () => {
|
|
415
|
+
await renderDashboard();
|
|
416
|
+
expect(canvasVariableNames()).toEqual([]);
|
|
417
|
+
|
|
418
|
+
await enterEditMode();
|
|
419
|
+
await openVariablesModal();
|
|
420
|
+
await addVariableInModal("cluster");
|
|
421
|
+
await saveVariablesModal();
|
|
422
|
+
|
|
423
|
+
// The variable is live while the edit is still in progress.
|
|
424
|
+
expect(canvasVariableNames()).toEqual(["cluster"]);
|
|
425
|
+
|
|
426
|
+
await discardEdits();
|
|
427
|
+
|
|
428
|
+
expect(canvasVariableNames()).toEqual([]);
|
|
429
|
+
});
|
|
430
|
+
|
|
431
|
+
test("strips the discarded variable's var- param from the URL", async () => {
|
|
432
|
+
await renderDashboard();
|
|
433
|
+
await enterEditMode();
|
|
434
|
+
await openVariablesModal();
|
|
435
|
+
await addVariableInModal("cluster");
|
|
436
|
+
await saveVariablesModal();
|
|
437
|
+
await discardEdits();
|
|
438
|
+
|
|
439
|
+
expect(currentVarParams()).toEqual({});
|
|
440
|
+
expect(window.location.search).not.toContain("var-");
|
|
441
|
+
});
|
|
442
|
+
|
|
443
|
+
test("stops rendering a toolbar selector for the discarded variable", async () => {
|
|
444
|
+
await renderDashboard();
|
|
445
|
+
await enterEditMode();
|
|
446
|
+
await openVariablesModal();
|
|
447
|
+
await addVariableInModal("cluster");
|
|
448
|
+
await saveVariablesModal();
|
|
449
|
+
await discardEdits();
|
|
450
|
+
|
|
451
|
+
/*
|
|
452
|
+
* Back in view mode the selector's label is the only place the name
|
|
453
|
+
* would appear — the canvas stub keeps it in a data attribute.
|
|
454
|
+
*/
|
|
455
|
+
expect(screen.queryByText("cluster")).not.toBeInTheDocument();
|
|
456
|
+
expect(screen.queryByRole("combobox")).not.toBeInTheDocument();
|
|
457
|
+
});
|
|
458
|
+
|
|
459
|
+
test("does not resurrect the discarded definition when the Variables modal is reopened", async () => {
|
|
460
|
+
await renderDashboard();
|
|
461
|
+
await enterEditMode();
|
|
462
|
+
await openVariablesModal();
|
|
463
|
+
await addVariableInModal("cluster");
|
|
464
|
+
await saveVariablesModal();
|
|
465
|
+
await discardEdits();
|
|
466
|
+
|
|
467
|
+
await enterEditMode();
|
|
468
|
+
await openVariablesModal();
|
|
469
|
+
|
|
470
|
+
expect(screen.getByText("No variables yet")).toBeInTheDocument();
|
|
471
|
+
expect(variableNameInputs()).toHaveLength(0);
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
test("keeps the new variable when the user backs out with Keep Editing", async () => {
|
|
475
|
+
/*
|
|
476
|
+
* The re-fetch has to hang off the confirmation's submit, not off
|
|
477
|
+
* leaving edit mode. If it ever moves to a `dashboardMode` effect,
|
|
478
|
+
* every mode transition would silently discard — and every other
|
|
479
|
+
* test here would still pass.
|
|
480
|
+
*/
|
|
481
|
+
await renderDashboard();
|
|
482
|
+
expect(getItemMock).toHaveBeenCalledTimes(1);
|
|
483
|
+
|
|
484
|
+
await enterEditMode();
|
|
485
|
+
await openVariablesModal();
|
|
486
|
+
await addVariableInModal("cluster");
|
|
487
|
+
await saveVariablesModal();
|
|
488
|
+
|
|
489
|
+
await keepEditing();
|
|
490
|
+
|
|
491
|
+
expect(getItemMock).toHaveBeenCalledTimes(1);
|
|
492
|
+
expect(canvasVariableNames()).toEqual(["cluster"]);
|
|
493
|
+
// Still editing: the edit-mode action bar is up.
|
|
494
|
+
expect(screen.getByText("Save Changes")).toBeInTheDocument();
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
test("keeps the new variable when the edit is saved rather than discarded", async () => {
|
|
498
|
+
await renderDashboard();
|
|
499
|
+
await enterEditMode();
|
|
500
|
+
await openVariablesModal();
|
|
501
|
+
await addVariableInModal("cluster");
|
|
502
|
+
await saveVariablesModal();
|
|
503
|
+
await saveDashboard();
|
|
504
|
+
|
|
505
|
+
expect(updateByIdMock).toHaveBeenCalledTimes(1);
|
|
506
|
+
expect(canvasVariableNames()).toEqual(["cluster"]);
|
|
507
|
+
|
|
508
|
+
/*
|
|
509
|
+
* And the save actually persisted the definition: a fresh mount of the
|
|
510
|
+
* same dashboard finds it on the server.
|
|
511
|
+
*/
|
|
512
|
+
cleanup();
|
|
513
|
+
await renderDashboard();
|
|
514
|
+
expect(canvasVariableNames()).toEqual(["cluster"]);
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
test("clears the runtime list when the saved config has an empty variables array", async () => {
|
|
518
|
+
seedServer(makeConfig([]));
|
|
519
|
+
|
|
520
|
+
await renderDashboard();
|
|
521
|
+
await enterEditMode();
|
|
522
|
+
await openVariablesModal();
|
|
523
|
+
await addVariableInModal("cluster");
|
|
524
|
+
await saveVariablesModal();
|
|
525
|
+
await discardEdits();
|
|
526
|
+
|
|
527
|
+
expect(canvasVariableNames()).toEqual([]);
|
|
528
|
+
});
|
|
529
|
+
});
|
|
530
|
+
|
|
531
|
+
describe("a dashboard that already saved variables", () => {
|
|
532
|
+
beforeEach(() => {
|
|
533
|
+
seedServer(
|
|
534
|
+
makeConfig([makeVariable({ id: "saved-cluster", name: "cluster" })]),
|
|
535
|
+
);
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
test("keeps the saved variable and drops only the newly added one", async () => {
|
|
539
|
+
await renderDashboard();
|
|
540
|
+
expect(canvasVariableNames()).toEqual(["cluster"]);
|
|
541
|
+
|
|
542
|
+
await enterEditMode();
|
|
543
|
+
await openVariablesModal();
|
|
544
|
+
await addVariableInModal("namespace");
|
|
545
|
+
await saveVariablesModal();
|
|
546
|
+
expect(canvasVariableNames()).toEqual(["cluster", "namespace"]);
|
|
547
|
+
|
|
548
|
+
await discardEdits();
|
|
549
|
+
|
|
550
|
+
expect(canvasVariableNames()).toEqual(["cluster"]);
|
|
551
|
+
});
|
|
552
|
+
|
|
553
|
+
test("strips the discarded variable's var- param while preserving the saved one's selection", async () => {
|
|
554
|
+
setUrl("?var-cluster=prod&team=platform");
|
|
555
|
+
|
|
556
|
+
await renderDashboard();
|
|
557
|
+
expect(canvasVariableSelections()).toEqual(["cluster=prod"]);
|
|
558
|
+
|
|
559
|
+
await enterEditMode();
|
|
560
|
+
await openVariablesModal();
|
|
561
|
+
await addVariableInModal("namespace");
|
|
562
|
+
await saveVariablesModal();
|
|
563
|
+
await discardEdits();
|
|
564
|
+
|
|
565
|
+
expect(currentVarParams()).toEqual({ "var-cluster": "prod" });
|
|
566
|
+
// Query state that has nothing to do with variables is left alone.
|
|
567
|
+
expect(new URLSearchParams(window.location.search).get("team")).toBe(
|
|
568
|
+
"platform",
|
|
569
|
+
);
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
test("restores a variable that was deleted in edit mode", async () => {
|
|
573
|
+
await renderDashboard();
|
|
574
|
+
await enterEditMode();
|
|
575
|
+
await openVariablesModal();
|
|
576
|
+
|
|
577
|
+
await act(async () => {
|
|
578
|
+
fireEvent.click(screen.getByTitle("Remove variable"));
|
|
579
|
+
});
|
|
580
|
+
await saveVariablesModal();
|
|
581
|
+
expect(canvasVariableNames()).toEqual([]);
|
|
582
|
+
|
|
583
|
+
await discardEdits();
|
|
584
|
+
|
|
585
|
+
expect(canvasVariableNames()).toEqual(["cluster"]);
|
|
586
|
+
});
|
|
587
|
+
|
|
588
|
+
test("restores the saved name after a rename in edit mode", async () => {
|
|
589
|
+
await renderDashboard();
|
|
590
|
+
await enterEditMode();
|
|
591
|
+
await openVariablesModal();
|
|
592
|
+
|
|
593
|
+
const nameInput: HTMLInputElement =
|
|
594
|
+
variableNameInputs()[0] as HTMLInputElement;
|
|
595
|
+
await act(async () => {
|
|
596
|
+
fireEvent.change(nameInput, { target: { value: "region" } });
|
|
597
|
+
});
|
|
598
|
+
await saveVariablesModal();
|
|
599
|
+
expect(canvasVariableNames()).toEqual(["region"]);
|
|
600
|
+
|
|
601
|
+
await discardEdits();
|
|
602
|
+
|
|
603
|
+
expect(canvasVariableNames()).toEqual(["cluster"]);
|
|
604
|
+
expect(currentVarParams()).toEqual({});
|
|
605
|
+
});
|
|
606
|
+
|
|
607
|
+
test("strips the URL param a discarded rename left pointing at a variable that no longer exists", async () => {
|
|
608
|
+
/*
|
|
609
|
+
* Renaming a variable carries its selection over to the new name and
|
|
610
|
+
* rewrites the URL to match. Discarding the rename puts the definition
|
|
611
|
+
* back, so the `var-region` param has nothing left to address — leaving
|
|
612
|
+
* it would hand anyone the link a selection for a variable that is not
|
|
613
|
+
* on the dashboard.
|
|
614
|
+
*/
|
|
615
|
+
setUrl("?var-cluster=prod");
|
|
616
|
+
|
|
617
|
+
await renderDashboard();
|
|
618
|
+
expect(canvasVariableSelections()).toEqual(["cluster=prod"]);
|
|
619
|
+
|
|
620
|
+
await enterEditMode();
|
|
621
|
+
await openVariablesModal();
|
|
622
|
+
const nameInput: HTMLInputElement =
|
|
623
|
+
variableNameInputs()[0] as HTMLInputElement;
|
|
624
|
+
await act(async () => {
|
|
625
|
+
fireEvent.change(nameInput, { target: { value: "region" } });
|
|
626
|
+
});
|
|
627
|
+
await saveVariablesModal();
|
|
628
|
+
expect(currentVarParams()).toEqual({ "var-region": "prod" });
|
|
629
|
+
|
|
630
|
+
await discardEdits();
|
|
631
|
+
|
|
632
|
+
expect(canvasVariableNames()).toEqual(["cluster"]);
|
|
633
|
+
expect(currentVarParams()).toEqual({});
|
|
634
|
+
/*
|
|
635
|
+
* The selection itself does not come back. `var-` params are keyed by
|
|
636
|
+
* name (VariableUrlState.ts:6-9), so the rename moved the only record
|
|
637
|
+
* of it and the discard removed that record. Restoring the definition
|
|
638
|
+
* is the contract; the selection is view state the rename destroyed.
|
|
639
|
+
*/
|
|
640
|
+
expect(canvasVariableSelections()).toEqual(["cluster="]);
|
|
641
|
+
});
|
|
642
|
+
|
|
643
|
+
test("a selection made in view mode survives an unrelated edit-and-discard cycle", async () => {
|
|
644
|
+
await renderDashboard();
|
|
645
|
+
|
|
646
|
+
/*
|
|
647
|
+
* The selector fetches its options, and a <select> silently ignores a
|
|
648
|
+
* change to a value it has no <option> for — so picking before they
|
|
649
|
+
* arrive would assert nothing.
|
|
650
|
+
*/
|
|
651
|
+
await screen.findByRole("option", { name: ATTRIBUTE_VALUE });
|
|
652
|
+
await act(async () => {
|
|
653
|
+
fireEvent.change(screen.getByRole("combobox"), {
|
|
654
|
+
target: { value: ATTRIBUTE_VALUE },
|
|
655
|
+
});
|
|
656
|
+
});
|
|
657
|
+
expect(canvasVariableSelections()).toEqual(["cluster=prod"]);
|
|
658
|
+
|
|
659
|
+
await enterEditMode();
|
|
660
|
+
await discardEdits();
|
|
661
|
+
|
|
662
|
+
expect(canvasVariableNames()).toEqual(["cluster"]);
|
|
663
|
+
expect(canvasVariableSelections()).toEqual(["cluster=prod"]);
|
|
664
|
+
expect(currentVarParams()).toEqual({ "var-cluster": "prod" });
|
|
665
|
+
});
|
|
666
|
+
});
|
|
667
|
+
|
|
668
|
+
describe("shared links", () => {
|
|
669
|
+
test("applies a var- selection from the URL to the saved variable on load", async () => {
|
|
670
|
+
seedServer(
|
|
671
|
+
makeConfig([makeVariable({ id: "saved-cluster", name: "cluster" })]),
|
|
672
|
+
);
|
|
673
|
+
setUrl("?var-cluster=staging");
|
|
674
|
+
|
|
675
|
+
await renderDashboard();
|
|
676
|
+
|
|
677
|
+
expect(canvasVariableSelections()).toEqual(["cluster=staging"]);
|
|
678
|
+
expect(currentVarParams()).toEqual({ "var-cluster": "staging" });
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
test("strips a var- param naming a variable the dashboard does not have", async () => {
|
|
682
|
+
seedServer(
|
|
683
|
+
makeConfig([makeVariable({ id: "saved-cluster", name: "cluster" })]),
|
|
684
|
+
);
|
|
685
|
+
setUrl("?var-cluster=prod&var-ghost=whatever");
|
|
686
|
+
|
|
687
|
+
await renderDashboard();
|
|
688
|
+
|
|
689
|
+
expect(canvasVariableNames()).toEqual(["cluster"]);
|
|
690
|
+
expect(currentVarParams()).toEqual({ "var-cluster": "prod" });
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
test("strips every var- param on a dashboard that has no variables at all", async () => {
|
|
694
|
+
seedServer(makeConfig());
|
|
695
|
+
setUrl("?var-ghost=whatever&keep=me");
|
|
696
|
+
|
|
697
|
+
await renderDashboard();
|
|
698
|
+
|
|
699
|
+
expect(canvasVariableNames()).toEqual([]);
|
|
700
|
+
expect(currentVarParams()).toEqual({});
|
|
701
|
+
expect(new URLSearchParams(window.location.search).get("keep")).toBe(
|
|
702
|
+
"me",
|
|
703
|
+
);
|
|
704
|
+
});
|
|
705
|
+
});
|
|
706
|
+
});
|