@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.
Files changed (516) hide show
  1. package/Models/DatabaseModels/AIRun.ts +38 -1
  2. package/Models/DatabaseModels/AlertFeed.ts +30 -0
  3. package/Models/DatabaseModels/CephCluster.ts +14 -0
  4. package/Models/DatabaseModels/CodeRepository.ts +14 -6
  5. package/Models/DatabaseModels/Dashboard.ts +28 -0
  6. package/Models/DatabaseModels/DockerHost.ts +14 -0
  7. package/Models/DatabaseModels/GlobalOidcProject.ts +18 -0
  8. package/Models/DatabaseModels/GlobalSsoProject.ts +18 -0
  9. package/Models/DatabaseModels/Incident.ts +2 -0
  10. package/Models/DatabaseModels/IncidentEpisode.ts +1 -0
  11. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +1 -0
  12. package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
  13. package/Models/DatabaseModels/IncidentFeed.ts +30 -0
  14. package/Models/DatabaseModels/IncidentPublicNote.ts +1 -0
  15. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
  16. package/Models/DatabaseModels/IoTFleet.ts +14 -0
  17. package/Models/DatabaseModels/KubernetesCluster.ts +14 -0
  18. package/Models/DatabaseModels/LogSavedView.ts +33 -0
  19. package/Models/DatabaseModels/NetworkDevice.ts +14 -0
  20. package/Models/DatabaseModels/NetworkInterface.ts +18 -0
  21. package/Models/DatabaseModels/Project.ts +247 -11
  22. package/Models/DatabaseModels/ProxmoxCluster.ts +14 -0
  23. package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -0
  24. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +1 -0
  25. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
  26. package/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.ts +4 -4
  27. package/Models/DatabaseModels/Service.ts +30 -0
  28. package/Models/DatabaseModels/StatusPage.ts +28 -0
  29. package/Models/DatabaseModels/StatusPageAnnouncement.ts +1 -0
  30. package/Models/DatabaseModels/StatusPagePrivateUser.ts +30 -0
  31. package/Models/DatabaseModels/User.ts +30 -0
  32. package/Server/API/AIAgentDataAPI.ts +75 -55
  33. package/Server/API/AIInvestigationAPI.ts +175 -17
  34. package/Server/API/DashboardAPI.ts +429 -22
  35. package/Server/API/GitHubAPI.ts +119 -283
  36. package/Server/API/StatusPageAPI.ts +38 -19
  37. package/Server/API/UserAPI.ts +263 -1
  38. package/Server/EnvironmentConfig.ts +23 -3
  39. package/Server/Infrastructure/ClickhouseConfig.ts +15 -1
  40. package/Server/Infrastructure/ClickhouseDatabase.ts +1 -1
  41. package/Server/Infrastructure/GlobalCache.ts +37 -0
  42. package/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.ts +21 -0
  43. package/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.ts +68 -0
  44. package/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.ts +27 -0
  45. package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +100 -0
  46. package/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.ts +89 -0
  47. package/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.ts +27 -0
  48. package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +214 -0
  49. package/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.ts +69 -0
  50. package/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.ts +40 -0
  51. package/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.ts +26 -0
  52. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
  53. package/Server/Services/AIRunService.ts +78 -10
  54. package/Server/Services/AIService.ts +94 -22
  55. package/Server/Services/AlertFeedService.ts +5 -0
  56. package/Server/Services/AnalyticsDatabaseService.ts +101 -1
  57. package/Server/Services/CodeRepositoryService.ts +105 -2
  58. package/Server/Services/DatabaseService.ts +227 -3
  59. package/Server/Services/IncidentFeedService.ts +5 -0
  60. package/Server/Services/LlmLogService.ts +46 -2
  61. package/Server/Services/OpenTelemetryIngestService.ts +230 -26
  62. package/Server/Services/UserService.ts +184 -0
  63. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +6 -0
  64. package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +4 -0
  65. package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +8 -5
  66. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +90 -16
  67. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +2 -0
  68. package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +2 -0
  69. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +223 -22
  70. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +25 -24
  71. package/Server/Utils/AI/SRE/ConfidenceSignal.ts +182 -71
  72. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +252 -43
  73. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +25 -24
  74. package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +47 -13
  75. package/Server/Utils/AI/SRE/InvestigationGrader.ts +9 -5
  76. package/Server/Utils/AI/SRE/InvestigationQueue.ts +141 -24
  77. package/Server/Utils/AI/SRE/InvestigationSubjectLock.ts +66 -0
  78. package/Server/Utils/AI/SRE/PostedRootCause.ts +94 -3
  79. package/Server/Utils/AI/SRE/README.md +1 -1
  80. package/Server/Utils/AI/SRE/SubjectCodeFixRun.ts +132 -10
  81. package/Server/Utils/AI/Toolbox/CodeTools.ts +45 -4
  82. package/Server/Utils/AnalyticsDatabase/ClusterConfig.ts +24 -0
  83. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +13 -0
  84. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +157 -4
  85. package/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.ts +130 -0
  86. package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +29 -0
  87. package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +56 -0
  88. package/Server/Utils/Monitor/MonitorMetricUtil.ts +46 -0
  89. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +1 -0
  90. package/Server/Utils/PasswordHash.ts +330 -0
  91. package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +251 -0
  92. package/Tests/App/Dashboard/EventStatusPanel.test.tsx +747 -0
  93. package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +480 -0
  94. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1184 -0
  95. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +500 -0
  96. package/Tests/App/Dashboard/OverviewCustomFields.test.tsx +333 -0
  97. package/Tests/App/Dashboard/PortMonitorCriteriaFilter.test.ts +93 -0
  98. package/Tests/App/Dashboard/UserCustomFields.test.tsx +392 -0
  99. package/Tests/App/StatusPage/PublicStatusPageAPIErrorHandling.test.ts +117 -0
  100. package/Tests/App/StatusPage/StatusPageModelAPIPolymorphism.test.ts +223 -0
  101. package/Tests/Models/DatabaseModels/PermissionCatalogueCoverage.test.ts +243 -0
  102. package/Tests/Server/API/AIAgentDataFixFromIncidentContext.test.ts +266 -0
  103. package/Tests/Server/API/AIAgentDataRepositoryToken.test.ts +381 -0
  104. package/Tests/Server/API/AIInvestigationAPI.test.ts +594 -0
  105. package/Tests/Server/API/AIInvestigationCreateFixTask.test.ts +80 -0
  106. package/Tests/Server/API/DashboardMasterPasswordAPI.test.ts +172 -1
  107. package/Tests/Server/API/DashboardPublicAttributeValuesAPI.test.ts +943 -0
  108. package/Tests/Server/API/DashboardPublicMetricsAggregateAPI.test.ts +1296 -0
  109. package/Tests/Server/API/DashboardPublicTemplatePayloads.test.ts +598 -0
  110. package/Tests/Server/API/GitHubAppInstallationBindingAPI.test.ts +539 -0
  111. package/Tests/Server/API/Helpers.ts +6 -1
  112. package/Tests/Server/API/StatusPageMasterPasswordAPI.test.ts +335 -0
  113. package/Tests/Server/API/UserProjectsAPI.test.ts +852 -0
  114. package/Tests/Server/Infrastructure/GlobalCache.test.ts +128 -0
  115. package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +215 -0
  116. package/Tests/Server/Services/AIRunCodeFixClaim.test.ts +59 -5
  117. package/Tests/Server/Services/AIRunHumanVerdict.test.ts +127 -58
  118. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +396 -20
  119. package/Tests/Server/Services/AddMasterPasswordSaltMigration.test.ts +283 -0
  120. package/Tests/Server/Services/AddPerUserPasswordSaltMigration.test.ts +178 -0
  121. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +582 -0
  122. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +30 -1
  123. package/Tests/Server/Services/CodeRepositoryInstallationBinding.test.ts +305 -0
  124. package/Tests/Server/Services/CodeRepositoryResolutionBinding.test.ts +147 -0
  125. package/Tests/Server/Services/DatabaseServicePerUserPasswordSalt.test.ts +880 -0
  126. package/Tests/Server/Services/DatabaseServiceUpdateColumnsWithoutHooks.test.ts +54 -0
  127. package/Tests/Server/Services/FeedAIRunAssociation.test.ts +125 -0
  128. package/Tests/Server/Services/FixFromIncidentTaskTrigger.test.ts +418 -57
  129. package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +173 -14
  130. package/Tests/Server/Services/MasterPasswordScrypt.test.ts +567 -0
  131. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +568 -0
  132. package/Tests/Server/Services/RestoreDroppedUniqueIndexesMigration.test.ts +386 -0
  133. package/Tests/Server/Services/RestoreServiceLowerNameIndexMigration.test.ts +240 -0
  134. package/Tests/Server/Services/SeparateIncidentAlertAiSettingsMigration.test.ts +194 -0
  135. package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +885 -0
  136. package/Tests/Server/Services/WidenHashedStringColumnsForScryptMigration.test.ts +220 -0
  137. package/Tests/Server/Utils/AI/AIAlertGating.test.ts +37 -4
  138. package/Tests/Server/Utils/AI/AIConfidenceSignal.test.ts +330 -29
  139. package/Tests/Server/Utils/AI/AIIncidentGating.test.ts +25 -0
  140. package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +293 -5
  141. package/Tests/Server/Utils/AI/CodeFixAgentCompletion.test.ts +59 -1
  142. package/Tests/Server/Utils/AI/CodeTools.test.ts +47 -1
  143. package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +10 -0
  144. package/Tests/Server/Utils/AI/FixFromIncidentAutoTrigger.test.ts +342 -19
  145. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +214 -30
  146. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +2 -0
  147. package/Tests/Server/Utils/AI/InvestigationGrader.test.ts +65 -17
  148. package/Tests/Server/Utils/AI/InvestigationQueueRemediationExecution.test.ts +3 -0
  149. package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +313 -20
  150. package/Tests/Server/Utils/AI/PostedRootCause.test.ts +254 -0
  151. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +4 -0
  152. package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +2 -0
  153. package/Tests/Server/Utils/AI/SubjectCodeFixRunDedupe.test.ts +44 -0
  154. package/Tests/Server/Utils/AnalyticsDatabase/ClusterAwareSchema.test.ts +30 -0
  155. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +120 -0
  156. package/Tests/Server/Utils/CodeRepository/GitHubInstallationBinding.test.ts +292 -0
  157. package/Tests/Server/Utils/GitHubInstallationOwnershipVerification.test.ts +340 -0
  158. package/Tests/Server/Utils/GitHubWebhookAndTreeCacheIsolation.test.ts +250 -0
  159. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +212 -0
  160. package/Tests/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.test.ts +401 -0
  161. package/Tests/Server/Utils/Monitor/MonitorMetricUtilPortTimings.test.ts +243 -0
  162. package/Tests/Server/Utils/PasswordHash.test.ts +585 -0
  163. package/Tests/Types/Dashboard/DashboardTemplates.test.ts +111 -0
  164. package/Tests/Types/Database/ColumnLength.test.ts +7 -1
  165. package/Tests/Types/HashedStringPerUserSalt.test.ts +476 -0
  166. package/Tests/Types/Monitor/CephMetricCatalog.test.ts +104 -0
  167. package/Tests/Types/Monitor/CriteriaFilter.test.ts +4 -0
  168. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +293 -0
  169. package/Tests/Types/Monitor/DockerMetricCatalog.test.ts +109 -0
  170. package/Tests/Types/Monitor/DockerSwarmMetricCatalog.test.ts +118 -0
  171. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +249 -0
  172. package/Tests/Types/Monitor/HostMetricCatalog.test.ts +104 -0
  173. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +320 -0
  174. package/Tests/Types/Monitor/IotMetricCatalog.test.ts +104 -0
  175. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +118 -0
  176. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +42 -0
  177. package/Tests/Types/Monitor/MonitorStep.test.ts +38 -0
  178. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +75 -0
  179. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +271 -0
  180. package/Tests/Types/Monitor/PodmanMetricCatalog.test.ts +109 -0
  181. package/Tests/Types/Monitor/ProxmoxMetricCatalog.test.ts +107 -0
  182. package/Tests/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.test.ts +151 -0
  183. package/Tests/Types/Permission.test.ts +137 -0
  184. package/Tests/Types/Rum/SessionReplayMaskingMode.test.ts +101 -0
  185. package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +5 -5
  186. package/Tests/UI/Components/CardModelDetailEdit.test.tsx +3 -5
  187. package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +696 -0
  188. package/Tests/UI/Components/ErrorBoundary.test.tsx +158 -0
  189. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +74 -0
  190. package/Tests/UI/Components/MoreMenu.test.tsx +756 -0
  191. package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +62 -0
  192. package/Tests/UI/Monitor/PortMonitorView.test.tsx +237 -0
  193. package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +91 -0
  194. package/Tests/UI/Utils/DownloadFile.test.ts +103 -0
  195. package/Tests/UI/Utils/ErrorSupportBundle.test.ts +582 -0
  196. package/Tests/UI/Utils/Project.test.ts +31 -0
  197. package/Tests/UI/Utils/StatusPageModelAPIInjection.test.ts +245 -0
  198. package/Tests/UI/Utils/UseDashboardGridDnd.test.tsx +820 -0
  199. package/Tests/UI/Utils/UserProjectsModelAPI.test.ts +714 -0
  200. package/Tests/Utils/Dashboard/DashboardViewConfig.test.ts +329 -0
  201. package/Tests/Utils/Dashboard/GridLayout.test.ts +951 -0
  202. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +117 -0
  203. package/Tests/Utils/RecordingRuleExpression.test.ts +327 -0
  204. package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +186 -0
  205. package/Tests/Utils/StatusPage/GroupTree.test.ts +456 -0
  206. package/Tests/Utils/StatusPage/OverviewGroupHierarchyVisibility.test.ts +588 -0
  207. package/Tests/Utils/TeamMembersByProject.test.ts +655 -0
  208. package/Tests/Utils/Telemetry/SavedViewTimeRange.test.ts +244 -0
  209. package/Tests/Utils/Telemetry/TelemetryQueryTimeRange.test.ts +825 -0
  210. package/Types/AI/AIRunCodeFixRecommendation.ts +17 -0
  211. package/Types/AI/CodeFixTaskContext.ts +63 -3
  212. package/Types/AI/CodeFixTaskType.ts +3 -3
  213. package/Types/Database/ColumnLength.ts +9 -1
  214. package/Types/Database/TableColumn.ts +11 -0
  215. package/Types/Database/UnsynchronizedIndex.ts +48 -0
  216. package/Types/HashedString.ts +140 -4
  217. package/Types/Monitor/CriteriaFilter.ts +4 -0
  218. package/Types/Monitor/DomainMonitor/DomainLookupMethod.ts +23 -0
  219. package/Types/Monitor/DomainMonitor/DomainMonitorResponse.ts +7 -0
  220. package/Types/Monitor/MonitorCriteriaInstance.ts +24 -7
  221. package/Types/Monitor/MonitorMetricType.ts +8 -0
  222. package/Types/Monitor/MonitorStep.ts +10 -1
  223. package/Types/Monitor/MonitorStepDomainMonitor.ts +21 -0
  224. package/Types/Monitor/PortMonitor/PortMonitorTimings.ts +10 -0
  225. package/Types/Permission.ts +23 -175
  226. package/Types/Probe/ProbeMonitorResponse.ts +6 -0
  227. package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +2 -3
  228. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +85 -11
  229. package/UI/Components/ErrorBoundary.tsx +138 -11
  230. package/UI/Components/Feed/FeedItem.tsx +9 -2
  231. package/UI/Components/ModelDetail/CardModelDetail.tsx +0 -12
  232. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  233. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +12 -2
  234. package/UI/Components/MoreMenu/MoreMenu.tsx +285 -97
  235. package/UI/Components/MoreMenu/MoreMenuItem.tsx +8 -5
  236. package/UI/Components/Navbar/NavBar.tsx +12 -2
  237. package/UI/Components/Navbar/NavBarMenuModal.tsx +19 -7
  238. package/UI/Utils/DownloadFile.ts +16 -8
  239. package/UI/Utils/ErrorSupportBundle.ts +805 -0
  240. package/UI/Utils/ModelAPI/ModelAPI.ts +19 -8
  241. package/UI/Utils/ModelAPI/UserProjectsModelAPI.ts +257 -0
  242. package/UI/Utils/Project.ts +4 -0
  243. package/UI/Utils/StatusPage.ts +8 -2
  244. package/UI/Utils/UseDashboardGridDnd.ts +917 -0
  245. package/Utils/Dashboard/DashboardViewConfig.ts +80 -36
  246. package/Utils/Dashboard/GridLayout.ts +523 -0
  247. package/Utils/Metrics/RecordingRuleExpression.ts +19 -17
  248. package/Utils/Monitor/MonitorMetricType.ts +44 -2
  249. package/Utils/StatusPage/GroupNestingLayout.ts +69 -0
  250. package/Utils/StatusPage/GroupTree.ts +157 -66
  251. package/Utils/StatusPage/ResourceUptime.ts +37 -2
  252. package/Utils/TeamMembersByProject.ts +237 -0
  253. package/Utils/Telemetry/SavedViewTimeRange.ts +114 -0
  254. package/Utils/Telemetry/TelemetryQueryTimeRange.ts +334 -0
  255. package/build/dist/Models/DatabaseModels/AIRun.js +39 -1
  256. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  257. package/build/dist/Models/DatabaseModels/AlertFeed.js +32 -0
  258. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
  259. package/build/dist/Models/DatabaseModels/CephCluster.js +16 -1
  260. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  261. package/build/dist/Models/DatabaseModels/CodeRepository.js +14 -6
  262. package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
  263. package/build/dist/Models/DatabaseModels/Dashboard.js +29 -0
  264. package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
  265. package/build/dist/Models/DatabaseModels/DockerHost.js +16 -1
  266. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  267. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +16 -1
  268. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
  269. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +16 -1
  270. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
  271. package/build/dist/Models/DatabaseModels/Incident.js +2 -0
  272. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  273. package/build/dist/Models/DatabaseModels/IncidentEpisode.js +1 -0
  274. package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
  275. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +1 -0
  276. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  277. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
  278. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
  279. package/build/dist/Models/DatabaseModels/IncidentFeed.js +32 -0
  280. package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
  281. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +1 -0
  282. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  283. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
  284. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  285. package/build/dist/Models/DatabaseModels/IoTFleet.js +16 -1
  286. package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
  287. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +16 -1
  288. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  289. package/build/dist/Models/DatabaseModels/LogSavedView.js +33 -0
  290. package/build/dist/Models/DatabaseModels/LogSavedView.js.map +1 -1
  291. package/build/dist/Models/DatabaseModels/NetworkDevice.js +16 -1
  292. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  293. package/build/dist/Models/DatabaseModels/NetworkInterface.js +16 -1
  294. package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
  295. package/build/dist/Models/DatabaseModels/Project.js +257 -13
  296. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  297. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +16 -1
  298. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  299. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -0
  300. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  301. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +1 -0
  302. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  303. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
  304. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  305. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.js +4 -4
  306. package/build/dist/Models/DatabaseModels/Service.js +28 -1
  307. package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
  308. package/build/dist/Models/DatabaseModels/StatusPage.js +29 -0
  309. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  310. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +1 -0
  311. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  312. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js +32 -0
  313. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js.map +1 -1
  314. package/build/dist/Models/DatabaseModels/User.js +32 -0
  315. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  316. package/build/dist/Server/API/AIAgentDataAPI.js +49 -48
  317. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  318. package/build/dist/Server/API/AIInvestigationAPI.js +111 -11
  319. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  320. package/build/dist/Server/API/DashboardAPI.js +312 -15
  321. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  322. package/build/dist/Server/API/GitHubAPI.js +94 -167
  323. package/build/dist/Server/API/GitHubAPI.js.map +1 -1
  324. package/build/dist/Server/API/StatusPageAPI.js +29 -11
  325. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  326. package/build/dist/Server/API/UserAPI.js +187 -2
  327. package/build/dist/Server/API/UserAPI.js.map +1 -1
  328. package/build/dist/Server/EnvironmentConfig.js +21 -3
  329. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  330. package/build/dist/Server/Infrastructure/ClickhouseConfig.js +12 -1
  331. package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
  332. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js +1 -1
  333. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js.map +1 -1
  334. package/build/dist/Server/Infrastructure/GlobalCache.js +29 -0
  335. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  336. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js +14 -0
  337. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js.map +1 -0
  338. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js +59 -0
  339. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js.map +1 -0
  340. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js +22 -0
  341. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js.map +1 -0
  342. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +93 -0
  343. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js.map +1 -0
  344. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js +36 -0
  345. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js.map +1 -0
  346. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js +18 -0
  347. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js.map +1 -0
  348. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js +101 -0
  349. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js.map +1 -0
  350. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js +66 -0
  351. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js.map +1 -0
  352. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js +19 -0
  353. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js.map +1 -0
  354. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js +19 -0
  355. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js.map +1 -0
  356. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
  357. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  358. package/build/dist/Server/Services/AIRunService.js +58 -12
  359. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  360. package/build/dist/Server/Services/AIService.js +74 -21
  361. package/build/dist/Server/Services/AIService.js.map +1 -1
  362. package/build/dist/Server/Services/AlertFeedService.js +3 -0
  363. package/build/dist/Server/Services/AlertFeedService.js.map +1 -1
  364. package/build/dist/Server/Services/AnalyticsDatabaseService.js +86 -2
  365. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  366. package/build/dist/Server/Services/CodeRepositoryService.js +90 -2
  367. package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
  368. package/build/dist/Server/Services/DatabaseService.js +180 -3
  369. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  370. package/build/dist/Server/Services/IncidentFeedService.js +3 -0
  371. package/build/dist/Server/Services/IncidentFeedService.js.map +1 -1
  372. package/build/dist/Server/Services/LlmLogService.js +22 -1
  373. package/build/dist/Server/Services/LlmLogService.js.map +1 -1
  374. package/build/dist/Server/Services/OpenTelemetryIngestService.js +155 -25
  375. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  376. package/build/dist/Server/Services/UserService.js +165 -0
  377. package/build/dist/Server/Services/UserService.js.map +1 -1
  378. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
  379. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  380. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +4 -0
  381. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -1
  382. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +8 -5
  383. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
  384. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +63 -24
  385. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  386. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +2 -0
  387. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  388. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +2 -0
  389. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
  390. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +156 -28
  391. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  392. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +21 -19
  393. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  394. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js +128 -49
  395. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js.map +1 -1
  396. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +170 -31
  397. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -1
  398. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +21 -19
  399. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  400. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +33 -9
  401. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -1
  402. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +9 -5
  403. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js.map +1 -1
  404. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +121 -41
  405. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
  406. package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js +46 -0
  407. package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js.map +1 -0
  408. package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js +61 -14
  409. package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js.map +1 -1
  410. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js +79 -1
  411. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js.map +1 -1
  412. package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js +31 -1
  413. package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js.map +1 -1
  414. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js +21 -0
  415. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js.map +1 -1
  416. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +13 -0
  417. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  418. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +126 -4
  419. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  420. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js +136 -0
  421. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js.map +1 -0
  422. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +20 -3
  423. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
  424. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +43 -0
  425. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
  426. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
  427. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  428. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +1 -0
  429. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  430. package/build/dist/Server/Utils/PasswordHash.js +258 -0
  431. package/build/dist/Server/Utils/PasswordHash.js.map +1 -0
  432. package/build/dist/Types/AI/AIRunCodeFixRecommendation.js +18 -0
  433. package/build/dist/Types/AI/AIRunCodeFixRecommendation.js.map +1 -0
  434. package/build/dist/Types/AI/CodeFixTaskContext.js +23 -3
  435. package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -1
  436. package/build/dist/Types/AI/CodeFixTaskType.js +3 -3
  437. package/build/dist/Types/Database/ColumnLength.js +9 -1
  438. package/build/dist/Types/Database/ColumnLength.js.map +1 -1
  439. package/build/dist/Types/Database/TableColumn.js.map +1 -1
  440. package/build/dist/Types/Database/UnsynchronizedIndex.js +46 -0
  441. package/build/dist/Types/Database/UnsynchronizedIndex.js.map +1 -0
  442. package/build/dist/Types/HashedString.js +96 -5
  443. package/build/dist/Types/HashedString.js.map +1 -1
  444. package/build/dist/Types/Monitor/CriteriaFilter.js +4 -0
  445. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  446. package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js +24 -0
  447. package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js.map +1 -0
  448. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +24 -7
  449. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  450. package/build/dist/Types/Monitor/MonitorMetricType.js +7 -0
  451. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  452. package/build/dist/Types/Monitor/MonitorStep.js +6 -1
  453. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  454. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +15 -0
  455. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -1
  456. package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js +2 -0
  457. package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js.map +1 -0
  458. package/build/dist/Types/Permission.js +23 -155
  459. package/build/dist/Types/Permission.js.map +1 -1
  460. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +2 -5
  461. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
  462. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +51 -10
  463. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  464. package/build/dist/UI/Components/ErrorBoundary.js +67 -8
  465. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  466. package/build/dist/UI/Components/Feed/FeedItem.js +2 -2
  467. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  468. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +0 -12
  469. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  470. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  471. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  472. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +12 -2
  473. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  474. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +193 -65
  475. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  476. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +1 -1
  477. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  478. package/build/dist/UI/Components/Navbar/NavBar.js +3 -1
  479. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  480. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +19 -7
  481. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  482. package/build/dist/UI/Utils/DownloadFile.js +15 -8
  483. package/build/dist/UI/Utils/DownloadFile.js.map +1 -1
  484. package/build/dist/UI/Utils/ErrorSupportBundle.js +476 -0
  485. package/build/dist/UI/Utils/ErrorSupportBundle.js.map +1 -0
  486. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -8
  487. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  488. package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js +156 -0
  489. package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js.map +1 -0
  490. package/build/dist/UI/Utils/Project.js +3 -0
  491. package/build/dist/UI/Utils/Project.js.map +1 -1
  492. package/build/dist/UI/Utils/StatusPage.js +4 -4
  493. package/build/dist/UI/Utils/StatusPage.js.map +1 -1
  494. package/build/dist/UI/Utils/UseDashboardGridDnd.js +551 -0
  495. package/build/dist/UI/Utils/UseDashboardGridDnd.js.map +1 -0
  496. package/build/dist/Utils/Dashboard/DashboardViewConfig.js +42 -26
  497. package/build/dist/Utils/Dashboard/DashboardViewConfig.js.map +1 -1
  498. package/build/dist/Utils/Dashboard/GridLayout.js +338 -0
  499. package/build/dist/Utils/Dashboard/GridLayout.js.map +1 -0
  500. package/build/dist/Utils/Metrics/RecordingRuleExpression.js +19 -17
  501. package/build/dist/Utils/Metrics/RecordingRuleExpression.js.map +1 -1
  502. package/build/dist/Utils/Monitor/MonitorMetricType.js +38 -6
  503. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  504. package/build/dist/Utils/StatusPage/GroupNestingLayout.js +46 -0
  505. package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -1
  506. package/build/dist/Utils/StatusPage/GroupTree.js +79 -34
  507. package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -1
  508. package/build/dist/Utils/StatusPage/ResourceUptime.js +22 -1
  509. package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
  510. package/build/dist/Utils/TeamMembersByProject.js +145 -0
  511. package/build/dist/Utils/TeamMembersByProject.js.map +1 -0
  512. package/build/dist/Utils/Telemetry/SavedViewTimeRange.js +79 -0
  513. package/build/dist/Utils/Telemetry/SavedViewTimeRange.js.map +1 -0
  514. package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js +236 -0
  515. package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js.map +1 -0
  516. 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 heightOfComponent: number = data.component.heightInDashboardUnits;
