@oneuptime/common 12.0.13 → 12.0.15

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 (561) hide show
  1. package/Models/DatabaseModels/GlobalOidc.ts +20 -0
  2. package/Models/DatabaseModels/GlobalSso.ts +20 -0
  3. package/Models/DatabaseModels/MarketingConversion.ts +19 -9
  4. package/Models/DatabaseModels/NetworkDeviceLinkRule.ts +46 -0
  5. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
  6. package/Models/DatabaseModels/StatusPage.ts +7 -4
  7. package/Models/DatabaseModels/UserCall.ts +94 -3
  8. package/Models/DatabaseModels/UserEmail.ts +94 -3
  9. package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
  10. package/Models/DatabaseModels/UserPush.ts +37 -0
  11. package/Models/DatabaseModels/UserSMS.ts +94 -3
  12. package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
  13. package/Server/API/BaseAPI.ts +79 -14
  14. package/Server/API/StatusPageAPI.ts +29 -4
  15. package/Server/API/UserCallAPI.ts +53 -45
  16. package/Server/API/UserEmailAPI.ts +53 -44
  17. package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
  18. package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
  19. package/Server/API/UserPushAPI.ts +126 -2
  20. package/Server/API/UserSmsAPI.ts +53 -44
  21. package/Server/API/UserWhatsAppAPI.ts +53 -50
  22. package/Server/EnvironmentConfig.ts +7 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.ts +19 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.ts +40 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  29. package/Server/Middleware/SlackAuthorization.ts +43 -6
  30. package/Server/Middleware/UserAuthorization.ts +236 -26
  31. package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
  32. package/Server/Middleware/WhatsAppAuthorization.ts +43 -3
  33. package/Server/Services/AnalyticsDatabaseService.ts +169 -0
  34. package/Server/Services/DatabaseService.ts +101 -0
  35. package/Server/Services/GlobalOidcProjectService.ts +126 -1
  36. package/Server/Services/GlobalOidcService.ts +132 -0
  37. package/Server/Services/GlobalSsoProjectService.ts +126 -1
  38. package/Server/Services/GlobalSsoService.ts +132 -0
  39. package/Server/Services/LogAggregationService.ts +5 -0
  40. package/Server/Services/PushNotificationService.ts +127 -12
  41. package/Server/Services/TeamMemberService.ts +53 -13
  42. package/Server/Services/UserCallService.ts +55 -24
  43. package/Server/Services/UserEmailService.ts +83 -17
  44. package/Server/Services/UserIncomingCallNumberService.ts +49 -85
  45. package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
  46. package/Server/Services/UserNotificationRuleService.ts +26 -0
  47. package/Server/Services/UserPushService.ts +89 -0
  48. package/Server/Services/UserSmsService.ts +50 -17
  49. package/Server/Services/UserWhatsAppService.ts +48 -15
  50. package/Server/Types/Database/QueryHelper.ts +30 -0
  51. package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
  52. package/Server/Utils/ChannelVerification.ts +510 -0
  53. package/Server/Utils/CronTab.ts +73 -0
  54. package/Server/Utils/GlobalSsoAuthorization.ts +175 -0
  55. package/Server/Utils/Marketing/ConversionUploadProvider.ts +35 -5
  56. package/Server/Utils/Marketing/Providers/GoogleAds.ts +1 -1
  57. package/Server/Utils/Marketing/Providers/LinkedIn.ts +1 -1
  58. package/Server/Utils/Marketing/Providers/Meta.ts +1 -1
  59. package/Server/Utils/Marketing/Providers/MicrosoftAds.ts +1 -1
  60. package/Server/Utils/Marketing/Providers/Reddit.ts +1 -1
  61. package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +48 -33
  62. package/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.ts +35 -30
  63. package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +33 -28
  64. package/Server/Utils/Monitor/Criteria/EvaluateOverTime.ts +475 -47
  65. package/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.ts +35 -30
  66. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +47 -44
  67. package/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.ts +33 -28
  68. package/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.ts +69 -40
  69. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +35 -29
  70. package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
  71. package/Server/Utils/Monitor/MonitorCriteriaEvaluator.ts +8 -0
  72. package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
  73. package/Server/Utils/Monitor/MonitorResource.ts +161 -21
  74. package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
  75. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
  76. package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
  77. package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
  78. package/Server/Utils/StatusPageContentSecurityPolicy.ts +56 -0
  79. package/Server/Utils/StatusPageCustomizationAccess.ts +117 -0
  80. package/Server/Utils/TotpAuth.ts +137 -9
  81. package/Server/Utils/UserRegistrationToken.ts +182 -0
  82. package/Server/Utils/VerificationCode.ts +134 -0
  83. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
  84. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
  85. package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
  86. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
  87. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
  88. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +28 -0
  89. package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
  90. package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
  91. package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
  92. package/Tests/Server/API/StatusPageCustomizationOrigin.test.ts +348 -0
  93. package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
  94. package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
  95. package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
  96. package/Tests/Server/API/UserSmsApi.test.ts +107 -14
  97. package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
  98. package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +265 -0
  99. package/Tests/Server/Infrastructure/Postgres/SchemaMigrationsOrdering.test.ts +227 -0
  100. package/Tests/Server/Middleware/SlackAuthorization.test.ts +149 -0
  101. package/Tests/Server/Middleware/UserAuthorization.test.ts +27 -13
  102. package/Tests/Server/Middleware/UserAuthorizationGlobalSsoGovernance.test.ts +1455 -0
  103. package/Tests/Server/Middleware/UserAuthorizationSSOProvider.test.ts +91 -2
  104. package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
  105. package/Tests/Server/Middleware/WhatsAppAuthorization.test.ts +233 -0
  106. package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +10 -62
  107. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
  108. package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
  109. package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
  110. package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
  111. package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
  112. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
  113. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +21 -8
  114. package/Tests/Server/Services/GlobalSsoProviderAuthorization.test.ts +1242 -0
  115. package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
  116. package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
  117. package/Tests/Server/Services/MonitorResourceProbeAgreementHydration.test.ts +459 -0
  118. package/Tests/Server/Services/MonitorResourceProbeAgreementReuse.test.ts +10 -0
  119. package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
  120. package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
  121. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
  122. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
  123. package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
  124. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
  125. package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
  126. package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
  127. package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
  128. package/Tests/Server/Types/AnalyticsDatabase/AggregateUtilBucketTimestamp.test.ts +416 -0
  129. package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
  130. package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
  131. package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
  132. package/Tests/Server/Types/Database/QueryHelperManyToManyAndEmptyValues.test.ts +551 -0
  133. package/Tests/Server/Types/Database/SelectUtil.test.ts +348 -0
  134. package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
  135. package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
  136. package/Tests/Server/Utils/Browser.test.ts +162 -0
  137. package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
  138. package/Tests/Server/Utils/CronTab.test.ts +116 -0
  139. package/Tests/Server/Utils/Express.test.ts +371 -0
  140. package/Tests/Server/Utils/GlobalSSOToken.test.ts +581 -0
  141. package/Tests/Server/Utils/GlobalSsoAuthorization.test.ts +1401 -0
  142. package/Tests/Server/Utils/Marketing/AdUploadableConversionTypes.test.ts +254 -0
  143. package/Tests/Server/Utils/Marketing/ConversionUploadProvider.test.ts +1 -1
  144. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaEvaluateOverTime.test.ts +508 -0
  145. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +30 -9
  146. package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
  147. package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
  148. package/Tests/Server/Utils/Monitor/Criteria/EvaluateOverTime.test.ts +987 -0
  149. package/Tests/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.test.ts +916 -0
  150. package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
  151. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
  152. package/Tests/Server/Utils/Monitor/Criteria/ProfileMonitorCriteria.test.ts +382 -0
  153. package/Tests/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.test.ts +1219 -0
  154. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
  155. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
  156. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
  157. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
  158. package/Tests/Server/Utils/Monitor/MonitorResourceIngestedStepSelection.test.ts +86 -0
  159. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
  160. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
  161. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
  162. package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
  163. package/Tests/Server/Utils/StatusPageContentSecurityPolicy.test.ts +136 -0
  164. package/Tests/Server/Utils/StatusPageCustomizationAccess.test.ts +223 -0
  165. package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
  166. package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
  167. package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
  168. package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
  169. package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
  170. package/Tests/Types/Call/CallRequest.test.ts +189 -0
  171. package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
  172. package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
  173. package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
  174. package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
  175. package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
  176. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
  177. package/Tests/Types/Monitor/MonitorStepConfigHelpers.test.ts +165 -0
  178. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
  179. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
  180. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
  181. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
  182. package/Tests/Types/NetworkDevice/NetworkDeviceLinkRuleScope.test.ts +215 -0
  183. package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
  184. package/Tests/Types/TextRandomGeneration.test.ts +211 -0
  185. package/Tests/UI/Components/Button.test.tsx +175 -1
  186. package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
  187. package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
  188. package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
  189. package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
  190. package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
  191. package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
  192. package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
  193. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
  194. package/Tests/UI/Components/Forms/FormSubmitAnalytics.test.tsx +206 -0
  195. package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
  196. package/Tests/UI/Components/List.test.tsx +9 -2
  197. package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
  198. package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
  199. package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
  200. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
  201. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
  202. package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
  203. package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
  204. package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
  205. package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
  206. package/Tests/UI/Components/Skeleton.test.tsx +71 -0
  207. package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
  208. package/Tests/UI/Components/Tabs.test.tsx +24 -0
  209. package/Tests/UI/Components/Toast.test.tsx +130 -7
  210. package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
  211. package/Tests/UI/Utils/AIChatExport/ConversationMarkdown.test.ts +774 -0
  212. package/Tests/UI/Utils/AIChatExport/MarkdownBlocks.test.ts +791 -0
  213. package/Tests/UI/Utils/AIChatExport/MarkdownSafety.test.ts +544 -0
  214. package/Tests/UI/Utils/Dropdown.test.ts +423 -0
  215. package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
  216. package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
  217. package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
  218. package/Tests/Utils/API.test.ts +16 -2
  219. package/Tests/Utils/Analytics.test.ts +187 -0
  220. package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
  221. package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
  222. package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
  223. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +80 -0
  224. package/Tests/Utils/Monitor/NetworkDeviceLinkRuleUtil.test.ts +1291 -0
  225. package/Tests/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.test.ts +214 -0
  226. package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
  227. package/Types/Email/EmailTemplateType.ts +1 -0
  228. package/Types/Marketing/MarketingConversion.ts +12 -0
  229. package/Types/Monitor/CriteriaFilter.ts +9 -0
  230. package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
  231. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
  232. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
  233. package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
  234. package/Types/NetworkDevice/NetworkDeviceLinkRuleScope.ts +51 -0
  235. package/Types/Permission.ts +35 -0
  236. package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
  237. package/Types/PushNotification/PushNotificationMessage.ts +15 -0
  238. package/Types/PushNotification/PushNotificationRequest.ts +8 -16
  239. package/Types/Service/ServiceLanguage.ts +144 -0
  240. package/Types/Text.ts +111 -19
  241. package/UI/Components/Button/Button.tsx +27 -14
  242. package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
  243. package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
  244. package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
  245. package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
  246. package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
  247. package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
  248. package/UI/Components/CommandPalette/Types.ts +49 -0
  249. package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
  250. package/UI/Components/Dropdown/Dropdown.tsx +6 -1
  251. package/UI/Components/Feed/FeedItem.tsx +1 -1
  252. package/UI/Components/FormModal/BasicFormModal.tsx +12 -0
  253. package/UI/Components/Forms/BasicForm.tsx +13 -1
  254. package/UI/Components/Forms/BasicModelForm.tsx +2 -1
  255. package/UI/Components/Forms/ModelForm.tsx +10 -1
  256. package/UI/Components/Forms/Utils/FormAnalyticsName.ts +39 -0
  257. package/UI/Components/List/List.tsx +37 -5
  258. package/UI/Components/List/ListSkeleton.tsx +54 -0
  259. package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +6 -1
  260. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
  261. package/UI/Components/Modal/Modal.tsx +2 -2
  262. package/UI/Components/ModelFormModal/ModelFormModal.tsx +6 -1
  263. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  264. package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
  265. package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
  266. package/UI/Components/Navbar/NavBar.tsx +14 -1
  267. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
  268. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
  269. package/UI/Components/SideOver/SideOver.tsx +37 -2
  270. package/UI/Components/Skeleton/Skeleton.tsx +53 -0
  271. package/UI/Components/Table/Table.tsx +74 -44
  272. package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
  273. package/UI/Components/Tabs/Tab.tsx +1 -1
  274. package/UI/Components/Toast/Toast.tsx +118 -53
  275. package/UI/Components/Toast/ToastInit.tsx +82 -32
  276. package/UI/Styles/Theme.css +40 -0
  277. package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
  278. package/UI/Utils/ModelListCache.ts +188 -0
  279. package/UI/Utils/Project.ts +29 -0
  280. package/Utils/API.ts +6 -1
  281. package/Utils/Analytics.ts +55 -2
  282. package/Utils/Monitor/MonitorMetricType.ts +40 -0
  283. package/Utils/Monitor/NetworkDeviceLinkRuleUtil.ts +587 -37
  284. package/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.ts +115 -0
  285. package/build/dist/Models/DatabaseModels/GlobalOidc.js +21 -0
  286. package/build/dist/Models/DatabaseModels/GlobalOidc.js.map +1 -1
  287. package/build/dist/Models/DatabaseModels/GlobalSso.js +21 -0
  288. package/build/dist/Models/DatabaseModels/GlobalSso.js.map +1 -1
  289. package/build/dist/Models/DatabaseModels/MarketingConversion.js +20 -10
  290. package/build/dist/Models/DatabaseModels/MarketingConversion.js.map +1 -1
  291. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js +47 -0
  292. package/build/dist/Models/DatabaseModels/NetworkDeviceLinkRule.js.map +1 -1
  293. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
  294. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  295. package/build/dist/Models/DatabaseModels/StatusPage.js +4 -4
  296. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  297. package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
  298. package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
  299. package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
  300. package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
  301. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
  302. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
  303. package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
  304. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  305. package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
  306. package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
  307. package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
  308. package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
  309. package/build/dist/Server/API/BaseAPI.js +69 -13
  310. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  311. package/build/dist/Server/API/StatusPageAPI.js +25 -4
  312. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  313. package/build/dist/Server/API/UserCallAPI.js +42 -38
  314. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  315. package/build/dist/Server/API/UserEmailAPI.js +42 -38
  316. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  317. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
  318. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
  319. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
  320. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
  321. package/build/dist/Server/API/UserPushAPI.js +95 -2
  322. package/build/dist/Server/API/UserPushAPI.js.map +1 -1
  323. package/build/dist/Server/API/UserSmsAPI.js +42 -38
  324. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  325. package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
  326. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  327. package/build/dist/Server/EnvironmentConfig.js +6 -0
  328. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  329. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
  330. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
  331. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
  332. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
  333. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
  334. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
  335. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js +12 -0
  336. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787800000000-AddScopeToNetworkDeviceLinkRule.js.map +1 -0
  337. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js +29 -0
  338. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787900000000-AddRestrictToAttachedProjectsToGlobalSso.js.map +1 -0
  339. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  340. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  341. package/build/dist/Server/Middleware/SlackAuthorization.js +28 -4
  342. package/build/dist/Server/Middleware/SlackAuthorization.js.map +1 -1
  343. package/build/dist/Server/Middleware/UserAuthorization.js +197 -22
  344. package/build/dist/Server/Middleware/UserAuthorization.js.map +1 -1
  345. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
  346. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
  347. package/build/dist/Server/Middleware/WhatsAppAuthorization.js +32 -2
  348. package/build/dist/Server/Middleware/WhatsAppAuthorization.js.map +1 -1
  349. package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
  350. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  351. package/build/dist/Server/Services/DatabaseService.js +74 -0
  352. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  353. package/build/dist/Server/Services/GlobalOidcProjectService.js +105 -0
  354. package/build/dist/Server/Services/GlobalOidcProjectService.js.map +1 -1
  355. package/build/dist/Server/Services/GlobalOidcService.js +127 -0
  356. package/build/dist/Server/Services/GlobalOidcService.js.map +1 -1
  357. package/build/dist/Server/Services/GlobalSsoProjectService.js +105 -0
  358. package/build/dist/Server/Services/GlobalSsoProjectService.js.map +1 -1
  359. package/build/dist/Server/Services/GlobalSsoService.js +127 -0
  360. package/build/dist/Server/Services/GlobalSsoService.js.map +1 -1
  361. package/build/dist/Server/Services/LogAggregationService.js +5 -0
  362. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  363. package/build/dist/Server/Services/PushNotificationService.js +69 -30
  364. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  365. package/build/dist/Server/Services/TeamMemberService.js +43 -7
  366. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  367. package/build/dist/Server/Services/UserCallService.js +54 -22
  368. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  369. package/build/dist/Server/Services/UserEmailService.js +78 -17
  370. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  371. package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
  372. package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
  373. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
  374. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
  375. package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
  376. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  377. package/build/dist/Server/Services/UserPushService.js +77 -0
  378. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  379. package/build/dist/Server/Services/UserSmsService.js +50 -17
  380. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  381. package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
  382. package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
  383. package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
  384. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  385. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
  386. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
  387. package/build/dist/Server/Utils/ChannelVerification.js +348 -0
  388. package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
  389. package/build/dist/Server/Utils/CronTab.js +66 -0
  390. package/build/dist/Server/Utils/CronTab.js.map +1 -1
  391. package/build/dist/Server/Utils/GlobalSsoAuthorization.js +112 -0
  392. package/build/dist/Server/Utils/GlobalSsoAuthorization.js.map +1 -0
  393. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js +17 -1
  394. package/build/dist/Server/Utils/Marketing/ConversionUploadProvider.js.map +1 -1
  395. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js +1 -1
  396. package/build/dist/Server/Utils/Marketing/Providers/GoogleAds.js.map +1 -1
  397. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js +1 -1
  398. package/build/dist/Server/Utils/Marketing/Providers/LinkedIn.js.map +1 -1
  399. package/build/dist/Server/Utils/Marketing/Providers/Meta.js +1 -1
  400. package/build/dist/Server/Utils/Marketing/Providers/Meta.js.map +1 -1
  401. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js +1 -1
  402. package/build/dist/Server/Utils/Marketing/Providers/MicrosoftAds.js.map +1 -1
  403. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js +1 -1
  404. package/build/dist/Server/Utils/Marketing/Providers/Reddit.js.map +1 -1
  405. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +37 -35
  406. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
  407. package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js +21 -25
  408. package/build/dist/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.js.map +1 -1
  409. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +20 -22
  410. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
  411. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js +370 -42
  412. package/build/dist/Server/Utils/Monitor/Criteria/EvaluateOverTime.js.map +1 -1
  413. package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js +21 -25
  414. package/build/dist/Server/Utils/Monitor/Criteria/ExternalStatusPageMonitorCriteria.js.map +1 -1
  415. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +34 -37
  416. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  417. package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js +21 -25
  418. package/build/dist/Server/Utils/Monitor/Criteria/SSLMonitorCriteria.js.map +1 -1
  419. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js +64 -52
  420. package/build/dist/Server/Utils/Monitor/Criteria/ServerMonitorCriteria.js.map +1 -1
  421. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +25 -29
  422. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  423. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
  424. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  425. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js +8 -0
  426. package/build/dist/Server/Utils/Monitor/MonitorCriteriaEvaluator.js.map +1 -1
  427. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
  428. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  429. package/build/dist/Server/Utils/Monitor/MonitorResource.js +123 -23
  430. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  431. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
  432. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
  433. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
  434. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
  435. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
  436. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
  437. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  438. package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js +39 -0
  439. package/build/dist/Server/Utils/StatusPageContentSecurityPolicy.js.map +1 -0
  440. package/build/dist/Server/Utils/StatusPageCustomizationAccess.js +85 -0
  441. package/build/dist/Server/Utils/StatusPageCustomizationAccess.js.map +1 -0
  442. package/build/dist/Server/Utils/TotpAuth.js +127 -8
  443. package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
  444. package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
  445. package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
  446. package/build/dist/Server/Utils/VerificationCode.js +120 -0
  447. package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
  448. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  449. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  450. package/build/dist/Types/Marketing/MarketingConversion.js +10 -0
  451. package/build/dist/Types/Marketing/MarketingConversion.js.map +1 -1
  452. package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
  453. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  454. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
  455. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  456. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
  457. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  458. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
  459. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  460. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
  461. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
  462. package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js +46 -0
  463. package/build/dist/Types/NetworkDevice/NetworkDeviceLinkRuleScope.js.map +1 -0
  464. package/build/dist/Types/Permission.js +33 -0
  465. package/build/dist/Types/Permission.js.map +1 -1
  466. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
  467. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
  468. package/build/dist/Types/Service/ServiceLanguage.js +96 -0
  469. package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
  470. package/build/dist/Types/Text.js +82 -17
  471. package/build/dist/Types/Text.js.map +1 -1
  472. package/build/dist/UI/Components/Button/Button.js +22 -14
  473. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  474. package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
  475. package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
  476. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
  477. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
  478. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
  479. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
  480. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
  481. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
  482. package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
  483. package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
  484. package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
  485. package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
  486. package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
  487. package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
  488. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
  489. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
  490. package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
  491. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  492. package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
  493. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  494. package/build/dist/UI/Components/FormModal/BasicFormModal.js +2 -1
  495. package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
  496. package/build/dist/UI/Components/Forms/BasicForm.js +10 -1
  497. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  498. package/build/dist/UI/Components/Forms/BasicModelForm.js +2 -1
  499. package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
  500. package/build/dist/UI/Components/Forms/ModelForm.js +4 -1
  501. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  502. package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js +33 -0
  503. package/build/dist/UI/Components/Forms/Utils/FormAnalyticsName.js.map +1 -0
  504. package/build/dist/UI/Components/List/List.js +19 -5
  505. package/build/dist/UI/Components/List/List.js.map +1 -1
  506. package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
  507. package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
  508. package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
  509. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
  510. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  511. package/build/dist/UI/Components/Modal/Modal.js +2 -2
  512. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js +2 -1
  513. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  514. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  515. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  516. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
  517. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  518. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
  519. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  520. package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
  521. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  522. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
  523. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  524. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
  525. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  526. package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
  527. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  528. package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
  529. package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
  530. package/build/dist/UI/Components/Table/Table.js +35 -24
  531. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  532. package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
  533. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
  534. package/build/dist/UI/Components/Tabs/Tab.js +1 -1
  535. package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
  536. package/build/dist/UI/Components/Toast/Toast.js +77 -23
  537. package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
  538. package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
  539. package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
  540. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
  541. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  542. package/build/dist/UI/Utils/ModelListCache.js +126 -0
  543. package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
  544. package/build/dist/UI/Utils/Project.js +24 -1
  545. package/build/dist/UI/Utils/Project.js.map +1 -1
  546. package/build/dist/Utils/API.js +6 -1
  547. package/build/dist/Utils/API.js.map +1 -1
  548. package/build/dist/Utils/Analytics.js +50 -2
  549. package/build/dist/Utils/Analytics.js.map +1 -1
  550. package/build/dist/Utils/Monitor/MonitorMetricType.js +37 -0
  551. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  552. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js +318 -37
  553. package/build/dist/Utils/Monitor/NetworkDeviceLinkRuleUtil.js.map +1 -1
  554. package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js +87 -0
  555. package/build/dist/Utils/NetworkDiscovery/UnclaimedScanDiagnosis.js.map +1 -0
  556. package/jest.config.json +1 -1
  557. package/package.json +2 -3
  558. package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
  559. package/Tests/__mocks__/otpauth.js +0 -30
  560. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
  561. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
