@oneuptime/common 12.0.13 → 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 (376) hide show
  1. package/Models/DatabaseModels/OnCallDutyPolicySchedule.ts +14 -0
  2. package/Models/DatabaseModels/UserCall.ts +94 -3
  3. package/Models/DatabaseModels/UserEmail.ts +94 -3
  4. package/Models/DatabaseModels/UserIncomingCallNumber.ts +94 -3
  5. package/Models/DatabaseModels/UserPush.ts +37 -0
  6. package/Models/DatabaseModels/UserSMS.ts +94 -3
  7. package/Models/DatabaseModels/UserWhatsApp.ts +93 -2
  8. package/Server/API/BaseAPI.ts +79 -14
  9. package/Server/API/UserCallAPI.ts +53 -45
  10. package/Server/API/UserEmailAPI.ts +53 -44
  11. package/Server/API/UserIncomingCallNumberAPI.ts +48 -38
  12. package/Server/API/UserNotificationMethodAdminAPI.ts +481 -0
  13. package/Server/API/UserPushAPI.ts +126 -2
  14. package/Server/API/UserSmsAPI.ts +53 -44
  15. package/Server/API/UserWhatsAppAPI.ts +53 -50
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.ts +154 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.ts +17 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.ts +45 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
  20. package/Server/Middleware/VerificationCodeRateLimit.ts +586 -0
  21. package/Server/Services/AnalyticsDatabaseService.ts +169 -0
  22. package/Server/Services/DatabaseService.ts +101 -0
  23. package/Server/Services/LogAggregationService.ts +5 -0
  24. package/Server/Services/PushNotificationService.ts +127 -12
  25. package/Server/Services/TeamMemberService.ts +53 -13
  26. package/Server/Services/UserCallService.ts +55 -24
  27. package/Server/Services/UserEmailService.ts +83 -17
  28. package/Server/Services/UserIncomingCallNumberService.ts +49 -85
  29. package/Server/Services/UserNotificationMethodAdminService.ts +1527 -0
  30. package/Server/Services/UserNotificationRuleService.ts +26 -0
  31. package/Server/Services/UserPushService.ts +89 -0
  32. package/Server/Services/UserSmsService.ts +50 -17
  33. package/Server/Services/UserWhatsAppService.ts +48 -15
  34. package/Server/Types/Database/QueryHelper.ts +30 -0
  35. package/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.ts +59 -0
  36. package/Server/Utils/ChannelVerification.ts +510 -0
  37. package/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.ts +13 -16
  38. package/Server/Utils/Monitor/MonitorAlert.ts +24 -21
  39. package/Server/Utils/Monitor/MonitorIncident.ts +21 -18
  40. package/Server/Utils/Monitor/MonitorResourceContext.ts +107 -0
  41. package/Server/Utils/Monitor/MonitorStepResourceIdentity.ts +442 -0
  42. package/Server/Utils/Monitor/SeriesResourceLabels.ts +3 -3
  43. package/Server/Utils/Monitor/SeriesResourceLinker.ts +96 -28
  44. package/Server/Utils/TotpAuth.ts +137 -9
  45. package/Server/Utils/UserRegistrationToken.ts +182 -0
  46. package/Server/Utils/VerificationCode.ts +134 -0
  47. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +173 -94
  48. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +1151 -0
  49. package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +905 -0
  50. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +338 -0
  51. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1 -1
  52. package/Tests/App/Dashboard/MonitorTypePicker.test.tsx +28 -0
  53. package/Tests/Models/UserPushCriticalAlertColumn.test.ts +172 -0
  54. package/Tests/Server/API/BaseAPIGetListParallel.test.ts +519 -0
  55. package/Tests/Server/API/NotificationChannelVerificationAPI.test.ts +543 -0
  56. package/Tests/Server/API/UserIncomingCallNumberApi.test.ts +108 -18
  57. package/Tests/Server/API/UserNotificationMethodAdminAPI.test.ts +963 -0
  58. package/Tests/Server/API/UserPushCriticalAlertsApi.test.ts +114 -0
  59. package/Tests/Server/API/UserSmsApi.test.ts +107 -14
  60. package/Tests/Server/API/UserTotpAuthAPI.test.ts +427 -0
  61. package/Tests/Server/Infrastructure/Postgres/FixTotpOtpUrlAlgorithmMigration.test.ts +315 -0
  62. package/Tests/Server/Middleware/VerificationCodeRateLimit.test.ts +775 -0
  63. package/Tests/Server/Services/AddNetworkDeviceReachabilityColumnsMigration.test.ts +10 -62
  64. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +33 -13
  65. package/Tests/Server/Services/AnalyticsDatabaseSortKeyBoundary.test.ts +658 -0
  66. package/Tests/Server/Services/CriticalOnCallAlertDelivery.test.ts +458 -0
  67. package/Tests/Server/Services/CriticalPushAlertPayload.test.ts +301 -0
  68. package/Tests/Server/Services/DatabaseServiceAtomicIncrement.test.ts +143 -0
  69. package/Tests/Server/Services/DeliverNotificationForRuleExtraction.test.ts +1 -0
  70. package/Tests/Server/Services/LogAggregationScanMemory.test.ts +421 -0
  71. package/Tests/Server/Services/LogAggregationService.test.ts +2 -2
  72. package/Tests/Server/Services/NotificationChannelCodeIssuance.test.ts +401 -0
  73. package/Tests/Server/Services/PushNotificationDeliveryOptions.test.ts +204 -0
  74. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +21 -1
  75. package/Tests/Server/Services/TeamMemberInviteRegistrationToken.test.ts +290 -0
  76. package/Tests/Server/Services/UserNotificationMethodAdminService.test.ts +948 -0
  77. package/Tests/Server/Services/UserNotificationRuleExecuteItem.test.ts +1 -0
  78. package/Tests/Server/Services/UserPushCriticalAlertToggle.test.ts +255 -0
  79. package/Tests/Server/Services/UserTotpAuthEnrolment.test.ts +218 -0
  80. package/Tests/Server/TestingUtils/AuthenticatorApp.ts +248 -0
  81. package/Tests/Server/Types/Database/Permissions/NotificationChannelVerificationColumns.test.ts +135 -0
  82. package/Tests/Server/Types/Database/Permissions/OnCallScheduleRelationSelect.test.ts +504 -0
  83. package/Tests/Server/Types/Database/QueryHelperFindWithSameTextAnyOf.test.ts +91 -0
  84. package/Tests/Server/Types/Workflow/Components/JsonToText.test.ts +384 -0
  85. package/Tests/Server/Types/Workflow/Components/MergeJson.test.ts +403 -0
  86. package/Tests/Server/Utils/Browser.test.ts +162 -0
  87. package/Tests/Server/Utils/ChannelVerification.test.ts +689 -0
  88. package/Tests/Server/Utils/Express.test.ts +371 -0
  89. package/Tests/Server/Utils/Monitor/Criteria/CustomCodeMonitorCriteria.test.ts +707 -0
  90. package/Tests/Server/Utils/Monitor/Criteria/DnsMonitorCriteria.test.ts +698 -0
  91. package/Tests/Server/Utils/Monitor/Criteria/IncomingEmailBodyCriteria.test.ts +243 -0
  92. package/Tests/Server/Utils/Monitor/Criteria/IncomingRequestBodyCriteria.test.ts +278 -0
  93. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +160 -20
  94. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +13 -8
  95. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +162 -18
  96. package/Tests/Server/Utils/Monitor/MonitorResourceContext.test.ts +349 -0
  97. package/Tests/Server/Utils/Monitor/MonitorStepResourceIdentity.test.ts +690 -0
  98. package/Tests/Server/Utils/Monitor/MonitorSummaryPersistence.test.ts +7 -2
  99. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +92 -18
  100. package/Tests/Server/Utils/PushNotificationUtilCreators.test.ts +267 -0
  101. package/Tests/Server/Utils/Telemetry/OneuptimeLabel.test.ts +439 -0
  102. package/Tests/Server/Utils/TotpAuth.test.ts +719 -0
  103. package/Tests/Server/Utils/UserRegistrationToken.test.ts +322 -0
  104. package/Tests/Server/Utils/VerificationCode.test.ts +296 -0
  105. package/Tests/Types/AutoRemediation/AutoRemediationSuggestionStatus.test.ts +192 -0
  106. package/Tests/Types/Call/CallRequest.test.ts +189 -0
  107. package/Tests/Types/Dashboard/DashboardSize.test.ts +226 -0
  108. package/Tests/Types/Incident/IncidentSlaStatus.test.ts +191 -0
  109. package/Tests/Types/Metrics/MetricDashboardMetricType.test.ts +278 -0
  110. package/Tests/Types/Metrics/MetricPipelineRuleType.test.ts +517 -0
  111. package/Tests/Types/Monitor/IncomingMonitorDefaultCriteria.test.ts +470 -0
  112. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +6 -4
  113. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +262 -5
  114. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +1 -1
  115. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +1 -1
  116. package/Tests/Types/Monitor/ServiceAlertTemplates.test.ts +905 -0
  117. package/Tests/Types/Service/ServiceLanguage.test.ts +255 -0
  118. package/Tests/Types/TextRandomGeneration.test.ts +211 -0
  119. package/Tests/UI/Components/Button.test.tsx +175 -1
  120. package/Tests/UI/Components/CodeBlockLanguages.test.tsx +236 -0
  121. package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +568 -0
  122. package/Tests/UI/Components/CommandPalette/CommandPaletteKeyboard.test.tsx +239 -0
  123. package/Tests/UI/Components/CommandPalette/CommandPaletteProviders.test.tsx +400 -0
  124. package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +234 -0
  125. package/Tests/UI/Components/CommandPalette/RecentCommands.test.ts +97 -0
  126. package/Tests/UI/Components/CountModelSideMenuItemGuard.test.tsx +198 -0
  127. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +1 -1
  128. package/Tests/UI/Components/Forms/Utils/FormFieldSchemaTypeUtil.test.ts +267 -0
  129. package/Tests/UI/Components/List.test.tsx +9 -2
  130. package/Tests/UI/Components/ListLoadingStates.test.tsx +173 -0
  131. package/Tests/UI/Components/MarkdownLazy.test.tsx +113 -0
  132. package/Tests/UI/Components/MarkdownMermaidRetry.test.tsx +110 -0
  133. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +8 -0
  134. package/Tests/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.test.ts +692 -0
  135. package/Tests/UI/Components/MoreMenuMotion.test.tsx +118 -0
  136. package/Tests/UI/Components/NavBarCommandKGating.test.tsx +178 -0
  137. package/Tests/UI/Components/OrderedStatesList.test.tsx +19 -2
  138. package/Tests/UI/Components/SideOverMotion.test.tsx +109 -0
  139. package/Tests/UI/Components/Skeleton.test.tsx +71 -0
  140. package/Tests/UI/Components/TableLoadingStates.test.tsx +279 -0
  141. package/Tests/UI/Components/Tabs.test.tsx +24 -0
  142. package/Tests/UI/Components/Toast.test.tsx +130 -7
  143. package/Tests/UI/Components/ToastStacking.test.tsx +198 -0
  144. package/Tests/UI/Utils/Dropdown.test.ts +423 -0
  145. package/Tests/UI/Utils/ModelAPITenantHeader.test.ts +122 -0
  146. package/Tests/UI/Utils/ModelListCache.test.ts +338 -0
  147. package/Tests/UI/Utils/ProjectListCacheInvalidation.test.ts +225 -0
  148. package/Tests/Utils/API.test.ts +16 -2
  149. package/Tests/Utils/Dashboard/Components/DashboardKubernetesResourceListShared.test.ts +347 -0
  150. package/Tests/Utils/Dashboard/Components/DashboardListSharedArgs.test.ts +259 -0
  151. package/Tests/Utils/Dashboard/Components/DashboardMonitorListComponent.test.ts +466 -0
  152. package/Tests/Utils/Rum/UrlScrubberSegments.test.ts +362 -0
  153. package/Types/Email/EmailTemplateType.ts +1 -0
  154. package/Types/Monitor/MonitorCriteriaInstance.ts +41 -20
  155. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +131 -8
  156. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +48 -8
  157. package/Types/Monitor/ServiceAlertTemplates.ts +1352 -0
  158. package/Types/Permission.ts +35 -0
  159. package/Types/PushNotification/AndroidNotificationChannel.ts +26 -0
  160. package/Types/PushNotification/PushNotificationMessage.ts +15 -0
  161. package/Types/PushNotification/PushNotificationRequest.ts +8 -16
  162. package/Types/Service/ServiceLanguage.ts +144 -0
  163. package/Types/Text.ts +111 -19
  164. package/UI/Components/Button/Button.tsx +27 -14
  165. package/UI/Components/CodeBlock/CodeBlock.tsx +54 -7
  166. package/UI/Components/CodeBlock/LanguageRegistry.ts +103 -0
  167. package/UI/Components/CommandPalette/CommandPalette.tsx +790 -0
  168. package/UI/Components/CommandPalette/PaletteFilter.ts +196 -0
  169. package/UI/Components/CommandPalette/PaletteRow.tsx +173 -0
  170. package/UI/Components/CommandPalette/RecentCommands.ts +57 -0
  171. package/UI/Components/CommandPalette/Types.ts +49 -0
  172. package/UI/Components/CommandPalette/UseProviderSearch.ts +129 -0
  173. package/UI/Components/Dropdown/Dropdown.tsx +6 -1
  174. package/UI/Components/Feed/FeedItem.tsx +1 -1
  175. package/UI/Components/List/List.tsx +37 -5
  176. package/UI/Components/List/ListSkeleton.tsx +54 -0
  177. package/UI/Components/Markdown.tsx/LazyMarkdownViewer.tsx +6 -1
  178. package/UI/Components/Markdown.tsx/MarkdownViewer.tsx +71 -26
  179. package/UI/Components/Modal/Modal.tsx +2 -2
  180. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  181. package/UI/Components/ModelTable/useCustomFieldColumns.ts +11 -5
  182. package/UI/Components/MoreMenu/MoreMenu.tsx +39 -1
  183. package/UI/Components/Navbar/NavBar.tsx +14 -1
  184. package/UI/Components/OrderedStatesList/OrderedStatesList.tsx +50 -5
  185. package/UI/Components/SideMenu/CountModelSideMenuItem.tsx +40 -1
  186. package/UI/Components/SideOver/SideOver.tsx +37 -2
  187. package/UI/Components/Skeleton/Skeleton.tsx +53 -0
  188. package/UI/Components/Table/Table.tsx +74 -44
  189. package/UI/Components/Table/TableSkeletonRows.tsx +141 -0
  190. package/UI/Components/Tabs/Tab.tsx +1 -1
  191. package/UI/Components/Toast/Toast.tsx +118 -53
  192. package/UI/Components/Toast/ToastInit.tsx +82 -32
  193. package/UI/Styles/Theme.css +40 -0
  194. package/UI/Utils/ModelAPI/ModelAPI.ts +20 -10
  195. package/UI/Utils/ModelListCache.ts +188 -0
  196. package/UI/Utils/Project.ts +29 -0
  197. package/Utils/API.ts +6 -1
  198. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js +14 -0
  199. package/build/dist/Models/DatabaseModels/OnCallDutyPolicySchedule.js.map +1 -1
  200. package/build/dist/Models/DatabaseModels/UserCall.js +101 -3
  201. package/build/dist/Models/DatabaseModels/UserCall.js.map +1 -1
  202. package/build/dist/Models/DatabaseModels/UserEmail.js +101 -3
  203. package/build/dist/Models/DatabaseModels/UserEmail.js.map +1 -1
  204. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js +101 -3
  205. package/build/dist/Models/DatabaseModels/UserIncomingCallNumber.js.map +1 -1
  206. package/build/dist/Models/DatabaseModels/UserPush.js +38 -0
  207. package/build/dist/Models/DatabaseModels/UserPush.js.map +1 -1
  208. package/build/dist/Models/DatabaseModels/UserSMS.js +101 -3
  209. package/build/dist/Models/DatabaseModels/UserSMS.js.map +1 -1
  210. package/build/dist/Models/DatabaseModels/UserWhatsApp.js +100 -2
  211. package/build/dist/Models/DatabaseModels/UserWhatsApp.js.map +1 -1
  212. package/build/dist/Server/API/BaseAPI.js +69 -13
  213. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  214. package/build/dist/Server/API/UserCallAPI.js +42 -38
  215. package/build/dist/Server/API/UserCallAPI.js.map +1 -1
  216. package/build/dist/Server/API/UserEmailAPI.js +42 -38
  217. package/build/dist/Server/API/UserEmailAPI.js.map +1 -1
  218. package/build/dist/Server/API/UserIncomingCallNumberAPI.js +37 -32
  219. package/build/dist/Server/API/UserIncomingCallNumberAPI.js.map +1 -1
  220. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js +341 -0
  221. package/build/dist/Server/API/UserNotificationMethodAdminAPI.js.map +1 -0
  222. package/build/dist/Server/API/UserPushAPI.js +95 -2
  223. package/build/dist/Server/API/UserPushAPI.js.map +1 -1
  224. package/build/dist/Server/API/UserSmsAPI.js +42 -38
  225. package/build/dist/Server/API/UserSmsAPI.js.map +1 -1
  226. package/build/dist/Server/API/UserWhatsAppAPI.js +42 -40
  227. package/build/dist/Server/API/UserWhatsAppAPI.js.map +1 -1
  228. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js +89 -0
  229. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787142779538-MigrationName.js.map +1 -0
  230. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js +12 -0
  231. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787156982416-MigrationName.js.map +1 -0
  232. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js +40 -0
  233. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787700000000-FixTotpOtpUrlAlgorithm.js.map +1 -0
  234. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
  235. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  236. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js +393 -0
  237. package/build/dist/Server/Middleware/VerificationCodeRateLimit.js.map +1 -0
  238. package/build/dist/Server/Services/AnalyticsDatabaseService.js +136 -0
  239. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  240. package/build/dist/Server/Services/DatabaseService.js +74 -0
  241. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  242. package/build/dist/Server/Services/LogAggregationService.js +5 -0
  243. package/build/dist/Server/Services/LogAggregationService.js.map +1 -1
  244. package/build/dist/Server/Services/PushNotificationService.js +69 -30
  245. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  246. package/build/dist/Server/Services/TeamMemberService.js +43 -7
  247. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  248. package/build/dist/Server/Services/UserCallService.js +54 -22
  249. package/build/dist/Server/Services/UserCallService.js.map +1 -1
  250. package/build/dist/Server/Services/UserEmailService.js +78 -17
  251. package/build/dist/Server/Services/UserEmailService.js.map +1 -1
  252. package/build/dist/Server/Services/UserIncomingCallNumberService.js +45 -74
  253. package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
  254. package/build/dist/Server/Services/UserNotificationMethodAdminService.js +1117 -0
  255. package/build/dist/Server/Services/UserNotificationMethodAdminService.js.map +1 -0
  256. package/build/dist/Server/Services/UserNotificationRuleService.js +20 -0
  257. package/build/dist/Server/Services/UserNotificationRuleService.js.map +1 -1
  258. package/build/dist/Server/Services/UserPushService.js +77 -0
  259. package/build/dist/Server/Services/UserPushService.js.map +1 -1
  260. package/build/dist/Server/Services/UserSmsService.js +50 -17
  261. package/build/dist/Server/Services/UserSmsService.js.map +1 -1
  262. package/build/dist/Server/Services/UserWhatsAppService.js +48 -15
  263. package/build/dist/Server/Services/UserWhatsAppService.js.map +1 -1
  264. package/build/dist/Server/Types/Database/QueryHelper.js +27 -0
  265. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  266. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js +46 -0
  267. package/build/dist/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.js.map +1 -1
  268. package/build/dist/Server/Utils/ChannelVerification.js +348 -0
  269. package/build/dist/Server/Utils/ChannelVerification.js.map +1 -0
  270. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js +13 -12
  271. package/build/dist/Server/Utils/Monitor/Criteria/IncomingRequestCriteria.js.map +1 -1
  272. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +20 -17
  273. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  274. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +17 -14
  275. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  276. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js +95 -0
  277. package/build/dist/Server/Utils/Monitor/MonitorResourceContext.js.map +1 -0
  278. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js +313 -0
  279. package/build/dist/Server/Utils/Monitor/MonitorStepResourceIdentity.js.map +1 -0
  280. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +3 -3
  281. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +67 -26
  282. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -1
  283. package/build/dist/Server/Utils/TotpAuth.js +127 -8
  284. package/build/dist/Server/Utils/TotpAuth.js.map +1 -1
  285. package/build/dist/Server/Utils/UserRegistrationToken.js +170 -0
  286. package/build/dist/Server/Utils/UserRegistrationToken.js.map +1 -0
  287. package/build/dist/Server/Utils/VerificationCode.js +120 -0
  288. package/build/dist/Server/Utils/VerificationCode.js.map +1 -0
  289. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  290. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  291. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +42 -21
  292. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  293. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +77 -5
  294. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -1
  295. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +18 -6
  296. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -1
  297. package/build/dist/Types/Monitor/ServiceAlertTemplates.js +1028 -0
  298. package/build/dist/Types/Monitor/ServiceAlertTemplates.js.map +1 -0
  299. package/build/dist/Types/Permission.js +33 -0
  300. package/build/dist/Types/Permission.js.map +1 -1
  301. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js +27 -0
  302. package/build/dist/Types/PushNotification/AndroidNotificationChannel.js.map +1 -0
  303. package/build/dist/Types/Service/ServiceLanguage.js +96 -0
  304. package/build/dist/Types/Service/ServiceLanguage.js.map +1 -0
  305. package/build/dist/Types/Text.js +82 -17
  306. package/build/dist/Types/Text.js.map +1 -1
  307. package/build/dist/UI/Components/Button/Button.js +22 -14
  308. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  309. package/build/dist/UI/Components/CodeBlock/CodeBlock.js +35 -3
  310. package/build/dist/UI/Components/CodeBlock/CodeBlock.js.map +1 -1
  311. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js +57 -0
  312. package/build/dist/UI/Components/CodeBlock/LanguageRegistry.js.map +1 -0
  313. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +439 -0
  314. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -0
  315. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +135 -0
  316. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -0
  317. package/build/dist/UI/Components/CommandPalette/PaletteRow.js +83 -0
  318. package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -0
  319. package/build/dist/UI/Components/CommandPalette/RecentCommands.js +47 -0
  320. package/build/dist/UI/Components/CommandPalette/RecentCommands.js.map +1 -0
  321. package/build/dist/UI/Components/CommandPalette/Types.js +2 -0
  322. package/build/dist/UI/Components/CommandPalette/Types.js.map +1 -0
  323. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js +88 -0
  324. package/build/dist/UI/Components/CommandPalette/UseProviderSearch.js.map +1 -0
  325. package/build/dist/UI/Components/Dropdown/Dropdown.js +6 -1
  326. package/build/dist/UI/Components/Dropdown/Dropdown.js.map +1 -1
  327. package/build/dist/UI/Components/Feed/FeedItem.js +1 -1
  328. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  329. package/build/dist/UI/Components/List/List.js +19 -5
  330. package/build/dist/UI/Components/List/List.js.map +1 -1
  331. package/build/dist/UI/Components/List/ListSkeleton.js +21 -0
  332. package/build/dist/UI/Components/List/ListSkeleton.js.map +1 -0
  333. package/build/dist/UI/Components/Markdown.tsx/LazyMarkdownViewer.js.map +1 -1
  334. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js +52 -25
  335. package/build/dist/UI/Components/Markdown.tsx/MarkdownViewer.js.map +1 -1
  336. package/build/dist/UI/Components/Modal/Modal.js +2 -2
  337. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  338. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  339. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +9 -2
  340. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  341. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +32 -1
  342. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  343. package/build/dist/UI/Components/Navbar/NavBar.js +5 -1
  344. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  345. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js +29 -5
  346. package/build/dist/UI/Components/OrderedStatesList/OrderedStatesList.js.map +1 -1
  347. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js +23 -1
  348. package/build/dist/UI/Components/SideMenu/CountModelSideMenuItem.js.map +1 -1
  349. package/build/dist/UI/Components/SideOver/SideOver.js +23 -2
  350. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  351. package/build/dist/UI/Components/Skeleton/Skeleton.js +23 -0
  352. package/build/dist/UI/Components/Skeleton/Skeleton.js.map +1 -0
  353. package/build/dist/UI/Components/Table/Table.js +35 -24
  354. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  355. package/build/dist/UI/Components/Table/TableSkeletonRows.js +52 -0
  356. package/build/dist/UI/Components/Table/TableSkeletonRows.js.map +1 -0
  357. package/build/dist/UI/Components/Tabs/Tab.js +1 -1
  358. package/build/dist/UI/Components/Tabs/Tab.js.map +1 -1
  359. package/build/dist/UI/Components/Toast/Toast.js +77 -23
  360. package/build/dist/UI/Components/Toast/Toast.js.map +1 -1
  361. package/build/dist/UI/Components/Toast/ToastInit.js +37 -15
  362. package/build/dist/UI/Components/Toast/ToastInit.js.map +1 -1
  363. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -9
  364. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  365. package/build/dist/UI/Utils/ModelListCache.js +126 -0
  366. package/build/dist/UI/Utils/ModelListCache.js.map +1 -0
  367. package/build/dist/UI/Utils/Project.js +24 -1
  368. package/build/dist/UI/Utils/Project.js.map +1 -1
  369. package/build/dist/Utils/API.js +6 -1
  370. package/build/dist/Utils/API.js.map +1 -1
  371. package/jest.config.json +1 -1
  372. package/package.json +2 -3
  373. package/Server/Utils/Monitor/MonitorClusterContext.ts +0 -182
  374. package/Tests/__mocks__/otpauth.js +0 -30
  375. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js +0 -141
  376. package/build/dist/Server/Utils/Monitor/MonitorClusterContext.js.map +0 -1
