@oneuptime/common 12.0.12 → 12.0.14

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 (596) hide show
  1. package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +32 -5
  2. package/Models/DatabaseModels/NetworkDevice.ts +64 -0
  3. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
  4. package/Models/DatabaseModels/StatusPage.ts +59 -0
  5. package/Models/DatabaseModels/StatusPageOidc.ts +2 -0
  6. package/Models/DatabaseModels/UserCall.ts +94 -3
  7. package/Models/DatabaseModels/UserEmail.ts +94 -3
  8. package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
  9. package/Models/DatabaseModels/UserPush.ts +37 -0
  10. package/Models/DatabaseModels/UserSMS.ts +94 -3
  11. package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
  12. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -2
  13. package/Server/API/AIChatAPI.ts +55 -56
  14. package/Server/API/BaseAPI.ts +79 -14
  15. package/Server/API/CommonAPI.ts +89 -0
  16. package/Server/API/MicrosoftTeamsAPI.ts +20 -9
  17. package/Server/API/SlackAPI.ts +13 -10
  18. package/Server/API/StatusPageAPI.ts +2197 -2128
  19. package/Server/API/TelemetryAPI.ts +72 -3
  20. package/Server/API/UserCallAPI.ts +53 -45
  21. package/Server/API/UserEmailAPI.ts +53 -44
  22. package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
  23. package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
  24. package/Server/API/UserPushAPI.ts +126 -2
  25. package/Server/API/UserSmsAPI.ts +53 -44
  26. package/Server/API/UserWhatsAppAPI.ts +53 -50
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.ts +30 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.ts +47 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  33. package/Server/Middleware/UserAuthorization.ts +11 -2
  34. package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
  35. package/Server/Services/AnalyticsDatabaseService.ts +169 -0
  36. package/Server/Services/ApiKeyPermissionService.ts +116 -2
  37. package/Server/Services/DatabaseService.ts +118 -6
  38. package/Server/Services/LogAggregationService.ts +39 -0
  39. package/Server/Services/LogService.ts +21 -0
  40. package/Server/Services/NetworkSiteService.ts +12 -0
  41. package/Server/Services/PushNotificationService.ts +127 -12
  42. package/Server/Services/SpanService.ts +21 -0
  43. package/Server/Services/TeamMemberService.ts +53 -13
  44. package/Server/Services/TraceAggregationService.ts +15 -0
  45. package/Server/Services/UserCallService.ts +55 -24
  46. package/Server/Services/UserEmailService.ts +83 -17
  47. package/Server/Services/UserIncomingCallNumberService.ts +49 -85
  48. package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
  49. package/Server/Services/UserNotificationRuleService.ts +26 -0
  50. package/Server/Services/UserPushService.ts +89 -0
  51. package/Server/Services/UserSmsService.ts +50 -17
  52. package/Server/Services/UserWhatsAppService.ts +48 -15
  53. package/Server/Services/WorkspaceNotificationRuleService.ts +172 -220
  54. package/Server/Types/AnalyticsDatabase/ModelPermission.ts +9 -0
  55. package/Server/Types/Database/Permissions/AccessControlPermission.ts +47 -16
  56. package/Server/Types/Database/QueryHelper.ts +30 -0
  57. package/Server/Utils/APIKey/AccessPermission.ts +16 -40
  58. package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
  59. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +144 -0
  60. package/Server/Utils/ChannelVerification.ts +510 -0
  61. package/Server/Utils/LogRedaction.ts +576 -0
  62. package/Server/Utils/Logger.ts +123 -46
  63. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +13 -16
  64. package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +94 -23
  65. package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
  66. package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
  67. package/Server/Utils/Monitor/MonitorResource.ts +29 -9
  68. package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
  69. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
  70. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +28 -7
  71. package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
  72. package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
  73. package/Server/Utils/SessionReplay/SessionReplayGateCacheStore.ts +56 -10
  74. package/Server/Utils/StartServer.ts +30 -9
  75. package/Server/Utils/StatusPageSearchEngineIndexing.ts +33 -0
  76. package/Server/Utils/Telemetry/ResourceEntityFilter.ts +441 -0
  77. package/Server/Utils/TotpAuth.ts +137 -9
  78. package/Server/Utils/UserRegistrationToken.ts +182 -0
  79. package/Server/Utils/VerificationCode.ts +134 -0
  80. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +488 -46
  81. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
  82. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
  83. package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
  84. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
  85. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
  86. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +328 -0
  87. package/Tests/App/StatusPage/StatusPageIndexPageRobotsMeta.test.ts +130 -0
  88. package/Tests/Models/DatabaseModels/DatabaseBaseModelToJSONObjectCache.test.ts +180 -0
  89. package/Tests/Models/StatusPageEnableSearchEngineIndexing.test.ts +157 -0
  90. package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
  91. package/Tests/Server/API/AIChatCancelAndFeedback.test.ts +23 -1
  92. package/Tests/Server/API/AIChatRouteAuthorization.test.ts +785 -0
  93. package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +21 -8
  94. package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
  95. package/Tests/Server/API/CommonAPIAuthGuard.test.ts +290 -0
  96. package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +7 -1
  97. package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
  98. package/Tests/Server/API/StatusPageOverviewCache.test.ts +474 -0
  99. package/Tests/Server/API/StatusPageSeoSearchEngineIndexing.test.ts +189 -0
  100. package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
  101. package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
  102. package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
  103. package/Tests/Server/API/UserSmsApi.test.ts +107 -14
  104. package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
  105. package/Tests/Server/Infrastructure/InMemoryTTLCache.test.ts +158 -0
  106. package/Tests/Server/Infrastructure/Postgres/DeviceRoleAndDeclaredLinkParentMigration.test.ts +9 -60
  107. package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +315 -0
  108. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +24 -15
  109. package/Tests/Server/Middleware/UserAuthorization.test.ts +79 -0
  110. package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
  111. package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +280 -0
  112. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
  113. package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
  114. package/Tests/Server/Services/ApiKeyPermissionService.test.ts +347 -0
  115. package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
  116. package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
  117. package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
  118. package/Tests/Server/Services/DatabaseServiceUpdateDebugLogging.test.ts +282 -0
  119. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
  120. package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
  121. package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
  122. package/Tests/Server/Services/NetworkSiteService.test.ts +56 -2
  123. package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
  124. package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
  125. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
  126. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
  127. package/Tests/Server/Services/TelemetryResourceFacetFilters.test.ts +267 -0
  128. package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
  129. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
  130. package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
  131. package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
  132. package/Tests/Server/Services/WorkspaceNotificationRuleTestRuleChannels.test.ts +702 -0
  133. package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
  134. package/Tests/Server/Types/Database/Permissions/AccessControlPermission.test.ts +165 -0
  135. package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
  136. package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
  137. package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
  138. package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
  139. package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
  140. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +48 -36
  141. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +213 -0
  142. package/Tests/Server/Utils/Browser.test.ts +162 -0
  143. package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
  144. package/Tests/Server/Utils/Express.test.ts +371 -0
  145. package/Tests/Server/Utils/LogRedaction.test.ts +415 -0
  146. package/Tests/Server/Utils/LoggerCredentialLeak.test.ts +245 -0
  147. package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
  148. package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
  149. package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
  150. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
  151. package/Tests/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.test.ts +374 -4
  152. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
  153. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
  154. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
  155. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
  156. package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +455 -0
  157. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
  158. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
  159. package/Tests/Server/Utils/Monitor/NetworkDeviceReachabilityRoundTrip.test.ts +369 -0
  160. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +86 -8
  161. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
  162. package/Tests/Server/Utils/PrivacyFilterUtil.test.ts +64 -0
  163. package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
  164. package/Tests/Server/Utils/SessionReplay/SessionReplayGateCacheStore.test.ts +207 -0
  165. package/Tests/Server/Utils/StartServerBodyVerify.test.ts +335 -0
  166. package/Tests/Server/Utils/StatusPageSearchEngineIndexing.test.ts +60 -0
  167. package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
  168. package/Tests/Server/Utils/Telemetry/ResourceEntityFilter.test.ts +435 -0
  169. package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
  170. package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
  171. package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
  172. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +607 -62
  173. package/Tests/Server/Utils/Workspace/MicrosoftTeamsInstalledTeamIdSpace.test.ts +778 -0
  174. package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +44 -10
  175. package/Tests/Types/API/HostnameFromAuthority.test.ts +164 -0
  176. package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
  177. package/Tests/Types/Call/CallRequest.test.ts +189 -0
  178. package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
  179. package/Tests/Types/Database/AccessControl/ColumnAccessControlCache.test.ts +344 -0
  180. package/Tests/Types/Database/DatabasePropertyFindOperator.test.ts +518 -0
  181. package/Tests/Types/Database/TableColumnMetadataCache.test.ts +286 -0
  182. package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
  183. package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
  184. package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
  185. package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
  186. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
  187. package/Tests/Types/Monitor/MonitorStep.test.ts +100 -0
  188. package/Tests/Types/Monitor/MonitorTypeKeywords.test.ts +360 -0
  189. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
  190. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
  191. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
  192. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
  193. package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
  194. package/Tests/Types/StatusPage/SearchEngineIndexing.test.ts +86 -0
  195. package/Tests/Types/Telemetry/ResourceEntityFacet.test.ts +254 -0
  196. package/Tests/Types/TextRandomGeneration.test.ts +211 -0
  197. package/Tests/UI/Components/Button.test.tsx +175 -1
  198. package/Tests/UI/Components/CardSelect.test.tsx +1021 -0
  199. package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
  200. package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
  201. package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
  202. package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
  203. package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
  204. package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
  205. package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
  206. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
  207. package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
  208. package/Tests/UI/Components/List.test.tsx +9 -2
  209. package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
  210. package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
  211. package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
  212. package/Tests/UI/Components/MasterPage.test.tsx +36 -1
  213. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
  214. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
  215. package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
  216. package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
  217. package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
  218. package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
  219. package/Tests/UI/Components/Skeleton.test.tsx +71 -0
  220. package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
  221. package/Tests/UI/Components/Tabs.test.tsx +24 -0
  222. package/Tests/UI/Components/Toast.test.tsx +130 -7
  223. package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
  224. package/Tests/UI/Utils/Dropdown.test.ts +423 -0
  225. package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
  226. package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
  227. package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
  228. package/Tests/Utils/API.test.ts +16 -2
  229. package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
  230. package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
  231. package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
  232. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +66 -1
  233. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +115 -6
  234. package/Tests/Utils/NetworkDevice/DeviceReachabilityUtil.test.ts +610 -0
  235. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +114 -45
  236. package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
  237. package/Types/API/Hostname.ts +79 -0
  238. package/Types/Database/AccessControl/ColumnAccessControl.ts +33 -11
  239. package/Types/Database/AccessControl/ColumnBillingAccessControl.ts +33 -11
  240. package/Types/Database/DatabaseProperty.ts +38 -0
  241. package/Types/Database/TableColumn.ts +34 -7
  242. package/Types/Email/EmailTemplateType.ts +1 -0
  243. package/Types/Events/Recurring.ts +16 -1
  244. package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
  245. package/Types/Monitor/MonitorStep.ts +13 -1
  246. package/Types/Monitor/MonitorType.ts +345 -40
  247. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
  248. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
  249. package/Types/Monitor/SSLMonitor/SslMonitorResponse.ts +43 -0
  250. package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
  251. package/Types/Permission.ts +35 -0
  252. package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
  253. package/Types/PushNotification/PushNotificationMessage.ts +15 -0
  254. package/Types/PushNotification/PushNotificationRequest.ts +8 -16
  255. package/Types/Service/ServiceLanguage.ts +144 -0
  256. package/Types/StatusPage/SearchEngineIndexing.ts +61 -0
  257. package/Types/Telemetry/ResourceEntityFacet.ts +211 -0
  258. package/Types/Text.ts +111 -19
  259. package/UI/Components/Button/Button.tsx +27 -14
  260. package/UI/Components/CardSelect/CardSelect.tsx +714 -105
  261. package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
  262. package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
  263. package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
  264. package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
  265. package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
  266. package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
  267. package/UI/Components/CommandPalette/Types.ts +49 -0
  268. package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
  269. package/UI/Components/Dropdown/Dropdown.tsx +6 -1
  270. package/UI/Components/EmptyState/EmptyState.tsx +8 -1
  271. package/UI/Components/Feed/FeedItem.tsx +1 -1
  272. package/UI/Components/Footer/Footer.tsx +32 -6
  273. package/UI/Components/Forms/Fields/FormField.tsx +3 -0
  274. package/UI/Components/Forms/Types/Field.ts +8 -0
  275. package/UI/Components/List/List.tsx +37 -5
  276. package/UI/Components/List/ListSkeleton.tsx +54 -0
  277. package/UI/Components/Loader/PageLoader.tsx +29 -8
  278. package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +26 -4
  279. package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +23 -2
  280. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
  281. package/UI/Components/MasterPage/MasterPage.tsx +24 -11
  282. package/UI/Components/Modal/Modal.tsx +2 -2
  283. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  284. package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
  285. package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
  286. package/UI/Components/Navbar/NavBar.tsx +14 -1
  287. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
  288. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
  289. package/UI/Components/SideOver/SideOver.tsx +37 -2
  290. package/UI/Components/Skeleton/Skeleton.tsx +53 -0
  291. package/UI/Components/Table/Table.tsx +74 -44
  292. package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
  293. package/UI/Components/Tabs/Tab.tsx +1 -1
  294. package/UI/Components/Toast/Toast.tsx +118 -53
  295. package/UI/Components/Toast/ToastInit.tsx +82 -32
  296. package/UI/Styles/Theme.css +40 -0
  297. package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
  298. package/UI/Utils/ModelListCache.ts +188 -0
  299. package/UI/Utils/Project.ts +29 -0
  300. package/Utils/API.ts +6 -1
  301. package/Utils/Monitor/MonitorMetricType.ts +16 -1
  302. package/Utils/Monitor/NetworkTopologyUtil.ts +60 -8
  303. package/Utils/NetworkDevice/DeviceReachabilityUtil.ts +262 -0
  304. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +41 -24
  305. package/Utils/Telemetry/CrossSignalScope.ts +75 -4
  306. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +20 -4
  307. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
  308. package/build/dist/Models/DatabaseModels/NetworkDevice.js +66 -0
  309. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  310. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
  311. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  312. package/build/dist/Models/DatabaseModels/StatusPage.js +60 -0
  313. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  314. package/build/dist/Models/DatabaseModels/StatusPageOidc.js +2 -0
  315. package/build/dist/Models/DatabaseModels/StatusPageOidc.js.map +1 -1
  316. package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
  317. package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
  318. package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
  319. package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
  320. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
  321. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
  322. package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
  323. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  324. package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
  325. package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
  326. package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
  327. package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
  328. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  329. package/build/dist/Server/API/AIChatAPI.js +48 -35
  330. package/build/dist/Server/API/AIChatAPI.js.map +1 -1
  331. package/build/dist/Server/API/BaseAPI.js +69 -13
  332. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  333. package/build/dist/Server/API/CommonAPI.js +59 -0
  334. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  335. package/build/dist/Server/API/MicrosoftTeamsAPI.js +20 -6
  336. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  337. package/build/dist/Server/API/SlackAPI.js +13 -10
  338. package/build/dist/Server/API/SlackAPI.js.map +1 -1
  339. package/build/dist/Server/API/StatusPageAPI.js +745 -673
  340. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  341. package/build/dist/Server/API/TelemetryAPI.js +34 -3
  342. package/build/dist/Server/API/TelemetryAPI.js.map +1 -1
  343. package/build/dist/Server/API/UserCallAPI.js +42 -38
  344. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  345. package/build/dist/Server/API/UserEmailAPI.js +42 -38
  346. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  347. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
  348. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
  349. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
  350. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
  351. package/build/dist/Server/API/UserPushAPI.js +95 -2
  352. package/build/dist/Server/API/UserPushAPI.js.map +1 -1
  353. package/build/dist/Server/API/UserSmsAPI.js +42 -38
  354. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  355. package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
  356. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  357. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
  358. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
  359. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
  360. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
  361. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js +23 -0
  362. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787500000000-AddEnableSearchEngineIndexingToStatusPage.js.map +1 -0
  363. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js +34 -0
  364. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787600000000-AddNetworkDeviceReachabilityColumns.js.map +1 -0
  365. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
  366. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
  367. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  368. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  369. package/build/dist/Server/Middleware/UserAuthorization.js +6 -2
  370. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  371. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
  372. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
  373. package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
  374. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  375. package/build/dist/Server/Services/ApiKeyPermissionService.js +90 -1
  376. package/build/dist/Server/Services/ApiKeyPermissionService.js.map +1 -1
  377. package/build/dist/Server/Services/DatabaseService.js +89 -6
  378. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  379. package/build/dist/Server/Services/LogAggregationService.js +7 -0
  380. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  381. package/build/dist/Server/Services/LogService.js +16 -0
  382. package/build/dist/Server/Services/LogService.js.map +1 -1
  383. package/build/dist/Server/Services/NetworkSiteService.js +12 -0
  384. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -1
  385. package/build/dist/Server/Services/PushNotificationService.js +69 -30
  386. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  387. package/build/dist/Server/Services/SpanService.js +16 -0
  388. package/build/dist/Server/Services/SpanService.js.map +1 -1
  389. package/build/dist/Server/Services/TeamMemberService.js +43 -7
  390. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  391. package/build/dist/Server/Services/TraceAggregationService.js +2 -0
  392. package/build/dist/Server/Services/TraceAggregationService.js.map +1 -1
  393. package/build/dist/Server/Services/UserCallService.js +54 -22
  394. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  395. package/build/dist/Server/Services/UserEmailService.js +78 -17
  396. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  397. package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
  398. package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
  399. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
  400. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
  401. package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
  402. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  403. package/build/dist/Server/Services/UserPushService.js +77 -0
  404. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  405. package/build/dist/Server/Services/UserSmsService.js +50 -17
  406. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  407. package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
  408. package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
  409. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +137 -164
  410. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  411. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js +9 -0
  412. package/build/dist/Server/Types/AnalyticsDatabase/ModelPermission.js.map +1 -1
  413. package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js +21 -13
  414. package/build/dist/Server/Types/Database/Permissions/AccessControlPermission.js.map +1 -1
  415. package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
  416. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  417. package/build/dist/Server/Utils/APIKey/AccessPermission.js +9 -32
  418. package/build/dist/Server/Utils/APIKey/AccessPermission.js.map +1 -1
  419. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
  420. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
  421. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +87 -0
  422. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  423. package/build/dist/Server/Utils/ChannelVerification.js +348 -0
  424. package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
  425. package/build/dist/Server/Utils/LogRedaction.js +449 -0
  426. package/build/dist/Server/Utils/LogRedaction.js.map +1 -0
  427. package/build/dist/Server/Utils/Logger.js +98 -45
  428. package/build/dist/Server/Utils/Logger.js.map +1 -1
  429. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +13 -12
  430. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  431. package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +65 -13
  432. package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
  433. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
  434. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  435. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
  436. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  437. package/build/dist/Server/Utils/Monitor/MonitorResource.js +20 -3
  438. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  439. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
  440. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
  441. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
  442. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
  443. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +27 -7
  444. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  445. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
  446. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
  447. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  448. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js +29 -10
  449. package/build/dist/Server/Utils/SessionReplay/SessionReplayGateCacheStore.js.map +1 -1
  450. package/build/dist/Server/Utils/StartServer.js +10 -7
  451. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  452. package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js +24 -0
  453. package/build/dist/Server/Utils/StatusPageSearchEngineIndexing.js.map +1 -0
  454. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js +311 -0
  455. package/build/dist/Server/Utils/Telemetry/ResourceEntityFilter.js.map +1 -0
  456. package/build/dist/Server/Utils/TotpAuth.js +127 -8
  457. package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
  458. package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
  459. package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
  460. package/build/dist/Server/Utils/VerificationCode.js +120 -0
  461. package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
  462. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +366 -37
  463. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  464. package/build/dist/Types/API/Hostname.js +63 -0
  465. package/build/dist/Types/API/Hostname.js.map +1 -1
  466. package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js +20 -6
  467. package/build/dist/Types/Database/AccessControl/ColumnAccessControl.js.map +1 -1
  468. package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js +20 -6
  469. package/build/dist/Types/Database/AccessControl/ColumnBillingAccessControl.js.map +1 -1
  470. package/build/dist/Types/Database/DatabaseProperty.js +38 -0
  471. package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
  472. package/build/dist/Types/Database/TableColumn.js +24 -6
  473. package/build/dist/Types/Database/TableColumn.js.map +1 -1
  474. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  475. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  476. package/build/dist/Types/Events/Recurring.js +13 -1
  477. package/build/dist/Types/Events/Recurring.js.map +1 -1
  478. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
  479. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  480. package/build/dist/Types/Monitor/MonitorStep.js +9 -1
  481. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  482. package/build/dist/Types/Monitor/MonitorType.js +330 -31
  483. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  484. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
  485. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  486. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
  487. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  488. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
  489. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
  490. package/build/dist/Types/Permission.js +33 -0
  491. package/build/dist/Types/Permission.js.map +1 -1
  492. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
  493. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
  494. package/build/dist/Types/Service/ServiceLanguage.js +96 -0
  495. package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
  496. package/build/dist/Types/StatusPage/SearchEngineIndexing.js +55 -0
  497. package/build/dist/Types/StatusPage/SearchEngineIndexing.js.map +1 -0
  498. package/build/dist/Types/Telemetry/ResourceEntityFacet.js +156 -0
  499. package/build/dist/Types/Telemetry/ResourceEntityFacet.js.map +1 -0
  500. package/build/dist/Types/Text.js +82 -17
  501. package/build/dist/Types/Text.js.map +1 -1
  502. package/build/dist/UI/Components/Button/Button.js +22 -14
  503. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  504. package/build/dist/UI/Components/CardSelect/CardSelect.js +360 -40
  505. package/build/dist/UI/Components/CardSelect/CardSelect.js.map +1 -1
  506. package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
  507. package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
  508. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
  509. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
  510. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
  511. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
  512. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
  513. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
  514. package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
  515. package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
  516. package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
  517. package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
  518. package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
  519. package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
  520. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
  521. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
  522. package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
  523. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  524. package/build/dist/UI/Components/EmptyState/EmptyState.js +1 -1
  525. package/build/dist/UI/Components/EmptyState/EmptyState.js.map +1 -1
  526. package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
  527. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  528. package/build/dist/UI/Components/Footer/Footer.js +7 -4
  529. package/build/dist/UI/Components/Footer/Footer.js.map +1 -1
  530. package/build/dist/UI/Components/Forms/Fields/FormField.js +1 -1
  531. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  532. package/build/dist/UI/Components/List/List.js +19 -5
  533. package/build/dist/UI/Components/List/List.js.map +1 -1
  534. package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
  535. package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
  536. package/build/dist/UI/Components/Loader/PageLoader.js +15 -5
  537. package/build/dist/UI/Components/Loader/PageLoader.js.map +1 -1
  538. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +16 -3
  539. package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
  540. package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js +13 -1
  541. package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
  542. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
  543. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  544. package/build/dist/UI/Components/MasterPage/MasterPage.js +10 -2
  545. package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
  546. package/build/dist/UI/Components/Modal/Modal.js +2 -2
  547. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  548. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  549. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
  550. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  551. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
  552. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  553. package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
  554. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  555. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
  556. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  557. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
  558. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  559. package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
  560. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  561. package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
  562. package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
  563. package/build/dist/UI/Components/Table/Table.js +35 -24
  564. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  565. package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
  566. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
  567. package/build/dist/UI/Components/Tabs/Tab.js +1 -1
  568. package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
  569. package/build/dist/UI/Components/Toast/Toast.js +77 -23
  570. package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
  571. package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
  572. package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
  573. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
  574. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  575. package/build/dist/UI/Utils/ModelListCache.js +126 -0
  576. package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
  577. package/build/dist/UI/Utils/Project.js +24 -1
  578. package/build/dist/UI/Utils/Project.js.map +1 -1
  579. package/build/dist/Utils/API.js +6 -1
  580. package/build/dist/Utils/API.js.map +1 -1
  581. package/build/dist/Utils/Monitor/MonitorMetricType.js +13 -1
  582. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  583. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +34 -7
  584. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  585. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js +177 -0
  586. package/build/dist/Utils/NetworkDevice/DeviceReachabilityUtil.js.map +1 -0
  587. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +23 -27
  588. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -1
  589. package/build/dist/Utils/Telemetry/CrossSignalScope.js +44 -4
  590. package/build/dist/Utils/Telemetry/CrossSignalScope.js.map +1 -1
  591. package/jest.config.json +1 -1
  592. package/package.json +2 -3
  593. package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
  594. package/Tests/__mocks__/otpauth.js +0 -30
  595. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
  596. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