@@ -8,6 +8,7 @@ import BasicForm, {
8
8
  import Fields from "./Types/Fields";
9
9
  import { FormStep } from "./Types/FormStep";
10
10
  import FormValues from "./Types/FormValues";
11
+ import FormAnalyticsName from "./Utils/FormAnalyticsName";
11
12
  import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
12
13
  import React, {
13
14
  MutableRefObject,
@@ -113,7 +114,7 @@ const BasicModelForm: <TBaseModel extends BaseModel>(
113
114
  onValidate={props.onValidate ? props.onValidate : DefaultValidateFunction}
114
115
  disableAutofocus={props.disableAutofocus}
115
116
  steps={props.steps}
116
- name={props.name}
117
+ name={FormAnalyticsName.resolve(props.name, props.title)}
117
118
  onFormStepChange={props.onFormStepChange}
118
119
  submitButtonStyleType={props.submitButtonStyleType}
119
120
  onSubmit={props.onSubmit}
@@ -21,6 +21,7 @@ import Field from "./Types/Field";
21
21
  import Fields from "./Types/Fields";
22
22
  import { FormStep } from "./Types/FormStep";
23
23
  import FormValues from "./Types/FormValues";
24
+ import FormAnalyticsName from "./Utils/FormAnalyticsName";
24
25
  import AnalyticsBaseModel from "../../../Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel";
25
26
  import AccessControlModel from "../../../Models/DatabaseModels/DatabaseBaseModel/AccessControlModel";
26
27
  import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
@@ -854,7 +855,15 @@ const ModelForm: <TBaseModel extends BaseModel>(
854
855
  disableAutofocus={props.disableAutofocus}
855
856
  model={model}
856
857
  id={props.id}
857
- name={props.name}
858
+ name={FormAnalyticsName.resolve(
859
+ props.name,
860
+ props.title,
861
+ model.singularName
862
+ ? `${
863
+ props.formType === FormType.Create ? "Create" : "Update"
864
+ } ${model.singularName}`
865
+ : undefined,
866
+ )}
858
867
  onFormStepChange={props.onFormStepChange}
859
868
  onIsLastFormStep={props.onIsLastFormStep}
860
869
  fields={fields}
@@ -0,0 +1,39 @@
1
+ /*
2
+ * Matches "undefined" / "null" as a whole word, which is what a missing value
3
+ * turns into once it is interpolated into a title (`Duplicate ${undefined}`).
4
+ * Case sensitive on purpose: titles are written in Title Case, so a real word
5
+ * like "Null" in a form title is left alone.
6
+ */
7
+ const STRINGIFIED_EMPTY_VALUE: RegExp = /\b(undefined|null)\b/;
8
+
9
+ /*
10
+ * Resolves the human readable name that identifies a form in the
11
+ * "FORM SUBMIT" analytics event.
12
+ *
13
+ * Wrappers around BasicForm pass a chain of candidates - the explicit name
14
+ * first, then whatever title they already render - and the first usable one
15
+ * wins. When no candidate is usable the caller is expected to skip the capture
16
+ * altogether, because an event named after a missing value collapses distinct
17
+ * conversions into one indistinguishable event.
18
+ */
19
+ export default class FormAnalyticsName {
20
+ public static resolve(
21
+ ...candidates: Array<string | undefined | null>
22
+ ): string | undefined {
23
+ for (const candidate of candidates) {
24
+ if (typeof candidate !== "string") {
25
+ continue;
26
+ }
27
+
28
+ const name: string = candidate.trim();
29
+
30
+ if (!name || STRINGIFIED_EMPTY_VALUE.test(name)) {
31
+ continue;
32
+ }
33
+
34
+ return name;
35
+ }
36
+
37
+ return undefined;
38
+ }
39
+ }
@@ -1,6 +1,5 @@
1
1
  import { GetReactElementFunction } from "../../Types/FunctionTypes";
2
2
  import ActionButtonSchema from "../ActionButton/ActionButtonSchema";
3
- import ComponentLoader from "../ComponentLoader/ComponentLoader";
4
3
  import Field from "../Detail/Field";
5
4
  import ErrorMessage from "../ErrorMessage/ErrorMessage";
6
5
  import FilterViewer from "../Filters/FilterViewer";
@@ -8,6 +7,7 @@ import FilterType from "../Filters/Types/Filter";
8
7
  import FilterData from "../Filters/Types/FilterData";
9
8
  import Pagination from "../Pagination/Pagination";
10
9
  import ListBody from "./ListBody";
10
+ import ListSkeleton from "./ListSkeleton";
11
11
  import { ListDetailProps } from "./ListRow";
12
12
  import GenericObject from "../../../Types/GenericObject";
13
13
  import React, { ReactElement } from "react";
@@ -67,12 +67,30 @@ type ListFunction = <T extends GenericObject>(
67
67
  const List: ListFunction = <T extends GenericObject>(
68
68
  props: ComponentProps<T>,
69
69
  ): ReactElement => {
70
+ /*
71
+ * A refetch with cards already on screen (pagination, sort, refresh - the
72
+ * parent never clears `data` while fetching) keeps those cards visible and
73
+ * dims them; skeletons are only for a load with nothing to show yet.
74
+ */
75
+ const isRefetchingWithData: boolean =
76
+ props.isLoading && props.data.length > 0;
77
+
70
78
  const getListbody: GetReactElementFunction = (): ReactElement => {
71
- if (props.isLoading) {
72
- return <ComponentLoader />;
79
+ if (props.isLoading && props.data.length === 0) {
80
+ return (
81
+ <ListSkeleton
82
+ fieldsCount={props.fields.length}
83
+ itemsOnPage={props.itemsOnPage}
84
+ />
85
+ );
73
86
  }
74
87
 
75
- if (props.error) {
88
+ /*
89
+ * Loading still wins over error and empty (same priority as before the
90
+ * skeletons): while a refetch is in flight the stale cards render, never
91
+ * a stale error or a premature "no items".
92
+ */
93
+ if (!props.isLoading && props.error) {
76
94
  return (
77
95
  <div className="p-6">
78
96
  <ErrorMessage
@@ -145,7 +163,21 @@ const List: ListFunction = <T extends GenericObject>(
145
163
  }
146
164
  }}
147
165
  >
148
- {getListbody()}
166
+ {/*
167
+ * Dims the stale cards while a refetch is in flight and blocks
168
+ * clicks on them - actions against data about to be replaced
169
+ * are a race.
170
+ */}
171
+ <div
172
+ data-testid="list-content"
173
+ className={
174
+ isRefetchingWithData
175
+ ? "opacity-60 pointer-events-none transition-opacity duration-150"
176
+ : "transition-opacity duration-150"
177
+ }
178
+ >
179
+ {getListbody()}
180
+ </div>
149
181
  </DragDropContext>
150
182
  {!props.disablePagination && (
151
183
  <div className="mt-5 -mb-6">
@@ -0,0 +1,54 @@
1
+ import Skeleton from "../Skeleton/Skeleton";
2
+ import React, { FunctionComponent, ReactElement } from "react";
3
+
4
+ export interface ComponentProps {
5
+ /*
6
+ * One placeholder line per field the real ListRow will render, so the
7
+ * cards are the right height before the data arrives.
8
+ */
9
+ fieldsCount: number;
10
+ itemsOnPage: number;
11
+ }
12
+
13
+ /*
14
+ * Card-shaped placeholders for the list's first load, matching ListBody's
15
+ * wrapper (space-y-6 p-6 border-t) so nothing shifts when real rows land.
16
+ */
17
+ const ListSkeleton: FunctionComponent<ComponentProps> = (
18
+ props: ComponentProps,
19
+ ): ReactElement => {
20
+ // Enough cards to look like a page without painting offscreen ones.
21
+ const cardCount: number = Math.max(1, Math.min(props.itemsOnPage || 0, 6));
22
+ const cardIndexes: Array<number> = Array.from(Array(cardCount).keys());
23
+ const lineIndexes: Array<number> = Array.from(
24
+ Array(Math.max(1, props.fieldsCount)).keys(),
25
+ );
26
+
27
+ return (
28
+ <div
29
+ data-testid="list-skeleton-loader"
30
+ role="status"
31
+ aria-live="polite"
32
+ className="space-y-6 p-6 border-t border-gray-200"
33
+ >
34
+ <span className="sr-only">Loading...</span>
35
+ {cardIndexes.map((cardIndex: number) => {
36
+ return (
37
+ <div key={cardIndex} className="space-y-3">
38
+ {lineIndexes.map((lineIndex: number) => {
39
+ return (
40
+ <Skeleton
41
+ key={lineIndex}
42
+ className="h-4"
43
+ widthVariantIndex={cardIndex + lineIndex}
44
+ />
45
+ );
46
+ })}
47
+ </div>
48
+ );
49
+ })}
50
+ </div>
51
+ );
52
+ };
53
+
54
+ export default ListSkeleton;
@@ -1,4 +1,9 @@
1
- import { ComponentProps } from "./MarkdownViewer";
1
+ /*
2
+ * Type-only on purpose: the sole static edge to MarkdownViewer must be
3
+ * erasable, so the viewer (and the mermaid chunk it lazily pulls) stays out
4
+ * of every eager bundle that imports this wrapper.
5
+ */
6
+ import type { ComponentProps } from "./MarkdownViewer";
2
7
  import React, {
3
8
  FunctionComponent,
4
9
  LazyExoticComponent,
@@ -76,7 +76,6 @@ SyntaxHighlighter.registerLanguage("ruby", ruby);
76
76
  SyntaxHighlighter.registerLanguage("php", php);
77
77
  SyntaxHighlighter.registerLanguage("graphql", graphql);
78
78
  SyntaxHighlighter.registerLanguage("http", http);
79
- import mermaid from "mermaid";
80
79
  import DOMPurify from "dompurify";
81
80
  import OneUptimeDate from "../../../Types/Date";
82
81
  import { Theme, useTheme } from "../../Utils/Theme";
@@ -90,7 +89,48 @@ import { Theme, useTheme } from "../../Utils/Theme";
90
89
  const ISO_8601_REGEX: RegExp =
91
90
  /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d{1,6})?Z$/;
92
91
 
93
- const initializeMermaid: (theme: Theme) => void = (theme: Theme): void => {
92
+ /*
93
+ * mermaid's pre-bundled build is ~4.5MB — by far the heaviest dependency of
94
+ * this component — so it is loaded on demand the first time a mermaid fence
95
+ * actually renders. Plain markdown (the overwhelmingly common case) never
96
+ * pays for it: there is no static import and no module-scope initialization.
97
+ * The promise is cached module-wide so multiple diagrams share one load, and
98
+ * theme setup runs only after the load resolves.
99
+ */
100
+ type MermaidApi = typeof import("mermaid").default;
101
+
102
+ let mermaidLoadPromise: Promise<MermaidApi> | null = null;
103
+
104
+ const loadMermaid: () => Promise<MermaidApi> = (): Promise<MermaidApi> => {
105
+ if (!mermaidLoadPromise) {
106
+ const loadPromise: Promise<MermaidApi> = import("mermaid").then(
107
+ (mermaidModule: { default: MermaidApi }): MermaidApi => {
108
+ return mermaidModule.default;
109
+ },
110
+ );
111
+
112
+ mermaidLoadPromise = loadPromise;
113
+
114
+ /*
115
+ * A failed chunk load (flaky network, deploy rotating hashed chunk
116
+ * names) must not be cached forever — clear the slot so the next
117
+ * diagram retries the import. The reset rides a side branch of the
118
+ * promise: the original is still returned below, so the caller that
119
+ * triggered this load sees the rejection through its own error path.
120
+ */
121
+ loadPromise.catch((): void => {
122
+ if (mermaidLoadPromise === loadPromise) {
123
+ mermaidLoadPromise = null;
124
+ }
125
+ });
126
+ }
127
+ return mermaidLoadPromise;
128
+ };
129
+
130
+ const initializeMermaid: (mermaid: MermaidApi, theme: Theme) => void = (
131
+ mermaid: MermaidApi,
132
+ theme: Theme,
133
+ ): void => {
94
134
  const isDark: boolean = theme === Theme.Dark;
95
135
 
96
136
  mermaid.initialize({
@@ -120,10 +160,8 @@ const initializeMermaid: (theme: Theme) => void = (theme: Theme): void => {
120
160
  });
121
161
  };
122
162
 
123
- initializeMermaid(Theme.Light);
124
-
125
- // Mermaid diagram component
126
- const MermaidDiagram: FunctionComponent<{ chart: string }> = ({
163
+ // Mermaid diagram component (exported so tests can exercise the lazy load directly)
164
+ export const MermaidDiagram: FunctionComponent<{ chart: string }> = ({
127
165
  chart,
128
166
  }: {
129
167
  chart: string;
@@ -136,27 +174,34 @@ const MermaidDiagram: FunctionComponent<{ chart: string }> = ({
136
174
  let isCancelled: boolean = false;
137
175
 
138
176
  const renderDiagram: () => Promise<void> = async (): Promise<void> => {
139
- if (containerRef.current) {
177
+ try {
178
+ /*
179
+ * Dynamic load first; a failed chunk load surfaces through the same
180
+ * error path as a failed render. Theme setup MUST follow the load —
181
+ * there is deliberately no module-scope initialization any more.
182
+ */
183
+ const mermaid: MermaidApi = await loadMermaid();
184
+ if (!containerRef.current || isCancelled) {
185
+ return;
186
+ }
140
187
  containerRef.current.innerHTML = "";
141
- try {
142
- initializeMermaid(theme);
143
- const id: string = `mermaid-${Math.random().toString(36).substr(2, 9)}`;
144
- const { svg } = await mermaid.render(id, chart);
145
- if (containerRef.current && !isCancelled) {
146
- containerRef.current.innerHTML = DOMPurify.sanitize(svg, {
147
- USE_PROFILES: { svg: true, svgFilters: true },
148
- ADD_TAGS: ["foreignObject"],
149
- });
150
- }
151
- } catch (error) {
152
- if (containerRef.current && !isCancelled) {
153
- const errorMessage: string = String(error);
154
- const errorEl: HTMLPreElement = document.createElement("pre");
155
- errorEl.className = "text-red-500";
156
- errorEl.textContent = `Error rendering diagram: ${errorMessage}`;
157
- containerRef.current.innerHTML = "";
158
- containerRef.current.appendChild(errorEl);
159
- }
188
+ initializeMermaid(mermaid, theme);
189
+ const id: string = `mermaid-${Math.random().toString(36).substr(2, 9)}`;
190
+ const { svg } = await mermaid.render(id, chart);
191
+ if (containerRef.current && !isCancelled) {
192
+ containerRef.current.innerHTML = DOMPurify.sanitize(svg, {
193
+ USE_PROFILES: { svg: true, svgFilters: true },
194
+ ADD_TAGS: ["foreignObject"],
195
+ });
196
+ }
197
+ } catch (error) {
198
+ if (containerRef.current && !isCancelled) {
199
+ const errorMessage: string = String(error);
200
+ const errorEl: HTMLPreElement = document.createElement("pre");
201
+ errorEl.className = "text-red-500";
202
+ errorEl.textContent = `Error rendering diagram: ${errorMessage}`;
203
+ containerRef.current.innerHTML = "";
204
+ containerRef.current.appendChild(errorEl);
160
205
  }
161
206
  }
162
207
  };
@@ -413,7 +413,7 @@ const Modal: FunctionComponent<ComponentProps> = (
413
413
  return (
414
414
  <div className="relative z-50">
415
415
  <div
416
- className={`fixed inset-0 bg-gray-950/45 backdrop-blur-[2px] transition-opacity duration-200 ease-out motion-reduce:transition-none ${
416
+ className={`fixed inset-0 bg-gray-950/45 backdrop-blur-[2px] transition-opacity duration-150 ease-out motion-reduce:transition-none ${
417
417
  hasEntered ? "opacity-100" : "opacity-0"
418
418
  }`}
419
419
  data-testid="modal-backdrop"
@@ -429,7 +429,7 @@ const Modal: FunctionComponent<ComponentProps> = (
429
429
  <div className="flex min-h-full items-end justify-center p-0 text-center sm:items-center sm:p-6">
430
430
  <div
431
431
  ref={modalRef}
432
- className={`relative flex max-h-[calc(100dvh-1rem)] w-full flex-col rounded-t-2xl border border-gray-200/80 bg-white text-left shadow-2xl ring-1 ring-black/5 transition duration-200 ease-out focus:outline-none motion-reduce:transition-none sm:my-8 sm:max-h-[calc(100dvh-4rem)] sm:rounded-xl ${modalWidthClassName} ${panelTransitionClassName}`}
432
+ className={`relative flex max-h-[calc(100dvh-1rem)] w-full flex-col rounded-t-2xl border border-gray-200/80 bg-white text-left shadow-2xl ring-1 ring-black/5 transition duration-150 ease-out focus:outline-none motion-reduce:transition-none sm:my-8 sm:max-h-[calc(100dvh-4rem)] sm:rounded-xl ${modalWidthClassName} ${panelTransitionClassName}`}
433
433
  data-testid="modal"
434
434
  aria-labelledby={titleId}
435
435
  aria-describedby={translatedDescription ? descriptionId : undefined}
@@ -7,6 +7,7 @@ import ModelForm, {
7
7
  ComponentProps as ModelFormComponentProps,
8
8
  } from "../Forms/ModelForm";
9
9
  import FormValues from "../Forms/Types/FormValues";
10
+ import FormAnalyticsName from "../Forms/Utils/FormAnalyticsName";
10
11
  import Modal, { ModalWidth } from "../Modal/Modal";
11
12
  import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
12
13
  import { JSONObject } from "../../../Types/JSON";
@@ -77,7 +78,11 @@ const ModelFormModal: <TBaseModel extends BaseModel>(
77
78
  <>
78
79
  <ModelForm<TBaseModel>
79
80
  {...props.formProps}
80
- name={props.name}
81
+ name={FormAnalyticsName.resolve(
82
+ props.name,
83
+ props.formProps.name,
84
+ props.title,
85
+ )}
81
86
  modelAPI={props.modelAPI}
82
87
  modelType={props.modelType}
83
88
  onIsLastFormStep={(isLastFormStep: boolean) => {
@@ -47,7 +47,7 @@ import List from "../List/List";
47
47
  import { ListDetailProps } from "../List/ListRow";
48
48
  import ConfirmModal from "../Modal/ConfirmModal";
49
49
  import Modal, { ModalWidth } from "../Modal/Modal";
50
- import MarkdownViewer from "../Markdown.tsx/MarkdownViewer";
50
+ import MarkdownViewer from "../Markdown.tsx/LazyMarkdownViewer";
51
51
  import Icon from "../Icon/Icon";
52
52
  import Filter from "../ModelFilter/Filter";
53
53
  import { DropdownOption, DropdownOptionLabel } from "../Dropdown/Dropdown";
@@ -4,7 +4,7 @@ import {
4
4
  getCustomFieldColumns,
5
5
  getCustomFieldDefinitions,
6
6
  } from "./CustomFieldColumns";
7
- import ModelAPI from "../../Utils/ModelAPI/ModelAPI";
7
+ import ModelListCache from "../../Utils/ModelListCache";
8
8
  import ProjectUtil from "../../Utils/Project";
9
9
  import { Logger } from "../../Utils/Logger";
10
10
  import AnalyticsBaseModel from "../../../Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel";
@@ -96,8 +96,14 @@ const useCustomFieldColumns: UseCustomFieldColumnsFunction = <
96
96
  setError("");
97
97
 
98
98
  try {
99
- const result: ListResult<BaseModel> = await ModelAPI.getList<BaseModel>(
100
- {
99
+ /*
100
+ * Through ModelListCache rather than ModelAPI: a table mounts two
101
+ * instances of this hook (the facet bar and the column set), and both
102
+ * want the same definition list - the cache turns that into one
103
+ * request, shared for the next minute.
104
+ */
105
+ const result: ListResult<BaseModel> =
106
+ await ModelListCache.getList<BaseModel>({
101
107
  modelType: customFieldsModelType,
102
108
  query: {
103
109
  projectId: projectId,
@@ -113,8 +119,8 @@ const useCustomFieldColumns: UseCustomFieldColumnsFunction = <
113
119
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
114
120
  } as any,
115
121
  sort: {},
116
- },
117
- );
122
+ projectId: projectId,
123
+ });
118
124
 
119
125
  if (isCancelled) {
120
126
  return;
@@ -114,6 +114,13 @@ const MoreMenu: React.ForwardRefExoticComponent<
114
114
 
115
115
  const [isDropdownVisible, setDropdownVisible] = useState<boolean>(false);
116
116
 
117
+ /*
118
+ * The menu is mounted in its closed state (faded, slightly shrunk towards
119
+ * origin-top-right) and flipped open one frame later so the browser has
120
+ * something to transition from — the same pattern Modal uses.
121
+ */
122
+ const [hasMenuEntered, setHasMenuEntered] = useState<boolean>(false);
123
+
117
124
  useEffect(() => {
118
125
  setDropdownVisible(isComponentVisible);
119
126
  if (isComponentVisible) {
@@ -123,6 +130,30 @@ const MoreMenu: React.ForwardRefExoticComponent<
123
130
  }
124
131
  }, [isComponentVisible]);
125
132
 
133
+ useEffect(() => {
134
+ if (!isComponentVisible) {
135
+ setHasMenuEntered(false);
136
+ return undefined;
137
+ }
138
+
139
+ const open: () => void = (): void => {
140
+ setHasMenuEntered(true);
141
+ };
142
+
143
+ const frame: number = requestAnimationFrame(open);
144
+
145
+ /*
146
+ * A hidden or throttled tab never runs an animation frame; the timer
147
+ * skips the transition rather than leaving the menu at zero opacity.
148
+ */
149
+ const fallbackTimer: ReturnType<typeof setTimeout> = setTimeout(open, 80);
150
+
151
+ return () => {
152
+ cancelAnimationFrame(frame);
153
+ clearTimeout(fallbackTimer);
154
+ };
155
+ }, [isComponentVisible]);
156
+
126
157
  useEffect(() => {
127
158
  if (props.isDisabled && isComponentVisible) {
128
159
  setIsComponentVisible(false);
@@ -427,7 +458,14 @@ const MoreMenu: React.ForwardRefExoticComponent<
427
458
  <div
428
459
  ref={ref}
429
460
  id={menuId}
430
- className="absolute right-0 z-50 mt-2 w-56 origin-top-right rounded-lg bg-white shadow-xl ring-1 ring-gray-200 focus:outline-none py-1"
461
+ /*
462
+ * Once settled the menu carries no transform class at all: a
463
+ * lingering scale would make it the containing block for any
464
+ * position:fixed descendant (the Modal invariant).
465
+ */
466
+ className={`absolute right-0 z-50 mt-2 w-56 origin-top-right rounded-lg bg-white shadow-xl ring-1 ring-gray-200 focus:outline-none py-1 transition duration-150 ease-out motion-reduce:transition-none ${
467
+ hasMenuEntered ? "opacity-100" : "opacity-0 scale-95"
468
+ }`}
431
469
  role="menu"
432
470
  aria-orientation="vertical"
433
471
  aria-labelledby={buttonId}
@@ -65,6 +65,14 @@ export interface ComponentProps {
65
65
  description: string;
66
66
  link: URL;
67
67
  };
68
+ /*
69
+ * When true, the document-level Cmd/Ctrl+K shortcut that toggles the
70
+ * products menu is not registered — for apps where another surface (e.g. a
71
+ * command palette) owns that shortcut. The menu itself stays fully usable
72
+ * via its trigger button. Defaults to false: existing consumers keep the
73
+ * shortcut.
74
+ */
75
+ disableCommandKShortcut?: boolean | undefined;
68
76
  className?: string;
69
77
  // Legacy support for children-based usage
70
78
  children?: ReactElement | Array<ReactElement>;
@@ -165,6 +173,11 @@ const Navbar: FunctionComponent<ComponentProps> = (
165
173
 
166
174
  // Open/close the products menu with Cmd/Ctrl + K from anywhere.
167
175
  useEffect(() => {
176
+ if (props.disableCommandKShortcut) {
177
+ // Another surface (e.g. a command palette) owns Cmd/Ctrl+K.
178
+ return;
179
+ }
180
+
168
181
  const handleGlobalKeyDown: (event: KeyboardEvent) => void = (
169
182
  event: KeyboardEvent,
170
183
  ): void => {
@@ -180,7 +193,7 @@ const Navbar: FunctionComponent<ComponentProps> = (
180
193
  return () => {
181
194
  document.removeEventListener("keydown", handleGlobalKeyDown);
182
195
  };
183
- }, []);
196
+ }, [props.disableCommandKShortcut]);
184
197
 
185
198
  // More menu open/close.
186
199
  const openMoreMenu: () => void = (): void => {
@@ -1,8 +1,8 @@
1
1
  import ActionButtonSchema from "../ActionButton/ActionButtonSchema";
2
- import ComponentLoader from "../ComponentLoader/ComponentLoader";
3
2
  import ErrorMessage from "../ErrorMessage/ErrorMessage";
4
3
  import Icon, { SizeProp } from "../Icon/Icon";
5
4
  import Item from "./Item";
5
+ import Skeleton from "../Skeleton/Skeleton";
6
6
  import GenericObject from "../../../Types/GenericObject";
7
7
  import IconProp from "../../../Types/Icon/IconProp";
8
8
  import React, { ReactElement } from "react";
@@ -33,11 +33,49 @@ type OrderedStatesListFunction = <T extends GenericObject>(
33
33
  const OrderedStatesList: OrderedStatesListFunction = <T extends GenericObject>(
34
34
  props: ComponentProps<T>,
35
35
  ): ReactElement => {
36
- if (props.isLoading) {
37
- return <ComponentLoader />;
36
+ /*
37
+ * A refetch with states already on screen keeps them visible and dims
38
+ * them; the skeleton stack is only for a load with nothing to show yet.
39
+ */
40
+ const isRefetchingWithData: boolean =
41
+ Boolean(props.isLoading) && props.data.length > 0;
42
+
43
+ if (props.isLoading && props.data.length === 0) {
44
+ /*
45
+ * Three card-shaped placeholders where the ordered state cards will
46
+ * land (matching Item's rounded bordered card), so the page keeps its
47
+ * shape instead of collapsing to a centered spinner.
48
+ */
49
+ return (
50
+ <div
51
+ data-testid="ordered-states-list-skeleton-loader"
52
+ role="status"
53
+ aria-live="polite"
54
+ className="m-32 text-center"
55
+ >
56
+ <span className="sr-only">Loading...</span>
57
+ {[0, 1, 2].map((index: number) => {
58
+ return (
59
+ <div key={index} className="w-fit m-auto">
60
+ <Skeleton className="h-32 w-64 rounded p-10" />
61
+ {index < 2 && (
62
+ <div className="items-center m-10">
63
+ <Skeleton className="m-auto h-5 w-5" />
64
+ </div>
65
+ )}
66
+ </div>
67
+ );
68
+ })}
69
+ </div>
70
+ );
38
71
  }
39
72
 
40
- if (props.error) {
73
+ /*
74
+ * Loading still wins over error and empty (same priority as before the
75
+ * skeletons): while a refetch is in flight the stale states render, never
76
+ * a stale error or a premature "no items".
77
+ */
78
+ if (!props.isLoading && props.error) {
41
79
  return (
42
80
  <ErrorMessage
43
81
  message={props.error}
@@ -82,7 +120,14 @@ const OrderedStatesList: OrderedStatesListFunction = <T extends GenericObject>(
82
120
  }
83
121
 
84
122
  return (
85
- <div className="m-32 text-center">
123
+ <div
124
+ data-testid="ordered-states-list-content"
125
+ className={`m-32 text-center${
126
+ isRefetchingWithData
127
+ ? " opacity-60 pointer-events-none transition-opacity duration-150"
128
+ : " transition-opacity duration-150"
129
+ }`}
130
+ >
86
131
  {props.error && <p>{props.error}</p>}
87
132
  {!props.error &&
88
133
  props.data &&
@@ -7,7 +7,14 @@ import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/Database
7
7
  import { PromiseVoidFunction } from "../../../Types/FunctionTypes";
8
8
  import IconProp from "../../../Types/Icon/IconProp";
9
9
  import Link from "../../../Types/Link";
10
- import React, { ReactElement, useEffect, useState, useCallback } from "react";
10
+ import React, {
11
+ MutableRefObject,
12
+ ReactElement,
13
+ useEffect,
14
+ useRef,
15
+ useState,
16
+ useCallback,
17
+ } from "react";
11
18
  import GlobalEvents from "../../Utils/GlobalEvents";
12
19
 
13
20
  export const REFRESH_SIDEBAR_COUNT_EVENT: string = "REFRESH_SIDEBAR_COUNTS";
@@ -70,7 +77,39 @@ const CountModelSideMenuItem: <TBaseModel extends BaseModel>(
70
77
  props.onCountFetchInit,
71
78
  ]);
72
79
 
80
+ /*
81
+ * Side menus rebuild `countQuery` / `requestOptions` as fresh object
82
+ * literals on every render, so their identity changes on every parent
83
+ * re-render (which happens on every in-section navigation). Guard the fetch
84
+ * with a value-level compare - the same JSON.stringify-in-a-ref pattern
85
+ * BaseModelTable uses for its `props.query` - so only a real change
86
+ * re-issues the count request. The global refresh event below still forces
87
+ * a refetch regardless of this guard.
88
+ */
89
+ const lastFetchedModelTypeRef: MutableRefObject<
90
+ { new (): TBaseModel } | undefined
91
+ > = useRef<{ new (): TBaseModel } | undefined>(undefined);
92
+ const lastFetchedQueryJsonRef: MutableRefObject<string | null> = useRef<
93
+ string | null
94
+ >(null);
95
+
73
96
  useEffect(() => {
97
+ const queryJson: string = JSON.stringify({
98
+ countQuery: props.countQuery || null,
99
+ requestOptions: props.requestOptions || null,
100
+ });
101
+
102
+ // only fetch if the query has changed by value (or on first mount).
103
+ if (
104
+ lastFetchedModelTypeRef.current === props.modelType &&
105
+ lastFetchedQueryJsonRef.current === queryJson
106
+ ) {
107
+ return;
108
+ }
109
+
110
+ lastFetchedModelTypeRef.current = props.modelType;
111
+ lastFetchedQueryJsonRef.current = queryJson;
112
+
74
113
  fetchCount().catch((err: Error) => {
75
114
  setError(API.getFriendlyMessage(err));
76
115
  });