@oneuptime/common 12.0.6 → 12.0.7
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/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/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/Index.ts +6 -0
- 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/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 +41 -2
- 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/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/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/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/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/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/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/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/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/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/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/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 +1 -1
- package/Tests/UI/Components/MasterPage.test.tsx +1 -1
- package/Tests/UI/Components/ModalPortalDismissal.test.tsx +489 -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 +1 -1
- package/Tests/UI/Components/TextArea.test.tsx +1 -1
- 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/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/Realtime.test.ts +78 -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/Telemetry/TelemetrySavedViewState.ts +9 -1
- package/Types/Workflow/Components/BaseModel.ts +92 -28
- package/Typings/Index.d.ts +12 -0
- package/UI/Components/GanttChart/ChartContainer.tsx +4 -3
- package/UI/Components/Modal/ConfirmModal.tsx +10 -5
- package/UI/Components/Modal/Modal.tsx +27 -47
- package/UI/Components/ModelDelete/ModelDelete.tsx +23 -6
- package/UI/Components/SideOver/SideOver.tsx +195 -68
- 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/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/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/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/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.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/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 +35 -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/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/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/Workflow/Components/BaseModel.js +83 -28
- package/build/dist/Types/Workflow/Components/BaseModel.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/Modal/ConfirmModal.js +3 -1
- package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
- package/build/dist/UI/Components/Modal/Modal.js +24 -34
- 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/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/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
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import ComponentsModal from "../../../UI/Components/Workflow/ComponentsModal";
|
|
2
2
|
import { describe, expect, it } from "@jest/globals";
|
|
3
|
-
|
|
3
|
+
/*
|
|
4
|
+
* The main entry, not "/extend-expect": the latter no longer ships type
|
|
5
|
+
* declarations, so every jest-dom matcher in this file fails to typecheck and
|
|
6
|
+
* the whole suite is skipped before a single assertion runs. This suite is one
|
|
7
|
+
* of only two that exercise SideOver, so it has to actually run.
|
|
8
|
+
*/
|
|
9
|
+
import "@testing-library/jest-dom";
|
|
4
10
|
import { fireEvent, render, screen } from "@testing-library/react";
|
|
5
11
|
import IconProp from "../../../Types/Icon/IconProp";
|
|
6
12
|
import ComponentMetadata, {
|
|
@@ -6,7 +6,7 @@ import DictionaryOfStrings, {
|
|
|
6
6
|
ComponentProps,
|
|
7
7
|
} from "../../../UI/Components/Dictionary/DictionaryOfStrings";
|
|
8
8
|
import { describe, expect, it, jest } from "@jest/globals";
|
|
9
|
-
import "@testing-library/jest-dom
|
|
9
|
+
import "@testing-library/jest-dom";
|
|
10
10
|
import { fireEvent, render, screen } from "@testing-library/react";
|
|
11
11
|
import Dictionary from "../../../Types/Dictionary";
|
|
12
12
|
import React from "react";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import Dropdown, {
|
|
2
2
|
DropdownOption,
|
|
3
3
|
} from "../../../UI/Components/Dropdown/Dropdown";
|
|
4
|
-
import "@testing-library/jest-dom
|
|
4
|
+
import "@testing-library/jest-dom";
|
|
5
5
|
import { fireEvent, render, screen } from "@testing-library/react";
|
|
6
6
|
import React from "react";
|
|
7
7
|
import { describe, expect } from "@jest/globals";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import FilePicker from "../../../UI/Components/FilePicker/FilePicker";
|
|
2
2
|
import ModelAPI from "../../../UI/Utils/ModelAPI/ModelAPI";
|
|
3
3
|
import { describe, expect, beforeEach, jest } from "@jest/globals";
|
|
4
|
-
import "@testing-library/jest-dom
|
|
4
|
+
import "@testing-library/jest-dom";
|
|
5
5
|
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
6
6
|
import HTTPResponse from "../../../Types/API/HTTPResponse";
|
|
7
7
|
import MimeType from "../../../Types/File/MimeType";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import HiddenText from "../../../UI/Components/HiddenText/HiddenText";
|
|
2
|
-
import "@testing-library/jest-dom
|
|
2
|
+
import "@testing-library/jest-dom";
|
|
3
3
|
import { fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
4
4
|
import React from "react";
|
|
5
5
|
import { describe, expect, test } from "@jest/globals";
|
|
@@ -2,7 +2,7 @@ import Input, {
|
|
|
2
2
|
ComponentProps,
|
|
3
3
|
InputType,
|
|
4
4
|
} from "../../../UI/Components/Input/Input";
|
|
5
|
-
import "@testing-library/jest-dom
|
|
5
|
+
import "@testing-library/jest-dom";
|
|
6
6
|
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
|
7
7
|
import React from "react";
|
|
8
8
|
import { describe, expect, afterEach, test } from "@jest/globals";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Loader, { LoaderType } from "../../../UI/Components/Loader/Loader";
|
|
2
|
-
import "@testing-library/jest-dom
|
|
2
|
+
import "@testing-library/jest-dom";
|
|
3
3
|
import { render, screen } from "@testing-library/react";
|
|
4
4
|
import Color from "../../../Types/Color";
|
|
5
5
|
import React from "react";
|
|
@@ -3,7 +3,7 @@ import LogTimeRangePicker, {
|
|
|
3
3
|
} from "../../../UI/Components/LogsViewer/components/LogTimeRangePicker";
|
|
4
4
|
import RangeStartAndEndDateTime from "../../../Types/Time/RangeStartAndEndDateTime";
|
|
5
5
|
import TimeRange from "../../../Types/Time/TimeRange";
|
|
6
|
-
import "@testing-library/jest-dom
|
|
6
|
+
import "@testing-library/jest-dom";
|
|
7
7
|
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
|
8
8
|
import React from "react";
|
|
9
9
|
import {
|
|
@@ -2,7 +2,7 @@ import MasterPage, {
|
|
|
2
2
|
ComponentProps,
|
|
3
3
|
} from "../../../UI/Components/MasterPage/MasterPage";
|
|
4
4
|
import { describe, expect, it } from "@jest/globals";
|
|
5
|
-
import "@testing-library/jest-dom
|
|
5
|
+
import "@testing-library/jest-dom";
|
|
6
6
|
import { render, screen } from "@testing-library/react";
|
|
7
7
|
import React from "react";
|
|
8
8
|
|
|
@@ -0,0 +1,489 @@
|
|
|
1
|
+
import AutocompleteTextInput from "../../../UI/Components/AutocompleteTextInput/AutocompleteTextInput";
|
|
2
|
+
import Dropdown, {
|
|
3
|
+
DropdownOption,
|
|
4
|
+
DropdownValue,
|
|
5
|
+
} from "../../../UI/Components/Dropdown/Dropdown";
|
|
6
|
+
import OperatorSelector from "../../../UI/Components/Filters/OperatorSelector";
|
|
7
|
+
import FilterOperator from "../../../UI/Components/Filters/Types/FilterOperator";
|
|
8
|
+
import ColorPicker from "../../../UI/Components/Forms/Fields/ColorPicker";
|
|
9
|
+
import IconPicker from "../../../UI/Components/Forms/Fields/IconPicker";
|
|
10
|
+
import Modal from "../../../UI/Components/Modal/Modal";
|
|
11
|
+
import IconProp from "../../../Types/Icon/IconProp";
|
|
12
|
+
/*
|
|
13
|
+
* The main entry, not "/extend-expect": the latter no longer ships type
|
|
14
|
+
* declarations, so every jest-dom matcher in this file fails to typecheck and
|
|
15
|
+
* the whole suite is skipped before a single assertion runs.
|
|
16
|
+
*/
|
|
17
|
+
import "@testing-library/jest-dom";
|
|
18
|
+
import { cleanup, fireEvent, render, screen } from "@testing-library/react";
|
|
19
|
+
import React, { ReactElement } from "react";
|
|
20
|
+
import { createPortal } from "react-dom";
|
|
21
|
+
import { afterEach, describe, expect, jest, test } from "@jest/globals";
|
|
22
|
+
|
|
23
|
+
/*
|
|
24
|
+
* The reported bug (issue #3133): in the "Dashboard Variables" modal, clicking
|
|
25
|
+
* a suggested Attribute Key closed the whole modal and dropped the half-filled
|
|
26
|
+
* variable on the floor.
|
|
27
|
+
*
|
|
28
|
+
* The cause is not in the autocomplete. Every dropdown in this codebase portals
|
|
29
|
+
* its menu to document.body so a scroll container cannot clip it, and React
|
|
30
|
+
* dispatches synthetic events through the REACT tree rather than the DOM tree.
|
|
31
|
+
* So a click on a portalled option still bubbles into Modal's backdrop handler
|
|
32
|
+
* — which decided "outside" by asking whether the panel DOM-contains the event
|
|
33
|
+
* target. A portalled option never is, so every such pick read as a backdrop
|
|
34
|
+
* click and dismissed the dialog.
|
|
35
|
+
*
|
|
36
|
+
* That makes this a Modal-level contract rather than a per-dropdown quirk, and
|
|
37
|
+
* these tests state it once for each portalling surface that can appear in a
|
|
38
|
+
* modal body. Crucially they fire mousedown *and* click: Modal only dismisses
|
|
39
|
+
* on a press that both starts and ends outside, so a click-only test passes
|
|
40
|
+
* even with the bug fully present — which is exactly why it went unnoticed.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
const SUGGESTIONS: Array<string> = [
|
|
44
|
+
"k8s.cluster.name",
|
|
45
|
+
"k8s.namespace.name",
|
|
46
|
+
"service.name",
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
const TEXT_OPERATORS: Array<FilterOperator> = [
|
|
50
|
+
FilterOperator.Contains,
|
|
51
|
+
FilterOperator.EqualTo,
|
|
52
|
+
FilterOperator.StartsWith,
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
const DROPDOWN_OPTIONS: Array<DropdownOption> = [
|
|
56
|
+
{ value: "production", label: "Production" },
|
|
57
|
+
{ value: "staging", label: "Staging" },
|
|
58
|
+
];
|
|
59
|
+
|
|
60
|
+
/*
|
|
61
|
+
* The layer a user actually presses is the one the panel is centred in — the
|
|
62
|
+
* tinted sheet behind it is aria-hidden and inert.
|
|
63
|
+
*/
|
|
64
|
+
type GetBackdropLayerFunction = () => HTMLElement;
|
|
65
|
+
|
|
66
|
+
const getBackdropLayer: GetBackdropLayerFunction = (): HTMLElement => {
|
|
67
|
+
return screen.getByTestId("modal").parentElement!;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/*
|
|
71
|
+
* A real pointer press is mousedown-then-click. Modal tracks both ends, so
|
|
72
|
+
* anything that only fires `click` cannot observe this bug at all.
|
|
73
|
+
*/
|
|
74
|
+
type PressFunction = (element: HTMLElement) => void;
|
|
75
|
+
|
|
76
|
+
const press: PressFunction = (element: HTMLElement): void => {
|
|
77
|
+
fireEvent.mouseDown(element);
|
|
78
|
+
fireEvent.click(element);
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
interface PortalHarness {
|
|
82
|
+
onClose: () => void;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
type RenderInModalFunction = (children: ReactElement) => PortalHarness;
|
|
86
|
+
|
|
87
|
+
const renderInModal: RenderInModalFunction = (
|
|
88
|
+
children: ReactElement,
|
|
89
|
+
): PortalHarness => {
|
|
90
|
+
const onClose: () => void = jest.fn();
|
|
91
|
+
|
|
92
|
+
render(
|
|
93
|
+
<Modal title="Dashboard Variables" onClose={onClose}>
|
|
94
|
+
{children}
|
|
95
|
+
</Modal>,
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
return { onClose: onClose };
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
describe("Modal dismissal and portalled dropdown menus", () => {
|
|
102
|
+
afterEach(() => {
|
|
103
|
+
cleanup();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
describe("the contract: a portalled pick is not a backdrop press", () => {
|
|
107
|
+
/*
|
|
108
|
+
* States the rule in isolation, with no real dropdown involved: any child
|
|
109
|
+
* a modal body portals out of the panel keeps its clicks to itself. Every
|
|
110
|
+
* component test below is a specific instance of this one.
|
|
111
|
+
*/
|
|
112
|
+
test("clicking any child portalled to document.body leaves the modal open", () => {
|
|
113
|
+
const onClose: () => void = jest.fn();
|
|
114
|
+
const onPick: () => void = jest.fn();
|
|
115
|
+
|
|
116
|
+
render(
|
|
117
|
+
<Modal title="Dashboard Variables" onClose={onClose}>
|
|
118
|
+
<div>
|
|
119
|
+
{createPortal(
|
|
120
|
+
<button
|
|
121
|
+
type="button"
|
|
122
|
+
data-testid="portalled-option"
|
|
123
|
+
onClick={onPick}
|
|
124
|
+
>
|
|
125
|
+
pick me
|
|
126
|
+
</button>,
|
|
127
|
+
document.body,
|
|
128
|
+
)}
|
|
129
|
+
</div>
|
|
130
|
+
</Modal>,
|
|
131
|
+
);
|
|
132
|
+
|
|
133
|
+
const option: HTMLElement = screen.getByTestId("portalled-option");
|
|
134
|
+
|
|
135
|
+
// Premise of the bug: the option is genuinely outside the panel's DOM.
|
|
136
|
+
expect(screen.getByTestId("modal").contains(option)).toBe(false);
|
|
137
|
+
expect(option.parentElement).toBe(document.body);
|
|
138
|
+
|
|
139
|
+
press(option);
|
|
140
|
+
|
|
141
|
+
expect(onPick).toHaveBeenCalledTimes(1);
|
|
142
|
+
expect(onClose).not.toHaveBeenCalled();
|
|
143
|
+
expect(screen.getByTestId("modal")).toBeInTheDocument();
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
test("a portalled press does not arm the next backdrop click", () => {
|
|
147
|
+
const onClose: () => void = jest.fn();
|
|
148
|
+
|
|
149
|
+
render(
|
|
150
|
+
<Modal title="Dashboard Variables" onClose={onClose}>
|
|
151
|
+
<div>
|
|
152
|
+
{createPortal(
|
|
153
|
+
<button type="button" data-testid="portalled-option">
|
|
154
|
+
pick me
|
|
155
|
+
</button>,
|
|
156
|
+
document.body,
|
|
157
|
+
)}
|
|
158
|
+
</div>
|
|
159
|
+
</Modal>,
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
/*
|
|
163
|
+
* Modal remembers where a press started so a drag out of the panel is not
|
|
164
|
+
* a dismissal. A portalled mousedown must not leave that memory set to
|
|
165
|
+
* "outside", or the user's very next click anywhere would close the
|
|
166
|
+
* dialog.
|
|
167
|
+
*/
|
|
168
|
+
fireEvent.mouseDown(screen.getByTestId("portalled-option"));
|
|
169
|
+
fireEvent.click(screen.getByTestId("modal-title"));
|
|
170
|
+
|
|
171
|
+
expect(onClose).not.toHaveBeenCalled();
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe("AutocompleteTextInput — the surface in the reported bug", () => {
|
|
176
|
+
test("picking a suggestion sets the value and keeps the modal open", () => {
|
|
177
|
+
const onChange: (value: string) => void = jest.fn();
|
|
178
|
+
const harness: PortalHarness = renderInModal(
|
|
179
|
+
<AutocompleteTextInput
|
|
180
|
+
dataTestId="attribute-key"
|
|
181
|
+
suggestions={SUGGESTIONS}
|
|
182
|
+
onChange={onChange}
|
|
183
|
+
/>,
|
|
184
|
+
);
|
|
185
|
+
|
|
186
|
+
fireEvent.focus(screen.getByTestId("attribute-key"));
|
|
187
|
+
|
|
188
|
+
const option: HTMLElement = screen.getAllByRole("option")[1]!;
|
|
189
|
+
|
|
190
|
+
expect(screen.getByTestId("modal").contains(option)).toBe(false);
|
|
191
|
+
|
|
192
|
+
press(option);
|
|
193
|
+
|
|
194
|
+
// Both halves of the report: the value lands *and* the dialog survives.
|
|
195
|
+
expect(onChange).toHaveBeenCalledWith("k8s.namespace.name");
|
|
196
|
+
expect(screen.getByTestId("attribute-key")).toHaveValue(
|
|
197
|
+
"k8s.namespace.name",
|
|
198
|
+
);
|
|
199
|
+
expect(harness.onClose).not.toHaveBeenCalled();
|
|
200
|
+
expect(screen.getByTestId("modal")).toBeInTheDocument();
|
|
201
|
+
});
|
|
202
|
+
|
|
203
|
+
test("picking several suggestions in a row never closes the modal", () => {
|
|
204
|
+
const values: Array<string> = [];
|
|
205
|
+
const harness: PortalHarness = renderInModal(
|
|
206
|
+
<AutocompleteTextInput
|
|
207
|
+
dataTestId="attribute-key"
|
|
208
|
+
suggestions={SUGGESTIONS}
|
|
209
|
+
onChange={(value: string) => {
|
|
210
|
+
values.push(value);
|
|
211
|
+
}}
|
|
212
|
+
/>,
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
/*
|
|
216
|
+
* A user correcting themselves: pick, retype to search again, pick a
|
|
217
|
+
* different one. Retyping is what reopens the menu and widens the list
|
|
218
|
+
* back out, since a picked value filters the suggestions down to itself.
|
|
219
|
+
*/
|
|
220
|
+
const input: HTMLElement = screen.getByTestId("attribute-key");
|
|
221
|
+
|
|
222
|
+
fireEvent.focus(input);
|
|
223
|
+
press(screen.getAllByRole("option")[0]!);
|
|
224
|
+
|
|
225
|
+
fireEvent.change(input, { target: { value: "service" } });
|
|
226
|
+
press(screen.getAllByRole("option")[0]!);
|
|
227
|
+
|
|
228
|
+
fireEvent.change(input, { target: { value: "k8s.n" } });
|
|
229
|
+
press(screen.getAllByRole("option")[0]!);
|
|
230
|
+
|
|
231
|
+
expect(values).toEqual([
|
|
232
|
+
"k8s.cluster.name",
|
|
233
|
+
"service",
|
|
234
|
+
"service.name",
|
|
235
|
+
"k8s.n",
|
|
236
|
+
"k8s.namespace.name",
|
|
237
|
+
]);
|
|
238
|
+
expect(input).toHaveValue("k8s.namespace.name");
|
|
239
|
+
expect(harness.onClose).not.toHaveBeenCalled();
|
|
240
|
+
expect(screen.getByTestId("modal")).toBeInTheDocument();
|
|
241
|
+
});
|
|
242
|
+
|
|
243
|
+
test("the menu closes on pick without taking the dialog with it", () => {
|
|
244
|
+
renderInModal(
|
|
245
|
+
<AutocompleteTextInput
|
|
246
|
+
dataTestId="attribute-key"
|
|
247
|
+
suggestions={SUGGESTIONS}
|
|
248
|
+
/>,
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
fireEvent.focus(screen.getByTestId("attribute-key"));
|
|
252
|
+
press(screen.getAllByRole("option")[0]!);
|
|
253
|
+
|
|
254
|
+
expect(screen.queryByTestId("attribute-key-suggestions")).toBeNull();
|
|
255
|
+
expect(screen.getByTestId("modal")).toBeInTheDocument();
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
test("picking the loading row's replacement after suggestions arrive still keeps the modal", () => {
|
|
259
|
+
const onChange: (value: string) => void = jest.fn();
|
|
260
|
+
const onClose: () => void = jest.fn();
|
|
261
|
+
|
|
262
|
+
const { rerender } = render(
|
|
263
|
+
<Modal title="Dashboard Variables" onClose={onClose}>
|
|
264
|
+
<AutocompleteTextInput
|
|
265
|
+
dataTestId="attribute-key"
|
|
266
|
+
suggestions={[]}
|
|
267
|
+
isLoadingSuggestions={true}
|
|
268
|
+
loadingMessage="Loading attributes..."
|
|
269
|
+
onChange={onChange}
|
|
270
|
+
/>
|
|
271
|
+
</Modal>,
|
|
272
|
+
);
|
|
273
|
+
|
|
274
|
+
fireEvent.focus(screen.getByTestId("attribute-key"));
|
|
275
|
+
expect(screen.getByTestId("attribute-key-suggestions")).toHaveTextContent(
|
|
276
|
+
"Loading attributes...",
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
// Suggestions land asynchronously in the real dashboard.
|
|
280
|
+
rerender(
|
|
281
|
+
<Modal title="Dashboard Variables" onClose={onClose}>
|
|
282
|
+
<AutocompleteTextInput
|
|
283
|
+
dataTestId="attribute-key"
|
|
284
|
+
suggestions={SUGGESTIONS}
|
|
285
|
+
isLoadingSuggestions={false}
|
|
286
|
+
onChange={onChange}
|
|
287
|
+
/>
|
|
288
|
+
</Modal>,
|
|
289
|
+
);
|
|
290
|
+
|
|
291
|
+
press(screen.getAllByRole("option")[0]!);
|
|
292
|
+
|
|
293
|
+
expect(onChange).toHaveBeenCalledWith("k8s.cluster.name");
|
|
294
|
+
expect(onClose).not.toHaveBeenCalled();
|
|
295
|
+
});
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
describe("OperatorSelector", () => {
|
|
299
|
+
test("picking an operator keeps the modal open", () => {
|
|
300
|
+
const onChange: (value: FilterOperator) => void = jest.fn();
|
|
301
|
+
const harness: PortalHarness = renderInModal(
|
|
302
|
+
<OperatorSelector
|
|
303
|
+
value={FilterOperator.Contains}
|
|
304
|
+
options={TEXT_OPERATORS}
|
|
305
|
+
onChange={onChange}
|
|
306
|
+
/>,
|
|
307
|
+
);
|
|
308
|
+
|
|
309
|
+
fireEvent.click(screen.getByRole("button", { name: /contains/i }));
|
|
310
|
+
|
|
311
|
+
const option: HTMLElement = screen.getByRole("option", {
|
|
312
|
+
name: "starts with",
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
expect(screen.getByTestId("modal").contains(option)).toBe(false);
|
|
316
|
+
|
|
317
|
+
press(option);
|
|
318
|
+
|
|
319
|
+
expect(onChange).toHaveBeenCalledWith(FilterOperator.StartsWith);
|
|
320
|
+
expect(harness.onClose).not.toHaveBeenCalled();
|
|
321
|
+
expect(screen.getByTestId("modal")).toBeInTheDocument();
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
/*
|
|
326
|
+
* ColorPicker and IconPicker share UseAnchoredFieldPopup, whose own
|
|
327
|
+
* outside-click guard is a native capture-phase document listener — it never
|
|
328
|
+
* touches React propagation, so both were as exposed as the autocomplete.
|
|
329
|
+
* They reach a modal through FormField's Color and Icon schema types, which
|
|
330
|
+
* is to say through every ModelFormModal that edits a label or an incident
|
|
331
|
+
* role: picking a colour used to throw the whole form away.
|
|
332
|
+
*/
|
|
333
|
+
describe("ColorPicker", () => {
|
|
334
|
+
test("pressing inside the colour popup keeps the modal open", () => {
|
|
335
|
+
const harness: PortalHarness = renderInModal(
|
|
336
|
+
<ColorPicker
|
|
337
|
+
dataTestId="color-value"
|
|
338
|
+
placeholder="Pick a color"
|
|
339
|
+
onChange={jest.fn()}
|
|
340
|
+
/>,
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
fireEvent.click(screen.getByTestId("color-value"));
|
|
344
|
+
|
|
345
|
+
const popup: HTMLElement = screen.getByTestId("color-picker-popup");
|
|
346
|
+
|
|
347
|
+
expect(screen.getByTestId("modal").contains(popup)).toBe(false);
|
|
348
|
+
|
|
349
|
+
// The hex field: the part of the popup a user is most likely to press.
|
|
350
|
+
press(popup.querySelector("input") as HTMLElement);
|
|
351
|
+
|
|
352
|
+
expect(harness.onClose).not.toHaveBeenCalled();
|
|
353
|
+
expect(screen.getByTestId("modal")).toBeInTheDocument();
|
|
354
|
+
expect(screen.getByTestId("color-picker-popup")).toBeInTheDocument();
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
describe("IconPicker", () => {
|
|
359
|
+
test("picking an icon keeps the modal open", () => {
|
|
360
|
+
const onChange: (value: IconProp | null) => void = jest.fn();
|
|
361
|
+
const harness: PortalHarness = renderInModal(
|
|
362
|
+
<IconPicker
|
|
363
|
+
dataTestId="icon-value"
|
|
364
|
+
placeholder="No icon"
|
|
365
|
+
onChange={onChange}
|
|
366
|
+
/>,
|
|
367
|
+
);
|
|
368
|
+
|
|
369
|
+
fireEvent.click(screen.getByTestId("icon-value"));
|
|
370
|
+
|
|
371
|
+
const popup: HTMLElement = screen.getByTestId("icon-picker-popup");
|
|
372
|
+
const iconCell: HTMLElement = popup.querySelector(
|
|
373
|
+
`[title="${IconProp.Alert}"]`,
|
|
374
|
+
) as HTMLElement;
|
|
375
|
+
|
|
376
|
+
expect(screen.getByTestId("modal").contains(popup)).toBe(false);
|
|
377
|
+
expect(iconCell).not.toBeNull();
|
|
378
|
+
|
|
379
|
+
press(iconCell);
|
|
380
|
+
|
|
381
|
+
expect(onChange).toHaveBeenLastCalledWith(IconProp.Alert);
|
|
382
|
+
expect(harness.onClose).not.toHaveBeenCalled();
|
|
383
|
+
expect(screen.getByTestId("modal")).toBeInTheDocument();
|
|
384
|
+
});
|
|
385
|
+
});
|
|
386
|
+
|
|
387
|
+
describe("Dropdown (react-select portalled menu)", () => {
|
|
388
|
+
test("picking an option keeps the modal open", () => {
|
|
389
|
+
const onChange: (
|
|
390
|
+
value: DropdownValue | Array<DropdownValue> | null,
|
|
391
|
+
) => void = jest.fn();
|
|
392
|
+
const harness: PortalHarness = renderInModal(
|
|
393
|
+
<Dropdown
|
|
394
|
+
options={DROPDOWN_OPTIONS}
|
|
395
|
+
onChange={onChange}
|
|
396
|
+
placeholder="Select an environment"
|
|
397
|
+
/>,
|
|
398
|
+
);
|
|
399
|
+
|
|
400
|
+
fireEvent.keyDown(screen.getByRole("combobox"), { key: "ArrowDown" });
|
|
401
|
+
|
|
402
|
+
const option: HTMLElement = screen.getByText("Staging");
|
|
403
|
+
|
|
404
|
+
/*
|
|
405
|
+
* react-select is configured with menuPortalTarget={document.body}, so
|
|
406
|
+
* its option is outside the panel exactly like the hand-rolled menus.
|
|
407
|
+
*
|
|
408
|
+
* This one was never broken: react-select's own `onMenuMouseDown` calls
|
|
409
|
+
* stopPropagation, so the press never armed Modal's backdrop tracking.
|
|
410
|
+
* That immunity is incidental to a third-party implementation detail
|
|
411
|
+
* rather than something this codebase decided, which is precisely why it
|
|
412
|
+
* is worth pinning — a react-select upgrade that drops it would otherwise
|
|
413
|
+
* reintroduce the bug on every dropdown in every modal, silently.
|
|
414
|
+
*/
|
|
415
|
+
expect(screen.getByTestId("modal").contains(option)).toBe(false);
|
|
416
|
+
|
|
417
|
+
press(option);
|
|
418
|
+
|
|
419
|
+
expect(onChange).toHaveBeenCalledWith("staging");
|
|
420
|
+
expect(harness.onClose).not.toHaveBeenCalled();
|
|
421
|
+
expect(screen.getByTestId("modal")).toBeInTheDocument();
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
describe("genuine backdrop dismissal still works", () => {
|
|
426
|
+
/*
|
|
427
|
+
* The fix narrows what counts as a backdrop press, so the far more common
|
|
428
|
+
* behaviour it sits next to has to be pinned down just as hard — a fix that
|
|
429
|
+
* made modals undismissable would be a worse bug than the one it replaced.
|
|
430
|
+
*/
|
|
431
|
+
test("a press that starts and ends on the backdrop closes the modal", () => {
|
|
432
|
+
const harness: PortalHarness = renderInModal(<div>Modal content</div>);
|
|
433
|
+
|
|
434
|
+
press(getBackdropLayer());
|
|
435
|
+
|
|
436
|
+
expect(harness.onClose).toHaveBeenCalledTimes(1);
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
test("a press on the scroll layer that holds the backdrop closes the modal", () => {
|
|
440
|
+
const harness: PortalHarness = renderInModal(<div>Modal content</div>);
|
|
441
|
+
|
|
442
|
+
// The 'fixed inset-0 overflow-y-auto' layer the handlers are bound to.
|
|
443
|
+
press(getBackdropLayer().parentElement!);
|
|
444
|
+
|
|
445
|
+
expect(harness.onClose).toHaveBeenCalledTimes(1);
|
|
446
|
+
});
|
|
447
|
+
|
|
448
|
+
test("a press inside the panel does not close the modal", () => {
|
|
449
|
+
const harness: PortalHarness = renderInModal(<div>Modal content</div>);
|
|
450
|
+
|
|
451
|
+
press(screen.getByText("Modal content"));
|
|
452
|
+
|
|
453
|
+
expect(harness.onClose).not.toHaveBeenCalled();
|
|
454
|
+
});
|
|
455
|
+
|
|
456
|
+
test("backdrop dismissal still works after a portalled pick", () => {
|
|
457
|
+
const harness: PortalHarness = renderInModal(
|
|
458
|
+
<AutocompleteTextInput
|
|
459
|
+
dataTestId="attribute-key"
|
|
460
|
+
suggestions={SUGGESTIONS}
|
|
461
|
+
/>,
|
|
462
|
+
);
|
|
463
|
+
|
|
464
|
+
fireEvent.focus(screen.getByTestId("attribute-key"));
|
|
465
|
+
press(screen.getAllByRole("option")[0]!);
|
|
466
|
+
|
|
467
|
+
expect(harness.onClose).not.toHaveBeenCalled();
|
|
468
|
+
|
|
469
|
+
// The dialog is still dismissable the ordinary way.
|
|
470
|
+
press(getBackdropLayer());
|
|
471
|
+
|
|
472
|
+
expect(harness.onClose).toHaveBeenCalledTimes(1);
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
test("the close button still closes a modal holding a portalled menu", () => {
|
|
476
|
+
const harness: PortalHarness = renderInModal(
|
|
477
|
+
<AutocompleteTextInput
|
|
478
|
+
dataTestId="attribute-key"
|
|
479
|
+
suggestions={SUGGESTIONS}
|
|
480
|
+
/>,
|
|
481
|
+
);
|
|
482
|
+
|
|
483
|
+
fireEvent.focus(screen.getByTestId("attribute-key"));
|
|
484
|
+
fireEvent.click(screen.getByTestId("close-button"));
|
|
485
|
+
|
|
486
|
+
expect(harness.onClose).toHaveBeenCalledTimes(1);
|
|
487
|
+
});
|
|
488
|
+
});
|
|
489
|
+
});
|