@@ -1,4 +1,10 @@
1
- import React, { FunctionComponent, ReactElement, useState } from "react";
1
+ import React, {
2
+ FunctionComponent,
3
+ ReactElement,
4
+ useEffect,
5
+ useRef,
6
+ useState,
7
+ } from "react";
2
8
  import Icon from "../Icon/Icon";
3
9
  import IconProp from "../../../Types/Icon/IconProp";
4
10
  import useTranslateValue from "../../Utils/Translation";
@@ -17,14 +23,78 @@ export interface ComponentProps {
17
23
  onClose?: undefined | (() => void);
18
24
  type?: undefined | ToastType;
19
25
  icon?: IconProp | undefined;
20
- index?: undefined | number;
21
26
  }
22
27
 
28
+ /* How long the exit fade runs before the toast actually unmounts. */
29
+ const EXIT_DURATION_IN_MS: number = 150;
30
+
23
31
  const Component: FunctionComponent<ComponentProps> = (
24
32
  props: ComponentProps,
25
33
  ): ReactElement => {
26
34
  const { translateString } = useTranslateValue();
27
35
  const [show, setShow] = useState<boolean>(true);
36
+
37
+ /*
38
+ * The toast is mounted in its closed state (faded, nudged down) and flipped
39
+ * open one frame later so the browser has something to transition from —
40
+ * the same pattern Modal uses for its entrance.
41
+ */
42
+ const [hasEntered, setHasEntered] = useState<boolean>(false);
43
+
44
+ /*
45
+ * Dismissal fades the card out first and only unmounts (and notifies the
46
+ * owner) once the fade has finished, so the toast never blinks away.
47
+ */
48
+ const [isLeaving, setIsLeaving] = useState<boolean>(false);
49
+
50
+ useEffect(() => {
51
+ const open: () => void = (): void => {
52
+ setHasEntered(true);
53
+ };
54
+
55
+ const frame: number = requestAnimationFrame(open);
56
+
57
+ /*
58
+ * A hidden or throttled tab never runs an animation frame; the timer
59
+ * skips the transition rather than leaving the toast at zero opacity.
60
+ */
61
+ const fallbackTimer: ReturnType<typeof setTimeout> = setTimeout(open, 80);
62
+
63
+ return () => {
64
+ cancelAnimationFrame(frame);
65
+ clearTimeout(fallbackTimer);
66
+ };
67
+ }, []);
68
+
69
+ /*
70
+ * The latest onClose lives in a ref so the exit effect can depend on
71
+ * isLeaving alone. Owners may recreate onClose every render, and a dep on
72
+ * it would restart the unmount timer whenever a sibling toast re-renders
73
+ * the stack mid-exit — leaving an invisible pointer-events-auto card
74
+ * intercepting clicks past its original deadline.
75
+ */
76
+ const onCloseRef: React.MutableRefObject<(() => void) | undefined> = useRef<
77
+ (() => void) | undefined
78
+ >(props.onClose);
79
+ onCloseRef.current = props.onClose;
80
+
81
+ useEffect(() => {
82
+ if (!isLeaving) {
83
+ return undefined;
84
+ }
85
+
86
+ const exitTimer: ReturnType<typeof setTimeout> = setTimeout(() => {
87
+ setShow(false);
88
+ if (onCloseRef.current) {
89
+ onCloseRef.current();
90
+ }
91
+ }, EXIT_DURATION_IN_MS);
92
+
93
+ return () => {
94
+ clearTimeout(exitTimer);
95
+ };
96
+ }, [isLeaving]);
97
+
28
98
  let typeCssClass: string = "text-gray-400";
29
99
  let iconType: IconProp = IconProp.Info;
30
100
 
@@ -53,65 +123,60 @@ const Component: FunctionComponent<ComponentProps> = (
53
123
  iconType = props.icon;
54
124
  }
55
125
 
56
- let top: number = 0;
126
+ /*
127
+ * Settled state carries no transform class at all — leaving a translate on
128
+ * the card would make it the containing block for position:fixed
129
+ * descendants (the Modal invariant).
130
+ */
131
+ let motionClassName: string = "translate-y-2 opacity-0";
57
132
 
58
- if (props.index) {
59
- top = props.index * 16; // move the second item lower than the first one. 16 is the height of the toast.
133
+ if (isLeaving) {
134
+ motionClassName = "opacity-0";
135
+ } else if (hasEntered) {
136
+ motionClassName = "opacity-100";
60
137
  }
61
138
 
62
139
  if (show) {
63
140
  return (
64
141
  <div
65
142
  data-testid="toast"
66
- aria-live="assertive"
67
- className={`pointer-events-none fixed z-40 top-${top} left-0 right-0 flex items-end px-4 py-6 sm:items-start sm:p-6`}
143
+ className={`pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5 transition duration-150 ease-out motion-reduce:transition-none ${motionClassName}`}
68
144
  >
69
- <div className="flex w-full flex-col items-center space-y-4 sm:items-end">
70
- <div className="pointer-events-auto w-full max-w-sm overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black ring-opacity-5">
71
- <div className="p-4">
72
- <div className="flex items-start">
73
- <div className="flex-shrink-0">
74
- <Icon
75
- className={`h-6 w-6 ${typeCssClass}`}
76
- data-testid="toast-icon"
77
- icon={iconType}
78
- />
79
- </div>
80
- <div className="ml-3 w-0 flex-1 pt-0.5">
81
- <p
82
- data-testid="title"
83
- className="text-sm font-medium text-gray-900"
84
- >
85
- {translateString(props.title)}
86
- </p>
87
- <p
88
- data-testid="description"
89
- className="mt-1 text-sm text-gray-500"
90
- >
91
- {translateString(props.description)}
92
- </p>
93
- {/* <div className="mt-3 flex space-x-7">
94
- <button type="button" className="rounded-md bg-white text-sm font-medium text-indigo-600 hover:text-indigo-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">Undo</button>
95
- <button type="button" className="rounded-md bg-white text-sm font-medium text-gray-700 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2">Dismiss</button>
96
- </div> */}
97
- </div>
98
- <div className="ml-4 flex flex-shrink-0">
99
- <button
100
- onClick={() => {
101
- setShow(false);
102
- if (props.onClose) {
103
- props.onClose();
104
- }
105
- }}
106
- data-testid="close-button"
107
- type="button"
108
- className="inline-flex rounded-md bg-white text-gray-400 hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
109
- >
110
- <span className="sr-only">Close</span>
111
- <Icon className={`h-5 w-5`} icon={IconProp.Close} />
112
- </button>
113
- </div>
114
- </div>
145
+ <div className="p-4">
146
+ <div className="flex items-start">
147
+ <div className="flex-shrink-0">
148
+ <Icon
149
+ className={`h-6 w-6 ${typeCssClass}`}
150
+ data-testid="toast-icon"
151
+ icon={iconType}
152
+ />
153
+ </div>
154
+ <div className="ml-3 w-0 flex-1 pt-0.5">
155
+ <p
156
+ data-testid="title"
157
+ className="text-sm font-medium text-gray-900"
158
+ >
159
+ {translateString(props.title)}
160
+ </p>
161
+ <p
162
+ data-testid="description"
163
+ className="mt-1 text-sm text-gray-500"
164
+ >
165
+ {translateString(props.description)}
166
+ </p>
167
+ </div>
168
+ <div className="ml-4 flex flex-shrink-0">
169
+ <button
170
+ onClick={() => {
171
+ setIsLeaving(true);
172
+ }}
173
+ data-testid="close-button"
174
+ type="button"
175
+ className="inline-flex rounded-md bg-white text-gray-400 transition-colors duration-150 ease-out hover:text-gray-500 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
176
+ >
177
+ <span className="sr-only">Close</span>
178
+ <Icon className={`h-5 w-5`} icon={IconProp.Close} />
179
+ </button>
115
180
  </div>
116
181
  </div>
117
182
  </div>
@@ -1,4 +1,9 @@
1
- import React, { FunctionComponent, ReactElement, useEffect } from "react";
1
+ import React, {
2
+ FunctionComponent,
3
+ ReactElement,
4
+ useEffect,
5
+ useRef,
6
+ } from "react";
2
7
  import Toast, { ComponentProps as ToastComponentProps } from "./Toast";
3
8
  import GlobalEvents from "../../Utils/GlobalEvents";
4
9
 
@@ -10,21 +15,60 @@ export const ShowToastNotification: ShowToastNotificationFunction = (
10
15
  GlobalEvents.dispatchEvent("toast", toast as any);
11
16
  };
12
17
 
18
+ /*
19
+ * Each queued toast gets a stable id so removals key correctly — keying by
20
+ * array index would re-key (and so re-mount and re-animate) every toast below
21
+ * the one that was dismissed.
22
+ */
23
+ interface ToastEntry {
24
+ id: number;
25
+ toast: ToastComponentProps;
26
+ /*
27
+ * Built once at dispatch and stable for the toast's lifetime: recreating
28
+ * onClose per render would hand every Toast a fresh prop on each stack
29
+ * re-render, which used to restart the exit-unmount timer of any toast
30
+ * mid-fade.
31
+ */
32
+ onClose: () => void;
33
+ }
34
+
13
35
  const ToastLayout: FunctionComponent = (): ReactElement => {
14
- const [currentToasts, setCurrentToasts] = React.useState<
15
- ToastComponentProps[]
16
- >([]);
36
+ const [currentToasts, setCurrentToasts] = React.useState<Array<ToastEntry>>(
37
+ [],
38
+ );
39
+ const nextToastIdRef: React.MutableRefObject<number> = useRef<number>(0);
17
40
 
18
- type AddToastNotificationFunction = (event: CustomEvent) => void;
41
+ useEffect(() => {
42
+ const addToastNotification: (event: CustomEvent) => void = (
43
+ event: CustomEvent,
44
+ ): void => {
45
+ const toast: ToastComponentProps = event.detail;
46
+ const id: number = nextToastIdRef.current;
47
+ nextToastIdRef.current += 1;
19
48
 
20
- const addToastNotification: AddToastNotificationFunction = (
21
- event: CustomEvent,
22
- ): void => {
23
- const toast: ToastComponentProps = event.detail;
24
- setCurrentToasts([...currentToasts, toast]);
25
- };
49
+ // setCurrentToasts is stable, so this closure never goes stale.
50
+ const onClose: () => void = (): void => {
51
+ if (toast.onClose) {
52
+ toast.onClose();
53
+ }
54
+
55
+ setCurrentToasts((toasts: Array<ToastEntry>) => {
56
+ return toasts.filter((candidate: ToastEntry) => {
57
+ return candidate.id !== id;
58
+ });
59
+ });
60
+ };
61
+
62
+ /*
63
+ * Functional update: this listener is registered once, so reading
64
+ * currentToasts from its closure would always see the mount-time empty
65
+ * array and every new toast would clobber the ones before it.
66
+ */
67
+ setCurrentToasts((toasts: Array<ToastEntry>) => {
68
+ return [...toasts, { id, toast, onClose }];
69
+ });
70
+ };
26
71
 
27
- useEffect(() => {
28
72
  GlobalEvents.addEventListener("toast", addToastNotification);
29
73
 
30
74
  return () => {
@@ -32,27 +76,33 @@ const ToastLayout: FunctionComponent = (): ReactElement => {
32
76
  };
33
77
  }, []);
34
78
 
79
+ /*
80
+ * ONE fixed container for every toast. Each toast used to render its own
81
+ * fixed strip at top-0 (the index prop that offset them was never passed),
82
+ * so stacked toasts painted on top of each other. A single region stacking
83
+ * cards with flex-col gap makes the order self-evident and keeps the
84
+ * z-index ladder in exactly one place (Toast z-40, under Modal z-50).
85
+ */
35
86
  return (
36
- <div>
37
- {currentToasts.map((toast: ToastComponentProps, index: number) => {
38
- return (
39
- <Toast
40
- key={index}
41
- title={toast.title}
42
- description={toast.description}
43
- type={toast.type}
44
- onClose={() => {
45
- if (toast.onClose) {
46
- toast.onClose();
47
- }
48
-
49
- const newToasts: Array<ToastComponentProps> = [...currentToasts];
50
- newToasts.splice(index, 1);
51
- setCurrentToasts(newToasts);
52
- }}
53
- />
54
- );
55
- })}
87
+ <div
88
+ data-testid="toast-region"
89
+ aria-live="assertive"
90
+ className="pointer-events-none fixed z-40 top-0 left-0 right-0 flex items-end px-4 py-6 sm:items-start sm:p-6"
91
+ >
92
+ <div className="flex w-full flex-col items-center gap-4 sm:items-end">
93
+ {currentToasts.map((entry: ToastEntry) => {
94
+ return (
95
+ <Toast
96
+ key={entry.id}
97
+ title={entry.toast.title}
98
+ description={entry.toast.description}
99
+ type={entry.toast.type}
100
+ icon={entry.toast.icon}
101
+ onClose={entry.onClose}
102
+ />
103
+ );
104
+ })}
105
+ </div>
56
106
  </div>
57
107
  );
58
108
  };
@@ -127,6 +127,7 @@ html.dark [class~="!bg-white"] {
127
127
 
128
128
  html.dark :is(
129
129
  [class~="bg-white/60"],
130
+ [class~="bg-white/70"],
130
131
  [class~="bg-white/80"],
131
132
  [class~="bg-white/90"],
132
133
  [class~="bg-white/95"]
@@ -204,6 +205,14 @@ html.dark [class~="bg-gray-900/5"] {
204
205
  background-color: rgb(148 163 184 / 12%);
205
206
  }
206
207
 
208
+ /*
209
+ * Overlay scrims built from a mid-gray: literal gray-500 at 25% paints a LIGHT
210
+ * veil over a dark page, so the command palette backdrop deepens instead.
211
+ */
212
+ html.dark [class~="bg-gray-500/25"] {
213
+ background-color: rgb(2 6 23 / 55%);
214
+ }
215
+
207
216
  /* State variants that otherwise flash back to literal light Tailwind colors. */
208
217
  html.dark :is(
209
218
  [class~="hover:bg-gray-50"],
@@ -1340,3 +1349,34 @@ html.dark :fullscreen,
1340
1349
  html.dark ::backdrop {
1341
1350
  background-color: var(--ou-background-primary);
1342
1351
  }
1352
+
1353
+ /*
1354
+ * Motion. Tailwind here is the Play-CDN runtime configured inline per app, so
1355
+ * a new animate-* utility name would silently generate nothing unless its
1356
+ * keyframes were duplicated into every EJS config. Plain CSS in this one
1357
+ * shared stylesheet sidesteps that entirely.
1358
+ *
1359
+ * ou-animate-pop-in exists for surfaces that MOUNT already open (react-select
1360
+ * portals its menu fully formed), where a transition has no closed state to
1361
+ * start from. It is an animation, so it ends by reverting to the element's
1362
+ * own style — no transform lingers to become a containing block for
1363
+ * position:fixed descendants. Surfaces that control their own mount use the
1364
+ * Modal hasEntered transition pattern instead.
1365
+ */
1366
+ @keyframes ou-pop-in {
1367
+ from {
1368
+ opacity: 0;
1369
+ transform: scale(0.98);
1370
+ }
1371
+
1372
+ to {
1373
+ opacity: 1;
1374
+ transform: scale(1);
1375
+ }
1376
+ }
1377
+
1378
+ @media (prefers-reduced-motion: no-preference) {
1379
+ .ou-animate-pop-in {
1380
+ animation: ou-pop-in 120ms ease-out;
1381
+ }
1382
+ }
@@ -347,19 +347,29 @@ export default class ModelAPI {
347
347
  !requestOptions.isMultiTenantRequest ||
348
348
  Object.keys(requestOptions).length === 0
349
349
  ) {
350
- const project: Project | null = ProjectUtil.getCurrentProject();
351
-
352
- if (project && project.id) {
353
- headers["tenantid"] = project.id.toString();
350
+ /*
351
+ * Read the tenant id via getCurrentProjectId() first - a plain string
352
+ * read off the URL/SessionStorage/LocalStorage id keys. This is what
353
+ * makes requests work in the SSO-login window where the project ID is
354
+ * already available in URL/SessionStorage but the full project data
355
+ * hasn't been fetched yet, and it avoids hydrating the entire Project
356
+ * model from LocalStorage on every single request just for the id.
357
+ */
358
+ const projectId: ObjectID | null = ProjectUtil.getCurrentProjectId();
359
+
360
+ if (projectId) {
361
+ headers["tenantid"] = projectId.toString();
354
362
  } else {
355
363
  /*
356
- * Fallback to getCurrentProjectId() when full project data is not yet loaded
357
- * This can happen after SSO login when the project ID is available in URL/SessionStorage
358
- * but the full project data hasn't been fetched yet
364
+ * Fallback to the stored project. getCurrentProject() resolves its id
365
+ * through getCurrentProjectId() too, so this only matters if that
366
+ * resolution ever diverges - kept to preserve the historical fallback
367
+ * chain.
359
368
  */
360
- const projectId: ObjectID | null = ProjectUtil.getCurrentProjectId();
361
- if (projectId) {
362
- headers["tenantid"] = projectId.toString();
369
+ const project: Project | null = ProjectUtil.getCurrentProject();
370
+
371
+ if (project && project.id) {
372
+ headers["tenantid"] = project.id.toString();
363
373
  }
364
374
  }
365
375
  }
@@ -0,0 +1,188 @@
1
+ import ListResult from "../../Types/BaseDatabase/ListResult";
2
+ import Query from "../../Types/BaseDatabase/Query";
3
+ import Select from "../../Types/BaseDatabase/Select";
4
+ import Sort from "../../Types/BaseDatabase/Sort";
5
+ import Dictionary from "../../Types/Dictionary";
6
+ import { JSONObject } from "../../Types/JSON";
7
+ import JSONFunctions from "../../Types/JSONFunctions";
8
+ import ObjectID from "../../Types/ObjectID";
9
+ import BaseModel from "../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
10
+ import ModelAPI, { RequestOptions } from "./ModelAPI/ModelAPI";
11
+
12
+ /*
13
+ * A tiny read-through cache for reference-data lists (incident states, alert
14
+ * states, custom-field definitions, ...): tables that hold a handful of rows
15
+ * per project and change approximately never, yet are fetched independently by
16
+ * every component that needs them - the Home view alone used to request the
17
+ * IncidentState list three times.
18
+ *
19
+ * Modeled on GlobalConfigUtil (./GlobalConfig.ts): a module-level cache plus
20
+ * in-flight promise dedup, so concurrent callers share one request and
21
+ * callers within the TTL share one response. Entries are keyed by the model's
22
+ * table name, the project id and the serialized query/select/sort/paging, so
23
+ * different projects and different shapes of the same list never collide.
24
+ *
25
+ * Callers share the returned ListResult (and the model instances inside it) -
26
+ * treat it as read-only and copy before mutating.
27
+ *
28
+ * Invalidation: the key carries the project id, so a project switch can never
29
+ * be served another project's rows even before anything is invalidated; the
30
+ * 60-second TTL bounds staleness after someone edits the underlying rows in
31
+ * settings. Screens that edit reference data and need to see the change
32
+ * immediately should call invalidate(modelType) on success.
33
+ */
34
+
35
+ const TTL_IN_MS: number = 60 * 1000;
36
+
37
+ interface CacheEntry {
38
+ tableName: string;
39
+ expiresAt: number;
40
+ result: ListResult<BaseModel>;
41
+ }
42
+
43
+ interface InFlightEntry {
44
+ tableName: string;
45
+ promise: Promise<ListResult<BaseModel>>;
46
+ }
47
+
48
+ export default class ModelListCache {
49
+ private static cache: Dictionary<CacheEntry> = {};
50
+ private static inFlight: Dictionary<InFlightEntry> = {};
51
+
52
+ public static async getList<TBaseModel extends BaseModel>(data: {
53
+ modelType: { new (): TBaseModel };
54
+ query: Query<TBaseModel>;
55
+ limit: number;
56
+ skip: number;
57
+ select: Select<TBaseModel>;
58
+ sort: Sort<TBaseModel>;
59
+ projectId?: ObjectID | null | undefined;
60
+ requestOptions?: RequestOptions | undefined;
61
+ }): Promise<ListResult<TBaseModel>> {
62
+ const tableName: string = new data.modelType().tableName || "";
63
+ const key: string = ModelListCache.buildKey({
64
+ tableName: tableName,
65
+ projectId: data.projectId,
66
+ query: data.query,
67
+ select: data.select,
68
+ sort: data.sort,
69
+ skip: data.skip,
70
+ limit: data.limit,
71
+ requestOptions: data.requestOptions,
72
+ });
73
+
74
+ const cached: CacheEntry | undefined = ModelListCache.cache[key];
75
+
76
+ if (cached) {
77
+ if (cached.expiresAt > Date.now()) {
78
+ return cached.result as ListResult<TBaseModel>;
79
+ }
80
+
81
+ delete ModelListCache.cache[key];
82
+ }
83
+
84
+ const existing: InFlightEntry | undefined = ModelListCache.inFlight[key];
85
+
86
+ if (existing) {
87
+ return existing.promise as Promise<ListResult<TBaseModel>>;
88
+ }
89
+
90
+ const promise: Promise<ListResult<TBaseModel>> =
91
+ ModelAPI.getList<TBaseModel>({
92
+ modelType: data.modelType,
93
+ query: data.query,
94
+ limit: data.limit,
95
+ skip: data.skip,
96
+ select: data.select,
97
+ sort: data.sort,
98
+ ...(data.requestOptions ? { requestOptions: data.requestOptions } : {}),
99
+ });
100
+
101
+ const entry: InFlightEntry = {
102
+ tableName: tableName,
103
+ promise: promise as Promise<ListResult<BaseModel>>,
104
+ };
105
+
106
+ ModelListCache.inFlight[key] = entry;
107
+
108
+ try {
109
+ const result: ListResult<TBaseModel> = await promise;
110
+
111
+ /*
112
+ * Only cache while this request is still the current one for its key -
113
+ * an invalidate() that ran mid-flight must not have its effect undone
114
+ * by a stale response landing afterwards. (Failures are never cached:
115
+ * the next caller simply issues a fresh request.)
116
+ */
117
+ if (ModelListCache.inFlight[key] === entry) {
118
+ ModelListCache.cache[key] = {
119
+ tableName: tableName,
120
+ expiresAt: Date.now() + TTL_IN_MS,
121
+ result: result as ListResult<BaseModel>,
122
+ };
123
+ }
124
+
125
+ return result;
126
+ } finally {
127
+ if (ModelListCache.inFlight[key] === entry) {
128
+ delete ModelListCache.inFlight[key];
129
+ }
130
+ }
131
+ }
132
+
133
+ // Drop every entry for one model type, or everything when none is given.
134
+ public static invalidate(modelType?: { new (): BaseModel }): void {
135
+ if (!modelType) {
136
+ ModelListCache.invalidateAll();
137
+ return;
138
+ }
139
+
140
+ const tableName: string = new modelType().tableName || "";
141
+
142
+ for (const key of Object.keys(ModelListCache.cache)) {
143
+ if (ModelListCache.cache[key]?.tableName === tableName) {
144
+ delete ModelListCache.cache[key];
145
+ }
146
+ }
147
+
148
+ for (const key of Object.keys(ModelListCache.inFlight)) {
149
+ if (ModelListCache.inFlight[key]?.tableName === tableName) {
150
+ delete ModelListCache.inFlight[key];
151
+ }
152
+ }
153
+ }
154
+
155
+ // Call on project switch (and logout): the next reads refetch everything.
156
+ public static invalidateAll(): void {
157
+ ModelListCache.cache = {};
158
+ ModelListCache.inFlight = {};
159
+ }
160
+
161
+ private static buildKey(data: {
162
+ tableName: string;
163
+ projectId?: ObjectID | null | undefined;
164
+ query: Query<BaseModel>;
165
+ select: Select<BaseModel>;
166
+ sort: Sort<BaseModel>;
167
+ skip: number;
168
+ limit: number;
169
+ requestOptions?: RequestOptions | undefined;
170
+ }): string {
171
+ /*
172
+ * JSONFunctions.serialize is the same serialization ModelAPI sends over
173
+ * the wire, so two requests get one key exactly when the server would see
174
+ * the same request body. Key order inside the literals is stable because
175
+ * call sites are static object literals.
176
+ */
177
+ return JSON.stringify({
178
+ tableName: data.tableName,
179
+ projectId: data.projectId?.toString() || "",
180
+ query: JSONFunctions.serialize(data.query as JSONObject),
181
+ select: JSONFunctions.serialize(data.select as JSONObject),
182
+ sort: JSONFunctions.serialize(data.sort as JSONObject),
183
+ skip: data.skip,
184
+ limit: data.limit,
185
+ url: data.requestOptions?.overrideRequestUrl?.toString() || "",
186
+ });
187
+ }
188
+ }
@@ -10,6 +10,7 @@ import Project from "../../Models/DatabaseModels/Project";
10
10
  import SubscriptionStatus, {
11
11
  SubscriptionStatusUtil,
12
12
  } from "../../Types/Billing/SubscriptionStatus";
13
+ import ModelListCache from "./ModelListCache";
13
14
  import Navigation from "./Navigation";
14
15
  import SessionStorage from "./SessionStorage";
15
16
  import Telemetry from "./Telemetry/Telemetry";
@@ -278,12 +279,37 @@ export default class ProjectUtil {
278
279
  public static setCurrentProject(project: JSONObject | Project): void {
279
280
  const currentProjectId: string | undefined =
280
281
  project._id?.toString() || this.getCurrentProjectId()?.toString();
282
+
283
+ /*
284
+ * What this tab was showing BEFORE this call, read straight off session
285
+ * storage (not getCurrentProjectId(), whose URL fallback may already
286
+ * carry the NEW project mid-switch) so it can be compared after the
287
+ * overwrite below.
288
+ */
289
+ const previousProjectId: string | undefined = this.toProjectId(
290
+ SessionStorage.getItem(CURRENT_PROJECT_ID_STORAGE_KEY),
291
+ )?.toString();
292
+
281
293
  if (project instanceof Project) {
282
294
  project = BaseModel.toJSON(project, Project);
283
295
  }
284
296
  LocalStorage.setItem(`project_${currentProjectId}`, project);
285
297
  SessionStorage.setItem(CURRENT_PROJECT_ID_STORAGE_KEY, currentProjectId);
286
298
 
299
+ /*
300
+ * Cached reference lists (incident/alert states, custom fields...) are
301
+ * keyed by project id, so a switch could never serve another project's
302
+ * rows — invalidation just guarantees fresh reads and frees the old
303
+ * entries now that project selection can happen without a full page
304
+ * reload. Only on an actual CHANGE though: setCurrentProject also runs
305
+ * on every boot, in the same commit as the Header/Home mounts whose
306
+ * reference-list requests are already in flight, and wiping the cache
307
+ * then would discard its very first fill.
308
+ */
309
+ if (previousProjectId !== currentProjectId) {
310
+ ModelListCache.invalidateAll();
311
+ }
312
+
287
313
  // Remember this project for the next time the user opens the dashboard.
288
314
  this.setLastAccessedProjectId(currentProjectId);
289
315
 
@@ -303,6 +329,9 @@ export default class ProjectUtil {
303
329
 
304
330
  SessionStorage.removeItem(CURRENT_PROJECT_ID_STORAGE_KEY);
305
331
 
332
+ // Project-scoped cached reference lists must not outlive the project.
333
+ ModelListCache.invalidateAll();
334
+
306
335
  /*
307
336
  * The project is gone (or the user is leaving it), so it must not be
308
337
  * reopened the next time the dashboard loads.