@oneuptime/common 12.0.3 → 12.0.5
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/AIRun.ts +38 -1
- package/Models/DatabaseModels/AlertFeed.ts +30 -0
- package/Models/DatabaseModels/CephCluster.ts +14 -0
- package/Models/DatabaseModels/CodeRepository.ts +14 -6
- package/Models/DatabaseModels/Dashboard.ts +28 -0
- package/Models/DatabaseModels/DockerHost.ts +14 -0
- package/Models/DatabaseModels/GlobalOidcProject.ts +18 -0
- package/Models/DatabaseModels/GlobalSsoProject.ts +18 -0
- package/Models/DatabaseModels/Incident.ts +2 -0
- package/Models/DatabaseModels/IncidentEpisode.ts +1 -0
- package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +1 -0
- package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IncidentFeed.ts +30 -0
- package/Models/DatabaseModels/IncidentPublicNote.ts +1 -0
- package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
- package/Models/DatabaseModels/IoTFleet.ts +14 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +14 -0
- package/Models/DatabaseModels/LogSavedView.ts +33 -0
- package/Models/DatabaseModels/NetworkDevice.ts +14 -0
- package/Models/DatabaseModels/NetworkInterface.ts +18 -0
- package/Models/DatabaseModels/Project.ts +247 -11
- package/Models/DatabaseModels/ProxmoxCluster.ts +14 -0
- package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -0
- package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +1 -0
- package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
- package/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.ts +4 -4
- package/Models/DatabaseModels/Service.ts +30 -0
- package/Models/DatabaseModels/StatusPage.ts +28 -0
- package/Models/DatabaseModels/StatusPageAnnouncement.ts +1 -0
- package/Models/DatabaseModels/StatusPagePrivateUser.ts +30 -0
- package/Models/DatabaseModels/User.ts +30 -0
- package/Server/API/AIAgentDataAPI.ts +75 -55
- package/Server/API/AIInvestigationAPI.ts +175 -17
- package/Server/API/DashboardAPI.ts +429 -22
- package/Server/API/GitHubAPI.ts +119 -283
- package/Server/API/StatusPageAPI.ts +38 -19
- package/Server/API/UserAPI.ts +263 -1
- package/Server/EnvironmentConfig.ts +23 -3
- package/Server/Infrastructure/ClickhouseConfig.ts +15 -1
- package/Server/Infrastructure/ClickhouseDatabase.ts +1 -1
- package/Server/Infrastructure/GlobalCache.ts +37 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.ts +21 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.ts +68 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.ts +27 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +100 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.ts +89 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.ts +27 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +214 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.ts +69 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.ts +40 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.ts +26 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
- package/Server/Services/AIRunService.ts +78 -10
- package/Server/Services/AIService.ts +94 -22
- package/Server/Services/AlertFeedService.ts +5 -0
- package/Server/Services/AnalyticsDatabaseService.ts +101 -1
- package/Server/Services/CodeRepositoryService.ts +105 -2
- package/Server/Services/DatabaseService.ts +227 -3
- package/Server/Services/IncidentFeedService.ts +5 -0
- package/Server/Services/LlmLogService.ts +46 -2
- package/Server/Services/OpenTelemetryIngestService.ts +230 -26
- package/Server/Services/UserService.ts +184 -0
- package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +6 -0
- package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +4 -0
- package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +8 -5
- package/Server/Utils/AI/CodeFix/FixRunBudget.ts +90 -16
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +2 -0
- package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +2 -0
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +223 -22
- package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +25 -24
- package/Server/Utils/AI/SRE/ConfidenceSignal.ts +182 -71
- package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +252 -43
- package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +25 -24
- package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +47 -13
- package/Server/Utils/AI/SRE/InvestigationGrader.ts +9 -5
- package/Server/Utils/AI/SRE/InvestigationQueue.ts +141 -24
- package/Server/Utils/AI/SRE/InvestigationSubjectLock.ts +66 -0
- package/Server/Utils/AI/SRE/PostedRootCause.ts +94 -3
- package/Server/Utils/AI/SRE/README.md +1 -1
- package/Server/Utils/AI/SRE/SubjectCodeFixRun.ts +132 -10
- package/Server/Utils/AI/Toolbox/CodeTools.ts +45 -4
- package/Server/Utils/AnalyticsDatabase/ClusterConfig.ts +24 -0
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +13 -0
- package/Server/Utils/CodeRepository/GitHub/GitHub.ts +157 -4
- package/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.ts +130 -0
- package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +29 -0
- package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +56 -0
- package/Server/Utils/Monitor/MonitorMetricUtil.ts +46 -0
- package/Server/Utils/Monitor/MonitorTemplateUtil.ts +1 -0
- package/Server/Utils/PasswordHash.ts +330 -0
- package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +251 -0
- package/Tests/App/Dashboard/EventStatusPanel.test.tsx +747 -0
- package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +480 -0
- package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1184 -0
- package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +500 -0
- package/Tests/App/Dashboard/OverviewCustomFields.test.tsx +333 -0
- package/Tests/App/Dashboard/PortMonitorCriteriaFilter.test.ts +93 -0
- package/Tests/App/Dashboard/UserCustomFields.test.tsx +392 -0
- package/Tests/App/StatusPage/PublicStatusPageAPIErrorHandling.test.ts +117 -0
- package/Tests/App/StatusPage/StatusPageModelAPIPolymorphism.test.ts +223 -0
- package/Tests/Models/DatabaseModels/PermissionCatalogueCoverage.test.ts +243 -0
- package/Tests/Server/API/AIAgentDataFixFromIncidentContext.test.ts +266 -0
- package/Tests/Server/API/AIAgentDataRepositoryToken.test.ts +381 -0
- package/Tests/Server/API/AIInvestigationAPI.test.ts +594 -0
- package/Tests/Server/API/AIInvestigationCreateFixTask.test.ts +80 -0
- package/Tests/Server/API/DashboardMasterPasswordAPI.test.ts +172 -1
- package/Tests/Server/API/DashboardPublicAttributeValuesAPI.test.ts +943 -0
- package/Tests/Server/API/DashboardPublicMetricsAggregateAPI.test.ts +1296 -0
- package/Tests/Server/API/DashboardPublicTemplatePayloads.test.ts +598 -0
- package/Tests/Server/API/GitHubAppInstallationBindingAPI.test.ts +539 -0
- package/Tests/Server/API/Helpers.ts +6 -1
- package/Tests/Server/API/StatusPageMasterPasswordAPI.test.ts +335 -0
- package/Tests/Server/API/UserProjectsAPI.test.ts +852 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +128 -0
- package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +215 -0
- package/Tests/Server/Services/AIRunCodeFixClaim.test.ts +59 -5
- package/Tests/Server/Services/AIRunHumanVerdict.test.ts +127 -58
- package/Tests/Server/Services/AIServiceDailyBudget.test.ts +396 -20
- package/Tests/Server/Services/AddMasterPasswordSaltMigration.test.ts +283 -0
- package/Tests/Server/Services/AddPerUserPasswordSaltMigration.test.ts +178 -0
- package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +582 -0
- package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +30 -1
- package/Tests/Server/Services/CodeRepositoryInstallationBinding.test.ts +305 -0
- package/Tests/Server/Services/CodeRepositoryResolutionBinding.test.ts +147 -0
- package/Tests/Server/Services/DatabaseServicePerUserPasswordSalt.test.ts +880 -0
- package/Tests/Server/Services/DatabaseServiceUpdateColumnsWithoutHooks.test.ts +54 -0
- package/Tests/Server/Services/FeedAIRunAssociation.test.ts +125 -0
- package/Tests/Server/Services/FixFromIncidentTaskTrigger.test.ts +418 -57
- package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +173 -14
- package/Tests/Server/Services/MasterPasswordScrypt.test.ts +567 -0
- package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +568 -0
- package/Tests/Server/Services/RestoreDroppedUniqueIndexesMigration.test.ts +386 -0
- package/Tests/Server/Services/RestoreServiceLowerNameIndexMigration.test.ts +240 -0
- package/Tests/Server/Services/SeparateIncidentAlertAiSettingsMigration.test.ts +194 -0
- package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +885 -0
- package/Tests/Server/Services/WidenHashedStringColumnsForScryptMigration.test.ts +220 -0
- package/Tests/Server/Utils/AI/AIAlertGating.test.ts +37 -4
- package/Tests/Server/Utils/AI/AIConfidenceSignal.test.ts +330 -29
- package/Tests/Server/Utils/AI/AIIncidentGating.test.ts +25 -0
- package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +293 -5
- package/Tests/Server/Utils/AI/CodeFixAgentCompletion.test.ts +59 -1
- package/Tests/Server/Utils/AI/CodeTools.test.ts +47 -1
- package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +10 -0
- package/Tests/Server/Utils/AI/FixFromIncidentAutoTrigger.test.ts +342 -19
- package/Tests/Server/Utils/AI/FixRunBudget.test.ts +214 -30
- package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +2 -0
- package/Tests/Server/Utils/AI/InvestigationGrader.test.ts +65 -17
- package/Tests/Server/Utils/AI/InvestigationQueueRemediationExecution.test.ts +3 -0
- package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +313 -20
- package/Tests/Server/Utils/AI/PostedRootCause.test.ts +254 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +4 -0
- package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +2 -0
- package/Tests/Server/Utils/AI/SubjectCodeFixRunDedupe.test.ts +44 -0
- package/Tests/Server/Utils/AnalyticsDatabase/ClusterAwareSchema.test.ts +30 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +120 -0
- package/Tests/Server/Utils/CodeRepository/GitHubInstallationBinding.test.ts +292 -0
- package/Tests/Server/Utils/GitHubInstallationOwnershipVerification.test.ts +340 -0
- package/Tests/Server/Utils/GitHubWebhookAndTreeCacheIsolation.test.ts +250 -0
- package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +212 -0
- package/Tests/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.test.ts +401 -0
- package/Tests/Server/Utils/Monitor/MonitorMetricUtilPortTimings.test.ts +243 -0
- package/Tests/Server/Utils/PasswordHash.test.ts +585 -0
- package/Tests/Types/Dashboard/DashboardTemplates.test.ts +111 -0
- package/Tests/Types/Database/ColumnLength.test.ts +7 -1
- package/Tests/Types/HashedStringPerUserSalt.test.ts +476 -0
- package/Tests/Types/Monitor/CephMetricCatalog.test.ts +104 -0
- package/Tests/Types/Monitor/CriteriaFilter.test.ts +4 -0
- package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +293 -0
- package/Tests/Types/Monitor/DockerMetricCatalog.test.ts +109 -0
- package/Tests/Types/Monitor/DockerSwarmMetricCatalog.test.ts +118 -0
- package/Tests/Types/Monitor/HostAlertTemplates.test.ts +249 -0
- package/Tests/Types/Monitor/HostMetricCatalog.test.ts +104 -0
- package/Tests/Types/Monitor/IotAlertTemplates.test.ts +320 -0
- package/Tests/Types/Monitor/IotMetricCatalog.test.ts +104 -0
- package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +118 -0
- package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +42 -0
- package/Tests/Types/Monitor/MonitorStep.test.ts +38 -0
- package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +75 -0
- package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +271 -0
- package/Tests/Types/Monitor/PodmanMetricCatalog.test.ts +109 -0
- package/Tests/Types/Monitor/ProxmoxMetricCatalog.test.ts +107 -0
- package/Tests/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.test.ts +151 -0
- package/Tests/Types/Permission.test.ts +137 -0
- package/Tests/Types/Rum/SessionReplayMaskingMode.test.ts +101 -0
- package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +5 -5
- package/Tests/UI/Components/CardModelDetailEdit.test.tsx +3 -5
- package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +696 -0
- package/Tests/UI/Components/ErrorBoundary.test.tsx +158 -0
- package/Tests/UI/Components/FeedItemSafeMode.test.tsx +74 -0
- package/Tests/UI/Components/MoreMenu.test.tsx +756 -0
- package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +62 -0
- package/Tests/UI/Monitor/PortMonitorView.test.tsx +237 -0
- package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +91 -0
- package/Tests/UI/Utils/DownloadFile.test.ts +103 -0
- package/Tests/UI/Utils/ErrorSupportBundle.test.ts +582 -0
- package/Tests/UI/Utils/Project.test.ts +31 -0
- package/Tests/UI/Utils/StatusPageModelAPIInjection.test.ts +245 -0
- package/Tests/UI/Utils/UseDashboardGridDnd.test.tsx +820 -0
- package/Tests/UI/Utils/UserProjectsModelAPI.test.ts +714 -0
- package/Tests/Utils/Dashboard/DashboardViewConfig.test.ts +329 -0
- package/Tests/Utils/Dashboard/GridLayout.test.ts +951 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +117 -0
- package/Tests/Utils/RecordingRuleExpression.test.ts +327 -0
- package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +186 -0
- package/Tests/Utils/StatusPage/GroupTree.test.ts +456 -0
- package/Tests/Utils/StatusPage/OverviewGroupHierarchyVisibility.test.ts +588 -0
- package/Tests/Utils/TeamMembersByProject.test.ts +655 -0
- package/Tests/Utils/Telemetry/SavedViewTimeRange.test.ts +244 -0
- package/Tests/Utils/Telemetry/TelemetryQueryTimeRange.test.ts +825 -0
- package/Types/AI/AIRunCodeFixRecommendation.ts +17 -0
- package/Types/AI/CodeFixTaskContext.ts +63 -3
- package/Types/AI/CodeFixTaskType.ts +3 -3
- package/Types/Database/ColumnLength.ts +9 -1
- package/Types/Database/TableColumn.ts +11 -0
- package/Types/Database/UnsynchronizedIndex.ts +48 -0
- package/Types/HashedString.ts +140 -4
- package/Types/Monitor/CriteriaFilter.ts +4 -0
- package/Types/Monitor/DomainMonitor/DomainLookupMethod.ts +23 -0
- package/Types/Monitor/DomainMonitor/DomainMonitorResponse.ts +7 -0
- package/Types/Monitor/MonitorCriteriaInstance.ts +24 -7
- package/Types/Monitor/MonitorMetricType.ts +8 -0
- package/Types/Monitor/MonitorStep.ts +10 -1
- package/Types/Monitor/MonitorStepDomainMonitor.ts +21 -0
- package/Types/Monitor/PortMonitor/PortMonitorTimings.ts +10 -0
- package/Types/Permission.ts +23 -175
- package/Types/Probe/ProbeMonitorResponse.ts +6 -0
- package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +2 -3
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +85 -11
- package/UI/Components/ErrorBoundary.tsx +138 -11
- package/UI/Components/Feed/FeedItem.tsx +9 -2
- package/UI/Components/ModelDetail/CardModelDetail.tsx +0 -12
- package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
- package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +12 -2
- package/UI/Components/MoreMenu/MoreMenu.tsx +285 -97
- package/UI/Components/MoreMenu/MoreMenuItem.tsx +8 -5
- package/UI/Components/Navbar/NavBar.tsx +12 -2
- package/UI/Components/Navbar/NavBarMenuModal.tsx +19 -7
- package/UI/Utils/DownloadFile.ts +16 -8
- package/UI/Utils/ErrorSupportBundle.ts +805 -0
- package/UI/Utils/ModelAPI/ModelAPI.ts +19 -8
- package/UI/Utils/ModelAPI/UserProjectsModelAPI.ts +257 -0
- package/UI/Utils/Project.ts +4 -0
- package/UI/Utils/StatusPage.ts +8 -2
- package/UI/Utils/UseDashboardGridDnd.ts +917 -0
- package/Utils/Dashboard/DashboardViewConfig.ts +80 -36
- package/Utils/Dashboard/GridLayout.ts +523 -0
- package/Utils/Metrics/RecordingRuleExpression.ts +19 -17
- package/Utils/Monitor/MonitorMetricType.ts +44 -2
- package/Utils/StatusPage/GroupNestingLayout.ts +69 -0
- package/Utils/StatusPage/GroupTree.ts +157 -66
- package/Utils/StatusPage/ResourceUptime.ts +37 -2
- package/Utils/TeamMembersByProject.ts +237 -0
- package/Utils/Telemetry/SavedViewTimeRange.ts +114 -0
- package/Utils/Telemetry/TelemetryQueryTimeRange.ts +334 -0
- package/build/dist/Models/DatabaseModels/AIRun.js +39 -1
- package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertFeed.js +32 -0
- package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CephCluster.js +16 -1
- package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/CodeRepository.js +14 -6
- package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Dashboard.js +29 -0
- package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js +16 -1
- package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +16 -1
- package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +16 -1
- package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Incident.js +2 -0
- package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentFeed.js +32 -0
- package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IoTFleet.js +16 -1
- package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +16 -1
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/LogSavedView.js +33 -0
- package/build/dist/Models/DatabaseModels/LogSavedView.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +16 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkInterface.js +16 -1
- package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +257 -13
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +16 -1
- package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.js +4 -4
- package/build/dist/Models/DatabaseModels/Service.js +28 -1
- package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPage.js +29 -0
- package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +1 -0
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js +32 -0
- package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js.map +1 -1
- package/build/dist/Models/DatabaseModels/User.js +32 -0
- package/build/dist/Models/DatabaseModels/User.js.map +1 -1
- package/build/dist/Server/API/AIAgentDataAPI.js +49 -48
- package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +111 -11
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/DashboardAPI.js +312 -15
- package/build/dist/Server/API/DashboardAPI.js.map +1 -1
- package/build/dist/Server/API/GitHubAPI.js +94 -167
- package/build/dist/Server/API/GitHubAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +29 -11
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/API/UserAPI.js +187 -2
- package/build/dist/Server/API/UserAPI.js.map +1 -1
- package/build/dist/Server/EnvironmentConfig.js +21 -3
- package/build/dist/Server/EnvironmentConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js +12 -1
- package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
- package/build/dist/Server/Infrastructure/ClickhouseDatabase.js +1 -1
- package/build/dist/Server/Infrastructure/ClickhouseDatabase.js.map +1 -1
- package/build/dist/Server/Infrastructure/GlobalCache.js +29 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js +14 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js +59 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js +22 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +93 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js +36 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js +18 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js +101 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js +66 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js +19 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js +19 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AIRunService.js +58 -12
- package/build/dist/Server/Services/AIRunService.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +74 -21
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertFeedService.js +3 -0
- package/build/dist/Server/Services/AlertFeedService.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +86 -2
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/CodeRepositoryService.js +90 -2
- package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
- package/build/dist/Server/Services/DatabaseService.js +180 -3
- package/build/dist/Server/Services/DatabaseService.js.map +1 -1
- package/build/dist/Server/Services/IncidentFeedService.js +3 -0
- package/build/dist/Server/Services/IncidentFeedService.js.map +1 -1
- package/build/dist/Server/Services/LlmLogService.js +22 -1
- package/build/dist/Server/Services/LlmLogService.js.map +1 -1
- package/build/dist/Server/Services/OpenTelemetryIngestService.js +155 -25
- package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
- package/build/dist/Server/Services/UserService.js +165 -0
- package/build/dist/Server/Services/UserService.js.map +1 -1
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
- package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +4 -0
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +8 -5
- package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +63 -24
- package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +2 -0
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +2 -0
- package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +156 -28
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +21 -19
- package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js +128 -49
- package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +170 -31
- package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +21 -19
- package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +33 -9
- package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +9 -5
- package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +121 -41
- package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js +46 -0
- package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js.map +1 -0
- package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js +61 -14
- package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js +79 -1
- package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js.map +1 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js +31 -1
- package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js +21 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +13 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +126 -4
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js +136 -0
- package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +20 -3
- package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +43 -0
- package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
- package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
- package/build/dist/Server/Utils/PasswordHash.js +258 -0
- package/build/dist/Server/Utils/PasswordHash.js.map +1 -0
- package/build/dist/Types/AI/AIRunCodeFixRecommendation.js +18 -0
- package/build/dist/Types/AI/AIRunCodeFixRecommendation.js.map +1 -0
- package/build/dist/Types/AI/CodeFixTaskContext.js +23 -3
- package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -1
- package/build/dist/Types/AI/CodeFixTaskType.js +3 -3
- package/build/dist/Types/Database/ColumnLength.js +9 -1
- package/build/dist/Types/Database/ColumnLength.js.map +1 -1
- package/build/dist/Types/Database/TableColumn.js.map +1 -1
- package/build/dist/Types/Database/UnsynchronizedIndex.js +46 -0
- package/build/dist/Types/Database/UnsynchronizedIndex.js.map +1 -0
- package/build/dist/Types/HashedString.js +96 -5
- package/build/dist/Types/HashedString.js.map +1 -1
- package/build/dist/Types/Monitor/CriteriaFilter.js +4 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js +24 -0
- package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js.map +1 -0
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +24 -7
- package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorMetricType.js +7 -0
- package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +6 -1
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +15 -0
- package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js +2 -0
- package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js.map +1 -0
- package/build/dist/Types/Permission.js +23 -155
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +2 -5
- package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +51 -10
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/ErrorBoundary.js +67 -8
- package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
- package/build/dist/UI/Components/Feed/FeedItem.js +2 -2
- package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +0 -12
- package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +12 -2
- package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +193 -65
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBar.js +3 -1
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +19 -7
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
- package/build/dist/UI/Utils/DownloadFile.js +15 -8
- package/build/dist/UI/Utils/DownloadFile.js.map +1 -1
- package/build/dist/UI/Utils/ErrorSupportBundle.js +476 -0
- package/build/dist/UI/Utils/ErrorSupportBundle.js.map +1 -0
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -8
- package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
- package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js +156 -0
- package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js.map +1 -0
- package/build/dist/UI/Utils/Project.js +3 -0
- package/build/dist/UI/Utils/Project.js.map +1 -1
- package/build/dist/UI/Utils/StatusPage.js +4 -4
- package/build/dist/UI/Utils/StatusPage.js.map +1 -1
- package/build/dist/UI/Utils/UseDashboardGridDnd.js +551 -0
- package/build/dist/UI/Utils/UseDashboardGridDnd.js.map +1 -0
- package/build/dist/Utils/Dashboard/DashboardViewConfig.js +42 -26
- package/build/dist/Utils/Dashboard/DashboardViewConfig.js.map +1 -1
- package/build/dist/Utils/Dashboard/GridLayout.js +338 -0
- package/build/dist/Utils/Dashboard/GridLayout.js.map +1 -0
- package/build/dist/Utils/Metrics/RecordingRuleExpression.js +19 -17
- package/build/dist/Utils/Metrics/RecordingRuleExpression.js.map +1 -1
- package/build/dist/Utils/Monitor/MonitorMetricType.js +38 -6
- package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js +46 -0
- package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -1
- package/build/dist/Utils/StatusPage/GroupTree.js +79 -34
- package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -1
- package/build/dist/Utils/StatusPage/ResourceUptime.js +22 -1
- package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
- package/build/dist/Utils/TeamMembersByProject.js +145 -0
- package/build/dist/Utils/TeamMembersByProject.js.map +1 -0
- package/build/dist/Utils/Telemetry/SavedViewTimeRange.js +79 -0
- package/build/dist/Utils/Telemetry/SavedViewTimeRange.js.map +1 -0
- package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js +236 -0
- package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js.map +1 -0
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ import DashboardViewConfig from "../../Types/Dashboard/DashboardViewConfig";
|
|
|
2
2
|
import { ObjectType } from "../../Types/JSON";
|
|
3
3
|
import DashboardSize from "../../Types/Dashboard/DashboardSize";
|
|
4
4
|
import DashboardBaseComponent from "../../Types/Dashboard/DashboardComponents/DashboardBaseComponent";
|
|
5
|
+
import GridLayoutUtil, { GridPosition, GridRect } from "./GridLayout";
|
|
5
6
|
|
|
6
7
|
export default class DashboardViewConfigUtil {
|
|
7
8
|
public static createDefaultDashboardViewConfig(): DashboardViewConfig {
|
|
@@ -12,57 +13,100 @@ export default class DashboardViewConfigUtil {
|
|
|
12
13
|
};
|
|
13
14
|
}
|
|
14
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Place a new component at the first free spot (scanning top-to-bottom,
|
|
18
|
+
* left-to-right) that fits it, falling back to a fresh row at the bottom.
|
|
19
|
+
* Does not mutate the passed-in config.
|
|
20
|
+
*/
|
|
15
21
|
public static addComponentToDashboard(data: {
|
|
16
22
|
component: DashboardBaseComponent;
|
|
17
23
|
dashboardViewConfig: DashboardViewConfig;
|
|
18
24
|
}): DashboardViewConfig {
|
|
19
|
-
const
|
|
25
|
+
const existingRects: Array<GridRect> =
|
|
26
|
+
GridLayoutUtil.fromDashboardComponents(
|
|
27
|
+
data.dashboardViewConfig.components,
|
|
28
|
+
);
|
|
20
29
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
30
|
+
const width: number = Math.min(
|
|
31
|
+
Math.max(1, data.component.widthInDashboardUnits),
|
|
32
|
+
GridLayoutUtil.DefaultColumns,
|
|
33
|
+
);
|
|
34
|
+
const height: number = Math.max(1, data.component.heightInDashboardUnits);
|
|
24
35
|
|
|
25
|
-
|
|
36
|
+
const position: GridPosition = GridLayoutUtil.findFirstFit({
|
|
37
|
+
rects: existingRects,
|
|
38
|
+
width,
|
|
39
|
+
height,
|
|
40
|
+
});
|
|
26
41
|
|
|
27
|
-
|
|
42
|
+
const newComponent: DashboardBaseComponent = {
|
|
43
|
+
...data.component,
|
|
44
|
+
topInDashboardUnits: position.top,
|
|
45
|
+
leftInDashboardUnits: position.left,
|
|
46
|
+
widthInDashboardUnits: width,
|
|
47
|
+
heightInDashboardUnits: height,
|
|
48
|
+
};
|
|
28
49
|
|
|
29
|
-
|
|
50
|
+
const components: Array<DashboardBaseComponent> = [
|
|
51
|
+
...data.dashboardViewConfig.components,
|
|
52
|
+
newComponent,
|
|
53
|
+
];
|
|
30
54
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
55
|
+
const requiredRows: number = GridLayoutUtil.requiredRows(
|
|
56
|
+
GridLayoutUtil.fromDashboardComponents(components),
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
return {
|
|
60
|
+
...data.dashboardViewConfig,
|
|
61
|
+
components,
|
|
62
|
+
heightInDashboardUnits: Math.max(
|
|
63
|
+
DashboardViewConfigUtil.getFiniteHeight(data.dashboardViewConfig),
|
|
64
|
+
requiredRows,
|
|
65
|
+
),
|
|
66
|
+
};
|
|
67
|
+
}
|
|
44
68
|
|
|
45
|
-
|
|
69
|
+
/**
|
|
70
|
+
* Heal a config that older builds could corrupt: clamp every component
|
|
71
|
+
* into the board and push overlapping components down so nothing
|
|
72
|
+
* occupies the same cells. Returns the same config object when the
|
|
73
|
+
* layout is already valid.
|
|
74
|
+
*/
|
|
75
|
+
public static normalizeLayout(
|
|
76
|
+
dashboardViewConfig: DashboardViewConfig,
|
|
77
|
+
): DashboardViewConfig {
|
|
78
|
+
const rects: Array<GridRect> = GridLayoutUtil.fromDashboardComponents(
|
|
79
|
+
dashboardViewConfig.components,
|
|
80
|
+
);
|
|
46
81
|
|
|
47
|
-
|
|
82
|
+
const normalized: Array<GridRect> = GridLayoutUtil.normalize(rects);
|
|
48
83
|
|
|
49
|
-
if (
|
|
50
|
-
|
|
51
|
-
data.dashboardViewConfig.heightInDashboardUnits
|
|
52
|
-
) {
|
|
53
|
-
data.dashboardViewConfig.heightInDashboardUnits =
|
|
54
|
-
componentTopPosition + heightOfComponent;
|
|
84
|
+
if (GridLayoutUtil.areLayoutsEqual(rects, normalized)) {
|
|
85
|
+
return dashboardViewConfig;
|
|
55
86
|
}
|
|
56
87
|
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
88
|
+
const components: Array<DashboardBaseComponent> =
|
|
89
|
+
GridLayoutUtil.applyRectsToComponents(
|
|
90
|
+
dashboardViewConfig.components,
|
|
91
|
+
normalized,
|
|
92
|
+
);
|
|
62
93
|
|
|
63
|
-
|
|
64
|
-
|
|
94
|
+
return {
|
|
95
|
+
...dashboardViewConfig,
|
|
96
|
+
components,
|
|
97
|
+
heightInDashboardUnits: Math.max(
|
|
98
|
+
DashboardViewConfigUtil.getFiniteHeight(dashboardViewConfig),
|
|
99
|
+
GridLayoutUtil.requiredRows(normalized),
|
|
100
|
+
),
|
|
101
|
+
};
|
|
102
|
+
}
|
|
65
103
|
|
|
66
|
-
|
|
104
|
+
/** A saved config can hold a missing/NaN height — never let it spread. */
|
|
105
|
+
private static getFiniteHeight(config: DashboardViewConfig): number {
|
|
106
|
+
const height: number = config.heightInDashboardUnits;
|
|
107
|
+
if (typeof height !== "number" || !Number.isFinite(height)) {
|
|
108
|
+
return 0;
|
|
109
|
+
}
|
|
110
|
+
return height;
|
|
67
111
|
}
|
|
68
112
|
}
|
|
@@ -0,0 +1,523 @@
|
|
|
1
|
+
import DefaultDashboardSize from "../../Types/Dashboard/DashboardSize";
|
|
2
|
+
import DashboardBaseComponent from "../../Types/Dashboard/DashboardComponents/DashboardBaseComponent";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A widget's footprint on the dashboard grid, in dashboard units.
|
|
6
|
+
*
|
|
7
|
+
* This is the currency of the layout engine: every operation takes an array
|
|
8
|
+
* of GridRects and returns a NEW array (inputs are never mutated), so callers
|
|
9
|
+
* can freely diff previous/next layouts and React can rely on reference
|
|
10
|
+
* equality for unchanged items.
|
|
11
|
+
*/
|
|
12
|
+
export interface GridRect {
|
|
13
|
+
id: string;
|
|
14
|
+
left: number;
|
|
15
|
+
top: number;
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
minWidth: number;
|
|
19
|
+
minHeight: number;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface GridPosition {
|
|
23
|
+
left: number;
|
|
24
|
+
top: number;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Pure grid-layout engine for dashboard widgets.
|
|
29
|
+
*
|
|
30
|
+
* Model: an infinite-height board that is `columns` units wide. Widgets are
|
|
31
|
+
* free-floating (no gravity — deliberate gaps are preserved), but they may
|
|
32
|
+
* never overlap. When an operation makes two widgets overlap, the lower-
|
|
33
|
+
* priority widget is pushed straight down, cascading as needed.
|
|
34
|
+
*
|
|
35
|
+
* Every function is deterministic and side-effect free, which is what makes
|
|
36
|
+
* live drag previews cheap: the preview is always recomputed from the
|
|
37
|
+
* committed layout plus the candidate position, so transient pushes never
|
|
38
|
+
* accumulate.
|
|
39
|
+
*/
|
|
40
|
+
export default class GridLayoutUtil {
|
|
41
|
+
public static readonly DefaultColumns: number =
|
|
42
|
+
DefaultDashboardSize.widthInDashboardUnits;
|
|
43
|
+
|
|
44
|
+
/** Do two rects occupy at least one common cell? */
|
|
45
|
+
public static rectsOverlap(a: GridRect, b: GridRect): boolean {
|
|
46
|
+
return (
|
|
47
|
+
a.left < b.left + b.width &&
|
|
48
|
+
b.left < a.left + a.width &&
|
|
49
|
+
a.top < b.top + b.height &&
|
|
50
|
+
b.top < a.top + a.height
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Round to an integer, falling back when the input is missing, NaN or
|
|
56
|
+
* infinite — saved configs from older builds can hold anything.
|
|
57
|
+
*/
|
|
58
|
+
private static toFiniteInt(value: number, fallback: number): number {
|
|
59
|
+
if (typeof value !== "number" || !Number.isFinite(value)) {
|
|
60
|
+
return fallback;
|
|
61
|
+
}
|
|
62
|
+
return Math.round(value);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Force a rect into a valid state: finite integer coordinates, at least
|
|
67
|
+
* its minimum size, no wider than the board, fully inside the columns
|
|
68
|
+
* and below the top edge.
|
|
69
|
+
*/
|
|
70
|
+
public static clampRect(rect: GridRect, columns?: number): GridRect {
|
|
71
|
+
const cols: number = GridLayoutUtil.getColumns(columns);
|
|
72
|
+
|
|
73
|
+
const minWidth: number = Math.min(
|
|
74
|
+
Math.max(1, GridLayoutUtil.toFiniteInt(rect.minWidth, 1)),
|
|
75
|
+
cols,
|
|
76
|
+
);
|
|
77
|
+
const minHeight: number = Math.max(
|
|
78
|
+
1,
|
|
79
|
+
GridLayoutUtil.toFiniteInt(rect.minHeight, 1),
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const width: number = Math.min(
|
|
83
|
+
Math.max(GridLayoutUtil.toFiniteInt(rect.width, minWidth), minWidth),
|
|
84
|
+
cols,
|
|
85
|
+
);
|
|
86
|
+
const height: number = Math.max(
|
|
87
|
+
GridLayoutUtil.toFiniteInt(rect.height, minHeight),
|
|
88
|
+
minHeight,
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
const left: number = Math.min(
|
|
92
|
+
Math.max(GridLayoutUtil.toFiniteInt(rect.left, 0), 0),
|
|
93
|
+
cols - width,
|
|
94
|
+
);
|
|
95
|
+
const top: number = Math.max(GridLayoutUtil.toFiniteInt(rect.top, 0), 0);
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
...rect,
|
|
99
|
+
left,
|
|
100
|
+
top,
|
|
101
|
+
width,
|
|
102
|
+
height,
|
|
103
|
+
minWidth,
|
|
104
|
+
minHeight,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Resolve every overlap by pushing lower-priority rects straight down.
|
|
110
|
+
*
|
|
111
|
+
* Priority: ids listed in `priorityIds` (in order) are immovable anchors —
|
|
112
|
+
* they keep exactly the position they were given. Everything else is
|
|
113
|
+
* processed top-to-bottom, left-to-right, and pushed below whatever it
|
|
114
|
+
* overlaps. The returned array preserves the input order.
|
|
115
|
+
*/
|
|
116
|
+
public static resolveCollisions(
|
|
117
|
+
rects: Array<GridRect>,
|
|
118
|
+
priorityIds: Array<string>,
|
|
119
|
+
): Array<GridRect> {
|
|
120
|
+
interface IndexedRect {
|
|
121
|
+
rect: GridRect;
|
|
122
|
+
index: number;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/*
|
|
126
|
+
* Everything below is keyed by ARRAY INDEX, not id — corrupt configs
|
|
127
|
+
* can contain duplicate ids, and keying by id would collapse the
|
|
128
|
+
* duplicates onto one resolved position (leaving overlaps behind).
|
|
129
|
+
*/
|
|
130
|
+
const entries: Array<IndexedRect> = rects.map(
|
|
131
|
+
(rect: GridRect, index: number) => {
|
|
132
|
+
return { rect, index };
|
|
133
|
+
},
|
|
134
|
+
);
|
|
135
|
+
|
|
136
|
+
const priorityIndexes: Set<number> = new Set<number>();
|
|
137
|
+
const priorityEntries: Array<IndexedRect> = [];
|
|
138
|
+
|
|
139
|
+
for (const id of priorityIds) {
|
|
140
|
+
const entry: IndexedRect | undefined = entries.find(
|
|
141
|
+
(candidate: IndexedRect) => {
|
|
142
|
+
return (
|
|
143
|
+
candidate.rect.id === id && !priorityIndexes.has(candidate.index)
|
|
144
|
+
);
|
|
145
|
+
},
|
|
146
|
+
);
|
|
147
|
+
if (entry) {
|
|
148
|
+
priorityIndexes.add(entry.index);
|
|
149
|
+
priorityEntries.push(entry);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
const otherEntries: Array<IndexedRect> = entries
|
|
154
|
+
.filter((entry: IndexedRect) => {
|
|
155
|
+
return !priorityIndexes.has(entry.index);
|
|
156
|
+
})
|
|
157
|
+
.sort((a: IndexedRect, b: IndexedRect) => {
|
|
158
|
+
if (a.rect.top !== b.rect.top) {
|
|
159
|
+
return a.rect.top - b.rect.top;
|
|
160
|
+
}
|
|
161
|
+
if (a.rect.left !== b.rect.left) {
|
|
162
|
+
return a.rect.left - b.rect.left;
|
|
163
|
+
}
|
|
164
|
+
return a.index - b.index;
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const placed: Array<GridRect> = [];
|
|
168
|
+
const resultByIndex: Map<number, GridRect> = new Map<number, GridRect>();
|
|
169
|
+
|
|
170
|
+
for (const entry of [...priorityEntries, ...otherEntries]) {
|
|
171
|
+
let rect: GridRect = entry.rect;
|
|
172
|
+
const isPriority: boolean = priorityIndexes.has(entry.index);
|
|
173
|
+
|
|
174
|
+
if (!isPriority) {
|
|
175
|
+
/*
|
|
176
|
+
* Push down until this rect overlaps nothing that is already
|
|
177
|
+
* placed. Each iteration strictly increases `top`, so this
|
|
178
|
+
* terminates; the guard is belt-and-braces.
|
|
179
|
+
*/
|
|
180
|
+
let guard: number = 0;
|
|
181
|
+
const maxIterations: number = rects.length * rects.length + 100;
|
|
182
|
+
|
|
183
|
+
while (guard < maxIterations) {
|
|
184
|
+
guard++;
|
|
185
|
+
|
|
186
|
+
let pushedTop: number | null = null;
|
|
187
|
+
|
|
188
|
+
for (const p of placed) {
|
|
189
|
+
if (GridLayoutUtil.rectsOverlap(p, rect)) {
|
|
190
|
+
const bottom: number = p.top + p.height;
|
|
191
|
+
pushedTop =
|
|
192
|
+
pushedTop === null ? bottom : Math.max(pushedTop, bottom);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (pushedTop === null) {
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
rect = { ...rect, top: pushedTop };
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
placed.push(rect);
|
|
205
|
+
resultByIndex.set(entry.index, rect);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
return rects.map((rect: GridRect, index: number) => {
|
|
209
|
+
const resolved: GridRect | undefined = resultByIndex.get(index);
|
|
210
|
+
if (!resolved) {
|
|
211
|
+
return rect;
|
|
212
|
+
}
|
|
213
|
+
// Preserve the caller's object when nothing about it changed.
|
|
214
|
+
return GridLayoutUtil.areRectsAtSamePlace(resolved, rect)
|
|
215
|
+
? rect
|
|
216
|
+
: resolved;
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Move one widget to a new position. The moved widget wins its spot;
|
|
222
|
+
* anything it lands on is pushed down (cascading). Returns the input
|
|
223
|
+
* array unchanged (same reference) when the move is a no-op.
|
|
224
|
+
*/
|
|
225
|
+
public static moveRect(data: {
|
|
226
|
+
rects: Array<GridRect>;
|
|
227
|
+
id: string;
|
|
228
|
+
left: number;
|
|
229
|
+
top: number;
|
|
230
|
+
columns?: number | undefined;
|
|
231
|
+
}): Array<GridRect> {
|
|
232
|
+
const current: GridRect | undefined = data.rects.find((r: GridRect) => {
|
|
233
|
+
return r.id === data.id;
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
if (!current) {
|
|
237
|
+
return data.rects;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
const candidate: GridRect = GridLayoutUtil.clampRect(
|
|
241
|
+
{ ...current, left: data.left, top: data.top },
|
|
242
|
+
data.columns,
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
if (candidate.left === current.left && candidate.top === current.top) {
|
|
246
|
+
return data.rects;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
const moved: Array<GridRect> = data.rects.map((r: GridRect) => {
|
|
250
|
+
return r.id === data.id ? candidate : r;
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
return GridLayoutUtil.resolveCollisions(moved, [data.id]);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Resize (and possibly reposition, for north/west resizes) one widget.
|
|
258
|
+
* The resized widget keeps the requested rect; overlapped widgets are
|
|
259
|
+
* pushed down. Returns the input array unchanged when nothing changes.
|
|
260
|
+
*/
|
|
261
|
+
public static resizeRect(data: {
|
|
262
|
+
rects: Array<GridRect>;
|
|
263
|
+
id: string;
|
|
264
|
+
left: number;
|
|
265
|
+
top: number;
|
|
266
|
+
width: number;
|
|
267
|
+
height: number;
|
|
268
|
+
columns?: number | undefined;
|
|
269
|
+
}): Array<GridRect> {
|
|
270
|
+
const current: GridRect | undefined = data.rects.find((r: GridRect) => {
|
|
271
|
+
return r.id === data.id;
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
if (!current) {
|
|
275
|
+
return data.rects;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const candidate: GridRect = GridLayoutUtil.clampRect(
|
|
279
|
+
{
|
|
280
|
+
...current,
|
|
281
|
+
left: data.left,
|
|
282
|
+
top: data.top,
|
|
283
|
+
width: data.width,
|
|
284
|
+
height: data.height,
|
|
285
|
+
},
|
|
286
|
+
data.columns,
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
if (GridLayoutUtil.areRectsAtSamePlace(candidate, current)) {
|
|
290
|
+
return data.rects;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const resized: Array<GridRect> = data.rects.map((r: GridRect) => {
|
|
294
|
+
return r.id === data.id ? candidate : r;
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
return GridLayoutUtil.resolveCollisions(resized, [data.id]);
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Heal a layout: clamp every rect into bounds and resolve any overlaps
|
|
302
|
+
* deterministically (top-left rects win, later/lower ones get pushed
|
|
303
|
+
* down). Safe to run on every load — a valid layout passes through
|
|
304
|
+
* untouched, with every object reference preserved.
|
|
305
|
+
*/
|
|
306
|
+
public static normalize(
|
|
307
|
+
rects: Array<GridRect>,
|
|
308
|
+
columns?: number,
|
|
309
|
+
): Array<GridRect> {
|
|
310
|
+
const clamped: Array<GridRect> = rects.map((rect: GridRect) => {
|
|
311
|
+
const c: GridRect = GridLayoutUtil.clampRect(rect, columns);
|
|
312
|
+
return GridLayoutUtil.areRectsAtSamePlace(c, rect) &&
|
|
313
|
+
c.minWidth === rect.minWidth &&
|
|
314
|
+
c.minHeight === rect.minHeight
|
|
315
|
+
? rect
|
|
316
|
+
: c;
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
return GridLayoutUtil.resolveCollisions(clamped, []);
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/** Number of rows needed to contain every rect. */
|
|
323
|
+
public static requiredRows(rects: Array<GridRect>): number {
|
|
324
|
+
let rows: number = 0;
|
|
325
|
+
for (const rect of rects) {
|
|
326
|
+
const bottom: number = rect.top + rect.height;
|
|
327
|
+
// Non-finite geometry (corrupt configs) must not poison the total.
|
|
328
|
+
if (Number.isFinite(bottom)) {
|
|
329
|
+
rows = Math.max(rows, bottom);
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
return rows;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/**
|
|
336
|
+
* First free position (scanning top-to-bottom, left-to-right) where a
|
|
337
|
+
* widget of the given size fits without touching anything. Falls back to
|
|
338
|
+
* a fresh row at the bottom.
|
|
339
|
+
*/
|
|
340
|
+
public static findFirstFit(data: {
|
|
341
|
+
rects: Array<GridRect>;
|
|
342
|
+
width: number;
|
|
343
|
+
height: number;
|
|
344
|
+
columns?: number | undefined;
|
|
345
|
+
}): GridPosition {
|
|
346
|
+
const cols: number = GridLayoutUtil.getColumns(data.columns);
|
|
347
|
+
const width: number = Math.min(Math.max(1, Math.round(data.width)), cols);
|
|
348
|
+
const height: number = Math.max(1, Math.round(data.height));
|
|
349
|
+
|
|
350
|
+
const bottom: number = GridLayoutUtil.requiredRows(data.rects);
|
|
351
|
+
|
|
352
|
+
for (let top: number = 0; top <= bottom; top++) {
|
|
353
|
+
for (let left: number = 0; left <= cols - width; left++) {
|
|
354
|
+
const candidate: GridRect = {
|
|
355
|
+
id: "__candidate__",
|
|
356
|
+
left,
|
|
357
|
+
top,
|
|
358
|
+
width,
|
|
359
|
+
height,
|
|
360
|
+
minWidth: 1,
|
|
361
|
+
minHeight: 1,
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
const collides: boolean = data.rects.some((rect: GridRect) => {
|
|
365
|
+
return GridLayoutUtil.rectsOverlap(rect, candidate);
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
if (!collides) {
|
|
369
|
+
return { left, top };
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
return { left: 0, top: bottom };
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/** True when both layouts place every widget at the same rect. */
|
|
378
|
+
public static areLayoutsEqual(
|
|
379
|
+
a: Array<GridRect>,
|
|
380
|
+
b: Array<GridRect>,
|
|
381
|
+
): boolean {
|
|
382
|
+
if (a.length !== b.length) {
|
|
383
|
+
return false;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
const byId: Map<string, GridRect> = new Map<string, GridRect>(
|
|
387
|
+
b.map((rect: GridRect) => {
|
|
388
|
+
return [rect.id, rect];
|
|
389
|
+
}),
|
|
390
|
+
);
|
|
391
|
+
|
|
392
|
+
return a.every((rect: GridRect, index: number) => {
|
|
393
|
+
/*
|
|
394
|
+
* Positional match first — engine operations preserve array order,
|
|
395
|
+
* and position keeps duplicate-id rects (corrupt configs) distinct
|
|
396
|
+
* where an id map would collapse them.
|
|
397
|
+
*/
|
|
398
|
+
const positional: GridRect | undefined = b[index];
|
|
399
|
+
const other: GridRect | undefined =
|
|
400
|
+
positional && positional.id === rect.id
|
|
401
|
+
? positional
|
|
402
|
+
: byId.get(rect.id);
|
|
403
|
+
return Boolean(other) && GridLayoutUtil.areRectsAtSamePlace(rect, other!);
|
|
404
|
+
});
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/** True when the layout contains no overlapping pair. */
|
|
408
|
+
public static hasNoOverlaps(rects: Array<GridRect>): boolean {
|
|
409
|
+
for (let i: number = 0; i < rects.length; i++) {
|
|
410
|
+
for (let j: number = i + 1; j < rects.length; j++) {
|
|
411
|
+
if (GridLayoutUtil.rectsOverlap(rects[i]!, rects[j]!)) {
|
|
412
|
+
return false;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return true;
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/** Same position and size (ignores min sizes). */
|
|
420
|
+
public static areRectsAtSamePlace(a: GridRect, b: GridRect): boolean {
|
|
421
|
+
return (
|
|
422
|
+
a.left === b.left &&
|
|
423
|
+
a.top === b.top &&
|
|
424
|
+
a.width === b.width &&
|
|
425
|
+
a.height === b.height
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// ── DashboardBaseComponent bridge ─────────────────────────────────────
|
|
430
|
+
|
|
431
|
+
public static fromDashboardComponents(
|
|
432
|
+
components: Array<DashboardBaseComponent>,
|
|
433
|
+
): Array<GridRect> {
|
|
434
|
+
return components.map((component: DashboardBaseComponent) => {
|
|
435
|
+
/*
|
|
436
|
+
* Sanitize on the way in: a single missing/NaN field in a saved
|
|
437
|
+
* config must not poison every downstream computation (requiredRows,
|
|
438
|
+
* findFirstFit, canvas px maths) with NaN.
|
|
439
|
+
*/
|
|
440
|
+
return {
|
|
441
|
+
id: component.componentId.toString(),
|
|
442
|
+
left: GridLayoutUtil.toFiniteInt(component.leftInDashboardUnits, 0),
|
|
443
|
+
top: GridLayoutUtil.toFiniteInt(component.topInDashboardUnits, 0),
|
|
444
|
+
width: Math.max(
|
|
445
|
+
GridLayoutUtil.toFiniteInt(component.widthInDashboardUnits, 1),
|
|
446
|
+
1,
|
|
447
|
+
),
|
|
448
|
+
height: Math.max(
|
|
449
|
+
GridLayoutUtil.toFiniteInt(component.heightInDashboardUnits, 1),
|
|
450
|
+
1,
|
|
451
|
+
),
|
|
452
|
+
minWidth: Math.max(
|
|
453
|
+
GridLayoutUtil.toFiniteInt(component.minWidthInDashboardUnits, 1),
|
|
454
|
+
1,
|
|
455
|
+
),
|
|
456
|
+
minHeight: Math.max(
|
|
457
|
+
GridLayoutUtil.toFiniteInt(component.minHeightInDashboardUnits, 1),
|
|
458
|
+
1,
|
|
459
|
+
),
|
|
460
|
+
};
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Write rect positions back onto components. Components whose rect did
|
|
466
|
+
* not change are returned by reference, so React.memo children skip
|
|
467
|
+
* re-rendering untouched widgets.
|
|
468
|
+
*/
|
|
469
|
+
public static applyRectsToComponents(
|
|
470
|
+
components: Array<DashboardBaseComponent>,
|
|
471
|
+
rects: Array<GridRect>,
|
|
472
|
+
): Array<DashboardBaseComponent> {
|
|
473
|
+
const rectById: Map<string, GridRect> = new Map<string, GridRect>(
|
|
474
|
+
rects.map((rect: GridRect) => {
|
|
475
|
+
return [rect.id, rect];
|
|
476
|
+
}),
|
|
477
|
+
);
|
|
478
|
+
|
|
479
|
+
return components.map(
|
|
480
|
+
(component: DashboardBaseComponent, index: number) => {
|
|
481
|
+
/*
|
|
482
|
+
* Prefer positional matching: rects normally come straight from
|
|
483
|
+
* fromDashboardComponents on this very array, and position keeps
|
|
484
|
+
* duplicate-id components (corrupt configs) distinct. Fall back to
|
|
485
|
+
* id lookup for callers passing reordered subsets.
|
|
486
|
+
*/
|
|
487
|
+
const positional: GridRect | undefined = rects[index];
|
|
488
|
+
const rect: GridRect | undefined =
|
|
489
|
+
positional && positional.id === component.componentId.toString()
|
|
490
|
+
? positional
|
|
491
|
+
: rectById.get(component.componentId.toString());
|
|
492
|
+
|
|
493
|
+
if (!rect) {
|
|
494
|
+
return component;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
if (
|
|
498
|
+
component.leftInDashboardUnits === rect.left &&
|
|
499
|
+
component.topInDashboardUnits === rect.top &&
|
|
500
|
+
component.widthInDashboardUnits === rect.width &&
|
|
501
|
+
component.heightInDashboardUnits === rect.height
|
|
502
|
+
) {
|
|
503
|
+
return component;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
return {
|
|
507
|
+
...component,
|
|
508
|
+
leftInDashboardUnits: rect.left,
|
|
509
|
+
topInDashboardUnits: rect.top,
|
|
510
|
+
widthInDashboardUnits: rect.width,
|
|
511
|
+
heightInDashboardUnits: rect.height,
|
|
512
|
+
};
|
|
513
|
+
},
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
private static getColumns(columns?: number): number {
|
|
518
|
+
if (!columns || columns < 1) {
|
|
519
|
+
return GridLayoutUtil.DefaultColumns;
|
|
520
|
+
}
|
|
521
|
+
return Math.round(columns);
|
|
522
|
+
}
|
|
523
|
+
}
|