@@ -0,0 +1,466 @@
1
+ import { describe, expect, test } from "@jest/globals";
2
+ import DashboardMonitorListComponentUtil from "../../../../Utils/Dashboard/Components/DashboardMonitorListComponent";
3
+ import DashboardComponentsUtil from "../../../../Utils/Dashboard/Components/Index";
4
+ import DashboardMonitorListComponent from "../../../../Types/Dashboard/DashboardComponents/DashboardMonitorListComponent";
5
+ import DashboardBaseComponent from "../../../../Types/Dashboard/DashboardComponents/DashboardBaseComponent";
6
+ import {
7
+ ComponentArgument,
8
+ ComponentInputType,
9
+ EntityFilterModelType,
10
+ } from "../../../../Types/Dashboard/DashboardComponents/ComponentArgument";
11
+ import DashboardComponentType from "../../../../Types/Dashboard/DashboardComponentType";
12
+ import { ObjectType } from "../../../../Types/JSON";
13
+ import {
14
+ MonitorTypeHelper,
15
+ MonitorTypeProps,
16
+ } from "../../../../Types/Monitor/MonitorType";
17
+
18
+ /*
19
+ * DashboardMonitorListComponentUtil is a pure factory with two
20
+ * responsibilities: getDefaultComponent() produces the widget the editor
21
+ * drops on the canvas when a user adds a "Monitor List", and
22
+ * getComponentConfigArguments() declares the fields its settings form renders.
23
+ *
24
+ * Nothing here touches the network, a database, the clock, or Math.random —
25
+ * componentId is the one non-deterministic field and comes from
26
+ * ObjectID.generate(), which only needs to be distinct per call, never a
27
+ * specific value. So this suite pins the machine-readable contract that the
28
+ * rest of the dashboard silently depends on: the persisted argument `id`s and
29
+ * their order, which editor each `type` renders, the exact dropdown `value`s
30
+ * the rendering code later switches on, the entity-model bindings, and the
31
+ * alphabetical monitor-type option list built from MonitorTypeHelper. If any
32
+ * of those drift, the widget misbehaves at runtime with no compiler error to
33
+ * catch it.
34
+ */
35
+
36
+ type MonitorListArgument = ComponentArgument<DashboardMonitorListComponent>;
37
+
38
+ type ArgumentId = keyof DashboardMonitorListComponent["arguments"];
39
+
40
+ interface OptionShape {
41
+ label: unknown;
42
+ value: unknown;
43
+ }
44
+
45
+ /*
46
+ * The declared argument ids, in the exact order the source pushes them. The
47
+ * order is not cosmetic — it is the top-to-bottom field order of the settings
48
+ * form.
49
+ */
50
+ const EXPECTED_ARGUMENT_IDS: Array<ArgumentId> = [
51
+ "title",
52
+ "maxRows",
53
+ "viewMode",
54
+ "statusFilter",
55
+ "monitorStatusIds",
56
+ "monitorTypes",
57
+ "labelIds",
58
+ ];
59
+
60
+ const DISPLAY_SECTION_ARGUMENT_IDS: Array<ArgumentId> = [
61
+ "title",
62
+ "maxRows",
63
+ "viewMode",
64
+ ];
65
+
66
+ const FILTER_SECTION_ARGUMENT_IDS: Array<ArgumentId> = [
67
+ "statusFilter",
68
+ "monitorStatusIds",
69
+ "monitorTypes",
70
+ "labelIds",
71
+ ];
72
+
73
+ const VALID_INPUT_TYPES: Set<string> = new Set<string>(
74
+ Object.values(ComponentInputType),
75
+ );
76
+
77
+ function getArguments(): Array<MonitorListArgument> {
78
+ return DashboardMonitorListComponentUtil.getComponentConfigArguments();
79
+ }
80
+
81
+ function getArgumentById(id: ArgumentId): MonitorListArgument {
82
+ const found: MonitorListArgument | undefined = getArguments().find(
83
+ (arg: MonitorListArgument) => {
84
+ return arg.id === id;
85
+ },
86
+ );
87
+
88
+ if (!found) {
89
+ throw new Error(`No monitor-list argument declared with id "${id}"`);
90
+ }
91
+
92
+ return found;
93
+ }
94
+
95
+ function getOptions(id: ArgumentId): Array<OptionShape> {
96
+ return (getArgumentById(id).dropdownOptions ?? []) as Array<OptionShape>;
97
+ }
98
+
99
+ describe("DashboardMonitorListComponentUtil", () => {
100
+ describe("getDefaultComponent", () => {
101
+ test("declares its componentType as MonitorList so the renderer dispatch matches", () => {
102
+ expect(
103
+ DashboardMonitorListComponentUtil.getDefaultComponent().componentType,
104
+ ).toBe(DashboardComponentType.MonitorList);
105
+ });
106
+
107
+ test("marks itself as a dashboard component so it survives config serialization", () => {
108
+ expect(
109
+ DashboardMonitorListComponentUtil.getDefaultComponent()._type,
110
+ ).toBe(ObjectType.DashboardComponent);
111
+ });
112
+
113
+ test("defaults to a 6x4 tile placed at the canvas origin", () => {
114
+ const component: DashboardMonitorListComponent =
115
+ DashboardMonitorListComponentUtil.getDefaultComponent();
116
+
117
+ expect(component.widthInDashboardUnits).toBe(6);
118
+ expect(component.heightInDashboardUnits).toBe(4);
119
+ expect(component.topInDashboardUnits).toBe(0);
120
+ expect(component.leftInDashboardUnits).toBe(0);
121
+ });
122
+
123
+ test("cannot be resized below its 6x3 minimum, and the minimum fits inside the default", () => {
124
+ const component: DashboardMonitorListComponent =
125
+ DashboardMonitorListComponentUtil.getDefaultComponent();
126
+
127
+ expect(component.minWidthInDashboardUnits).toBe(6);
128
+ expect(component.minHeightInDashboardUnits).toBe(3);
129
+
130
+ /*
131
+ * A minimum larger than the default size would make the widget
132
+ * un-shrinkable from the moment it is dropped, so the two must be
133
+ * consistent.
134
+ */
135
+ expect(component.minWidthInDashboardUnits).toBeLessThanOrEqual(
136
+ component.widthInDashboardUnits,
137
+ );
138
+ expect(component.minHeightInDashboardUnits).toBeLessThanOrEqual(
139
+ component.heightInDashboardUnits,
140
+ );
141
+ });
142
+
143
+ test("defaults maxRows to 25 and leaves every filter unset", () => {
144
+ const component: DashboardMonitorListComponent =
145
+ DashboardMonitorListComponentUtil.getDefaultComponent();
146
+
147
+ expect(component.arguments.maxRows).toBe(25);
148
+
149
+ /*
150
+ * A freshly dropped widget must show all monitors — none of the optional
151
+ * filters may be pre-populated, or the user sees a mysteriously empty
152
+ * list they never asked to narrow.
153
+ */
154
+ expect(component.arguments.title).toBeUndefined();
155
+ expect(component.arguments.viewMode).toBeUndefined();
156
+ expect(component.arguments.statusFilter).toBeUndefined();
157
+ expect(component.arguments.monitorStatusIds).toBeUndefined();
158
+ expect(component.arguments.monitorTypes).toBeUndefined();
159
+ expect(component.arguments.labelIds).toBeUndefined();
160
+ });
161
+
162
+ test("uses the same default row count that the maxRows field shows as its placeholder", () => {
163
+ /*
164
+ * The 25 in getDefaultComponent and the "25" placeholder on the maxRows
165
+ * field are the same promise made twice; if they drift, the form hints a
166
+ * default the widget does not actually use.
167
+ */
168
+ const component: DashboardMonitorListComponent =
169
+ DashboardMonitorListComponentUtil.getDefaultComponent();
170
+ const maxRowsArgument: MonitorListArgument = getArgumentById("maxRows");
171
+
172
+ expect(String(component.arguments.maxRows)).toBe(
173
+ maxRowsArgument.placeholder,
174
+ );
175
+ });
176
+
177
+ test("generates a well-formed, distinct componentId per call so two widgets never collide", () => {
178
+ const first: DashboardMonitorListComponent =
179
+ DashboardMonitorListComponentUtil.getDefaultComponent();
180
+ const second: DashboardMonitorListComponent =
181
+ DashboardMonitorListComponentUtil.getDefaultComponent();
182
+
183
+ expect(first.componentId.toString().length).toBeGreaterThan(0);
184
+ expect(first.componentId.toString()).not.toBe(
185
+ second.componentId.toString(),
186
+ );
187
+ });
188
+ });
189
+
190
+ describe("getComponentConfigArguments", () => {
191
+ test("declares exactly the seven documented arguments, in form order", () => {
192
+ expect(
193
+ getArguments().map((arg: MonitorListArgument) => {
194
+ return arg.id;
195
+ }),
196
+ ).toEqual(EXPECTED_ARGUMENT_IDS);
197
+ });
198
+
199
+ test("gives every argument a name, description, valid input type and boolean required flag", () => {
200
+ for (const arg of getArguments()) {
201
+ expect(typeof arg.name).toBe("string");
202
+ expect(arg.name.length).toBeGreaterThan(0);
203
+ expect(typeof arg.description).toBe("string");
204
+ expect(arg.description.length).toBeGreaterThan(0);
205
+ expect(VALID_INPUT_TYPES.has(arg.type)).toBe(true);
206
+ expect(typeof arg.required).toBe("boolean");
207
+ }
208
+ });
209
+
210
+ test("marks every argument optional so the widget renders with no configuration", () => {
211
+ /*
212
+ * Nothing about a monitor-list widget is mandatory to configure — it
213
+ * works with defaults — so a required field here would block the form
214
+ * from ever validating.
215
+ */
216
+ for (const arg of getArguments()) {
217
+ expect(arg.required).toBe(false);
218
+ }
219
+ });
220
+
221
+ test("declares no duplicate argument ids", () => {
222
+ const ids: Array<ArgumentId> = getArguments().map(
223
+ (arg: MonitorListArgument) => {
224
+ return arg.id;
225
+ },
226
+ );
227
+
228
+ /*
229
+ * A duplicate id means the second field silently overwrites the first
230
+ * field's stored value.
231
+ */
232
+ expect(new Set<ArgumentId>(ids).size).toBe(ids.length);
233
+ });
234
+
235
+ test("puts every argument in a section so the settings panel can group them", () => {
236
+ for (const arg of getArguments()) {
237
+ expect(arg.section).toBeDefined();
238
+ expect((arg.section?.name.length ?? 0) > 0).toBe(true);
239
+ expect(typeof arg.section?.order).toBe("number");
240
+ }
241
+ });
242
+
243
+ test("returns a fresh, equivalent array on each call so one rendering cannot corrupt another", () => {
244
+ const first: Array<MonitorListArgument> = getArguments();
245
+ const second: Array<MonitorListArgument> = getArguments();
246
+
247
+ expect(second).toEqual(first);
248
+ expect(second).not.toBe(first);
249
+ });
250
+ });
251
+
252
+ describe("Display Options section", () => {
253
+ test("groups the title, maxRows and viewMode fields under 'Display Options' at order 1", () => {
254
+ for (const id of DISPLAY_SECTION_ARGUMENT_IDS) {
255
+ const arg: MonitorListArgument = getArgumentById(id);
256
+ expect(arg.section?.name).toBe("Display Options");
257
+ expect(arg.section?.order).toBe(1);
258
+ }
259
+ });
260
+
261
+ test("renders the title as an optional free-text field", () => {
262
+ const arg: MonitorListArgument = getArgumentById("title");
263
+
264
+ expect(arg.type).toBe(ComponentInputType.Text);
265
+ expect(arg.required).toBe(false);
266
+ expect(arg.entityFilterModelType).toBeUndefined();
267
+ });
268
+
269
+ test("renders maxRows as a Number field hinting the default of 25", () => {
270
+ const arg: MonitorListArgument = getArgumentById("maxRows");
271
+
272
+ expect(arg.type).toBe(ComponentInputType.Number);
273
+ expect(arg.placeholder).toBe("25");
274
+ });
275
+
276
+ test("wires in the shared viewMode dropdown offering list and honeycomb", () => {
277
+ const arg: MonitorListArgument = getArgumentById("viewMode");
278
+
279
+ expect(arg.type).toBe(ComponentInputType.Dropdown);
280
+ expect(
281
+ getOptions("viewMode").map((option: OptionShape) => {
282
+ return option.value;
283
+ }),
284
+ ).toEqual(["list", "honeycomb"]);
285
+ });
286
+ });
287
+
288
+ describe("Filters section", () => {
289
+ test("groups every filter under 'Filters' at order 2, collapsed by default", () => {
290
+ for (const id of FILTER_SECTION_ARGUMENT_IDS) {
291
+ const arg: MonitorListArgument = getArgumentById(id);
292
+ expect(arg.section?.name).toBe("Filters");
293
+ expect(arg.section?.order).toBe(2);
294
+ expect(arg.section?.defaultCollapsed).toBe(true);
295
+ }
296
+ });
297
+
298
+ test("orders the Filters section after the Display Options section", () => {
299
+ const displayOrder: number = getArgumentById("title").section?.order ?? 0;
300
+ const filterOrder: number =
301
+ getArgumentById("statusFilter").section?.order ?? 0;
302
+
303
+ expect(filterOrder).toBeGreaterThan(displayOrder);
304
+ });
305
+
306
+ test("offers the operational quick-filter with an empty 'All' sentinel first", () => {
307
+ const arg: MonitorListArgument = getArgumentById("statusFilter");
308
+
309
+ expect(arg.type).toBe(ComponentInputType.Dropdown);
310
+ expect(getOptions("statusFilter")).toEqual([
311
+ { label: "All", value: "" },
312
+ { label: "Operational only", value: "operational" },
313
+ { label: "Not operational only", value: "non-operational" },
314
+ ]);
315
+
316
+ /*
317
+ * The first option's empty-string value is the deliberate "no filter"
318
+ * sentinel; it is the one dropdown value in this widget that is allowed
319
+ * to be falsy, so a generic truthiness check must not be applied to it.
320
+ */
321
+ const firstOption: OptionShape | undefined =
322
+ getOptions("statusFilter")[0];
323
+ expect(firstOption?.value).toBe("");
324
+ });
325
+
326
+ test("binds the status filter to the MonitorStatus entity model", () => {
327
+ const arg: MonitorListArgument = getArgumentById("monitorStatusIds");
328
+
329
+ expect(arg.type).toBe(ComponentInputType.EntityMultiSelectDropdown);
330
+ expect(arg.entityFilterModelType).toBe(
331
+ EntityFilterModelType.MonitorStatus,
332
+ );
333
+ expect(arg.placeholder).toBe("All statuses");
334
+ expect(arg.dropdownOptions).toBeUndefined();
335
+ });
336
+
337
+ test("binds the label filter to the Label entity model", () => {
338
+ const arg: MonitorListArgument = getArgumentById("labelIds");
339
+
340
+ expect(arg.type).toBe(ComponentInputType.EntityMultiSelectDropdown);
341
+ expect(arg.entityFilterModelType).toBe(EntityFilterModelType.Label);
342
+ expect(arg.placeholder).toBe("All labels");
343
+ expect(arg.dropdownOptions).toBeUndefined();
344
+ });
345
+
346
+ test("renders the monitor-type filter as a static multi-select, not an entity lookup", () => {
347
+ const arg: MonitorListArgument = getArgumentById("monitorTypes");
348
+
349
+ expect(arg.type).toBe(ComponentInputType.MultiSelectDropdown);
350
+ expect(arg.placeholder).toBe("All monitor types");
351
+
352
+ /*
353
+ * Monitor types are a fixed enum, not a project-scoped model, so this
354
+ * field must carry a static option list and no entity binding.
355
+ */
356
+ expect(arg.entityFilterModelType).toBeUndefined();
357
+ expect(Array.isArray(arg.dropdownOptions)).toBe(true);
358
+ });
359
+ });
360
+
361
+ describe("monitor-type dropdown options", () => {
362
+ test("offers exactly one option per known monitor type", () => {
363
+ const options: Array<OptionShape> = getOptions("monitorTypes");
364
+
365
+ expect(options.length).toBe(
366
+ MonitorTypeHelper.getAllMonitorTypeProps().length,
367
+ );
368
+ expect(options.length).toBeGreaterThan(0);
369
+ });
370
+
371
+ test("labels each option with the type title and stores the monitor-type value", () => {
372
+ const propsByType: Map<string, MonitorTypeProps> = new Map<
373
+ string,
374
+ MonitorTypeProps
375
+ >(
376
+ MonitorTypeHelper.getAllMonitorTypeProps().map(
377
+ (props: MonitorTypeProps): [string, MonitorTypeProps] => {
378
+ return [String(props.monitorType), props];
379
+ },
380
+ ),
381
+ );
382
+
383
+ for (const option of getOptions("monitorTypes")) {
384
+ const matched: MonitorTypeProps | undefined = propsByType.get(
385
+ String(option.value),
386
+ );
387
+
388
+ /*
389
+ * Every option value must be a real monitor type, and its label must
390
+ * be that type's own title — otherwise the picker shows a name that
391
+ * stores an unrelated (or invalid) filter value.
392
+ */
393
+ expect(matched).toBeDefined();
394
+ expect(option.label).toBe(matched?.title);
395
+ }
396
+ });
397
+
398
+ test("sorts the options alphabetically by label", () => {
399
+ const labels: Array<string> = getOptions("monitorTypes").map(
400
+ (option: OptionShape): string => {
401
+ return String(option.label);
402
+ },
403
+ );
404
+
405
+ const sortedLabels: Array<string> = [...labels].sort(
406
+ (a: string, b: string) => {
407
+ return a.localeCompare(b);
408
+ },
409
+ );
410
+
411
+ expect(labels).toEqual(sortedLabels);
412
+ });
413
+
414
+ test("contains no duplicate values so two options never map to the same filter", () => {
415
+ const values: Array<string> = getOptions("monitorTypes").map(
416
+ (option: OptionShape): string => {
417
+ return String(option.value);
418
+ },
419
+ );
420
+
421
+ expect(new Set<string>(values).size).toBe(values.length);
422
+ });
423
+
424
+ test("gives every option a non-empty string label and a truthy value", () => {
425
+ for (const option of getOptions("monitorTypes")) {
426
+ expect(typeof option.label).toBe("string");
427
+ expect((option.label as string).length).toBeGreaterThan(0);
428
+ expect(option.value).toBeTruthy();
429
+ }
430
+ });
431
+ });
432
+
433
+ /*
434
+ * These go through the registry's public lookup rather than the util
435
+ * directly, so forgetting to wire DashboardComponentType.MonitorList into
436
+ * Common/Utils/Dashboard/Components/Index.ts would fail the suite.
437
+ */
438
+ describe("registration in DashboardComponentsUtil", () => {
439
+ test("resolves DashboardComponentType.MonitorList instead of throwing", () => {
440
+ expect(() => {
441
+ return DashboardComponentsUtil.getComponentSettingsArguments(
442
+ DashboardComponentType.MonitorList,
443
+ );
444
+ }).not.toThrow();
445
+ });
446
+
447
+ test("returns the monitor-list widget's own arguments through the registry", () => {
448
+ const fromRegistry: Array<ComponentArgument<DashboardBaseComponent>> =
449
+ DashboardComponentsUtil.getComponentSettingsArguments(
450
+ DashboardComponentType.MonitorList,
451
+ );
452
+
453
+ expect(
454
+ fromRegistry.map(
455
+ (arg: ComponentArgument<DashboardBaseComponent>): unknown => {
456
+ return arg.id;
457
+ },
458
+ ),
459
+ ).toEqual(
460
+ getArguments().map((arg: MonitorListArgument): unknown => {
461
+ return arg.id;
462
+ }),
463
+ );
464
+ });
465
+ });
466
+ });