@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,250 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
FunctionComponent,
|
|
3
|
+
ReactElement,
|
|
4
|
+
useCallback,
|
|
5
|
+
useEffect,
|
|
6
|
+
useRef,
|
|
7
|
+
useState,
|
|
8
|
+
} from "react";
|
|
9
|
+
import InBetween from "../../../Types/BaseDatabase/InBetween";
|
|
10
|
+
import IconProp from "../../../Types/Icon/IconProp";
|
|
11
|
+
import RangeStartAndEndDateTime, {
|
|
12
|
+
RangeStartAndEndDateTimeUtil,
|
|
13
|
+
} from "../../../Types/Time/RangeStartAndEndDateTime";
|
|
14
|
+
import TimeRange from "../../../Types/Time/TimeRange";
|
|
15
|
+
import {
|
|
16
|
+
DropdownHorizontalAlignment,
|
|
17
|
+
getDropdownAlignmentClassName,
|
|
18
|
+
useDropdownHorizontalAlignment,
|
|
19
|
+
} from "../../Utils/DropdownAlignment";
|
|
20
|
+
import Icon from "../Icon/Icon";
|
|
21
|
+
import CustomTimeRangeModal from "./CustomTimeRangeModal";
|
|
22
|
+
|
|
23
|
+
export interface TimeRangePickerPresetOption {
|
|
24
|
+
range: TimeRange;
|
|
25
|
+
label: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ComponentProps {
|
|
29
|
+
value: RangeStartAndEndDateTime;
|
|
30
|
+
onChange: (value: RangeStartAndEndDateTime) => void;
|
|
31
|
+
/*
|
|
32
|
+
* Prefix for the trigger and panel test ids, so each surface embedding this
|
|
33
|
+
* picker keeps the selector its own tests were written against.
|
|
34
|
+
*/
|
|
35
|
+
dataTestIdPrefix: string;
|
|
36
|
+
dropdownWidthInPx: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export const CUSTOM_RANGE_OPTION_LABEL: string = "Custom Range...";
|
|
40
|
+
|
|
41
|
+
// Preset options to show in the dropdown, ordered shortest window first.
|
|
42
|
+
export const TIME_RANGE_PRESET_OPTIONS: Array<TimeRangePickerPresetOption> = [
|
|
43
|
+
{ range: TimeRange.PAST_FIVE_MINS, label: "Past 5 Minutes" },
|
|
44
|
+
{ range: TimeRange.PAST_FIFTEEN_MINS, label: "Past 15 Minutes" },
|
|
45
|
+
{ range: TimeRange.PAST_THIRTY_MINS, label: "Past 30 Minutes" },
|
|
46
|
+
{ range: TimeRange.PAST_ONE_HOUR, label: "Past 1 Hour" },
|
|
47
|
+
{ range: TimeRange.PAST_TWO_HOURS, label: "Past 2 Hours" },
|
|
48
|
+
{ range: TimeRange.PAST_THREE_HOURS, label: "Past 3 Hours" },
|
|
49
|
+
{ range: TimeRange.PAST_ONE_DAY, label: "Past 1 Day" },
|
|
50
|
+
{ range: TimeRange.PAST_TWO_DAYS, label: "Past 2 Days" },
|
|
51
|
+
{ range: TimeRange.PAST_ONE_WEEK, label: "Past 1 Week" },
|
|
52
|
+
{ range: TimeRange.PAST_TWO_WEEKS, label: "Past 2 Weeks" },
|
|
53
|
+
{ range: TimeRange.PAST_ONE_MONTH, label: "Past 1 Month" },
|
|
54
|
+
{ range: TimeRange.PAST_THREE_MONTHS, label: "Past 3 Months" },
|
|
55
|
+
];
|
|
56
|
+
|
|
57
|
+
function formatDateShort(date: Date): string {
|
|
58
|
+
const month: string = date.toLocaleString("en-US", { month: "short" });
|
|
59
|
+
const day: number = date.getDate();
|
|
60
|
+
const hours: string = date.getHours().toString().padStart(2, "0");
|
|
61
|
+
const minutes: string = date.getMinutes().toString().padStart(2, "0");
|
|
62
|
+
return `${month} ${day}, ${hours}:${minutes}`;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export function getTimeRangeButtonLabel(
|
|
66
|
+
value: RangeStartAndEndDateTime,
|
|
67
|
+
): string {
|
|
68
|
+
if (value.range === TimeRange.CUSTOM && value.startAndEndDate) {
|
|
69
|
+
const start: string = formatDateShort(value.startAndEndDate.startValue);
|
|
70
|
+
const end: string = formatDateShort(value.startAndEndDate.endValue);
|
|
71
|
+
return `${start} – ${end}`;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const preset: TimeRangePickerPresetOption | undefined =
|
|
75
|
+
TIME_RANGE_PRESET_OPTIONS.find((opt: TimeRangePickerPresetOption) => {
|
|
76
|
+
return opt.range === value.range;
|
|
77
|
+
});
|
|
78
|
+
return preset ? preset.label : value.range;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const TimeRangePickerDropdown: FunctionComponent<ComponentProps> = (
|
|
82
|
+
props: ComponentProps,
|
|
83
|
+
): ReactElement => {
|
|
84
|
+
const [isOpen, setIsOpen] = useState<boolean>(false);
|
|
85
|
+
/*
|
|
86
|
+
* The custom window is edited in a modal rather than inline in this panel.
|
|
87
|
+
* Two `datetime-local` fields never fitted the 288px dropdown, and the native
|
|
88
|
+
* calendar those fields open renders outside this container — so the
|
|
89
|
+
* click-outside handler below tore the panel down the moment a date was
|
|
90
|
+
* clicked, which is what made "Custom Range..." look broken.
|
|
91
|
+
*/
|
|
92
|
+
const [customSeedValue, setCustomSeedValue] =
|
|
93
|
+
useState<InBetween<Date> | null>(null);
|
|
94
|
+
const containerRef: React.RefObject<HTMLDivElement> = useRef<HTMLDivElement>(
|
|
95
|
+
null!,
|
|
96
|
+
);
|
|
97
|
+
const buttonRef: React.RefObject<HTMLButtonElement> =
|
|
98
|
+
useRef<HTMLButtonElement>(null!);
|
|
99
|
+
const dropdownRef: React.RefObject<HTMLDivElement> = useRef<HTMLDivElement>(
|
|
100
|
+
null!,
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
const alignment: DropdownHorizontalAlignment = useDropdownHorizontalAlignment(
|
|
104
|
+
{
|
|
105
|
+
isOpen: isOpen,
|
|
106
|
+
anchorRef: buttonRef,
|
|
107
|
+
dropdownRef: dropdownRef,
|
|
108
|
+
dropdownWidthInPx: props.dropdownWidthInPx,
|
|
109
|
+
},
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
// Close on click outside
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
const handleClickOutside: (e: MouseEvent) => void = (
|
|
115
|
+
e: MouseEvent,
|
|
116
|
+
): void => {
|
|
117
|
+
if (
|
|
118
|
+
containerRef.current &&
|
|
119
|
+
!containerRef.current.contains(e.target as Node)
|
|
120
|
+
) {
|
|
121
|
+
setIsOpen(false);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
126
|
+
return () => {
|
|
127
|
+
document.removeEventListener("mousedown", handleClickOutside);
|
|
128
|
+
};
|
|
129
|
+
}, []);
|
|
130
|
+
|
|
131
|
+
const handlePresetSelect: (range: TimeRange) => void = useCallback(
|
|
132
|
+
(range: TimeRange): void => {
|
|
133
|
+
props.onChange({ range });
|
|
134
|
+
setIsOpen(false);
|
|
135
|
+
},
|
|
136
|
+
[props],
|
|
137
|
+
);
|
|
138
|
+
|
|
139
|
+
const openCustomModal: () => void = useCallback((): void => {
|
|
140
|
+
/*
|
|
141
|
+
* Seed the editor with the window currently on screen — the custom range
|
|
142
|
+
* if one is already applied, otherwise the absolute bounds of the selected
|
|
143
|
+
* preset, so the user edits what they are looking at.
|
|
144
|
+
*/
|
|
145
|
+
setCustomSeedValue(
|
|
146
|
+
props.value.range === TimeRange.CUSTOM && props.value.startAndEndDate
|
|
147
|
+
? props.value.startAndEndDate
|
|
148
|
+
: RangeStartAndEndDateTimeUtil.getStartAndEndDate(props.value),
|
|
149
|
+
);
|
|
150
|
+
setIsOpen(false);
|
|
151
|
+
}, [props.value]);
|
|
152
|
+
|
|
153
|
+
const buttonLabel: string = getTimeRangeButtonLabel(props.value);
|
|
154
|
+
|
|
155
|
+
return (
|
|
156
|
+
<div ref={containerRef} className="relative">
|
|
157
|
+
<button
|
|
158
|
+
ref={buttonRef}
|
|
159
|
+
type="button"
|
|
160
|
+
data-testid={`${props.dataTestIdPrefix}-button`}
|
|
161
|
+
aria-haspopup="true"
|
|
162
|
+
aria-expanded={isOpen}
|
|
163
|
+
className={`inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1.5 text-xs font-medium shadow-sm transition-colors ${
|
|
164
|
+
isOpen
|
|
165
|
+
? "border-indigo-300 bg-indigo-50 text-indigo-700"
|
|
166
|
+
: "border-gray-200 bg-white text-gray-700 hover:border-gray-300 hover:bg-gray-50"
|
|
167
|
+
}`}
|
|
168
|
+
onClick={() => {
|
|
169
|
+
setIsOpen(!isOpen);
|
|
170
|
+
}}
|
|
171
|
+
>
|
|
172
|
+
<Icon icon={IconProp.Clock} className="h-3.5 w-3.5" />
|
|
173
|
+
<span>{buttonLabel}</span>
|
|
174
|
+
<Icon
|
|
175
|
+
icon={IconProp.ChevronDown}
|
|
176
|
+
className={`h-3 w-3 transition-transform ${isOpen ? "rotate-180" : ""}`}
|
|
177
|
+
/>
|
|
178
|
+
</button>
|
|
179
|
+
|
|
180
|
+
{isOpen && (
|
|
181
|
+
<div
|
|
182
|
+
ref={dropdownRef}
|
|
183
|
+
data-testid={`${props.dataTestIdPrefix}-dropdown`}
|
|
184
|
+
data-align={alignment}
|
|
185
|
+
className={`absolute ${getDropdownAlignmentClassName(
|
|
186
|
+
alignment,
|
|
187
|
+
)} top-full z-50 mt-1 w-72 max-w-[calc(100vw-1rem)] rounded-lg border border-gray-200 bg-white shadow-lg`}
|
|
188
|
+
>
|
|
189
|
+
{/* Preset options */}
|
|
190
|
+
<div className="max-h-64 overflow-y-auto py-1">
|
|
191
|
+
{TIME_RANGE_PRESET_OPTIONS.map(
|
|
192
|
+
(option: TimeRangePickerPresetOption) => {
|
|
193
|
+
const isActive: boolean = props.value.range === option.range;
|
|
194
|
+
|
|
195
|
+
return (
|
|
196
|
+
<button
|
|
197
|
+
key={option.range}
|
|
198
|
+
type="button"
|
|
199
|
+
className={`flex w-full items-center px-3 py-1.5 text-left text-sm transition-colors ${
|
|
200
|
+
isActive
|
|
201
|
+
? "bg-indigo-50 font-medium text-indigo-700"
|
|
202
|
+
: "text-gray-700 hover:bg-gray-50"
|
|
203
|
+
}`}
|
|
204
|
+
onClick={() => {
|
|
205
|
+
handlePresetSelect(option.range);
|
|
206
|
+
}}
|
|
207
|
+
>
|
|
208
|
+
{option.label}
|
|
209
|
+
</button>
|
|
210
|
+
);
|
|
211
|
+
},
|
|
212
|
+
)}
|
|
213
|
+
|
|
214
|
+
{/* Custom option — opens the editor in a modal */}
|
|
215
|
+
<button
|
|
216
|
+
type="button"
|
|
217
|
+
data-testid={`${props.dataTestIdPrefix}-custom-option`}
|
|
218
|
+
className={`flex w-full items-center px-3 py-1.5 text-left text-sm transition-colors ${
|
|
219
|
+
props.value.range === TimeRange.CUSTOM
|
|
220
|
+
? "bg-indigo-50 font-medium text-indigo-700"
|
|
221
|
+
: "text-gray-700 hover:bg-gray-50"
|
|
222
|
+
}`}
|
|
223
|
+
onClick={openCustomModal}
|
|
224
|
+
>
|
|
225
|
+
{CUSTOM_RANGE_OPTION_LABEL}
|
|
226
|
+
</button>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
)}
|
|
230
|
+
|
|
231
|
+
{customSeedValue && (
|
|
232
|
+
<CustomTimeRangeModal
|
|
233
|
+
initialValue={customSeedValue}
|
|
234
|
+
onClose={() => {
|
|
235
|
+
setCustomSeedValue(null);
|
|
236
|
+
}}
|
|
237
|
+
onSave={(startAndEndDate: InBetween<Date>) => {
|
|
238
|
+
setCustomSeedValue(null);
|
|
239
|
+
props.onChange({
|
|
240
|
+
range: TimeRange.CUSTOM,
|
|
241
|
+
startAndEndDate: startAndEndDate,
|
|
242
|
+
});
|
|
243
|
+
}}
|
|
244
|
+
/>
|
|
245
|
+
)}
|
|
246
|
+
</div>
|
|
247
|
+
);
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
export default TimeRangePickerDropdown;
|
|
@@ -164,7 +164,16 @@ const DictionaryForm: FunctionComponent<ComponentProps> = (
|
|
|
164
164
|
* numeric/boolean inputs always represent equality.
|
|
165
165
|
*/
|
|
166
166
|
if (item.type === ValueType.Number) {
|
|
167
|
-
|
|
167
|
+
/*
|
|
168
|
+
* An empty number box is a row the user is still filling in, not a
|
|
169
|
+
* filter for "". Leaving the key out of the result keeps it out of the
|
|
170
|
+
* query until an actual number is typed — which is what the value
|
|
171
|
+
* input used to achieve by deleting the row outright.
|
|
172
|
+
*/
|
|
173
|
+
if (typeof item.value !== "number" || isNaN(item.value)) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
result[item.key] = item.value;
|
|
168
177
|
return;
|
|
169
178
|
}
|
|
170
179
|
if (item.type === ValueType.Boolean) {
|
|
@@ -495,12 +504,20 @@ const DictionaryForm: FunctionComponent<ComponentProps> = (
|
|
|
495
504
|
placeholder={props.valuePlaceholder}
|
|
496
505
|
onChange={(value: string) => {
|
|
497
506
|
const newData: Array<Item> = [...data];
|
|
507
|
+
const parsedValue: number = parseInt(value);
|
|
498
508
|
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
509
|
+
/*
|
|
510
|
+
* Emptying the box empties this row's value — it does not
|
|
511
|
+
* remove the row. `delete` on an array leaves a hole, so
|
|
512
|
+
* clearing the number silently threw away the filter the
|
|
513
|
+
* user was in the middle of writing, and the next
|
|
514
|
+
* `[...data]` materialised that hole as `undefined` and
|
|
515
|
+
* crashed the whole form on the following render.
|
|
516
|
+
*/
|
|
517
|
+
newData[index]!.value =
|
|
518
|
+
value.length > 0 && !isNaN(parsedValue)
|
|
519
|
+
? parsedValue
|
|
520
|
+
: "";
|
|
504
521
|
|
|
505
522
|
setData(newData);
|
|
506
523
|
onDataChange(newData);
|
|
@@ -10,6 +10,7 @@ import React, {
|
|
|
10
10
|
FunctionComponent,
|
|
11
11
|
ReactElement,
|
|
12
12
|
useEffect,
|
|
13
|
+
useId,
|
|
13
14
|
useState,
|
|
14
15
|
} from "react";
|
|
15
16
|
import { createPortal } from "react-dom";
|
|
@@ -43,14 +44,20 @@ const ColorPicker: FunctionComponent<ComponentProps> = (
|
|
|
43
44
|
anchorRef,
|
|
44
45
|
popupRef,
|
|
45
46
|
isPopupOpen,
|
|
47
|
+
popupId,
|
|
46
48
|
popupPosition,
|
|
47
49
|
portalTarget,
|
|
50
|
+
onTriggerKeyDown,
|
|
48
51
|
togglePopup,
|
|
49
52
|
}: AnchoredFieldPopup = useAnchoredFieldPopup({
|
|
50
53
|
popupMaxHeight: COLOR_PICKER_POPUP_MAX_HEIGHT_PX,
|
|
51
54
|
popupWidth: COLOR_PICKER_POPUP_WIDTH_PX,
|
|
52
55
|
});
|
|
53
56
|
|
|
57
|
+
const isInteractive: boolean = !props.readOnly && !props.disabled;
|
|
58
|
+
const generatedId: string = useId();
|
|
59
|
+
const errorId: string = `${generatedId}-color-picker-error`;
|
|
60
|
+
|
|
54
61
|
const [isInitialValuesInitialized, setIsInitialValuesInitialized] =
|
|
55
62
|
useState<boolean>(false);
|
|
56
63
|
|
|
@@ -79,20 +86,39 @@ const ColorPicker: FunctionComponent<ComponentProps> = (
|
|
|
79
86
|
>
|
|
80
87
|
<div
|
|
81
88
|
onClick={() => {
|
|
82
|
-
if (
|
|
89
|
+
if (isInteractive) {
|
|
83
90
|
togglePopup();
|
|
84
91
|
}
|
|
85
92
|
}}
|
|
93
|
+
aria-hidden="true"
|
|
86
94
|
className="rounded h-5 w-5 border border-gray-200 cursor-pointer"
|
|
87
95
|
style={{ backgroundColor: color.toString() }}
|
|
88
96
|
></div>
|
|
89
97
|
|
|
90
98
|
<Input
|
|
91
99
|
onClick={() => {
|
|
92
|
-
if (
|
|
100
|
+
if (isInteractive) {
|
|
93
101
|
togglePopup();
|
|
94
102
|
}
|
|
95
103
|
}}
|
|
104
|
+
/*
|
|
105
|
+
* The field is a trigger, not a text box: it is readOnly and its only
|
|
106
|
+
* job is to open the picker. Without this a keyboard user cannot
|
|
107
|
+
* reach the picker at all, which on a required colour - the Create
|
|
108
|
+
* Label form - means they cannot submit the form either.
|
|
109
|
+
*/
|
|
110
|
+
onKeyDown={isInteractive ? onTriggerKeyDown : undefined}
|
|
111
|
+
ariaHasPopup="dialog"
|
|
112
|
+
ariaExpanded={isPopupOpen}
|
|
113
|
+
ariaControls={isPopupOpen ? popupId : undefined}
|
|
114
|
+
/*
|
|
115
|
+
* The message below belongs to the whole control rather than to this
|
|
116
|
+
* input, so it has to be pointed at explicitly - otherwise "Label
|
|
117
|
+
* Color is required." is on screen and nowhere in the accessibility
|
|
118
|
+
* tree, and a screen reader user is told only that the form failed.
|
|
119
|
+
*/
|
|
120
|
+
ariaDescribedby={props.error ? errorId : undefined}
|
|
121
|
+
ariaInvalid={Boolean(props.error)}
|
|
96
122
|
disabled={props.disabled}
|
|
97
123
|
dataTestId={props.dataTestId}
|
|
98
124
|
onBlur={props.onBlur}
|
|
@@ -113,16 +139,24 @@ const ColorPicker: FunctionComponent<ComponentProps> = (
|
|
|
113
139
|
onFocus={props.onFocus || undefined}
|
|
114
140
|
/>
|
|
115
141
|
{color && !props.disabled && (
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
142
|
+
/*
|
|
143
|
+
* A button, not a bare svg with a click handler: undoing a choice has
|
|
144
|
+
* to be reachable by the same keyboard that made it.
|
|
145
|
+
*/
|
|
146
|
+
<button
|
|
147
|
+
type="button"
|
|
148
|
+
aria-label="Clear color"
|
|
149
|
+
title="Clear color"
|
|
150
|
+
className="flex items-center text-gray-400 hover:text-gray-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 rounded"
|
|
119
151
|
onClick={() => {
|
|
120
152
|
setColor("");
|
|
121
153
|
if (props.onChange) {
|
|
122
154
|
props.onChange(null);
|
|
123
155
|
}
|
|
124
156
|
}}
|
|
125
|
-
|
|
157
|
+
>
|
|
158
|
+
<Icon icon={IconProp.Close} className="h-5 w-5 cursor-pointer" />
|
|
159
|
+
</button>
|
|
126
160
|
)}
|
|
127
161
|
</div>
|
|
128
162
|
{/*
|
|
@@ -134,6 +168,9 @@ const ColorPicker: FunctionComponent<ComponentProps> = (
|
|
|
134
168
|
<div
|
|
135
169
|
ref={popupRef}
|
|
136
170
|
data-testid="color-picker-popup"
|
|
171
|
+
id={popupId}
|
|
172
|
+
role="dialog"
|
|
173
|
+
aria-label="Color picker"
|
|
137
174
|
tabIndex={-1}
|
|
138
175
|
className="fixed overflow-auto rounded-md shadow-lg"
|
|
139
176
|
style={{
|
|
@@ -147,10 +184,24 @@ const ColorPicker: FunctionComponent<ComponentProps> = (
|
|
|
147
184
|
>
|
|
148
185
|
<ChromePicker
|
|
149
186
|
color={color}
|
|
187
|
+
/*
|
|
188
|
+
* The field stores a bare hex, so an alpha channel it cannot
|
|
189
|
+
* represent is worse than no alpha at all: react-color reports
|
|
190
|
+
* a fully transparent colour as the literal "transparent",
|
|
191
|
+
* which sails through Color (it validates nothing) and is then
|
|
192
|
+
* rejected on save as longer than the ten characters the column
|
|
193
|
+
* holds - for a colour the user can see in the swatch.
|
|
194
|
+
*/
|
|
195
|
+
disableAlpha={true}
|
|
196
|
+
/*
|
|
197
|
+
* One callback, not two. The swatch used to be painted from
|
|
198
|
+
* onChange and the form fed from onChangeComplete, which
|
|
199
|
+
* react-color debounces by 100ms — so for that window the field
|
|
200
|
+
* showed a colour the form did not hold yet. The value always
|
|
201
|
+
* arrived in the end, but there is no reason for the two to
|
|
202
|
+
* disagree at all.
|
|
203
|
+
*/
|
|
150
204
|
onChange={(color: ColorResult) => {
|
|
151
|
-
setColor(color.hex);
|
|
152
|
-
}}
|
|
153
|
-
onChangeComplete={(color: ColorResult) => {
|
|
154
205
|
return handleChange(color.hex);
|
|
155
206
|
}}
|
|
156
207
|
/>
|
|
@@ -159,7 +210,12 @@ const ColorPicker: FunctionComponent<ComponentProps> = (
|
|
|
159
210
|
)
|
|
160
211
|
: null}
|
|
161
212
|
{props.error && (
|
|
162
|
-
<p
|
|
213
|
+
<p
|
|
214
|
+
id={errorId}
|
|
215
|
+
role="alert"
|
|
216
|
+
data-testid="error-message"
|
|
217
|
+
className="mt-1 text-sm text-red-400"
|
|
218
|
+
>
|
|
163
219
|
{props.error}
|
|
164
220
|
</p>
|
|
165
221
|
)}
|
|
@@ -9,6 +9,7 @@ import React, {
|
|
|
9
9
|
FunctionComponent,
|
|
10
10
|
ReactElement,
|
|
11
11
|
useEffect,
|
|
12
|
+
useId,
|
|
12
13
|
useState,
|
|
13
14
|
} from "react";
|
|
14
15
|
import { createPortal } from "react-dom";
|
|
@@ -41,15 +42,21 @@ const IconPicker: FunctionComponent<ComponentProps> = (
|
|
|
41
42
|
anchorRef,
|
|
42
43
|
popupRef,
|
|
43
44
|
isPopupOpen,
|
|
45
|
+
popupId,
|
|
44
46
|
popupPosition,
|
|
45
47
|
portalTarget,
|
|
46
48
|
closePopup,
|
|
49
|
+
onTriggerKeyDown,
|
|
47
50
|
togglePopup,
|
|
48
51
|
}: AnchoredFieldPopup = useAnchoredFieldPopup({
|
|
49
52
|
popupMaxHeight: ICON_PICKER_POPUP_MAX_HEIGHT_PX,
|
|
50
53
|
popupWidth: ICON_PICKER_POPUP_WIDTH_PX,
|
|
51
54
|
});
|
|
52
55
|
|
|
56
|
+
const isInteractive: boolean = !props.readOnly && !props.disabled;
|
|
57
|
+
const generatedId: string = useId();
|
|
58
|
+
const errorId: string = `${generatedId}-icon-picker-error`;
|
|
59
|
+
|
|
53
60
|
const [isInitialValuesInitialized, setIsInitialValuesInitialized] =
|
|
54
61
|
useState<boolean>(false);
|
|
55
62
|
|
|
@@ -84,10 +91,11 @@ const IconPicker: FunctionComponent<ComponentProps> = (
|
|
|
84
91
|
>
|
|
85
92
|
<div
|
|
86
93
|
onClick={() => {
|
|
87
|
-
if (
|
|
94
|
+
if (isInteractive) {
|
|
88
95
|
togglePopup();
|
|
89
96
|
}
|
|
90
97
|
}}
|
|
98
|
+
aria-hidden="true"
|
|
91
99
|
className="flex items-center justify-center h-5 w-5 cursor-pointer"
|
|
92
100
|
>
|
|
93
101
|
{selectedIcon ? (
|
|
@@ -99,10 +107,18 @@ const IconPicker: FunctionComponent<ComponentProps> = (
|
|
|
99
107
|
|
|
100
108
|
<Input
|
|
101
109
|
onClick={() => {
|
|
102
|
-
if (
|
|
110
|
+
if (isInteractive) {
|
|
103
111
|
togglePopup();
|
|
104
112
|
}
|
|
105
113
|
}}
|
|
114
|
+
// The field is a trigger, not a text box - see ColorPicker.
|
|
115
|
+
onKeyDown={isInteractive ? onTriggerKeyDown : undefined}
|
|
116
|
+
ariaHasPopup="dialog"
|
|
117
|
+
ariaExpanded={isPopupOpen}
|
|
118
|
+
ariaControls={isPopupOpen ? popupId : undefined}
|
|
119
|
+
// The message below belongs to the control, not to this input.
|
|
120
|
+
ariaDescribedby={props.error ? errorId : undefined}
|
|
121
|
+
ariaInvalid={Boolean(props.error)}
|
|
106
122
|
disabled={props.disabled}
|
|
107
123
|
dataTestId={props.dataTestId}
|
|
108
124
|
onBlur={props.onBlur}
|
|
@@ -119,14 +135,19 @@ const IconPicker: FunctionComponent<ComponentProps> = (
|
|
|
119
135
|
onFocus={props.onFocus || undefined}
|
|
120
136
|
/>
|
|
121
137
|
{selectedIcon && !props.disabled && (
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
138
|
+
// A button, not a bare svg with a click handler - see ColorPicker.
|
|
139
|
+
<button
|
|
140
|
+
type="button"
|
|
141
|
+
aria-label="Clear icon"
|
|
142
|
+
title="Clear icon"
|
|
143
|
+
className="flex items-center text-gray-400 hover:text-gray-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 rounded"
|
|
125
144
|
onClick={() => {
|
|
126
145
|
setSelectedIcon(null);
|
|
127
146
|
props.onChange(null);
|
|
128
147
|
}}
|
|
129
|
-
|
|
148
|
+
>
|
|
149
|
+
<Icon icon={IconProp.Close} className="h-5 w-5 cursor-pointer" />
|
|
150
|
+
</button>
|
|
130
151
|
)}
|
|
131
152
|
</div>
|
|
132
153
|
{/*
|
|
@@ -138,6 +159,9 @@ const IconPicker: FunctionComponent<ComponentProps> = (
|
|
|
138
159
|
<div
|
|
139
160
|
ref={popupRef}
|
|
140
161
|
data-testid="icon-picker-popup"
|
|
162
|
+
id={popupId}
|
|
163
|
+
role="dialog"
|
|
164
|
+
aria-label="Icon picker"
|
|
141
165
|
tabIndex={-1}
|
|
142
166
|
className="fixed flex flex-col overflow-hidden bg-white border border-gray-200 rounded-lg shadow-lg p-3"
|
|
143
167
|
style={{
|
|
@@ -166,13 +190,22 @@ const IconPicker: FunctionComponent<ComponentProps> = (
|
|
|
166
190
|
{/* Icons grid */}
|
|
167
191
|
<div className="grid grid-cols-6 gap-2 min-h-0 flex-1 overflow-y-auto">
|
|
168
192
|
{filteredIcons.map((icon: IconProp) => {
|
|
193
|
+
/*
|
|
194
|
+
* A button rather than a div: the grid is the only way to set
|
|
195
|
+
* this field, so every cell has to be reachable by Tab and
|
|
196
|
+
* answer to Enter and Space. type="button" keeps it from
|
|
197
|
+
* submitting the form the field sits in.
|
|
198
|
+
*/
|
|
169
199
|
return (
|
|
170
|
-
<
|
|
200
|
+
<button
|
|
171
201
|
key={icon}
|
|
202
|
+
type="button"
|
|
172
203
|
onClick={() => {
|
|
173
204
|
handleChange(icon);
|
|
174
205
|
}}
|
|
175
|
-
|
|
206
|
+
aria-pressed={selectedIcon === icon}
|
|
207
|
+
aria-label={icon}
|
|
208
|
+
className={`flex items-center justify-center p-2 rounded cursor-pointer hover:bg-gray-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 ${
|
|
176
209
|
selectedIcon === icon
|
|
177
210
|
? "bg-indigo-100 ring-2 ring-indigo-500"
|
|
178
211
|
: ""
|
|
@@ -180,7 +213,7 @@ const IconPicker: FunctionComponent<ComponentProps> = (
|
|
|
180
213
|
title={icon}
|
|
181
214
|
>
|
|
182
215
|
<Icon icon={icon} className="h-5 w-5 text-gray-600" />
|
|
183
|
-
</
|
|
216
|
+
</button>
|
|
184
217
|
);
|
|
185
218
|
})}
|
|
186
219
|
</div>
|
|
@@ -195,7 +228,12 @@ const IconPicker: FunctionComponent<ComponentProps> = (
|
|
|
195
228
|
)
|
|
196
229
|
: null}
|
|
197
230
|
{props.error && (
|
|
198
|
-
<p
|
|
231
|
+
<p
|
|
232
|
+
id={errorId}
|
|
233
|
+
role="alert"
|
|
234
|
+
data-testid="error-message"
|
|
235
|
+
className="mt-1 text-sm text-red-400"
|
|
236
|
+
>
|
|
199
237
|
{props.error}
|
|
200
238
|
</p>
|
|
201
239
|
)}
|
|
@@ -92,6 +92,13 @@ export default interface Field<TEntity> {
|
|
|
92
92
|
| undefined;
|
|
93
93
|
styleType?: FormFieldStyleType | undefined;
|
|
94
94
|
showIf?: ((item: FormValues<TEntity>) => boolean) | undefined;
|
|
95
|
+
/**
|
|
96
|
+
* For a JSON field: judge its contents by JSON5's rules rather than JSON's.
|
|
97
|
+
* Set it where the code that eventually reads this value uses
|
|
98
|
+
* JSONFunctions.parse, so validation cannot reject a value that would have
|
|
99
|
+
* been read back perfectly well.
|
|
100
|
+
*/
|
|
101
|
+
allowJSON5?: boolean | undefined;
|
|
95
102
|
onChange?:
|
|
96
103
|
| ((
|
|
97
104
|
value: any,
|
|
@@ -12,8 +12,12 @@ import Email from "../../../Types/Email";
|
|
|
12
12
|
import BadDataException from "../../../Types/Exception/BadDataException";
|
|
13
13
|
import Exception from "../../../Types/Exception/Exception";
|
|
14
14
|
import GenericObject from "../../../Types/GenericObject";
|
|
15
|
-
import { JSONObject } from "../../../Types/JSON";
|
|
15
|
+
import { JSONObject, JSONValue } from "../../../Types/JSON";
|
|
16
16
|
import Phone from "../../../Types/Phone";
|
|
17
|
+
import {
|
|
18
|
+
JSONSyntaxCheckResult,
|
|
19
|
+
checkJSONSyntax,
|
|
20
|
+
} from "../../../Types/Workflow/TemplateSyntax";
|
|
17
21
|
import { Logger } from "../../Utils/Logger";
|
|
18
22
|
import Port from "../../../Types/Port";
|
|
19
23
|
import Typeof from "../../../Types/Typeof";
|
|
@@ -320,6 +324,50 @@ export default class Validation {
|
|
|
320
324
|
return null;
|
|
321
325
|
}
|
|
322
326
|
|
|
327
|
+
/**
|
|
328
|
+
* A JSON field whose contents are not JSON.
|
|
329
|
+
*
|
|
330
|
+
* Until this existed, a stray trailing comma saved cleanly and only surfaced
|
|
331
|
+
* when something tried to parse it — for a workflow that meant a real run,
|
|
332
|
+
* at whatever hour the trigger fired, ending in
|
|
333
|
+
* "Invalid JSON provided for argument request-body"
|
|
334
|
+
* (RunWorkflow.getComponentArguments).
|
|
335
|
+
*
|
|
336
|
+
* Takes the raw value rather than the stringified `content` the other
|
|
337
|
+
* validators get, because a JSON-typed field can legitimately already hold a
|
|
338
|
+
* parsed object, and `String(anObject)` is "[object Object]" — which is not
|
|
339
|
+
* JSON, and would fail every time.
|
|
340
|
+
*
|
|
341
|
+
* Tolerates {{...}} handlebars: workflow arguments are templates, and
|
|
342
|
+
* `{"retries": {{local.variables.retryCount}}}` is not JSON as written but is
|
|
343
|
+
* JSON by the time it is parsed. checkJSONSyntax masks those before parsing
|
|
344
|
+
* and declines to judge anything containing a {{#each}} loop at all.
|
|
345
|
+
*/
|
|
346
|
+
public static validateJSONSyntax<T extends GenericObject>(
|
|
347
|
+
value: JSONValue | undefined,
|
|
348
|
+
field: Field<T>,
|
|
349
|
+
): string | null {
|
|
350
|
+
if (field.fieldType !== FormFieldSchemaType.JSON) {
|
|
351
|
+
return null;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
const result: JSONSyntaxCheckResult = checkJSONSyntax(value, {
|
|
355
|
+
allowJSON5: field.allowJSON5,
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
if (result.isValid) {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
return translateValidationMessage(
|
|
363
|
+
"{{field}} is not valid JSON. {{parserMessage}}",
|
|
364
|
+
{
|
|
365
|
+
field: field.title || field.name || "",
|
|
366
|
+
parserMessage: result.errorMessage || "",
|
|
367
|
+
},
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
|
|
323
371
|
public static validate<T extends GenericObject>(args: {
|
|
324
372
|
formFields: Array<Field<T>>;
|
|
325
373
|
values: FormValues<T>;
|
|
@@ -375,6 +423,20 @@ export default class Validation {
|
|
|
375
423
|
errors[name] = resultValidateData;
|
|
376
424
|
}
|
|
377
425
|
|
|
426
|
+
/*
|
|
427
|
+
* Fed the raw value, not `content` — see validateJSONSyntax. An
|
|
428
|
+
* already-parsed object stringifies to "[object Object]", which would
|
|
429
|
+
* fail the check every time it was handed the stringified form.
|
|
430
|
+
*/
|
|
431
|
+
const resultJSONSyntax: string | null = this.validateJSONSyntax(
|
|
432
|
+
(entries as JSONObject)[name] as JSONValue | undefined,
|
|
433
|
+
field,
|
|
434
|
+
);
|
|
435
|
+
|
|
436
|
+
if (resultJSONSyntax) {
|
|
437
|
+
errors[name] = resultJSONSyntax;
|
|
438
|
+
}
|
|
439
|
+
|
|
378
440
|
const resultMatch: string | null = this.validateMatchField(
|
|
379
441
|
content,
|
|
380
442
|
field,
|