25
+ const existingRects: Array<GridRect> =
26
+ GridLayoutUtil.fromDashboardComponents(
27
+ data.dashboardViewConfig.components,
28
+ );
20
29
 
21
- // find the last row that has enough space to fit the component. If there is no such row, create a new row or rows to fit the component.
22
- const allComponentsFromDashboard: Array<DashboardBaseComponent> =
23
- data.dashboardViewConfig.components;
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
- let componentTopPosition: number = 0;
36
+ const position: GridPosition = GridLayoutUtil.findFirstFit({
37
+ rects: existingRects,
38
+ width,
39
+ height,
40
+ });
26
41
 
27
- // find the last row that has the component.
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
- let lastRowThatHasComponent: number = -1;
50
+ const components: Array<DashboardBaseComponent> = [
51
+ ...data.dashboardViewConfig.components,
52
+ newComponent,
53
+ ];
30
54
 
31
- for (const dashboardComponent of allComponentsFromDashboard) {
32
- if (
33
- lastRowThatHasComponent <
34
- dashboardComponent.topInDashboardUnits +
35
- dashboardComponent.heightInDashboardUnits -
36
- 1
37
- ) {
38
- lastRowThatHasComponent =
39
- dashboardComponent.topInDashboardUnits +
40
- dashboardComponent.heightInDashboardUnits -
41
- 1;
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
- componentTopPosition = lastRowThatHasComponent + 1;
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
- // check height of the component. If it is bigger than the last row that has the component, create more rows and udate the height of dashboardViewConfig.
82
+ const normalized: Array<GridRect> = GridLayoutUtil.normalize(rects);
48
83
 
49
- if (
50
- componentTopPosition + heightOfComponent >
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 newComponent: DashboardBaseComponent = {
58
- ...data.component,
59
- topInDashboardUnits: componentTopPosition,
60
- leftInDashboardUnits: 0,
61
- };
88
+ const components: Array<DashboardBaseComponent> =
89
+ GridLayoutUtil.applyRectsToComponents(
90
+ dashboardViewConfig.components,
91
+ normalized,
92
+ );
62
93
 
63
- // Add the new component to the dashboard configuration
64
- data.dashboardViewConfig.components.push(newComponent);
94
+ return {
95
+ ...dashboardViewConfig,
96
+ components,
97
+ heightInDashboardUnits: Math.max(
98
+ DashboardViewConfigUtil.getFiniteHeight(dashboardViewConfig),
99
+ GridLayoutUtil.requiredRows(normalized),
100
+ ),
101
+ };
102
+ }
65
103
 
66
- return { ...data.dashboardViewConfig };
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
+ }