@oneuptime/common 14.0.13 → 14.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 (1045) hide show
  1. package/Models/DatabaseModels/AlertGroupingRule.ts +10 -6
  2. package/Models/DatabaseModels/File.ts +41 -2
  3. package/Models/DatabaseModels/Form.ts +126 -0
  4. package/Models/DatabaseModels/IncidentGroupingRule.ts +10 -6
  5. package/Models/DatabaseModels/LogDropFilter.ts +1 -0
  6. package/Models/DatabaseModels/LogPipeline.ts +1 -0
  7. package/Models/DatabaseModels/LogScrubRule.ts +14 -8
  8. package/Models/DatabaseModels/MetricRecordingRule.ts +2 -1
  9. package/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.ts +4 -2
  10. package/Models/DatabaseModels/OnCallDutyPolicyUserOverride.ts +22 -9
  11. package/Models/DatabaseModels/ProjectCallSMSConfig.ts +6 -1
  12. package/Models/DatabaseModels/StatusPage.ts +8 -4
  13. package/Models/DatabaseModels/TraceDropFilter.ts +1 -0
  14. package/Models/DatabaseModels/TracePipeline.ts +1 -0
  15. package/Models/DatabaseModels/TraceRecordingRule.ts +2 -1
  16. package/Models/DatabaseModels/TraceScrubRule.ts +14 -8
  17. package/Models/DatabaseModels/UserOnCallLog.ts +4 -2
  18. package/Server/API/CustomDomainRoutes.ts +251 -0
  19. package/Server/API/DashboardAPI.ts +33 -4
  20. package/Server/API/DashboardDomainAPI.ts +63 -93
  21. package/Server/API/StatusPageAPI.ts +92 -0
  22. package/Server/API/StatusPageDomainAPI.ts +59 -96
  23. package/Server/Infrastructure/GlobalCache.ts +84 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/1797700000000-AddFormBranding.ts +47 -0
  25. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  26. package/Server/Services/AlertGroupingEngineService.ts +48 -70
  27. package/Server/Services/AlertGroupingRuleService.ts +38 -0
  28. package/Server/Services/CephClusterService.ts +25 -0
  29. package/Server/Services/CloudResourceService.ts +42 -0
  30. package/Server/Services/DashboardDomainService.ts +640 -214
  31. package/Server/Services/DashboardService.ts +30 -8
  32. package/Server/Services/DatabaseService.ts +143 -12
  33. package/Server/Services/DockerHostService.ts +60 -0
  34. package/Server/Services/DockerSwarmClusterService.ts +25 -0
  35. package/Server/Services/FileService.ts +60 -0
  36. package/Server/Services/FormService.ts +212 -2
  37. package/Server/Services/GlobalOidcService.ts +10 -0
  38. package/Server/Services/GlobalSsoService.ts +10 -0
  39. package/Server/Services/HostService.ts +58 -0
  40. package/Server/Services/IncidentGroupingEngineService.ts +48 -70
  41. package/Server/Services/IncidentGroupingRuleService.ts +38 -0
  42. package/Server/Services/IoTFleetService.ts +26 -0
  43. package/Server/Services/KubernetesClusterService.ts +64 -0
  44. package/Server/Services/LabelService.ts +6 -17
  45. package/Server/Services/LogScrubRuleService.ts +50 -0
  46. package/Server/Services/OnCallDutyPolicyScheduleService.ts +264 -0
  47. package/Server/Services/OnCallDutyPolicyUserOverrideService.ts +9 -1
  48. package/Server/Services/OnCallNotificationAlertingService.ts +24 -29
  49. package/Server/Services/OnCallSetupReminderService.ts +41 -40
  50. package/Server/Services/PodmanHostService.ts +60 -0
  51. package/Server/Services/ProfileAggregationService.ts +38 -0
  52. package/Server/Services/ProjectCallSMSConfigService.ts +76 -3
  53. package/Server/Services/ProjectOidcService.ts +20 -0
  54. package/Server/Services/ProjectSsoService.ts +20 -0
  55. package/Server/Services/ProxmoxClusterService.ts +25 -0
  56. package/Server/Services/RumApplicationService.ts +45 -0
  57. package/Server/Services/ScheduledMaintenanceService.ts +9 -23
  58. package/Server/Services/ServerlessFunctionService.ts +47 -0
  59. package/Server/Services/ServiceService.ts +33 -10
  60. package/Server/Services/StatusPageDomainService.ts +622 -213
  61. package/Server/Services/StatusPageOidcService.ts +20 -0
  62. package/Server/Services/StatusPageResourceService.ts +89 -34
  63. package/Server/Services/StatusPageService.ts +270 -54
  64. package/Server/Services/StatusPageSsoService.ts +20 -0
  65. package/Server/Services/TraceScrubRuleService.ts +50 -0
  66. package/Server/Services/UserIncomingCallNumberService.ts +28 -14
  67. package/Server/Services/VMwareVCenterService.ts +25 -0
  68. package/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.ts +3 -3
  69. package/Server/Utils/Greenlock/CertificateOrder.ts +482 -0
  70. package/Server/Utils/Greenlock/CertificateOrderBudget.ts +134 -0
  71. package/Server/Utils/Greenlock/CertificateOrderFailures.ts +288 -0
  72. package/Server/Utils/Greenlock/CertificateOrderLock.ts +163 -0
  73. package/Server/Utils/Greenlock/CertificateOrderOutcome.ts +29 -0
  74. package/Server/Utils/Greenlock/CertificateOwners.ts +72 -0
  75. package/Server/Utils/Greenlock/CertificateReissueOrder.ts +99 -0
  76. package/Server/Utils/Greenlock/CustomDomainOrders.ts +397 -0
  77. package/Server/Utils/Greenlock/Greenlock.ts +839 -203
  78. package/Server/Utils/Rules/GroupingRuleEpisodeOwners.ts +551 -0
  79. package/Server/Utils/Rules/OwnerRuleAssignment.ts +8 -1
  80. package/Server/Utils/ScrubRuleValidation.ts +248 -0
  81. package/Server/Utils/StatusPage/AffectedStatusPageResources.ts +138 -0
  82. package/Server/Utils/StatusPage/StatusPagesListingMonitorsBuilder.ts +294 -0
  83. package/Server/Utils/Telemetry/DiscoveredResourceCreate.ts +275 -0
  84. package/Server/Utils/Telemetry/DiscoveredResourceUpdate.ts +217 -0
  85. package/Server/Utils/Telemetry/MessageQueueDiscovery.ts +8 -2
  86. package/Tests/App/Accounts/FormPage.test.tsx +238 -0
  87. package/Tests/App/Accounts/FormUtils.test.ts +108 -0
  88. package/Tests/App/AdminDashboard/AdminAddToProjectMembersTeam.test.tsx +1087 -0
  89. package/Tests/App/AdminDashboard/AdminAuthenticationRequireSso.test.tsx +140 -138
  90. package/Tests/App/AdminDashboard/AdminAuthenticationSsoCardLocales.test.tsx +144 -145
  91. package/Tests/App/AdminDashboard/AdminSettingsFormsOnePage.test.tsx +907 -0
  92. package/Tests/App/AdminDashboard/AdminSettingsSwitches.test.tsx +906 -0
  93. package/Tests/App/AdminDashboard/AdminSmtpSettingsForm.test.tsx +823 -0
  94. package/Tests/App/AdminDashboard/BulkAddUsersToProjectModal.test.tsx +341 -368
  95. package/Tests/App/AdminDashboard/GlobalSsoOidcPages.test.tsx +199 -54
  96. package/Tests/App/AdminDashboard/ProjectScopedTeamsPicker.test.tsx +991 -0
  97. package/Tests/App/Dashboard/AIInvestigationSettingsLimits.test.tsx +147 -90
  98. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +224 -104
  99. package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +302 -0
  100. package/Tests/App/Dashboard/AdminUserOnCallPages.test.tsx +408 -152
  101. package/Tests/App/Dashboard/AffectedResourcesPicker.test.tsx +55 -0
  102. package/Tests/App/Dashboard/AffectedResourcesPickerEditForm.test.tsx +206 -115
  103. package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +32 -0
  104. package/Tests/App/Dashboard/AffectedResourcesSummaryStep.test.tsx +206 -71
  105. package/Tests/App/Dashboard/AlertEpisodeViewFields.test.tsx +45 -9
  106. package/Tests/App/Dashboard/AnnouncementCreateForm.test.tsx +1208 -0
  107. package/Tests/App/Dashboard/AnnouncementEditAndTemplateForms.test.tsx +693 -0
  108. package/Tests/App/Dashboard/AnnouncementFormsStructure.test.ts +546 -0
  109. package/Tests/App/Dashboard/AnnouncementStatusPageSuggestions.test.tsx +425 -0
  110. package/Tests/App/Dashboard/AnnouncementsTableCreateLinks.test.tsx +267 -0
  111. package/Tests/App/Dashboard/ApiKeyCreateForm.test.ts +68 -51
  112. package/Tests/App/Dashboard/ApiKeyViewPermissions.test.tsx +11 -9
  113. package/Tests/App/Dashboard/ApiKeysCreateAccess.test.tsx +24 -16
  114. package/Tests/App/Dashboard/BulkChangeStateModalOnePage.test.tsx +333 -0
  115. package/Tests/App/Dashboard/CardDescriptionsSayWhatFor.test.tsx +307 -0
  116. package/Tests/App/Dashboard/ChangeAlertStateAIHeader.test.tsx +18 -4
  117. package/Tests/App/Dashboard/CloudDocumentationCard.test.tsx +7 -2
  118. package/Tests/App/Dashboard/ColorFieldsPrefilledPages.test.tsx +453 -0
  119. package/Tests/App/Dashboard/CreateFromRecordBreadcrumbs.test.ts +272 -0
  120. package/Tests/App/Dashboard/CreateFromRecordLinks.test.tsx +495 -0
  121. package/Tests/App/Dashboard/CreateFromRecordPages.test.tsx +1026 -0
  122. package/Tests/App/Dashboard/CreateWorkflowModal.test.tsx +65 -23
  123. package/Tests/App/Dashboard/CriteriaName.test.ts +5 -1
  124. package/Tests/App/Dashboard/CustomDomainCreateFlow.test.tsx +516 -0
  125. package/Tests/App/Dashboard/CustomDomainDnsSetupModal.test.tsx +547 -0
  126. package/Tests/App/Dashboard/CustomDomainsPages.test.tsx +1077 -0
  127. package/Tests/App/Dashboard/CustomFieldSimpleCreate.test.tsx +2 -2
  128. package/Tests/App/Dashboard/CustomFieldSimpleCreateRender.test.tsx +12 -6
  129. package/Tests/App/Dashboard/CustomFieldsSettingsIncidentOptions.test.tsx +1 -1
  130. package/Tests/App/Dashboard/CustomSmtpConfigForm.test.tsx +969 -0
  131. package/Tests/App/Dashboard/DashboardBlankCanvasAddWidget.test.tsx +425 -0
  132. package/Tests/App/Dashboard/DashboardCommandPalette.test.tsx +400 -0
  133. package/Tests/App/Dashboard/DashboardComponentsMRTranslation.test.tsx +4 -3
  134. package/Tests/App/Dashboard/DashboardCreateForm.test.ts +375 -0
  135. package/Tests/App/Dashboard/DashboardCreateFromTemplate.test.tsx +727 -0
  136. package/Tests/App/Dashboard/DashboardEmptyCanvasAddWidget.test.tsx +86 -0
  137. package/Tests/App/Dashboard/DashboardPhoneProductsMenu.test.tsx +99 -9
  138. package/Tests/App/Dashboard/DashboardSharingCard.test.tsx +1226 -0
  139. package/Tests/App/Dashboard/DashboardSharingEntryPoints.test.tsx +383 -0
  140. package/Tests/App/Dashboard/DashboardSharingPage.test.tsx +478 -0
  141. package/Tests/App/Dashboard/DeclareFormsAdvancedRender.test.tsx +90 -34
  142. package/Tests/App/Dashboard/DeclareIncidentMonitorsApart.test.tsx +1028 -0
  143. package/Tests/App/Dashboard/DefaultSsoTeams.test.tsx +215 -0
  144. package/Tests/App/Dashboard/DisabledWarningArchived.test.tsx +3 -3
  145. package/Tests/App/Dashboard/DisabledWarningRobustness.test.tsx +15 -12
  146. package/Tests/App/Dashboard/DiscoveredResourceCreateForms.test.tsx +936 -0
  147. package/Tests/App/Dashboard/EmbeddedMetricCardGroup.test.tsx +720 -0
  148. package/Tests/App/Dashboard/EpisodeMemberRoleAssignmentsFormField.test.tsx +331 -0
  149. package/Tests/App/Dashboard/EpisodePostmortemPage.test.tsx +327 -0
  150. package/Tests/App/Dashboard/EscalationRuleForm.test.ts +2 -2
  151. package/Tests/App/Dashboard/EscalationRuleFormGuard.test.ts +6 -2
  152. package/Tests/App/Dashboard/EscalationRuleOneStep.test.tsx +8 -4
  153. package/Tests/App/Dashboard/EventMeasurements.test.ts +1175 -0
  154. package/Tests/App/Dashboard/EventMeasurementsCard.test.tsx +993 -0
  155. package/Tests/App/Dashboard/EventNoteComposerDialog.test.tsx +939 -0
  156. package/Tests/App/Dashboard/EventNotes.test.tsx +34 -1
  157. package/Tests/App/Dashboard/EventOverviewPages.test.tsx +186 -1
  158. package/Tests/App/Dashboard/EventSettingsSwitchPages.test.tsx +625 -0
  159. package/Tests/App/Dashboard/ExceptionMonitorEnvironmentFilter.test.tsx +6 -2
  160. package/Tests/App/Dashboard/FeedNoteComposerDialog.test.tsx +1327 -0
  161. package/Tests/App/Dashboard/FeedNoteDialogHelpers.ts +109 -0
  162. package/Tests/App/Dashboard/FilterChipClearButton.test.tsx +356 -0
  163. package/Tests/App/Dashboard/FormBrandingSection.test.tsx +504 -0
  164. package/Tests/App/Dashboard/FormBrandingValues.test.ts +255 -0
  165. package/Tests/App/Dashboard/FormBuilderParts.test.tsx +38 -1
  166. package/Tests/App/Dashboard/FormBuilderUi.test.tsx +176 -2
  167. package/Tests/App/Dashboard/FormMappingCard.test.tsx +33 -13
  168. package/Tests/App/Dashboard/FormsMovedPagesAndSubmissions.test.tsx +1 -1
  169. package/Tests/App/Dashboard/GeneratedKeyForms.test.tsx +30 -7
  170. package/Tests/App/Dashboard/GlobalProbesOnNewMonitorsCard.test.tsx +258 -0
  171. package/Tests/App/Dashboard/GroupingRuleFormFlow.test.tsx +653 -37
  172. package/Tests/App/Dashboard/GroupingRulePages.test.tsx +218 -9
  173. package/Tests/App/Dashboard/IncidentCreateStatusPageScope.test.tsx +52 -4
  174. package/Tests/App/Dashboard/IncidentEpisodeFeedPublicNoteNotifyDefault.test.tsx +230 -338
  175. package/Tests/App/Dashboard/IncidentEpisodeViewFields.test.tsx +45 -9
  176. package/Tests/App/Dashboard/IncidentFeedPublicNoteNotifyDefault.test.tsx +227 -295
  177. package/Tests/App/Dashboard/IncidentLinkedAlertsSettingsPage.test.tsx +157 -181
  178. package/Tests/App/Dashboard/IncidentPostmortemPage.test.tsx +775 -0
  179. package/Tests/App/Dashboard/IncidentRoleFormField.test.tsx +379 -15
  180. package/Tests/App/Dashboard/IncidentRolesSettingsPage.test.tsx +148 -32
  181. package/Tests/App/Dashboard/IncidentTemplateInitialState.test.tsx +430 -0
  182. package/Tests/App/Dashboard/IncidentTemplateMonitorsApart.test.tsx +492 -0
  183. package/Tests/App/Dashboard/IncomingCallEscalationOneStep.test.tsx +830 -0
  184. package/Tests/App/Dashboard/IncomingCallEscalationRuleForm.test.ts +510 -0
  185. package/Tests/App/Dashboard/IncomingCallEscalationRuleFormGuard.test.ts +378 -0
  186. package/Tests/App/Dashboard/IngestionKeyForm.test.ts +664 -0
  187. package/Tests/App/Dashboard/IngestionKeySelectorCreate.test.tsx +523 -0
  188. package/Tests/App/Dashboard/InventoryTypeAndStatusFacets.test.tsx +130 -9
  189. package/Tests/App/Dashboard/IpAllowlistCopy.test.ts +122 -0
  190. package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +19 -3
  191. package/Tests/App/Dashboard/KubernetesMetricsSetupEmptyState.test.tsx +275 -0
  192. package/Tests/App/Dashboard/KubernetesMetricsSetupHints.test.tsx +720 -0
  193. package/Tests/App/Dashboard/LabelsFormField.test.tsx +18 -13
  194. package/Tests/App/Dashboard/LegacyDefaultAssigneeNote.test.tsx +359 -0
  195. package/Tests/App/Dashboard/LogMonitorAttributeOperatorPreview.test.tsx +10 -10
  196. package/Tests/App/Dashboard/MarkdownTemplateDialogsWide.test.tsx +42 -20
  197. package/Tests/App/Dashboard/MeasurementForms.test.tsx +191 -5
  198. package/Tests/App/Dashboard/MeasurementPagesI18n.test.ts +2 -0
  199. package/Tests/App/Dashboard/MeasurementSetup.test.ts +5 -2
  200. package/Tests/App/Dashboard/MenuSpecificFoldedSections.test.tsx +38 -12
  201. package/Tests/App/Dashboard/MessageQueueRulePages.test.tsx +34 -11
  202. package/Tests/App/Dashboard/MetricAndRecordingRuleFormsRender.test.tsx +1206 -0
  203. package/Tests/App/Dashboard/MetricResultsState.test.ts +248 -0
  204. package/Tests/App/Dashboard/MetricViewResultsState.test.tsx +404 -0
  205. package/Tests/App/Dashboard/MonitorCreateFromMonitorBackedDevice.test.tsx +1 -1
  206. package/Tests/App/Dashboard/MonitorCriteriaAdvancedOptions.test.tsx +77 -27
  207. package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +5 -8
  208. package/Tests/App/Dashboard/MonitorCriteriaHeaderControls.test.tsx +228 -0
  209. package/Tests/App/Dashboard/MonitorCriteriaIncidentRoles.test.tsx +411 -0
  210. package/Tests/App/Dashboard/MonitorFeedRefresh.test.tsx +5 -1
  211. package/Tests/App/Dashboard/MonitorFormIncidentRoles.test.tsx +460 -0
  212. package/Tests/App/Dashboard/MonitorIntervalRedirect.test.tsx +299 -0
  213. package/Tests/App/Dashboard/MonitorOverviewHero.test.tsx +243 -2
  214. package/Tests/App/Dashboard/MonitorProbesAndIntervalPage.test.tsx +638 -0
  215. package/Tests/App/Dashboard/MonitorStepsDefaultStatusAdvanced.test.tsx +2 -2
  216. package/Tests/App/Dashboard/MonitorSummaryTestMonitorButton.test.tsx +2 -2
  217. package/Tests/App/Dashboard/MonitoringIntervalCard.test.tsx +493 -0
  218. package/Tests/App/Dashboard/MonitoringSwitch.test.tsx +597 -0
  219. package/Tests/App/Dashboard/MovedRunnerSettingsRedirects.test.tsx +4 -5
  220. package/Tests/App/Dashboard/NotificationChannelOffSwitchLists.test.tsx +636 -0
  221. package/Tests/App/Dashboard/OnCallPolicyCreateFormGuard.test.ts +8 -4
  222. package/Tests/App/Dashboard/OnCallPolicyFirstResponders.test.tsx +1 -1
  223. package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +54 -0
  224. package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +43 -24
  225. package/Tests/App/Dashboard/OnCallRulesRedirects.test.tsx +530 -0
  226. package/Tests/App/Dashboard/OnCallRulesTable.test.tsx +158 -74
  227. package/Tests/App/Dashboard/OnCallRulesTabs.test.tsx +511 -0
  228. package/Tests/App/Dashboard/OnCallScheduleAddLayerDefaults.test.tsx +236 -0
  229. package/Tests/App/Dashboard/OnCallScheduleCreateFormGuard.test.ts +633 -0
  230. package/Tests/App/Dashboard/OnCallScheduleOverrideClarity.test.tsx +13 -2
  231. package/Tests/App/Dashboard/OnCallScheduleWhoTakesTurns.test.tsx +771 -0
  232. package/Tests/App/Dashboard/OnCallSharedCalendarFeedSettingsForm.test.tsx +357 -0
  233. package/Tests/App/Dashboard/OnCallShiftRemindersAndUpcomingShifts.test.tsx +16 -6
  234. package/Tests/App/Dashboard/OnboardingSsoEmptyState.test.tsx +112 -23
  235. package/Tests/App/Dashboard/PageSearchIndexCoversMenus.test.tsx +594 -0
  236. package/Tests/App/Dashboard/PageSearchIndexCoversRoutes.test.tsx +271 -0
  237. package/Tests/App/Dashboard/PageSearchRanking.test.tsx +373 -0
  238. package/Tests/App/Dashboard/PostmortemPageParts.test.tsx +548 -0
  239. package/Tests/App/Dashboard/ProbeAgreementCard.test.tsx +483 -0
  240. package/Tests/App/Dashboard/ProductOrientation.test.tsx +9 -2
  241. package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +282 -404
  242. package/Tests/App/Dashboard/ProjectAiSettingsSwitchPages.test.tsx +1414 -0
  243. package/Tests/App/Dashboard/ProjectNotificationChannels.test.tsx +1191 -0
  244. package/Tests/App/Dashboard/ProjectSettingsSwitchCards.test.tsx +603 -0
  245. package/Tests/App/Dashboard/RemindersCard.test.tsx +477 -0
  246. package/Tests/App/Dashboard/ResourceDetailsCard.test.tsx +458 -0
  247. package/Tests/App/Dashboard/ResourceRuleForm.test.ts +525 -0
  248. package/Tests/App/Dashboard/ResourceRuleFormsRender.test.tsx +803 -0
  249. package/Tests/App/Dashboard/RoleAccess.test.ts +753 -0
  250. package/Tests/App/Dashboard/RoleCardSelectOptions.test.ts +13 -6
  251. package/Tests/App/Dashboard/RouteUtilPageRoute.test.ts +116 -0
  252. package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +1 -1
  253. package/Tests/App/Dashboard/RumSessionReplayRetentionSettings.test.tsx +172 -219
  254. package/Tests/App/Dashboard/RunbookStepHeaderControls.test.tsx +269 -0
  255. package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +45 -85
  256. package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +16 -23
  257. package/Tests/App/Dashboard/ScheduledMaintenanceAffectedResourcesEditForm.test.tsx +485 -0
  258. package/Tests/App/Dashboard/ScheduledMaintenanceChangeStateNotifyDefault.test.tsx +27 -2
  259. package/Tests/App/Dashboard/ScheduledMaintenanceCreateForm.test.tsx +65 -28
  260. package/Tests/App/Dashboard/ScheduledMaintenanceFeedPublicNoteNotifyDefault.test.tsx +208 -309
  261. package/Tests/App/Dashboard/ScheduledMaintenanceFeedRefresh.test.tsx +36 -53
  262. package/Tests/App/Dashboard/ScheduledMaintenanceFormsStructure.test.ts +83 -14
  263. package/Tests/App/Dashboard/ScheduledMaintenanceMonitorsApart.test.tsx +1085 -0
  264. package/Tests/App/Dashboard/ScheduledMaintenanceOverviewPage.test.tsx +378 -25
  265. package/Tests/App/Dashboard/ScheduledMaintenanceStatusPageSuggestions.test.tsx +513 -0
  266. package/Tests/App/Dashboard/ScheduledMaintenanceTemplateForm.test.tsx +31 -9
  267. package/Tests/App/Dashboard/ScheduledMaintenanceTemplateMonitorsApart.test.tsx +760 -0
  268. package/Tests/App/Dashboard/SecurityEventConnectionFormModal.test.tsx +11 -13
  269. package/Tests/App/Dashboard/SecurityEventsMonitorStepForm.test.tsx +228 -69
  270. package/Tests/App/Dashboard/SelectedProjectSwitches.test.tsx +359 -0
  271. package/Tests/App/Dashboard/ServerlessSetupGuide.test.ts +1 -1
  272. package/Tests/App/Dashboard/SessionReplayAllowedCard.test.tsx +297 -0
  273. package/Tests/App/Dashboard/SetupGuideCard.test.tsx +7 -1
  274. package/Tests/App/Dashboard/ShortFormsOnePage.test.tsx +591 -0
  275. package/Tests/App/Dashboard/SloNoticeBanner.test.tsx +253 -6
  276. package/Tests/App/Dashboard/SloOverviewData.test.tsx +99 -0
  277. package/Tests/App/Dashboard/SloOverviewLayout.test.tsx +3 -1
  278. package/Tests/App/Dashboard/SloSettings.test.tsx +257 -4
  279. package/Tests/App/Dashboard/SsoPages.test.tsx +448 -52
  280. package/Tests/App/Dashboard/StateChangeDialogsFolded.test.tsx +695 -0
  281. package/Tests/App/Dashboard/StateChangeFormFields.test.ts +376 -0
  282. package/Tests/App/Dashboard/StatusPageAccessCard.test.tsx +1088 -0
  283. package/Tests/App/Dashboard/StatusPageAccessCopy.test.ts +450 -0
  284. package/Tests/App/Dashboard/StatusPageAccessMenu.test.tsx +137 -0
  285. package/Tests/App/Dashboard/StatusPageAccessPage.test.tsx +458 -0
  286. package/Tests/App/Dashboard/StatusPageAdvancedSettingsPage.test.tsx +30 -86
  287. package/Tests/App/Dashboard/StatusPageBrandingPage.test.tsx +28 -15
  288. package/Tests/App/Dashboard/StatusPageDisplaySettingsCard.test.tsx +949 -14
  289. package/Tests/App/Dashboard/StatusPagePrivateUsersNotice.test.tsx +233 -0
  290. package/Tests/App/Dashboard/StatusPageReportsCard.test.tsx +1001 -0
  291. package/Tests/App/Dashboard/StatusPageRequireSsoCard.test.tsx +247 -0
  292. package/Tests/App/Dashboard/StatusPageSubscriberSettingsPages.test.tsx +4 -17
  293. package/Tests/App/Dashboard/StatusPageSuggestions.test.tsx +930 -0
  294. package/Tests/App/Dashboard/StatusPageSwitchCardPages.test.tsx +335 -0
  295. package/Tests/App/Dashboard/TeamBlockPermissionsRedirect.test.tsx +332 -0
  296. package/Tests/App/Dashboard/TeamCreateForm.test.ts +206 -0
  297. package/Tests/App/Dashboard/TeamViewPermissions.test.tsx +713 -0
  298. package/Tests/App/Dashboard/TeamViewSideMenuBlockPermissions.test.tsx +113 -0
  299. package/Tests/App/Dashboard/TeamsCreateAccess.test.tsx +799 -0
  300. package/Tests/App/Dashboard/TelemetryDataRuleForms.test.ts +655 -0
  301. package/Tests/App/Dashboard/TelemetryDataRuleFormsRender.test.tsx +1014 -0
  302. package/Tests/App/Dashboard/TelemetryIngestionKeyEdit.test.tsx +6 -3
  303. package/Tests/App/Dashboard/TelemetryIngestionKeyForm.test.tsx +446 -446
  304. package/Tests/App/Dashboard/TelemetryMonitorFiltersFold.test.tsx +613 -0
  305. package/Tests/App/Dashboard/TelemetryRetentionShells.test.tsx +37 -2
  306. package/Tests/App/Dashboard/TemplateFormsNoInternalDataWarning.test.tsx +3 -3
  307. package/Tests/App/Dashboard/TraceExplorer.test.tsx +338 -0
  308. package/Tests/App/Dashboard/TwilioConfigFirstDefault.test.tsx +786 -0
  309. package/Tests/App/Dashboard/UpcomingShiftGetCover.test.tsx +306 -0
  310. package/Tests/App/Dashboard/UseBulkShortenDeviceNames.test.tsx +36 -11
  311. package/Tests/App/Dashboard/UserOverrideForm.test.ts +505 -0
  312. package/Tests/App/Dashboard/UserOverrideFormGuard.test.ts +334 -0
  313. package/Tests/App/Dashboard/UserOverrideWhoIsAway.test.tsx +999 -0
  314. package/Tests/App/Dashboard/UserSettingsSetupChecklistModel.test.ts +33 -11
  315. package/Tests/App/Dashboard/UserSettingsSetupChecklistPage.test.tsx +49 -4
  316. package/Tests/App/Dashboard/UsersPageEmptyState.test.tsx +245 -0
  317. package/Tests/App/Dashboard/WorkflowVariableOAuthSettingsEditSteps.test.tsx +13 -6
  318. package/Tests/App/Dashboard/WorkspaceMenusConnected.test.tsx +0 -2
  319. package/Tests/App/StatusPage/BulkAddStatusPageMonitorsModal.test.tsx +108 -86
  320. package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +397 -0
  321. package/Tests/App/StatusPage/StatusPageResourceForm.test.tsx +931 -0
  322. package/Tests/App/StatusPage/StatusPageSubscribeOnePage.test.tsx +686 -0
  323. package/Tests/DialogActionRules.ts +16 -5
  324. package/Tests/Helpers/CardHeaderScan.ts +258 -0
  325. package/Tests/Helpers/FormStepsScan.ts +576 -11
  326. package/Tests/Helpers/MonitorGroupStatusPageRows.ts +237 -0
  327. package/Tests/Helpers/NestedControls.ts +184 -0
  328. package/Tests/Helpers/NestedControlsScan.ts +414 -0
  329. package/Tests/Helpers/SteppedFooterScan.ts +722 -0
  330. package/Tests/Models/DatabaseModels/FormModel.test.ts +31 -7
  331. package/Tests/Models/DatabaseModels/UserOverrideColumnDescriptions.test.ts +123 -0
  332. package/Tests/Models/TelemetryDataRuleColumnDefaults.test.ts +239 -0
  333. package/Tests/ResponsiveFlexLayout.test.ts +111 -0
  334. package/Tests/ResponsiveFlexLayout.ts +165 -0
  335. package/Tests/Server/API/DashboardDomainOrderSslAPI.test.ts +372 -0
  336. package/Tests/Server/API/DashboardDomainVerifyCnameAPI.test.ts +921 -0
  337. package/Tests/Server/API/DashboardSharingPublicRoutes.test.ts +559 -0
  338. package/Tests/Server/API/FormBrandingPublicRoutes.test.ts +680 -0
  339. package/Tests/Server/API/ProjectAPICreateWithTenantHeader.test.ts +300 -0
  340. package/Tests/Server/API/ProjectCreateTestHelpers.ts +211 -0
  341. package/Tests/Server/API/ProjectCreateWithTenantHeaderPostgres.test.ts +387 -0
  342. package/Tests/Server/API/PublicRouteInvalidAccessToken.test.ts +29 -12
  343. package/Tests/Server/API/StatusPageDomainVerifyCnameAPI.test.ts +1090 -0
  344. package/Tests/Server/API/StatusPageMasterPageAccess.test.ts +254 -0
  345. package/Tests/Server/API/StatusPageReportScheduleWrites.test.ts +829 -0
  346. package/Tests/Server/API/StatusPageUptimeSettingsWrites.test.ts +417 -0
  347. package/Tests/Server/API/StatusPagesListingMonitorsAPI.test.ts +1029 -0
  348. package/Tests/Server/API/StatusPagesListingMonitorsRoute.test.ts +286 -0
  349. package/Tests/Server/Infrastructure/GlobalCache.test.ts +156 -0
  350. package/Tests/Server/Infrastructure/Postgres/MigrateIncidentFormsToFormsMigration.test.ts +52 -1
  351. package/Tests/Server/Services/CustomDomainCertificateLifecycle.test.ts +1559 -0
  352. package/Tests/Server/Services/CustomDomainCertificateReissue.test.ts +186 -16
  353. package/Tests/Server/Services/DashboardAccessChoice.test.ts +657 -0
  354. package/Tests/Server/Services/DashboardCreateFromTemplate.test.ts +200 -0
  355. package/Tests/Server/Services/DashboardDomainCertificateSweeps.test.ts +1142 -0
  356. package/Tests/Server/Services/DiscoveredResourceCreate.test.ts +864 -0
  357. package/Tests/Server/Services/DiscoveredResourceUpdate.test.ts +822 -0
  358. package/Tests/Server/Services/EpisodeRuleSeverityRepair.test.ts +3 -4
  359. package/Tests/Server/Services/FileServiceProject.test.ts +345 -0
  360. package/Tests/Server/Services/FormBranding.test.ts +982 -0
  361. package/Tests/Server/Services/FormPublicForm.test.ts +15 -0
  362. package/Tests/Server/Services/GroupingRuleEpisodeOwners.test.ts +857 -0
  363. package/Tests/Server/Services/IncidentFormPostgres.test.ts +297 -1
  364. package/Tests/Server/Services/MachinePickedColors.test.ts +202 -0
  365. package/Tests/Server/Services/OidcProviderCreateDefaults.test.ts +252 -0
  366. package/Tests/Server/Services/OnCallDutyPolicyScheduleFirstLayer.test.ts +799 -0
  367. package/Tests/Server/Services/OnCallDutyPolicyScheduleFirstLayerPlans.test.ts +172 -0
  368. package/Tests/Server/Services/OnCallDutyPolicyUserOverrideWhoIsAway.test.ts +571 -0
  369. package/Tests/Server/Services/OnCallSetupReminder.test.ts +35 -13
  370. package/Tests/Server/Services/OnCallUndeliverablePageRulesLink.test.ts +217 -0
  371. package/Tests/Server/Services/ProfileAggregationService.test.ts +213 -4
  372. package/Tests/Server/Services/ProjectCallSMSConfigFirstDefault.test.ts +699 -0
  373. package/Tests/Server/Services/ProjectCallSMSConfigFirstDefaultBilling.test.ts +247 -0
  374. package/Tests/Server/Services/SamlProviderCreateDefaults.test.ts +255 -0
  375. package/Tests/Server/Services/ScheduledMaintenanceSubscriberMonitorGroups.test.ts +333 -0
  376. package/Tests/Server/Services/ScrubRuleSaveValidation.test.ts +947 -0
  377. package/Tests/Server/Services/StaticRuleCriteriaRuntimeCoverage.test.ts +17 -4
  378. package/Tests/Server/Services/StatusPageAccessChoice.test.ts +548 -0
  379. package/Tests/Server/Services/StatusPageDomainCertificateSweeps.test.ts +1238 -0
  380. package/Tests/Server/Services/TeamCreateAccessGrant.test.ts +607 -0
  381. package/Tests/Server/Services/TwilioConfigSendersGuard.test.ts +249 -0
  382. package/Tests/Server/Services/VerificationCodesUseProjectTwilioConfig.test.ts +264 -0
  383. package/Tests/Server/Types/Database/Permissions/FormBrandingColumns.test.ts +270 -0
  384. package/Tests/Server/Utils/Greenlock/CertificateCleanup.test.ts +526 -0
  385. package/Tests/Server/Utils/Greenlock/CertificateOrder.test.ts +1062 -0
  386. package/Tests/Server/Utils/Greenlock/CertificateOrderBudget.test.ts +243 -0
  387. package/Tests/Server/Utils/Greenlock/CertificateOrderFailures.test.ts +293 -0
  388. package/Tests/Server/Utils/Greenlock/CertificateOrderLock.test.ts +152 -0
  389. package/Tests/Server/Utils/Greenlock/CertificateOwnersGuard.test.ts +119 -0
  390. package/Tests/Server/Utils/Greenlock/CertificateRenewalOwnership.test.ts +1170 -0
  391. package/Tests/Server/Utils/Greenlock/CertificateRenewalSafety.test.ts +368 -0
  392. package/Tests/Server/Utils/Greenlock/CertificateRenewalSchedule.test.ts +188 -11
  393. package/Tests/Server/Utils/Greenlock/CustomDomainOrders.test.ts +723 -0
  394. package/Tests/Server/Utils/Greenlock/InMemoryRedis.ts +189 -0
  395. package/Tests/Server/Utils/Greenlock/NginxAcmeCertificatesToDisk.test.ts +242 -0
  396. package/Tests/Server/Utils/Greenlock/NginxCustomCertificatesToDisk.test.ts +305 -0
  397. package/Tests/Server/Utils/Greenlock/OrderCertGuards.test.ts +583 -0
  398. package/Tests/Server/Utils/Greenlock/OrderCertStorage.test.ts +203 -0
  399. package/Tests/Server/Utils/StatusPage/AffectedStatusPageResources.test.ts +700 -0
  400. package/Tests/Server/Utils/StatusPage/StatusPagesListingMonitorsBuilder.test.ts +744 -0
  401. package/Tests/Types/CustomDomain/CustomDomainCertificates.test.ts +106 -0
  402. package/Tests/Types/CustomDomain/CustomDomainVerification.test.ts +94 -0
  403. package/Tests/Types/Dashboard/DashboardAccess.test.ts +460 -0
  404. package/Tests/Types/Filter/FilterConditionUtil.test.ts +59 -0
  405. package/Tests/Types/Form/FormBranding.test.ts +760 -0
  406. package/Tests/Types/IncomingCall/IncomingCallRingTime.test.ts +80 -0
  407. package/Tests/Types/NotificationRule/OnCallRuleKind.test.ts +271 -0
  408. package/Tests/Types/OnCallDutyPolicy/ScheduleFirstLayer.test.ts +300 -0
  409. package/Tests/Types/OnCallDutyPolicy/ScheduleLayerDefaults.test.ts +316 -0
  410. package/Tests/Types/OnCallDutyPolicy/UserOverrideCoverRequest.test.ts +257 -0
  411. package/Tests/Types/SSO/OidcProviderDefaults.test.ts +474 -0
  412. package/Tests/Types/SSO/SamlProviderDefaults.test.ts +150 -0
  413. package/Tests/Types/SSO/SsoProviderDefaults.test.ts +181 -0
  414. package/Tests/Types/StatusPage/StatusPageAccess.test.ts +393 -0
  415. package/Tests/Types/StatusPage/StatusPagesListingMonitors.test.ts +149 -0
  416. package/Tests/Types/Telemetry/ScrubRule.test.ts +375 -0
  417. package/Tests/UI/Components/AdvancedPageSection.test.tsx +201 -61
  418. package/Tests/UI/Components/BasicFormModalSteps.test.tsx +129 -153
  419. package/Tests/UI/Components/Card.test.tsx +354 -367
  420. package/Tests/UI/Components/CardHeaderActionsGuard.test.tsx +605 -0
  421. package/Tests/UI/Components/CardModelDetailHeaderLayout.test.tsx +23 -8
  422. package/Tests/UI/Components/CardModelDetailOnBeforeUpdate.test.tsx +224 -0
  423. package/Tests/UI/Components/CardModelDetailPageButtons.test.tsx +231 -0
  424. package/Tests/UI/Components/ChoiceRows.test.tsx +365 -0
  425. package/Tests/UI/Components/CommandPalette/CommandPalette.test.tsx +341 -5
  426. package/Tests/UI/Components/CommandPalette/PaletteFilter.test.ts +655 -64
  427. package/Tests/UI/Components/Detail/DetailCreatedOnIdLine.test.tsx +669 -0
  428. package/Tests/UI/Components/Detail/DetailIdLineDarkMode.test.ts +34 -7
  429. package/Tests/UI/Components/Detail/DetailIdLineInLocale.test.tsx +71 -0
  430. package/Tests/UI/Components/Detail/DetailRecordIdLine.test.tsx +26 -7
  431. package/Tests/UI/Components/Detail/DetailRecordLine.test.tsx +326 -0
  432. package/Tests/UI/Components/Detail/DetailRecordTime.test.ts +324 -0
  433. package/Tests/UI/Components/DetailCompactStyle.test.tsx +7 -3
  434. package/Tests/UI/Components/Dropdown/DropdownChange.test.ts +163 -0
  435. package/Tests/UI/Components/EntityDropdown.test.tsx +103 -1
  436. package/Tests/UI/Components/EntityDropdownClearButton.test.tsx +638 -0
  437. package/Tests/UI/Components/EntityDropdownEscape.test.tsx +6 -6
  438. package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +21 -4
  439. package/Tests/UI/Components/EntityDropdownQuery.test.tsx +411 -0
  440. package/Tests/UI/Components/EntityDropdownQueryHelpers.test.ts +131 -0
  441. package/Tests/UI/Components/FilePicker.test.tsx +220 -1
  442. package/Tests/UI/Components/FoldedSection/FoldedSection.test.tsx +582 -0
  443. package/Tests/UI/Components/FoldedSection/FoldedSectionDarkMode.test.ts +197 -0
  444. package/Tests/UI/Components/FoldedSection/FoldedSectionItem.test.ts +247 -0
  445. package/Tests/UI/Components/FoldedSection/FoldedSectionQueries.ts +86 -0
  446. package/Tests/UI/Components/Forms/AdvancedStepsGuard.test.ts +358 -32
  447. package/Tests/UI/Components/Forms/AnchoredFieldPopupPlacement.test.tsx +195 -0
  448. package/Tests/UI/Components/Forms/BasicFormCollapsibleSections.test.tsx +187 -23
  449. package/Tests/UI/Components/Forms/BasicFormFillsInOnShow.test.tsx +246 -0
  450. package/Tests/UI/Components/Forms/BasicFormFooterSetValue.test.tsx +283 -0
  451. package/Tests/UI/Components/Forms/BasicFormPrimaryActionLastStep.test.tsx +780 -0
  452. package/Tests/UI/Components/Forms/BasicFormSingleStep.test.tsx +232 -0
  453. package/Tests/UI/Components/Forms/BasicFormStepValidation.test.tsx +7 -4
  454. package/Tests/UI/Components/Forms/BasicFormSubmitAllSteps.test.tsx +4 -3
  455. package/Tests/UI/Components/Forms/CreateFormDefaultsGuard.test.ts +252 -7
  456. package/Tests/UI/Components/Forms/DeclareAndCreateFormsGuard.test.ts +247 -7
  457. package/Tests/UI/Components/Forms/DiscoveredResourceCreateFormsGuard.test.ts +492 -0
  458. package/Tests/UI/Components/Forms/FilterConditionOnlyWithTwoFiltersGuard.test.ts +333 -0
  459. package/Tests/UI/Components/Forms/FoldedEditorWidthTiming.test.tsx +127 -0
  460. package/Tests/UI/Components/Forms/FoldedSectionsGuard.test.ts +523 -0
  461. package/Tests/UI/Components/Forms/FollowPickName.test.ts +88 -0
  462. package/Tests/UI/Components/Forms/FormFieldDropdownChange.test.tsx +294 -0
  463. package/Tests/UI/Components/Forms/FormModalWidth.test.tsx +237 -2
  464. package/Tests/UI/Components/Forms/FormSummary.test.tsx +181 -0
  465. package/Tests/UI/Components/Forms/IncidentEpisodePublicNoteNotifyPayload.test.tsx +110 -86
  466. package/Tests/UI/Components/Forms/LabelsFormFieldGuard.test.ts +101 -96
  467. package/Tests/UI/Components/Forms/LongFormStepsGuard.test.ts +559 -10
  468. package/Tests/UI/Components/Forms/MarkdownFormsAreWide.test.ts +56 -4
  469. package/Tests/UI/Components/Forms/MetricAndRecordingRuleFormsGuard.test.ts +400 -0
  470. package/Tests/UI/Components/Forms/ModelFormColorDefaults.test.tsx +659 -0
  471. package/Tests/UI/Components/Forms/ModelFormCreateDefaults.test.tsx +108 -4
  472. package/Tests/UI/Components/Forms/ModelFormDropdownQuery.test.tsx +403 -0
  473. package/Tests/UI/Components/Forms/ModelFormPreservesUserInput.test.tsx +126 -0
  474. package/Tests/UI/Components/Forms/ModelFormSinglePickPeoplePicker.test.tsx +453 -0
  475. package/Tests/UI/Components/Forms/OidcProviderFormsGuard.test.ts +321 -0
  476. package/Tests/UI/Components/Forms/OneIncidentRolePickerGuard.test.ts +823 -0
  477. package/Tests/UI/Components/Forms/OneSwitchCardsGuard.test.ts +739 -0
  478. package/Tests/UI/Components/Forms/OpenFormSections.test.tsx +169 -0
  479. package/Tests/UI/Components/Forms/OverloadedFormStepsGuard.test.ts +21 -9
  480. package/Tests/UI/Components/Forms/PrimaryActionLastStepGuard.test.ts +478 -0
  481. package/Tests/UI/Components/Forms/ProjectTeamFormsGuard.test.ts +240 -0
  482. package/Tests/UI/Components/Forms/ResourceDetailsOnePlaceGuard.test.ts +936 -0
  483. package/Tests/UI/Components/Forms/ResourceRuleFormsGuard.test.ts +527 -0
  484. package/Tests/UI/Components/Forms/SamlProviderFormsGuard.test.ts +387 -0
  485. package/Tests/UI/Components/Forms/SmallWizardsOnePageGuard.test.ts +331 -0
  486. package/Tests/UI/Components/Forms/SmtpConfigFormsGuard.test.ts +470 -0
  487. package/Tests/UI/Components/Forms/StateChangeDialogsFoldTheNote.test.ts +322 -0
  488. package/Tests/UI/Components/Forms/StatusPageResourceFormsGuard.test.ts +381 -0
  489. package/Tests/UI/Components/Forms/SteppedFormFooter.test.ts +225 -0
  490. package/Tests/UI/Components/Forms/SteppedFormFooterTiming.test.tsx +82 -40
  491. package/Tests/UI/Components/Forms/SwitchCardsGuard.test.ts +339 -0
  492. package/Tests/UI/Components/Forms/TelemetryDataRuleFormsGuard.test.ts +383 -0
  493. package/Tests/UI/Components/Forms/UniqueName.test.ts +163 -0
  494. package/Tests/UI/Components/Forms/Utils/AdvancedFormSection.test.ts +131 -11
  495. package/Tests/UI/Components/Forms/Utils/CreateFormColorDefaults.test.ts +373 -0
  496. package/Tests/UI/Components/Forms/Utils/FoldedFormFields.test.ts +482 -0
  497. package/Tests/UI/Components/LabelRuleImportExport.test.tsx +32 -0
  498. package/Tests/UI/Components/MemberRoleAssignment.test.tsx +51 -7
  499. package/Tests/UI/Components/ModalSecondaryButton.test.tsx +60 -3
  500. package/Tests/UI/Components/ModelFormDraftValues.test.tsx +255 -0
  501. package/Tests/UI/Components/ModelPageHeaderChanged.test.tsx +293 -0
  502. package/Tests/UI/Components/ModelSwitchCard.test.tsx +813 -0
  503. package/Tests/UI/Components/ModelSwitchEvents.test.ts +188 -0
  504. package/Tests/UI/Components/ModelSwitchRow.test.tsx +861 -0
  505. package/Tests/UI/Components/ModelSwitchUtil.test.ts +239 -0
  506. package/Tests/UI/Components/ModelSwitchesCard.test.tsx +699 -0
  507. package/Tests/UI/Components/NavBar.test.tsx +41 -2
  508. package/Tests/UI/Components/NavBarCategoryToggleDarkMode.test.ts +12 -0
  509. package/Tests/UI/Components/NavBarMenuCatalog.test.tsx +197 -30
  510. package/Tests/UI/Components/NavBarMenuFolding.test.tsx +221 -39
  511. package/Tests/UI/Components/NavBarMenuSearch.test.tsx +15 -10
  512. package/Tests/UI/Components/NestedControlsGuard.test.ts +300 -0
  513. package/Tests/UI/Components/PageBreadcrumbOverride.test.tsx +202 -0
  514. package/Tests/UI/Components/PeoplePicker/OwnersFieldGuard.test.ts +269 -5
  515. package/Tests/UI/Components/PeoplePicker/PeoplePickerChange.test.tsx +414 -0
  516. package/Tests/UI/Components/PeoplePicker/PeoplePickerExcludePicks.test.tsx +582 -0
  517. package/Tests/UI/Components/PeoplePicker/PeoplePickerSinglePick.test.tsx +519 -0
  518. package/Tests/UI/Components/PeoplePicker/PeoplePickerSinglePickTypes.test.ts +174 -0
  519. package/Tests/UI/Components/RuleCriteria/RuleCriteriaModelTable.test.tsx +8 -3
  520. package/Tests/UI/Components/RuleCriteria/RuleCriteriaNamesGuard.test.ts +14 -6
  521. package/Tests/UI/Components/RuleRun/RuleViewDescription.test.tsx +107 -0
  522. package/Tests/UI/Components/SaveStatus.test.tsx +81 -0
  523. package/Tests/UI/Components/SmtpConfig/SmtpConfigFormFields.test.ts +1078 -0
  524. package/Tests/UI/Components/Sso/OidcProviderForm.test.tsx +608 -0
  525. package/Tests/UI/Components/Sso/OidcProviderFormFields.test.ts +698 -0
  526. package/Tests/UI/Components/Sso/SamlProviderForm.test.tsx +583 -0
  527. package/Tests/UI/Components/Sso/SamlProviderFormFields.test.ts +619 -0
  528. package/Tests/UI/Components/SteppedEditFormSave.test.tsx +199 -141
  529. package/Tests/UI/Components/Table/TableEmptyStateComponent.test.tsx +143 -0
  530. package/Tests/UI/Components/UseSaveModelSwitch.test.tsx +409 -0
  531. package/Tests/UI/Components/Workflow/ArgumentsForm.test.tsx +3 -3
  532. package/Tests/UI/Components/Workflow/ArgumentsFormAdvancedSettings.test.tsx +83 -27
  533. package/Tests/UI/Components/Workflow/WorkflowLogModal.test.tsx +7 -2
  534. package/Tests/UI/Components/useSaveOnChange.test.tsx +341 -0
  535. package/Tests/UI/Monitor/MonitorStepRetrySettings.test.tsx +1 -1
  536. package/Tests/UI/Rum/ReplayTimeline.test.tsx +75 -5
  537. package/Tests/UI/Rum/SessionReplaySettingsPolicyLoading.test.tsx +97 -0
  538. package/Tests/UI/Utils/Breadcrumb/fixtures/RealBreadcrumbTrails.ts +12 -39
  539. package/Tests/UI/Utils/Breadcrumb/fixtures/RealRoutePatterns.ts +1 -6
  540. package/Tests/{App/Dashboard → UI/Utils}/DefaultInviteTeam.test.ts +126 -4
  541. package/Tests/UI/Utils/GrantablePermission.test.ts +172 -0
  542. package/Tests/UI/Utils/PermissionGateColumnUpdate.test.ts +211 -0
  543. package/Tests/UI/Utils/TranslateTemplate.test.ts +31 -0
  544. package/Tests/Utils/DistinctColor.test.ts +446 -0
  545. package/Tests/Utils/Monitor/MonitorOverviewPresentationUtil.test.ts +14 -2
  546. package/Tests/Utils/Monitor/MonitoringIntervalUtil.test.ts +1 -1
  547. package/Tests/Utils/NetworkDiscovery/ShortHostnameUtil.test.ts +2 -2
  548. package/Tests/Utils/Slo/SloHealth.test.ts +28 -6
  549. package/Tests/Utils/StatusPage/ReportSchedule.test.ts +867 -0
  550. package/Tests/Utils/Telemetry/DiscoveredResourceName.test.ts +189 -0
  551. package/Tests/Utils/WordMatch.test.ts +104 -0
  552. package/Types/BrandColors.ts +10 -0
  553. package/Types/CustomDomain/CustomDomainCertificates.ts +128 -0
  554. package/Types/CustomDomain/CustomDomainVerification.ts +78 -0
  555. package/Types/Dashboard/DashboardAccess.ts +250 -0
  556. package/Types/Dashboard/DashboardTemplates.ts +33 -0
  557. package/Types/Filter/FilterConditionUtil.ts +29 -0
  558. package/Types/Form/FormBranding.ts +475 -0
  559. package/Types/Form/FormPublic.ts +26 -0
  560. package/Types/IncomingCall/IncomingCallRingTime.ts +48 -0
  561. package/Types/Log/LogScrubField.ts +14 -0
  562. package/Types/Monitor/SeriesContext/SeriesLabelDisplay.ts +1 -1
  563. package/Types/NotificationRule/OnCallRuleKind.ts +194 -0
  564. package/Types/OnCallDutyPolicy/FirstResponders.ts +3 -32
  565. package/Types/OnCallDutyPolicy/MiscDataId.ts +38 -0
  566. package/Types/OnCallDutyPolicy/ScheduleFirstLayer.ts +165 -0
  567. package/Types/OnCallDutyPolicy/ScheduleLayerDefaults.ts +160 -0
  568. package/Types/OnCallDutyPolicy/UserOverrideCoverRequest.ts +148 -0
  569. package/Types/SSO/OidcProviderDefaults.ts +282 -0
  570. package/Types/SSO/SamlProviderDefaults.ts +77 -0
  571. package/Types/SSO/SsoProviderDefaults.ts +101 -0
  572. package/Types/StatusPage/StatusPageAccess.ts +215 -0
  573. package/Types/StatusPage/StatusPagesListingMonitors.ts +150 -0
  574. package/Types/Telemetry/ScrubRule.ts +240 -0
  575. package/UI/Components/AdvancedPageSection/AdvancedPageSection.tsx +59 -29
  576. package/UI/Components/Card/Card.tsx +139 -80
  577. package/UI/Components/ChoiceRows/ChoiceRows.tsx +249 -0
  578. package/UI/Components/CommandPalette/CommandPalette.tsx +28 -12
  579. package/UI/Components/CommandPalette/PaletteFilter.ts +962 -75
  580. package/UI/Components/CommandPalette/PaletteRow.tsx +35 -3
  581. package/UI/Components/CommandPalette/Types.ts +37 -1
  582. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +6 -0
  583. package/UI/Components/Detail/Detail.tsx +52 -15
  584. package/UI/Components/Detail/DetailRecordLine.tsx +96 -0
  585. package/UI/Components/Detail/DetailRecordTime.ts +196 -0
  586. package/UI/Components/Dropdown/DropdownChange.ts +198 -0
  587. package/UI/Components/EntityDropdown/EntityDropdown.tsx +270 -106
  588. package/UI/Components/EntityDropdown/EntityDropdownQuery.ts +119 -0
  589. package/UI/Components/FilePicker/FilePicker.tsx +90 -6
  590. package/UI/Components/FoldedSection/FoldedSection.tsx +370 -0
  591. package/UI/Components/FoldedSection/FoldedSectionItem.ts +141 -0
  592. package/UI/Components/FoldedSection/FoldedSectionTitles.ts +39 -0
  593. package/UI/Components/FormModal/BasicFormModal.tsx +40 -67
  594. package/UI/Components/Forms/BasicForm.tsx +218 -119
  595. package/UI/Components/Forms/BasicModelForm.tsx +0 -2
  596. package/UI/Components/Forms/CollapsibleFormSection.tsx +108 -18
  597. package/UI/Components/Forms/Fields/FormField.tsx +62 -15
  598. package/UI/Components/Forms/Fields/GeneratedKeyField.tsx +1 -5
  599. package/UI/Components/Forms/FormSummary.tsx +5 -3
  600. package/UI/Components/Forms/ModelForm.tsx +123 -16
  601. package/UI/Components/Forms/Types/Field.ts +98 -16
  602. package/UI/Components/Forms/Utils/AdvancedFormSection.ts +102 -31
  603. package/UI/Components/Forms/Utils/CreateFormDefaults.ts +158 -17
  604. package/UI/Components/Forms/Utils/FoldedFormFields.ts +393 -0
  605. package/UI/Components/Forms/Utils/FollowPickName.ts +52 -0
  606. package/UI/Components/Forms/Utils/FormModalWidth.ts +35 -4
  607. package/UI/Components/Forms/Utils/OpenFormSections.ts +104 -0
  608. package/UI/Components/Forms/Utils/SteppedFormFooter.ts +151 -0
  609. package/UI/Components/Forms/Utils/UniqueName.ts +81 -0
  610. package/UI/Components/LabelRule/ImportLabelRulesModal.tsx +22 -3
  611. package/UI/Components/MemberRoleAssignment/MemberRoleAssignment.tsx +6 -5
  612. package/UI/Components/Modal/ModalFooter.tsx +10 -1
  613. package/UI/Components/ModelDetail/CardModelDetail.tsx +33 -8
  614. package/UI/Components/ModelFormModal/ModelFormModal.tsx +44 -58
  615. package/UI/Components/ModelSwitch/ModelSwitchCard.tsx +305 -0
  616. package/UI/Components/ModelSwitch/ModelSwitchEvents.ts +109 -0
  617. package/UI/Components/ModelSwitch/ModelSwitchRow.tsx +438 -0
  618. package/UI/Components/ModelSwitch/ModelSwitchUtil.ts +120 -0
  619. package/UI/Components/ModelSwitch/ModelSwitchesCard.tsx +265 -0
  620. package/UI/Components/ModelSwitch/useSaveModelSwitch.ts +144 -0
  621. package/UI/Components/ModelTable/BaseModelTable.tsx +6 -0
  622. package/UI/Components/ModelTable/ModelTable.tsx +5 -0
  623. package/UI/Components/Navbar/NavBar.tsx +10 -9
  624. package/UI/Components/Navbar/NavBarMenuCatalog.ts +57 -22
  625. package/UI/Components/Navbar/NavBarMenuModal.tsx +17 -13
  626. package/UI/Components/Navbar/NavBarMobileMenu.tsx +40 -23
  627. package/UI/Components/Page/ModelHeaderEvents.ts +75 -0
  628. package/UI/Components/Page/ModelPage.tsx +21 -1
  629. package/UI/Components/Page/Page.tsx +68 -13
  630. package/UI/Components/PeoplePicker/PeoplePicker.tsx +150 -45
  631. package/UI/Components/PeoplePicker/PeoplePickerTypes.ts +193 -4
  632. package/UI/Components/PeoplePicker/PeopleSearchPopup.tsx +37 -10
  633. package/UI/Components/PublicForm/PublicFormFavicon.ts +99 -0
  634. package/UI/Components/PublicForm/PublicFormLogo.tsx +81 -0
  635. package/UI/Components/RuleCriteria/RuleCriteriaBuilder.tsx +5 -3
  636. package/UI/Components/RuleRun/RuleView.tsx +2 -5
  637. package/UI/Components/SaveStatus/SaveStatus.tsx +76 -0
  638. package/UI/Components/SaveStatus/useSaveOnChange.ts +178 -0
  639. package/UI/Components/SmtpConfig/SmtpConfigFormFields.ts +815 -0
  640. package/UI/Components/Sso/OidcProviderFormFields.ts +481 -0
  641. package/UI/Components/Sso/SamlProviderFormFields.ts +322 -0
  642. package/UI/Components/Sso/SsoProviderFormFields.ts +331 -0
  643. package/UI/Components/Table/TableEmptyState.tsx +39 -5
  644. package/UI/Components/Workflow/ArgumentsForm.tsx +21 -78
  645. package/UI/Components/Workflow/ComponentPicker/ComponentSearch.ts +18 -145
  646. package/UI/Components/Workflow/WorkflowLogModal.tsx +1 -3
  647. package/UI/Types/UseAnchoredFieldPopup.ts +46 -4
  648. package/UI/Utils/DefaultInviteTeam.ts +306 -0
  649. package/UI/Utils/GrantablePermission.ts +46 -0
  650. package/UI/Utils/PermissionGate.ts +80 -7
  651. package/UI/Utils/TranslateTemplate.ts +22 -0
  652. package/Utils/DistinctColor.ts +223 -0
  653. package/Utils/Monitor/MonitorOverviewPresentationUtil.ts +47 -2
  654. package/Utils/Slo/SloHealth.ts +9 -3
  655. package/Utils/StatusPage/ReportSchedule.ts +462 -0
  656. package/Utils/Telemetry/DiscoveredResourceName.ts +95 -0
  657. package/Utils/WordMatch.ts +185 -0
  658. package/build/dist/Models/DatabaseModels/AlertGroupingRule.js +6 -6
  659. package/build/dist/Models/DatabaseModels/AlertGroupingRule.js.map +1 -1
  660. package/build/dist/Models/DatabaseModels/File.js +47 -1
  661. package/build/dist/Models/DatabaseModels/File.js.map +1 -1
  662. package/build/dist/Models/DatabaseModels/Form.js +125 -0
  663. package/build/dist/Models/DatabaseModels/Form.js.map +1 -1
  664. package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js +6 -6
  665. package/build/dist/Models/DatabaseModels/IncidentGroupingRule.js.map +1 -1
  666. package/build/dist/Models/DatabaseModels/LogDropFilter.js +1 -0
  667. package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
  668. package/build/dist/Models/DatabaseModels/LogPipeline.js +1 -0
  669. package/build/dist/Models/DatabaseModels/LogPipeline.js.map +1 -1
  670. package/build/dist/Models/DatabaseModels/LogScrubRule.js +14 -8
  671. package/build/dist/Models/DatabaseModels/LogScrubRule.js.map +1 -1
  672. package/build/dist/Models/DatabaseModels/MetricRecordingRule.js +1 -1
  673. package/build/dist/Models/DatabaseModels/MetricRecordingRule.js.map +1 -1
  674. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.js +2 -2
  675. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyExecutionLogTimeline.js.map +1 -1
  676. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js +20 -9
  677. package/build/dist/Models/DatabaseModels/OnCallDutyPolicyUserOverride.js.map +1 -1
  678. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js +6 -1
  679. package/build/dist/Models/DatabaseModels/ProjectCallSMSConfig.js.map +1 -1
  680. package/build/dist/Models/DatabaseModels/StatusPage.js +4 -4
  681. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  682. package/build/dist/Models/DatabaseModels/TraceDropFilter.js +1 -0
  683. package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
  684. package/build/dist/Models/DatabaseModels/TracePipeline.js +1 -0
  685. package/build/dist/Models/DatabaseModels/TracePipeline.js.map +1 -1
  686. package/build/dist/Models/DatabaseModels/TraceRecordingRule.js +1 -1
  687. package/build/dist/Models/DatabaseModels/TraceRecordingRule.js.map +1 -1
  688. package/build/dist/Models/DatabaseModels/TraceScrubRule.js +14 -8
  689. package/build/dist/Models/DatabaseModels/TraceScrubRule.js.map +1 -1
  690. package/build/dist/Models/DatabaseModels/UserOnCallLog.js +2 -2
  691. package/build/dist/Models/DatabaseModels/UserOnCallLog.js.map +1 -1
  692. package/build/dist/Server/API/CustomDomainRoutes.js +124 -0
  693. package/build/dist/Server/API/CustomDomainRoutes.js.map +1 -0
  694. package/build/dist/Server/API/DashboardAPI.js +22 -4
  695. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  696. package/build/dist/Server/API/DashboardDomainAPI.js +56 -49
  697. package/build/dist/Server/API/DashboardDomainAPI.js.map +1 -1
  698. package/build/dist/Server/API/StatusPageAPI.js +101 -39
  699. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  700. package/build/dist/Server/API/StatusPageDomainAPI.js +52 -51
  701. package/build/dist/Server/API/StatusPageDomainAPI.js.map +1 -1
  702. package/build/dist/Server/Infrastructure/GlobalCache.js +63 -0
  703. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  704. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1797700000000-AddFormBranding.js +36 -0
  705. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1797700000000-AddFormBranding.js.map +1 -0
  706. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  707. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  708. package/build/dist/Server/Services/AlertGroupingEngineService.js +44 -61
  709. package/build/dist/Server/Services/AlertGroupingEngineService.js.map +1 -1
  710. package/build/dist/Server/Services/AlertGroupingRuleService.js +45 -0
  711. package/build/dist/Server/Services/AlertGroupingRuleService.js.map +1 -1
  712. package/build/dist/Server/Services/CephClusterService.js +23 -0
  713. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  714. package/build/dist/Server/Services/CloudResourceService.js +39 -0
  715. package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
  716. package/build/dist/Server/Services/DashboardDomainService.js +510 -172
  717. package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
  718. package/build/dist/Server/Services/DashboardService.js +22 -9
  719. package/build/dist/Server/Services/DashboardService.js.map +1 -1
  720. package/build/dist/Server/Services/DatabaseService.js +114 -10
  721. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  722. package/build/dist/Server/Services/DockerHostService.js +51 -0
  723. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  724. package/build/dist/Server/Services/DockerSwarmClusterService.js +23 -0
  725. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  726. package/build/dist/Server/Services/FileService.js +45 -0
  727. package/build/dist/Server/Services/FileService.js.map +1 -1
  728. package/build/dist/Server/Services/FormService.js +158 -14
  729. package/build/dist/Server/Services/FormService.js.map +1 -1
  730. package/build/dist/Server/Services/GlobalOidcService.js +9 -0
  731. package/build/dist/Server/Services/GlobalOidcService.js.map +1 -1
  732. package/build/dist/Server/Services/GlobalSsoService.js +9 -0
  733. package/build/dist/Server/Services/GlobalSsoService.js.map +1 -1
  734. package/build/dist/Server/Services/HostService.js +50 -0
  735. package/build/dist/Server/Services/HostService.js.map +1 -1
  736. package/build/dist/Server/Services/IncidentGroupingEngineService.js +45 -62
  737. package/build/dist/Server/Services/IncidentGroupingEngineService.js.map +1 -1
  738. package/build/dist/Server/Services/IncidentGroupingRuleService.js +45 -0
  739. package/build/dist/Server/Services/IncidentGroupingRuleService.js.map +1 -1
  740. package/build/dist/Server/Services/IoTFleetService.js +23 -0
  741. package/build/dist/Server/Services/IoTFleetService.js.map +1 -1
  742. package/build/dist/Server/Services/KubernetesClusterService.js +54 -0
  743. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  744. package/build/dist/Server/Services/LabelService.js +6 -16
  745. package/build/dist/Server/Services/LabelService.js.map +1 -1
  746. package/build/dist/Server/Services/LogScrubRuleService.js +31 -0
  747. package/build/dist/Server/Services/LogScrubRuleService.js.map +1 -1
  748. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js +202 -0
  749. package/build/dist/Server/Services/OnCallDutyPolicyScheduleService.js.map +1 -1
  750. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js +7 -1
  751. package/build/dist/Server/Services/OnCallDutyPolicyUserOverrideService.js.map +1 -1
  752. package/build/dist/Server/Services/OnCallNotificationAlertingService.js +17 -24
  753. package/build/dist/Server/Services/OnCallNotificationAlertingService.js.map +1 -1
  754. package/build/dist/Server/Services/OnCallSetupReminderService.js +32 -38
  755. package/build/dist/Server/Services/OnCallSetupReminderService.js.map +1 -1
  756. package/build/dist/Server/Services/PodmanHostService.js +51 -0
  757. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  758. package/build/dist/Server/Services/ProfileAggregationService.js +34 -0
  759. package/build/dist/Server/Services/ProfileAggregationService.js.map +1 -1
  760. package/build/dist/Server/Services/ProjectCallSMSConfigService.js +53 -3
  761. package/build/dist/Server/Services/ProjectCallSMSConfigService.js.map +1 -1
  762. package/build/dist/Server/Services/ProjectOidcService.js +28 -0
  763. package/build/dist/Server/Services/ProjectOidcService.js.map +1 -1
  764. package/build/dist/Server/Services/ProjectSsoService.js +28 -0
  765. package/build/dist/Server/Services/ProjectSsoService.js.map +1 -1
  766. package/build/dist/Server/Services/ProxmoxClusterService.js +23 -0
  767. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  768. package/build/dist/Server/Services/RumApplicationService.js +42 -0
  769. package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
  770. package/build/dist/Server/Services/ScheduledMaintenanceService.js +18 -26
  771. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  772. package/build/dist/Server/Services/ServerlessFunctionService.js +44 -0
  773. package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
  774. package/build/dist/Server/Services/ServiceService.js +30 -4
  775. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  776. package/build/dist/Server/Services/StatusPageDomainService.js +495 -174
  777. package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
  778. package/build/dist/Server/Services/StatusPageOidcService.js +28 -0
  779. package/build/dist/Server/Services/StatusPageOidcService.js.map +1 -1
  780. package/build/dist/Server/Services/StatusPageResourceService.js +82 -46
  781. package/build/dist/Server/Services/StatusPageResourceService.js.map +1 -1
  782. package/build/dist/Server/Services/StatusPageService.js +174 -45
  783. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  784. package/build/dist/Server/Services/StatusPageSsoService.js +28 -0
  785. package/build/dist/Server/Services/StatusPageSsoService.js.map +1 -1
  786. package/build/dist/Server/Services/TraceScrubRuleService.js +31 -0
  787. package/build/dist/Server/Services/TraceScrubRuleService.js.map +1 -1
  788. package/build/dist/Server/Services/UserIncomingCallNumberService.js +20 -10
  789. package/build/dist/Server/Services/UserIncomingCallNumberService.js.map +1 -1
  790. package/build/dist/Server/Services/VMwareVCenterService.js +23 -0
  791. package/build/dist/Server/Services/VMwareVCenterService.js.map +1 -1
  792. package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js +3 -3
  793. package/build/dist/Server/Utils/AI/PerfEvidence/SpanTreeAnalyzer.js.map +1 -1
  794. package/build/dist/Server/Utils/Greenlock/CertificateOrder.js +353 -0
  795. package/build/dist/Server/Utils/Greenlock/CertificateOrder.js.map +1 -0
  796. package/build/dist/Server/Utils/Greenlock/CertificateOrderBudget.js +119 -0
  797. package/build/dist/Server/Utils/Greenlock/CertificateOrderBudget.js.map +1 -0
  798. package/build/dist/Server/Utils/Greenlock/CertificateOrderFailures.js +208 -0
  799. package/build/dist/Server/Utils/Greenlock/CertificateOrderFailures.js.map +1 -0
  800. package/build/dist/Server/Utils/Greenlock/CertificateOrderLock.js +111 -0
  801. package/build/dist/Server/Utils/Greenlock/CertificateOrderLock.js.map +1 -0
  802. package/build/dist/Server/Utils/Greenlock/CertificateOrderOutcome.js +30 -0
  803. package/build/dist/Server/Utils/Greenlock/CertificateOrderOutcome.js.map +1 -0
  804. package/build/dist/Server/Utils/Greenlock/CertificateOwners.js +52 -0
  805. package/build/dist/Server/Utils/Greenlock/CertificateOwners.js.map +1 -0
  806. package/build/dist/Server/Utils/Greenlock/CertificateReissueOrder.js +80 -0
  807. package/build/dist/Server/Utils/Greenlock/CertificateReissueOrder.js.map +1 -0
  808. package/build/dist/Server/Utils/Greenlock/CustomDomainOrders.js +296 -0
  809. package/build/dist/Server/Utils/Greenlock/CustomDomainOrders.js.map +1 -0
  810. package/build/dist/Server/Utils/Greenlock/Greenlock.js +595 -146
  811. package/build/dist/Server/Utils/Greenlock/Greenlock.js.map +1 -1
  812. package/build/dist/Server/Utils/Rules/GroupingRuleEpisodeOwners.js +366 -0
  813. package/build/dist/Server/Utils/Rules/GroupingRuleEpisodeOwners.js.map +1 -0
  814. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js +7 -0
  815. package/build/dist/Server/Utils/Rules/OwnerRuleAssignment.js.map +1 -1
  816. package/build/dist/Server/Utils/ScrubRuleValidation.js +127 -0
  817. package/build/dist/Server/Utils/ScrubRuleValidation.js.map +1 -0
  818. package/build/dist/Server/Utils/StatusPage/AffectedStatusPageResources.js +97 -0
  819. package/build/dist/Server/Utils/StatusPage/AffectedStatusPageResources.js.map +1 -0
  820. package/build/dist/Server/Utils/StatusPage/StatusPagesListingMonitorsBuilder.js +195 -0
  821. package/build/dist/Server/Utils/StatusPage/StatusPagesListingMonitorsBuilder.js.map +1 -0
  822. package/build/dist/Server/Utils/Telemetry/DiscoveredResourceCreate.js +177 -0
  823. package/build/dist/Server/Utils/Telemetry/DiscoveredResourceCreate.js.map +1 -0
  824. package/build/dist/Server/Utils/Telemetry/DiscoveredResourceUpdate.js +129 -0
  825. package/build/dist/Server/Utils/Telemetry/DiscoveredResourceUpdate.js.map +1 -0
  826. package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js +8 -2
  827. package/build/dist/Server/Utils/Telemetry/MessageQueueDiscovery.js.map +1 -1
  828. package/build/dist/Types/BrandColors.js +9 -0
  829. package/build/dist/Types/BrandColors.js.map +1 -1
  830. package/build/dist/Types/CustomDomain/CustomDomainCertificates.js +71 -0
  831. package/build/dist/Types/CustomDomain/CustomDomainCertificates.js.map +1 -0
  832. package/build/dist/Types/CustomDomain/CustomDomainVerification.js +58 -0
  833. package/build/dist/Types/CustomDomain/CustomDomainVerification.js.map +1 -0
  834. package/build/dist/Types/Dashboard/DashboardAccess.js +157 -0
  835. package/build/dist/Types/Dashboard/DashboardAccess.js.map +1 -0
  836. package/build/dist/Types/Dashboard/DashboardTemplates.js +26 -0
  837. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  838. package/build/dist/Types/Filter/FilterConditionUtil.js +24 -0
  839. package/build/dist/Types/Filter/FilterConditionUtil.js.map +1 -0
  840. package/build/dist/Types/Form/FormBranding.js +266 -0
  841. package/build/dist/Types/Form/FormBranding.js.map +1 -0
  842. package/build/dist/Types/Form/FormPublic.js +6 -0
  843. package/build/dist/Types/Form/FormPublic.js.map +1 -1
  844. package/build/dist/Types/IncomingCall/IncomingCallRingTime.js +37 -0
  845. package/build/dist/Types/IncomingCall/IncomingCallRingTime.js.map +1 -0
  846. package/build/dist/Types/Log/LogScrubField.js +15 -0
  847. package/build/dist/Types/Log/LogScrubField.js.map +1 -0
  848. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js +1 -1
  849. package/build/dist/Types/Monitor/SeriesContext/SeriesLabelDisplay.js.map +1 -1
  850. package/build/dist/Types/NotificationRule/OnCallRuleKind.js +134 -0
  851. package/build/dist/Types/NotificationRule/OnCallRuleKind.js.map +1 -0
  852. package/build/dist/Types/OnCallDutyPolicy/FirstResponders.js +2 -23
  853. package/build/dist/Types/OnCallDutyPolicy/FirstResponders.js.map +1 -1
  854. package/build/dist/Types/OnCallDutyPolicy/MiscDataId.js +30 -0
  855. package/build/dist/Types/OnCallDutyPolicy/MiscDataId.js.map +1 -0
  856. package/build/dist/Types/OnCallDutyPolicy/ScheduleFirstLayer.js +113 -0
  857. package/build/dist/Types/OnCallDutyPolicy/ScheduleFirstLayer.js.map +1 -0
  858. package/build/dist/Types/OnCallDutyPolicy/ScheduleLayerDefaults.js +95 -0
  859. package/build/dist/Types/OnCallDutyPolicy/ScheduleLayerDefaults.js.map +1 -0
  860. package/build/dist/Types/OnCallDutyPolicy/UserOverrideCoverRequest.js +99 -0
  861. package/build/dist/Types/OnCallDutyPolicy/UserOverrideCoverRequest.js.map +1 -0
  862. package/build/dist/Types/SSO/OidcProviderDefaults.js +189 -0
  863. package/build/dist/Types/SSO/OidcProviderDefaults.js.map +1 -0
  864. package/build/dist/Types/SSO/SamlProviderDefaults.js +55 -0
  865. package/build/dist/Types/SSO/SamlProviderDefaults.js.map +1 -0
  866. package/build/dist/Types/SSO/SsoProviderDefaults.js +67 -0
  867. package/build/dist/Types/SSO/SsoProviderDefaults.js.map +1 -0
  868. package/build/dist/Types/StatusPage/StatusPageAccess.js +132 -0
  869. package/build/dist/Types/StatusPage/StatusPageAccess.js.map +1 -0
  870. package/build/dist/Types/StatusPage/StatusPagesListingMonitors.js +84 -0
  871. package/build/dist/Types/StatusPage/StatusPagesListingMonitors.js.map +1 -0
  872. package/build/dist/Types/Telemetry/ScrubRule.js +180 -0
  873. package/build/dist/Types/Telemetry/ScrubRule.js.map +1 -0
  874. package/build/dist/UI/Components/AdvancedPageSection/AdvancedPageSection.js +9 -7
  875. package/build/dist/UI/Components/AdvancedPageSection/AdvancedPageSection.js.map +1 -1
  876. package/build/dist/UI/Components/Card/Card.js +81 -35
  877. package/build/dist/UI/Components/Card/Card.js.map +1 -1
  878. package/build/dist/UI/Components/ChoiceRows/ChoiceRows.js +54 -0
  879. package/build/dist/UI/Components/ChoiceRows/ChoiceRows.js.map +1 -0
  880. package/build/dist/UI/Components/CommandPalette/CommandPalette.js +25 -12
  881. package/build/dist/UI/Components/CommandPalette/CommandPalette.js.map +1 -1
  882. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js +632 -64
  883. package/build/dist/UI/Components/CommandPalette/PaletteFilter.js.map +1 -1
  884. package/build/dist/UI/Components/CommandPalette/PaletteRow.js +7 -1
  885. package/build/dist/UI/Components/CommandPalette/PaletteRow.js.map +1 -1
  886. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +7 -1
  887. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  888. package/build/dist/UI/Components/Detail/Detail.js +26 -13
  889. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  890. package/build/dist/UI/Components/Detail/DetailRecordLine.js +32 -0
  891. package/build/dist/UI/Components/Detail/DetailRecordLine.js.map +1 -0
  892. package/build/dist/UI/Components/Detail/DetailRecordTime.js +134 -0
  893. package/build/dist/UI/Components/Detail/DetailRecordTime.js.map +1 -0
  894. package/build/dist/UI/Components/Dropdown/DropdownChange.js +102 -0
  895. package/build/dist/UI/Components/Dropdown/DropdownChange.js.map +1 -0
  896. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +134 -57
  897. package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
  898. package/build/dist/UI/Components/EntityDropdown/EntityDropdownQuery.js +78 -0
  899. package/build/dist/UI/Components/EntityDropdown/EntityDropdownQuery.js.map +1 -0
  900. package/build/dist/UI/Components/FilePicker/FilePicker.js +55 -6
  901. package/build/dist/UI/Components/FilePicker/FilePicker.js.map +1 -1
  902. package/build/dist/UI/Components/FoldedSection/FoldedSection.js +139 -0
  903. package/build/dist/UI/Components/FoldedSection/FoldedSection.js.map +1 -0
  904. package/build/dist/UI/Components/FoldedSection/FoldedSectionItem.js +58 -0
  905. package/build/dist/UI/Components/FoldedSection/FoldedSectionItem.js.map +1 -0
  906. package/build/dist/UI/Components/FoldedSection/FoldedSectionTitles.js +34 -0
  907. package/build/dist/UI/Components/FoldedSection/FoldedSectionTitles.js.map +1 -0
  908. package/build/dist/UI/Components/FormModal/BasicFormModal.js +29 -45
  909. package/build/dist/UI/Components/FormModal/BasicFormModal.js.map +1 -1
  910. package/build/dist/UI/Components/Forms/BasicForm.js +148 -89
  911. package/build/dist/UI/Components/Forms/BasicForm.js.map +1 -1
  912. package/build/dist/UI/Components/Forms/BasicModelForm.js +1 -1
  913. package/build/dist/UI/Components/Forms/BasicModelForm.js.map +1 -1
  914. package/build/dist/UI/Components/Forms/CollapsibleFormSection.js +49 -10
  915. package/build/dist/UI/Components/Forms/CollapsibleFormSection.js.map +1 -1
  916. package/build/dist/UI/Components/Forms/Fields/FormField.js +25 -11
  917. package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
  918. package/build/dist/UI/Components/Forms/Fields/GeneratedKeyField.js +2 -5
  919. package/build/dist/UI/Components/Forms/Fields/GeneratedKeyField.js.map +1 -1
  920. package/build/dist/UI/Components/Forms/FormSummary.js +5 -3
  921. package/build/dist/UI/Components/Forms/FormSummary.js.map +1 -1
  922. package/build/dist/UI/Components/Forms/ModelForm.js +72 -14
  923. package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
  924. package/build/dist/UI/Components/Forms/Types/Field.js.map +1 -1
  925. package/build/dist/UI/Components/Forms/Utils/AdvancedFormSection.js +80 -23
  926. package/build/dist/UI/Components/Forms/Utils/AdvancedFormSection.js.map +1 -1
  927. package/build/dist/UI/Components/Forms/Utils/CreateFormDefaults.js +91 -9
  928. package/build/dist/UI/Components/Forms/Utils/CreateFormDefaults.js.map +1 -1
  929. package/build/dist/UI/Components/Forms/Utils/FoldedFormFields.js +243 -0
  930. package/build/dist/UI/Components/Forms/Utils/FoldedFormFields.js.map +1 -0
  931. package/build/dist/UI/Components/Forms/Utils/FollowPickName.js +32 -0
  932. package/build/dist/UI/Components/Forms/Utils/FollowPickName.js.map +1 -0
  933. package/build/dist/UI/Components/Forms/Utils/FormModalWidth.js +25 -5
  934. package/build/dist/UI/Components/Forms/Utils/FormModalWidth.js.map +1 -1
  935. package/build/dist/UI/Components/Forms/Utils/OpenFormSections.js +32 -0
  936. package/build/dist/UI/Components/Forms/Utils/OpenFormSections.js.map +1 -0
  937. package/build/dist/UI/Components/Forms/Utils/SteppedFormFooter.js +71 -0
  938. package/build/dist/UI/Components/Forms/Utils/SteppedFormFooter.js.map +1 -0
  939. package/build/dist/UI/Components/Forms/Utils/UniqueName.js +56 -0
  940. package/build/dist/UI/Components/Forms/Utils/UniqueName.js.map +1 -0
  941. package/build/dist/UI/Components/LabelRule/ImportLabelRulesModal.js +17 -1
  942. package/build/dist/UI/Components/LabelRule/ImportLabelRulesModal.js.map +1 -1
  943. package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js +1 -2
  944. package/build/dist/UI/Components/MemberRoleAssignment/MemberRoleAssignment.js.map +1 -1
  945. package/build/dist/UI/Components/Modal/ModalFooter.js +8 -1
  946. package/build/dist/UI/Components/Modal/ModalFooter.js.map +1 -1
  947. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +19 -6
  948. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  949. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js +33 -43
  950. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  951. package/build/dist/UI/Components/ModelSwitch/ModelSwitchCard.js +151 -0
  952. package/build/dist/UI/Components/ModelSwitch/ModelSwitchCard.js.map +1 -0
  953. package/build/dist/UI/Components/ModelSwitch/ModelSwitchEvents.js +54 -0
  954. package/build/dist/UI/Components/ModelSwitch/ModelSwitchEvents.js.map +1 -0
  955. package/build/dist/UI/Components/ModelSwitch/ModelSwitchRow.js +201 -0
  956. package/build/dist/UI/Components/ModelSwitch/ModelSwitchRow.js.map +1 -0
  957. package/build/dist/UI/Components/ModelSwitch/ModelSwitchUtil.js +60 -0
  958. package/build/dist/UI/Components/ModelSwitch/ModelSwitchUtil.js.map +1 -0
  959. package/build/dist/UI/Components/ModelSwitch/ModelSwitchesCard.js +116 -0
  960. package/build/dist/UI/Components/ModelSwitch/ModelSwitchesCard.js.map +1 -0
  961. package/build/dist/UI/Components/ModelSwitch/useSaveModelSwitch.js +68 -0
  962. package/build/dist/UI/Components/ModelSwitch/useSaveModelSwitch.js.map +1 -0
  963. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -0
  964. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  965. package/build/dist/UI/Components/ModelTable/ModelTable.js +3 -1
  966. package/build/dist/UI/Components/ModelTable/ModelTable.js.map +1 -1
  967. package/build/dist/UI/Components/Navbar/NavBar.js +2 -2
  968. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  969. package/build/dist/UI/Components/Navbar/NavBarMenuCatalog.js +21 -10
  970. package/build/dist/UI/Components/Navbar/NavBarMenuCatalog.js.map +1 -1
  971. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +10 -7
  972. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  973. package/build/dist/UI/Components/Navbar/NavBarMobileMenu.js +17 -9
  974. package/build/dist/UI/Components/Navbar/NavBarMobileMenu.js.map +1 -1
  975. package/build/dist/UI/Components/Page/ModelHeaderEvents.js +43 -0
  976. package/build/dist/UI/Components/Page/ModelHeaderEvents.js.map +1 -0
  977. package/build/dist/UI/Components/Page/ModelPage.js +19 -1
  978. package/build/dist/UI/Components/Page/ModelPage.js.map +1 -1
  979. package/build/dist/UI/Components/Page/Page.js +31 -13
  980. package/build/dist/UI/Components/Page/Page.js.map +1 -1
  981. package/build/dist/UI/Components/PeoplePicker/PeoplePicker.js +62 -20
  982. package/build/dist/UI/Components/PeoplePicker/PeoplePicker.js.map +1 -1
  983. package/build/dist/UI/Components/PeoplePicker/PeoplePickerTypes.js +98 -1
  984. package/build/dist/UI/Components/PeoplePicker/PeoplePickerTypes.js.map +1 -1
  985. package/build/dist/UI/Components/PeoplePicker/PeopleSearchPopup.js +35 -14
  986. package/build/dist/UI/Components/PeoplePicker/PeopleSearchPopup.js.map +1 -1
  987. package/build/dist/UI/Components/PublicForm/PublicFormFavicon.js +66 -0
  988. package/build/dist/UI/Components/PublicForm/PublicFormFavicon.js.map +1 -0
  989. package/build/dist/UI/Components/PublicForm/PublicFormLogo.js +38 -0
  990. package/build/dist/UI/Components/PublicForm/PublicFormLogo.js.map +1 -0
  991. package/build/dist/UI/Components/RuleCriteria/RuleCriteriaBuilder.js +5 -3
  992. package/build/dist/UI/Components/RuleCriteria/RuleCriteriaBuilder.js.map +1 -1
  993. package/build/dist/UI/Components/RuleRun/RuleView.js +2 -2
  994. package/build/dist/UI/Components/RuleRun/RuleView.js.map +1 -1
  995. package/build/dist/UI/Components/SaveStatus/SaveStatus.js +46 -0
  996. package/build/dist/UI/Components/SaveStatus/SaveStatus.js.map +1 -0
  997. package/build/dist/UI/Components/SaveStatus/useSaveOnChange.js +98 -0
  998. package/build/dist/UI/Components/SaveStatus/useSaveOnChange.js.map +1 -0
  999. package/build/dist/UI/Components/SmtpConfig/SmtpConfigFormFields.js +503 -0
  1000. package/build/dist/UI/Components/SmtpConfig/SmtpConfigFormFields.js.map +1 -0
  1001. package/build/dist/UI/Components/Sso/OidcProviderFormFields.js +283 -0
  1002. package/build/dist/UI/Components/Sso/OidcProviderFormFields.js.map +1 -0
  1003. package/build/dist/UI/Components/Sso/SamlProviderFormFields.js +182 -0
  1004. package/build/dist/UI/Components/Sso/SamlProviderFormFields.js.map +1 -0
  1005. package/build/dist/UI/Components/Sso/SsoProviderFormFields.js +208 -0
  1006. package/build/dist/UI/Components/Sso/SsoProviderFormFields.js.map +1 -0
  1007. package/build/dist/UI/Components/Table/TableEmptyState.js +17 -4
  1008. package/build/dist/UI/Components/Table/TableEmptyState.js.map +1 -1
  1009. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +17 -52
  1010. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  1011. package/build/dist/UI/Components/Workflow/ComponentPicker/ComponentSearch.js +7 -89
  1012. package/build/dist/UI/Components/Workflow/ComponentPicker/ComponentSearch.js.map +1 -1
  1013. package/build/dist/UI/Components/Workflow/WorkflowLogModal.js +1 -1
  1014. package/build/dist/UI/Components/Workflow/WorkflowLogModal.js.map +1 -1
  1015. package/build/dist/UI/Types/UseAnchoredFieldPopup.js +22 -3
  1016. package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
  1017. package/build/dist/UI/Utils/DefaultInviteTeam.js +207 -0
  1018. package/build/dist/UI/Utils/DefaultInviteTeam.js.map +1 -0
  1019. package/build/dist/UI/Utils/GrantablePermission.js +31 -0
  1020. package/build/dist/UI/Utils/GrantablePermission.js.map +1 -1
  1021. package/build/dist/UI/Utils/PermissionGate.js +54 -3
  1022. package/build/dist/UI/Utils/PermissionGate.js.map +1 -1
  1023. package/build/dist/UI/Utils/TranslateTemplate.js +16 -0
  1024. package/build/dist/UI/Utils/TranslateTemplate.js.map +1 -1
  1025. package/build/dist/Utils/DistinctColor.js +151 -0
  1026. package/build/dist/Utils/DistinctColor.js.map +1 -0
  1027. package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js +12 -1
  1028. package/build/dist/Utils/Monitor/MonitorOverviewPresentationUtil.js.map +1 -1
  1029. package/build/dist/Utils/Slo/SloHealth.js +9 -3
  1030. package/build/dist/Utils/Slo/SloHealth.js.map +1 -1
  1031. package/build/dist/Utils/StatusPage/ReportSchedule.js +304 -0
  1032. package/build/dist/Utils/StatusPage/ReportSchedule.js.map +1 -0
  1033. package/build/dist/Utils/Telemetry/DiscoveredResourceName.js +65 -0
  1034. package/build/dist/Utils/Telemetry/DiscoveredResourceName.js.map +1 -0
  1035. package/build/dist/Utils/WordMatch.js +115 -0
  1036. package/build/dist/Utils/WordMatch.js.map +1 -0
  1037. package/package.json +1 -1
  1038. package/Tests/App/Dashboard/BulkChangeStateModalSteps.test.ts +0 -109
  1039. package/Tests/App/StatusPage/StatusPageSubscribeFromFirstStep.test.tsx +0 -382
  1040. package/Tests/UI/Components/Forms/BasicFormFinishFromAnyStep.test.tsx +0 -729
  1041. package/Tests/UI/Components/Forms/FinishFromAnyStep.test.ts +0 -571
  1042. package/Tests/UI/Components/Forms/FinishFromAnyStepGuard.test.ts +0 -566
  1043. package/UI/Components/Forms/Utils/FinishFromAnyStep.ts +0 -284
  1044. package/build/dist/UI/Components/Forms/Utils/FinishFromAnyStep.js +0 -132
  1045. package/build/dist/UI/Components/Forms/Utils/FinishFromAnyStep.js.map +0 -1
@@ -13,12 +13,16 @@ import path from "path";
13
13
  * out of onSubmit, and nothing here mocks a create: a create appearing in this
14
14
  * file would mean the collecting and the creating had been fused back together,
15
15
  * which is what keeps the picker off the progress modal in the first place.
16
+ *
17
+ * It is one page: the project, the team under it - the project's members team
18
+ * as soon as the project is picked - and the auto-accept box. Adding people to
19
+ * a project's members team is a project pick and one press. The team picker
20
+ * on its own is tested in ProjectScopedTeamsPicker.test.tsx.
16
21
  */
17
22
 
18
23
  /*
19
24
  * Common/jest.config.json sets no testTimeout, so the default 5s has to cover
20
- * mounting Modal + BasicForm + the async teams fetch, twice over in the tests
21
- * that walk both steps.
25
+ * mounting Modal + BasicForm + the async teams fetch.
22
26
  */
23
27
  jest.setTimeout(30000);
24
28
 
@@ -31,14 +35,20 @@ const WAIT_FOR_TIMEOUT: number = 20000;
31
35
  const PROJECT_ID: string = "0198c8ec-2a1d-7f0c-9e75-384194162001";
32
36
  const TEAM_ENGINEERING_ID: string = "0198c8ec-2a1d-7f0c-9e75-384194162002";
33
37
  const TEAM_SUPPORT_ID: string = "0198c8ec-2a1d-7f0c-9e75-384194162003";
38
+ const TEAM_MEMBERS_ID: string = "0198c8ec-2a1d-7f0c-9e75-384194162006";
34
39
  /*
35
40
  * A second project with a team of its own. The two team sets are disjoint on
36
41
  * purpose: it is the only way a test can tell "the team of the project that is
37
42
  * selected now" apart from "the team of the project that was selected before",
38
- * which is the whole of the stale-selection bug.
43
+ * which is the whole of the stale-selection bug. Its members team is called
44
+ * Billing: what makes a members team is the ProjectMember role, not the name.
39
45
  */
40
46
  const OTHER_PROJECT_ID: string = "0198c8ec-2a1d-7f0c-9e75-384194162004";
41
47
  const TEAM_BILLING_ID: string = "0198c8ec-2a1d-7f0c-9e75-384194162005";
48
+ // A project whose teams hold no ProjectMember and none is called Members.
49
+ const NO_MEMBERS_PROJECT_ID: string = "0198c8ec-2a1d-7f0c-9e75-384194162007";
50
+ const TEAM_AUDITORS_ID: string = "0198c8ec-2a1d-7f0c-9e75-384194162008";
51
+
42
52
  const USER_ONE_ID: string = "0198c8ec-2a1d-7f0c-9e75-384194162011";
43
53
  const USER_TWO_ID: string = "0198c8ec-2a1d-7f0c-9e75-384194162012";
44
54
  const USER_THREE_ID: string = "0198c8ec-2a1d-7f0c-9e75-384194162013";
@@ -84,7 +94,7 @@ jest.mock("react-i18next", () => {
84
94
  * The project field is an entity dropdown, so the real one would lazily search
85
95
  * the Projects endpoint. All this file needs from it is a way to say "the admin
86
96
  * picked this project", in the shape the real component reports a single
87
- * selection in: the bare id string, not an option object. Two projects are on
97
+ * selection in: the bare id string, not an option object. Three projects are on
88
98
  * offer so a test can change its mind about which one, which is what surfaces
89
99
  * the stale-team bug.
90
100
  */
@@ -112,6 +122,14 @@ jest.mock("Common/UI/Components/EntityDropdown/EntityDropdown", () => {
112
122
  >
113
123
  Choose the other project
114
124
  </button>
125
+ <button
126
+ type="button"
127
+ onClick={() => {
128
+ props.onChange?.(NO_MEMBERS_PROJECT_ID);
129
+ }}
130
+ >
131
+ Choose the project with no members team
132
+ </button>
115
133
  </div>
116
134
  );
117
135
  },
@@ -151,8 +169,13 @@ jest.mock("Common/UI/Components/Dropdown/Dropdown", () => {
151
169
  default: (props: DropdownStubProps): React.ReactElement => {
152
170
  capturedDropdownProps = props;
153
171
 
172
+ const selected: DropdownStubOption | undefined = props.value as
173
+ | DropdownStubOption
174
+ | undefined;
175
+
154
176
  return (
155
177
  <div>
178
+ <p data-testid="selected-team">{selected?.label || "(none)"}</p>
156
179
  {props.options.map((option: DropdownStubOption) => {
157
180
  return (
158
181
  <button
@@ -191,17 +214,13 @@ jest.mock(
191
214
  import BulkAddUsersToProjectModal, {
192
215
  BulkAddUsersToProjectSelection,
193
216
  } from "../../../../App/FeatureSet/AdminDashboard/src/Components/User/BulkAddUsersToProjectModal";
194
- /*
195
- * The picker is rendered by this modal, but a few of its rules cannot be driven
196
- * through the modal at all - an in-flight fetch and a failed fetch are states
197
- * the step rail cannot hold still in - so it is also exercised on its own here,
198
- * with the same isMultiSelect={false} wiring the modal gives it.
199
- */
200
- import ProjectScopedTeamsPicker from "../../../../App/FeatureSet/AdminDashboard/src/Components/GlobalProvider/ProjectScopedTeamsPicker";
201
217
  import AdminModelAPI from "../../../../App/FeatureSet/AdminDashboard/src/Utils/ModelAPI";
202
218
  import SortOrder from "../../../Types/BaseDatabase/SortOrder";
219
+ import PermissionScope from "../../../Types/Database/AccessControl/PermissionScope";
203
220
  import ObjectID from "../../../Types/ObjectID";
221
+ import Permission from "../../../Types/Permission";
204
222
  import Team from "../../../Models/DatabaseModels/Team";
223
+ import TeamPermission from "../../../Models/DatabaseModels/TeamPermission";
205
224
  import User from "../../../Models/DatabaseModels/User";
206
225
 
207
226
  const mockGetList: jest.MockedFunction<any> =
@@ -212,34 +231,87 @@ const LOCALE_FILE_PATH: string = path.join(
212
231
  "../../../../App/FeatureSet/AdminDashboard/src/Locales/en.json",
213
232
  );
214
233
 
215
- type MakeTeamFunction = (id: string, name: string) => Team;
216
-
217
- const makeTeam: MakeTeamFunction = (id: string, name: string): Team => {
218
- const team: Team = new Team();
219
- team._id = id;
220
- team.name = name;
221
- return team;
222
- };
223
-
224
- type TeamsOfProjectFunction = (projectId: string) => Array<Team>;
234
+ interface TeamFixture {
235
+ id: string;
236
+ name: string;
237
+ permission: Permission;
238
+ }
225
239
 
226
240
  /*
227
- * Two projects with nothing in common. `getList` is scoped by projectId, so a
241
+ * The projects, with nothing in common. `getList` is scoped by projectId, so a
228
242
  * mock that ignored the query would hand back the same teams whichever project
229
243
  * was chosen - and a picker that kept showing the old project's teams would
230
244
  * look exactly like one that had refetched.
231
245
  */
232
- const teamsOfProject: TeamsOfProjectFunction = (
233
- projectId: string,
234
- ): Array<Team> => {
235
- if (projectId === OTHER_PROJECT_ID) {
236
- return [makeTeam(TEAM_BILLING_ID, "Billing")];
246
+ const PROJECT_TEAMS: Record<string, Array<TeamFixture>> = {
247
+ [PROJECT_ID]: [
248
+ {
249
+ id: TEAM_ENGINEERING_ID,
250
+ name: "Engineering",
251
+ permission: Permission.ProjectAdmin,
252
+ },
253
+ {
254
+ id: TEAM_MEMBERS_ID,
255
+ name: "Members",
256
+ permission: Permission.ProjectMember,
257
+ },
258
+ { id: TEAM_SUPPORT_ID, name: "Support", permission: Permission.Viewer },
259
+ ],
260
+ [OTHER_PROJECT_ID]: [
261
+ {
262
+ id: TEAM_BILLING_ID,
263
+ name: "Billing",
264
+ permission: Permission.ProjectMember,
265
+ },
266
+ ],
267
+ [NO_MEMBERS_PROJECT_ID]: [
268
+ {
269
+ id: TEAM_AUDITORS_ID,
270
+ name: "Auditors",
271
+ permission: Permission.Viewer,
272
+ },
273
+ ],
274
+ };
275
+
276
+ let projectTeams: Record<string, Array<TeamFixture>> = PROJECT_TEAMS;
277
+
278
+ interface ListArgs {
279
+ modelType: unknown;
280
+ query?: { projectId?: ObjectID | undefined } | undefined;
281
+ sort?: Record<string, unknown> | undefined;
282
+ }
283
+
284
+ // The project's teams, or their permission rows, as the API answers them.
285
+ const answerList: (args: ListArgs) => Promise<unknown> = async (
286
+ args: ListArgs,
287
+ ): Promise<unknown> => {
288
+ const fixtures: Array<TeamFixture> =
289
+ projectTeams[args?.query?.projectId?.toString() || ""] || [];
290
+
291
+ if (args.modelType === TeamPermission) {
292
+ const rows: Array<TeamPermission> = fixtures.map(
293
+ (fixture: TeamFixture): TeamPermission => {
294
+ const row: TeamPermission = new TeamPermission();
295
+ row._id = ObjectID.generate().toString();
296
+ row.teamId = new ObjectID(fixture.id);
297
+ row.permission = fixture.permission;
298
+ row.isBlockPermission = false;
299
+ row.scope = PermissionScope.All;
300
+ return row;
301
+ },
302
+ );
303
+
304
+ return { data: rows, count: rows.length };
237
305
  }
238
306
 
239
- return [
240
- makeTeam(TEAM_ENGINEERING_ID, "Engineering"),
241
- makeTeam(TEAM_SUPPORT_ID, "Support"),
242
- ];
307
+ const teams: Array<Team> = fixtures.map((fixture: TeamFixture): Team => {
308
+ const team: Team = new Team();
309
+ team._id = fixture.id;
310
+ team.name = fixture.name;
311
+ return team;
312
+ });
313
+
314
+ return { data: teams, count: teams.length };
243
315
  };
244
316
 
245
317
  type MakeUserFunction = (id: string) => User;
@@ -270,15 +342,15 @@ const renderModal: RenderModalFunction = (
270
342
  );
271
343
  };
272
344
 
273
- type ChooseProjectFunction = (view: ReturnType<typeof render>) => void;
345
+ type ClickFunction = (view: ReturnType<typeof render>) => void;
274
346
 
275
- const chooseProject: ChooseProjectFunction = (
347
+ const chooseProject: ClickFunction = (
276
348
  view: ReturnType<typeof render>,
277
349
  ): void => {
278
350
  fireEvent.click(view.getByRole("button", { name: "Choose a project" }));
279
351
  };
280
352
 
281
- const chooseOtherProject: ChooseProjectFunction = (
353
+ const chooseOtherProject: ClickFunction = (
282
354
  view: ReturnType<typeof render>,
283
355
  ): void => {
284
356
  fireEvent.click(
@@ -286,67 +358,47 @@ const chooseOtherProject: ChooseProjectFunction = (
286
358
  );
287
359
  };
288
360
 
289
- type GoBackToProjectStepFunction = (
290
- view: ReturnType<typeof render>,
291
- ) => Promise<void>;
292
-
293
- /*
294
- * The way back is the step rail, the same as in the browser: a completed step
295
- * is clickable and returns the form to it. There is no back button - the modal
296
- * footer only ever goes forward - so this is the only route an admin has to
297
- * change their mind about the project after picking a team.
298
- */
299
- const goBackToProjectStep: GoBackToProjectStepFunction = async (
361
+ const chooseProjectWithoutMembersTeam: ClickFunction = (
300
362
  view: ReturnType<typeof render>,
301
- ): Promise<void> => {
302
- fireEvent.click(view.getByText("pages.users.bulkAddToProjectStepProject"));
303
-
304
- await waitFor(
305
- () => {
306
- expect(view.getByTestId("modal-footer-submit-button")).toHaveTextContent(
307
- "pages.users.bulkAddToProjectNext",
308
- );
309
- },
310
- { timeout: WAIT_FOR_TIMEOUT },
363
+ ): void => {
364
+ fireEvent.click(
365
+ view.getByRole("button", {
366
+ name: "Choose the project with no members team",
367
+ }),
311
368
  );
312
369
  };
313
370
 
314
- type SubmitFunction = (view: ReturnType<typeof render>) => void;
315
-
316
- const submitModal: SubmitFunction = (view: ReturnType<typeof render>): void => {
371
+ const submitModal: ClickFunction = (view: ReturnType<typeof render>): void => {
317
372
  fireEvent.click(view.getByTestId("modal-footer-submit-button"));
318
373
  };
319
374
 
320
- type GoToTeamStepFunction = (
375
+ type WaitForTeamFunction = (
321
376
  view: ReturnType<typeof render>,
322
- expectedTeamName?: string,
377
+ teamName: string,
323
378
  ) => Promise<void>;
324
379
 
325
- /*
326
- * Step two is where every interesting assertion lives, and getting there means
327
- * both the step change and the teams fetch have to have settled. The team named
328
- * here is the one the fetch is waited on through, so it has to be a team of the
329
- * project that was just chosen.
330
- */
331
- const goToTeamStep: GoToTeamStepFunction = async (
380
+ // The picker shows this team as the one selected.
381
+ const waitForSelectedTeam: WaitForTeamFunction = async (
332
382
  view: ReturnType<typeof render>,
333
- expectedTeamName: string = "Engineering",
383
+ teamName: string,
334
384
  ): Promise<void> => {
335
- submitModal(view);
336
-
337
385
  await waitFor(
338
386
  () => {
339
- expect(view.getByTestId("modal-footer-submit-button")).toHaveTextContent(
340
- "pages.users.bulkAddToProjectSubmit",
341
- );
387
+ expect(view.getByTestId("selected-team")).toHaveTextContent(teamName);
342
388
  },
343
389
  { timeout: WAIT_FOR_TIMEOUT },
344
390
  );
391
+ };
345
392
 
393
+ // The picker offers this team (its teams have loaded).
394
+ const waitForTeamOnOffer: WaitForTeamFunction = async (
395
+ view: ReturnType<typeof render>,
396
+ teamName: string,
397
+ ): Promise<void> => {
346
398
  await waitFor(
347
399
  () => {
348
400
  expect(
349
- view.getByRole("button", { name: `Pick ${expectedTeamName}` }),
401
+ view.getByRole("button", { name: `Pick ${teamName}` }),
350
402
  ).toBeVisible();
351
403
  },
352
404
  { timeout: WAIT_FOR_TIMEOUT },
@@ -386,80 +438,70 @@ const chooseTeam: ChooseTeamFunction = (
386
438
  fireEvent.click(view.getByRole("button", { name: `Pick ${teamName}` }));
387
439
  };
388
440
 
441
+ type SettleFunction = () => Promise<void>;
442
+
443
+ /*
444
+ * Drains the microtask queue so a `.then` that was going to fire has fired.
445
+ * "onSubmit was not called" is only worth anything once the promise chain the
446
+ * call would have come from has had its turn.
447
+ */
448
+ const settle: SettleFunction = async (): Promise<void> => {
449
+ for (let index: number = 0; index < 10; index++) {
450
+ await Promise.resolve();
451
+ }
452
+ };
453
+
389
454
  describe("BulkAddUsersToProjectModal", () => {
390
455
  beforeEach(() => {
391
456
  jest.clearAllMocks();
392
457
  translationCalls.length = 0;
393
458
  capturedDropdownProps = null;
459
+ projectTeams = PROJECT_TEAMS;
394
460
 
395
- mockGetList.mockImplementation(
396
- async (args: {
397
- query?: { projectId?: ObjectID | undefined } | undefined;
398
- }): Promise<any> => {
399
- const teams: Array<Team> = teamsOfProject(
400
- args?.query?.projectId?.toString() || "",
401
- );
402
-
403
- return {
404
- data: teams,
405
- count: teams.length,
406
- };
407
- },
408
- );
461
+ mockGetList.mockImplementation((args: ListArgs): Promise<unknown> => {
462
+ return answerList(args);
463
+ });
409
464
  });
410
465
 
411
- type RenderPickerFunction = (overrides: {
412
- projectId: ObjectID;
413
- selectedTeamIds: Array<string>;
414
- onChange: (teamIds: Array<string>) => void;
415
- }) => ReturnType<typeof render>;
416
-
417
- /*
418
- * The picker exactly as this modal configures it: one team, not a list.
419
- */
420
- const renderPicker: RenderPickerFunction = (overrides: {
421
- projectId: ObjectID;
422
- selectedTeamIds: Array<string>;
423
- onChange: (teamIds: Array<string>) => void;
424
- }): ReturnType<typeof render> => {
425
- return render(
426
- <ProjectScopedTeamsPicker
427
- isMultiSelect={false}
428
- projectId={overrides.projectId}
429
- selectedTeamIds={overrides.selectedTeamIds}
430
- onChange={overrides.onChange}
431
- />,
432
- );
433
- };
434
-
435
- type SettleFunction = () => Promise<void>;
436
-
437
- /*
438
- * Drains the microtask queue so a `.then` that was going to fire has fired.
439
- * "onChange was not called" is only worth anything once the promise chain the
440
- * call would have come from has had its turn.
441
- */
442
- const settle: SettleFunction = async (): Promise<void> => {
443
- for (let index: number = 0; index < 10; index++) {
444
- await Promise.resolve();
445
- }
446
- };
447
-
448
466
  /*
449
- * The teams on offer are the chosen project's, so there is nothing to ask on
450
- * step one but the project. A team picker rendered alongside it would either
451
- * sit there empty or - worse - fetch before a project exists and offer the
452
- * teams of no project at all.
467
+ * One page. The project, the team under it and the auto-accept box are all
468
+ * on screen together, with no step list and no Next: the team is the chosen
469
+ * project's, so until a project is picked the picker says so, and asks the
470
+ * server nothing - a team picker that fetched before a project exists would
471
+ * offer the teams of no project at all.
453
472
  */
454
- test("asks for the project on its own step, with no team picker beside it", () => {
473
+ test("asks for the project, its team and the invitations on one page", async () => {
455
474
  const view: ReturnType<typeof render> = renderModal();
456
475
 
457
476
  expect(
458
477
  view.getByText("pages.users.bulkAddToProjectFieldProject"),
459
478
  ).toBeVisible();
460
479
  expect(
461
- view.queryByText("pages.users.bulkAddToProjectFieldTeam"),
480
+ view.getByText("pages.users.bulkAddToProjectFieldTeam"),
481
+ ).toBeVisible();
482
+ expect(
483
+ view.getByText("pages.users.bulkAddToProjectFieldAutoAccept"),
484
+ ).toBeVisible();
485
+
486
+ // Under the team, until a project is picked.
487
+ expect(
488
+ view.getByText("pages.users.bulkAddToProjectSelectProject"),
489
+ ).toBeVisible();
490
+
491
+ // No step list, no "Step 1 of 2", no Next.
492
+ expect(
493
+ view.queryByRole("navigation", { name: "Progress" }),
462
494
  ).not.toBeInTheDocument();
495
+ expect(view.queryByText(/Step 1 of/)).not.toBeInTheDocument();
496
+ expect(view.queryByRole("button", { name: "Next" })).toBeNull();
497
+
498
+ // The footer offers the action from the start.
499
+ expect(view.getByTestId("modal-footer-submit-button")).toHaveTextContent(
500
+ "pages.users.bulkAddToProjectSubmit",
501
+ );
502
+
503
+ await settle();
504
+
463
505
  expect(capturedDropdownProps).toBeNull();
464
506
  expect(mockGetList).not.toHaveBeenCalled();
465
507
  });
@@ -469,39 +511,89 @@ describe("BulkAddUsersToProjectModal", () => {
469
511
  * would offer every team on the instance, and an admin picking one would move
470
512
  * users into a project they never chose.
471
513
  */
472
- test("fetches the chosen project's teams, by name, on the team step", async () => {
514
+ test("picking a project loads its teams, by name, and starts on its members team", async () => {
473
515
  const view: ReturnType<typeof render> = renderModal();
474
516
 
475
517
  chooseProject(view);
476
- await goToTeamStep(view);
518
+ await waitForSelectedTeam(view, "Members");
519
+
520
+ const calls: Array<ListArgs> = mockGetList.mock.calls.map(
521
+ (call: Array<unknown>): ListArgs => {
522
+ return call[0] as ListArgs;
523
+ },
524
+ );
477
525
 
478
- expect(mockGetList).toHaveBeenCalledTimes(1);
526
+ for (const call of calls) {
527
+ expect(Object.keys(call.query || {})).toEqual(["projectId"]);
528
+ expect(call.query?.projectId?.toString()).toBe(PROJECT_ID);
529
+ }
479
530
 
480
- const getListArgs: {
481
- modelType: unknown;
482
- query: Record<string, ObjectID>;
483
- sort: Record<string, SortOrder>;
484
- } = mockGetList.mock.calls[0]![0];
531
+ // The options, by name; the members team from the teams and their roles.
532
+ expect(
533
+ calls.filter((call: ListArgs) => {
534
+ return call.modelType === Team;
535
+ }),
536
+ ).toHaveLength(2);
537
+ expect(
538
+ calls.some((call: ListArgs) => {
539
+ return (
540
+ call.modelType === Team &&
541
+ JSON.stringify(call.sort) ===
542
+ JSON.stringify({ name: SortOrder.Ascending })
543
+ );
544
+ }),
545
+ ).toBe(true);
546
+ expect(
547
+ calls.filter((call: ListArgs) => {
548
+ return call.modelType === TeamPermission;
549
+ }),
550
+ ).toHaveLength(1);
485
551
 
486
- expect(getListArgs.modelType).toBe(Team);
487
- expect(Object.keys(getListArgs.query)).toEqual(["projectId"]);
488
- expect(getListArgs.query["projectId"]?.toString()).toBe(PROJECT_ID);
489
- expect(getListArgs.sort).toEqual({ name: SortOrder.Ascending });
552
+ // Every team of the project is still on offer.
553
+ expect(
554
+ view.getByRole("button", { name: "Pick Engineering" }),
555
+ ).toBeVisible();
556
+ expect(view.getByRole("button", { name: "Pick Support" })).toBeVisible();
490
557
  });
491
558
 
492
559
  /*
493
- * The one thing this component exists to produce. hasAcceptedInvitation has
494
- * to come out false when the box was never ticked rather than undefined -
495
- * TeamMemberService rejects an already-accepted membership for anyone who is
496
- * not a master admin, so the flag is not a field to leave unset.
560
+ * The one thing this component exists to produce, in two presses: the
561
+ * project, then Add. hasAcceptedInvitation has to come out false when the
562
+ * box was never ticked rather than undefined - TeamMemberService rejects an
563
+ * already-accepted membership for anyone who is not a master admin, so the
564
+ * flag is not a field to leave unset.
497
565
  */
498
- test("hands the caller the chosen project and team once", async () => {
566
+ test("adds to the project's members team with the project picked and one press", async () => {
499
567
  const onSubmit: OnSubmitFunction = makeOnSubmit();
500
568
  const view: ReturnType<typeof render> = renderModal({ onSubmit: onSubmit });
501
569
 
502
570
  chooseProject(view);
503
- await goToTeamStep(view);
571
+ await waitForSelectedTeam(view, "Members");
572
+ submitModal(view);
573
+
574
+ await waitFor(
575
+ () => {
576
+ expect(onSubmit).toHaveBeenCalledTimes(1);
577
+ },
578
+ { timeout: WAIT_FOR_TIMEOUT },
579
+ );
580
+
581
+ const selection: BulkAddUsersToProjectSelection =
582
+ submittedSelection(onSubmit);
583
+
584
+ expect(selection.projectId.toString()).toBe(PROJECT_ID);
585
+ expect(selection.teamId.toString()).toBe(TEAM_MEMBERS_ID);
586
+ expect(selection.hasAcceptedInvitation).toBe(false);
587
+ });
588
+
589
+ test("hands the caller another team of the project when the admin picks one", async () => {
590
+ const onSubmit: OnSubmitFunction = makeOnSubmit();
591
+ const view: ReturnType<typeof render> = renderModal({ onSubmit: onSubmit });
592
+
593
+ chooseProject(view);
594
+ await waitForSelectedTeam(view, "Members");
504
595
  chooseTeam(view, "Engineering");
596
+ await waitForSelectedTeam(view, "Engineering");
505
597
  submitModal(view);
506
598
 
507
599
  await waitFor(
@@ -516,7 +608,6 @@ describe("BulkAddUsersToProjectModal", () => {
516
608
 
517
609
  expect(selection.projectId.toString()).toBe(PROJECT_ID);
518
610
  expect(selection.teamId.toString()).toBe(TEAM_ENGINEERING_ID);
519
- expect(selection.hasAcceptedInvitation).toBe(false);
520
611
  });
521
612
 
522
613
  /*
@@ -529,8 +620,7 @@ describe("BulkAddUsersToProjectModal", () => {
529
620
  const view: ReturnType<typeof render> = renderModal({ onSubmit: onSubmit });
530
621
 
531
622
  chooseProject(view);
532
- await goToTeamStep(view);
533
- chooseTeam(view, "Engineering");
623
+ await waitForSelectedTeam(view, "Members");
534
624
  fireEvent.click(view.getByRole("checkbox"));
535
625
  submitModal(view);
536
626
 
@@ -545,236 +635,143 @@ describe("BulkAddUsersToProjectModal", () => {
545
635
  });
546
636
 
547
637
  /*
548
- * A submit with no team must not reach the caller. It would either create
549
- * memberships against an undefined team or - since the page closes this modal
550
- * before it starts creating - tear the picker down over nothing.
551
- *
552
- * Which layer refuses: BasicForm's own required-field validation. `team` is
553
- * `required: true`, so submitForm collects a validation error and returns
554
- * before it ever calls props.onSubmit, which means the modal's own
555
- * `!teamId` guard is not entered and its
556
- * `pages.users.bulkAddToProjectSelectTeam` message is not what is being
557
- * pinned here. This test pins the outcome - nothing reaches the caller and
558
- * the form stays on the team step - not the guard.
638
+ * A submit with no project must not reach the caller: BasicForm's own
639
+ * required-field validation holds it, before the modal's guards.
559
640
  */
560
- test("does not submit while no team has been chosen", async () => {
641
+ test("does not submit before a project is picked", async () => {
561
642
  const onSubmit: OnSubmitFunction = makeOnSubmit();
562
643
  const view: ReturnType<typeof render> = renderModal({ onSubmit: onSubmit });
563
644
 
564
- chooseProject(view);
565
- await goToTeamStep(view);
566
645
  submitModal(view);
567
646
 
568
- // Still on the last step, still asking - it held rather than advanced.
569
- await waitFor(
570
- () => {
571
- expect(
572
- view.getByTestId("modal-footer-submit-button"),
573
- ).toHaveTextContent("pages.users.bulkAddToProjectSubmit");
574
- },
575
- { timeout: WAIT_FOR_TIMEOUT },
576
- );
647
+ await settle();
577
648
 
578
649
  expect(onSubmit).not.toHaveBeenCalled();
650
+ expect(mockGetList).not.toHaveBeenCalled();
579
651
  });
580
652
 
581
653
  /*
582
- * Changing your mind about the project after having picked a team.
583
- *
584
- * The team lives in the form value, and the form value survives the walk back
585
- * to step one. Refetching the teams alone does not fix that: the dropdown
586
- * filters its selection against the options it now has, so the old project's
587
- * team stops being *shown* while it is still *set*. Required-validation reads
588
- * the value, not the dropdown, so the form would happily submit, and nothing
589
- * downstream would catch it - TeamMemberService checks that the team exists,
590
- * not that it belongs to the project being written - leaving memberships
591
- * whose team is in one project and whose projectId is another.
592
- *
593
- * So: pick a project, pick its team, go back, pick the other project. The
594
- * team of the first project must not come out the other end.
654
+ * A project without a members team (no team holds ProjectMember for the
655
+ * whole project and none is called Members) starts with nothing picked, as
656
+ * the whole form did before. A submit with no team must not reach the
657
+ * caller: BasicForm's required-field validation holds it, and the form
658
+ * stays as it is until a team is picked.
595
659
  */
596
- test("does not carry a team of the old project into the new one", async () => {
660
+ test("a project with no members team waits for a team to be picked", async () => {
597
661
  const onSubmit: OnSubmitFunction = makeOnSubmit();
598
662
  const view: ReturnType<typeof render> = renderModal({ onSubmit: onSubmit });
599
663
 
600
- chooseProject(view);
601
- await goToTeamStep(view);
602
- chooseTeam(view, "Engineering");
664
+ chooseProjectWithoutMembersTeam(view);
665
+ await waitForTeamOnOffer(view, "Auditors");
666
+ await settle();
603
667
 
604
- await goBackToProjectStep(view);
605
- chooseOtherProject(view);
606
- await goToTeamStep(view, "Billing");
668
+ expect(view.getByTestId("selected-team")).toHaveTextContent("(none)");
607
669
 
608
- // The refetch really was scoped to the newly chosen project.
609
- expect(mockGetList).toHaveBeenCalledTimes(2);
610
- expect(
611
- (
612
- mockGetList.mock.calls[1]![0] as {
613
- query: Record<string, ObjectID>;
614
- }
615
- ).query["projectId"]?.toString(),
616
- ).toBe(OTHER_PROJECT_ID);
617
-
618
- // The old project's team is not on offer, and nothing is selected anymore.
619
- expect(
620
- view.queryByRole("button", { name: "Pick Engineering" }),
621
- ).not.toBeInTheDocument();
622
- expect(capturedDropdownProps!.value).toBeUndefined();
670
+ submitModal(view);
671
+ await settle();
623
672
 
673
+ expect(onSubmit).not.toHaveBeenCalled();
674
+
675
+ chooseTeam(view, "Auditors");
624
676
  submitModal(view);
625
677
 
626
- /*
627
- * Nothing may reach the caller carrying the first project's team. In
628
- * practice the cleared value fails required-validation and the form stays
629
- * on the team step, but the assertion is written to accept any outcome
630
- * except a membership pointing at a team of the project that was
631
- * abandoned.
632
- */
633
678
  await waitFor(
634
679
  () => {
635
- expect(
636
- view.getByTestId("modal-footer-submit-button"),
637
- ).toHaveTextContent("pages.users.bulkAddToProjectSubmit");
680
+ expect(onSubmit).toHaveBeenCalledTimes(1);
638
681
  },
639
682
  { timeout: WAIT_FOR_TIMEOUT },
640
683
  );
641
684
 
642
- await settle();
643
-
644
- const submitMock: jest.MockedFunction<any> =
645
- onSubmit as unknown as jest.MockedFunction<any>;
646
-
647
- const submittedTeamIds: Array<string> = submitMock.mock.calls.map(
648
- (call: Array<BulkAddUsersToProjectSelection>) => {
649
- return call[0]!.teamId.toString();
650
- },
685
+ expect(submittedSelection(onSubmit).projectId.toString()).toBe(
686
+ NO_MEMBERS_PROJECT_ID,
687
+ );
688
+ expect(submittedSelection(onSubmit).teamId.toString()).toBe(
689
+ TEAM_AUDITORS_ID,
651
690
  );
652
-
653
- expect(submittedTeamIds).not.toContain(TEAM_ENGINEERING_ID);
654
- expect(submittedTeamIds).not.toContain(TEAM_SUPPORT_ID);
655
- expect(onSubmit).not.toHaveBeenCalled();
656
691
  });
657
692
 
658
693
  /*
659
- * The same invariant one layer down, where it is stated rather than inferred:
660
- * a selection the fetched project does not offer is dropped, and only that
661
- * one - ids that ARE the project's teams stay. A blanket clear would be just
662
- * as wrong in the other direction, wiping a valid pick on every refetch.
694
+ * Changing your mind about the project after having picked a team.
695
+ *
696
+ * The team lives in the form value, and the form value survives the switch.
697
+ * Refetching the teams alone does not fix that: the dropdown filters its
698
+ * selection against the options it now has, so the old project's team stops
699
+ * being *shown* while it is still *set*. Required-validation reads the value,
700
+ * not the dropdown, so the form would happily submit, and nothing downstream
701
+ * would catch it - TeamMemberService checks that the team exists, not that it
702
+ * belongs to the project being written - leaving memberships whose team is in
703
+ * one project and whose projectId is another.
704
+ *
705
+ * So: pick a project, pick its team, pick the other project. The team of the
706
+ * first project must not come out the other end: the other project's members
707
+ * team takes its place.
663
708
  */
664
- test("drops only the team ids the fetched project does not offer", async () => {
665
- const onChange: (teamIds: Array<string>) => void = jest.fn(
666
- (_teamIds: Array<string>): void => {},
667
- );
709
+ test("does not carry a team of the old project into the new one", async () => {
710
+ const onSubmit: OnSubmitFunction = makeOnSubmit();
711
+ const view: ReturnType<typeof render> = renderModal({ onSubmit: onSubmit });
668
712
 
669
- renderPicker({
670
- projectId: new ObjectID(OTHER_PROJECT_ID),
671
- selectedTeamIds: [TEAM_ENGINEERING_ID, TEAM_BILLING_ID],
672
- onChange: onChange,
673
- });
713
+ chooseProject(view);
714
+ await waitForSelectedTeam(view, "Members");
715
+ chooseTeam(view, "Engineering");
716
+ await waitForSelectedTeam(view, "Engineering");
674
717
 
675
- await waitFor(
676
- () => {
677
- expect(onChange).toHaveBeenCalledTimes(1);
678
- },
679
- { timeout: WAIT_FOR_TIMEOUT },
680
- );
718
+ chooseOtherProject(view);
719
+ await waitForSelectedTeam(view, "Billing");
681
720
 
682
- const onChangeMock: jest.MockedFunction<any> =
683
- onChange as unknown as jest.MockedFunction<any>;
721
+ // The refetch really was scoped to the newly chosen project.
722
+ const otherProjectCalls: Array<ListArgs> = mockGetList.mock.calls
723
+ .map((call: Array<unknown>): ListArgs => {
724
+ return call[0] as ListArgs;
725
+ })
726
+ .filter((call: ListArgs) => {
727
+ return call.query?.projectId?.toString() === OTHER_PROJECT_ID;
728
+ });
684
729
 
685
- expect(onChangeMock.mock.calls[0]![0]).toEqual([TEAM_BILLING_ID]);
686
- });
730
+ expect(otherProjectCalls).toHaveLength(3);
687
731
 
688
- /*
689
- * The other half of that: when everything selected is still a team of the
690
- * project, the picker must leave the value alone. Reporting a change here
691
- * would make the form dirty - and, in a form that reacted to its own onChange
692
- * by re-rendering the custom element, would be a loop.
693
- */
694
- test("leaves a selection the fetched project does offer alone", async () => {
695
- const onChange: (teamIds: Array<string>) => void = jest.fn(
696
- (_teamIds: Array<string>): void => {},
697
- );
732
+ // The old project's teams are not on offer.
733
+ expect(
734
+ view.queryByRole("button", { name: "Pick Engineering" }),
735
+ ).not.toBeInTheDocument();
698
736
 
699
- const view: ReturnType<typeof render> = renderPicker({
700
- projectId: new ObjectID(PROJECT_ID),
701
- selectedTeamIds: [TEAM_ENGINEERING_ID],
702
- onChange: onChange,
703
- });
737
+ submitModal(view);
704
738
 
705
739
  await waitFor(
706
740
  () => {
707
- expect(
708
- view.getByRole("button", { name: "Pick Engineering" }),
709
- ).toBeVisible();
741
+ expect(onSubmit).toHaveBeenCalledTimes(1);
710
742
  },
711
743
  { timeout: WAIT_FOR_TIMEOUT },
712
744
  );
713
745
 
714
- await settle();
746
+ const selection: BulkAddUsersToProjectSelection =
747
+ submittedSelection(onSubmit);
715
748
 
716
- expect(onChange).not.toHaveBeenCalled();
749
+ expect(selection.projectId.toString()).toBe(OTHER_PROJECT_ID);
750
+ expect(selection.teamId.toString()).toBe(TEAM_BILLING_ID);
717
751
  });
718
752
 
719
753
  /*
720
- * Clearing is bound to the fetch's success path, and this is why. While the
721
- * request is in flight the picker knows nothing about which teams the project
722
- * has, so a selection cleared here would be one thrown away on no evidence -
723
- * and the admin, watching "Loading teams...", would never see it go.
754
+ * And the stale team is dropped even when the new project has no members
755
+ * team to put in its place: nothing is picked, and nothing reaches the
756
+ * caller carrying the first project's team.
724
757
  */
725
- test("does not clear the selection while the teams are still loading", async () => {
726
- mockGetList.mockImplementation((): Promise<any> => {
727
- // Never settles: the picker is held in its loading state for the test.
728
- return new Promise((): void => {});
729
- });
730
-
731
- const onChange: (teamIds: Array<string>) => void = jest.fn(
732
- (_teamIds: Array<string>): void => {},
733
- );
734
-
735
- const view: ReturnType<typeof render> = renderPicker({
736
- projectId: new ObjectID(OTHER_PROJECT_ID),
737
- selectedTeamIds: [TEAM_ENGINEERING_ID],
738
- onChange: onChange,
739
- });
758
+ test("drops the old project's team when the new one has no members team", async () => {
759
+ const onSubmit: OnSubmitFunction = makeOnSubmit();
760
+ const view: ReturnType<typeof render> = renderModal({ onSubmit: onSubmit });
740
761
 
741
- expect(view.getByText("Loading teams...")).toBeVisible();
762
+ chooseProject(view);
763
+ await waitForSelectedTeam(view, "Members");
742
764
 
765
+ chooseProjectWithoutMembersTeam(view);
766
+ await waitForTeamOnOffer(view, "Auditors");
743
767
  await settle();
744
768
 
745
- expect(onChange).not.toHaveBeenCalled();
746
- });
747
-
748
- /*
749
- * And when the request fails outright. The teams may well be fine and the
750
- * network not; discarding the pick on an error would turn a retryable blip
751
- * into silently lost input, on top of the error the admin is already reading.
752
- */
753
- test("does not clear the selection when the teams fail to load", async () => {
754
- mockGetList.mockImplementation(async (): Promise<any> => {
755
- throw new Error("Teams could not be loaded.");
756
- });
757
-
758
- const onChange: (teamIds: Array<string>) => void = jest.fn(
759
- (_teamIds: Array<string>): void => {},
760
- );
761
-
762
- const view: ReturnType<typeof render> = renderPicker({
763
- projectId: new ObjectID(OTHER_PROJECT_ID),
764
- selectedTeamIds: [TEAM_ENGINEERING_ID],
765
- onChange: onChange,
766
- });
767
-
768
- await waitFor(
769
- () => {
770
- expect(view.getByText("Teams could not be loaded.")).toBeVisible();
771
- },
772
- { timeout: WAIT_FOR_TIMEOUT },
773
- );
769
+ expect(view.getByTestId("selected-team")).toHaveTextContent("(none)");
774
770
 
771
+ submitModal(view);
775
772
  await settle();
776
773
 
777
- expect(onChange).not.toHaveBeenCalled();
774
+ expect(onSubmit).not.toHaveBeenCalled();
778
775
  });
779
776
 
780
777
  /*
@@ -784,15 +781,12 @@ describe("BulkAddUsersToProjectModal", () => {
784
781
  * submittable out of that state.
785
782
  */
786
783
  test("cannot be submitted when the chosen project has no teams", async () => {
787
- mockGetList.mockImplementation(async (): Promise<any> => {
788
- return { data: [], count: 0 };
789
- });
784
+ projectTeams = {};
790
785
 
791
786
  const onSubmit: OnSubmitFunction = makeOnSubmit();
792
787
  const view: ReturnType<typeof render> = renderModal({ onSubmit: onSubmit });
793
788
 
794
789
  chooseProject(view);
795
- submitModal(view);
796
790
 
797
791
  await waitFor(
798
792
  () => {
@@ -808,15 +802,6 @@ describe("BulkAddUsersToProjectModal", () => {
808
802
 
809
803
  submitModal(view);
810
804
 
811
- await waitFor(
812
- () => {
813
- expect(
814
- view.getByTestId("modal-footer-submit-button"),
815
- ).toHaveTextContent("pages.users.bulkAddToProjectSubmit");
816
- },
817
- { timeout: WAIT_FOR_TIMEOUT },
818
- );
819
-
820
805
  await settle();
821
806
 
822
807
  expect(onSubmit).not.toHaveBeenCalled();
@@ -838,8 +823,7 @@ describe("BulkAddUsersToProjectModal", () => {
838
823
  const view: ReturnType<typeof render> = renderModal({ onSubmit: onSubmit });
839
824
 
840
825
  chooseProject(view);
841
- await goToTeamStep(view);
842
- chooseTeam(view, "Engineering");
826
+ await waitForSelectedTeam(view, "Members");
843
827
 
844
828
  submitModal(view);
845
829
 
@@ -871,20 +855,19 @@ describe("BulkAddUsersToProjectModal", () => {
871
855
  * `isMultiSelect ? selectedOptions : selectedOptions[0]`). Then that a second
872
856
  * pick replaces the first instead of piling up next to it, which is the
873
857
  * modal's `teamIds[0]`.
874
- *
875
- * What is NOT pinned: that the emitted teamId is a scalar and not an array.
876
- * The Dropdown here is a stub that hands its onChange a single string in
877
- * either mode, so the shape of what comes back is the stub's doing, not the
878
- * component's - asserting on it would be asserting on this file.
879
858
  */
880
859
  test("takes one team, not a list of them", async () => {
881
860
  const onSubmit: OnSubmitFunction = makeOnSubmit();
882
861
  const view: ReturnType<typeof render> = renderModal({ onSubmit: onSubmit });
883
862
 
884
863
  chooseProject(view);
885
- await goToTeamStep(view);
864
+ await waitForSelectedTeam(view, "Members");
886
865
 
887
866
  expect(capturedDropdownProps!.isMultiSelect).toBe(false);
867
+ expect(capturedDropdownProps!.value).toEqual({
868
+ label: "Members",
869
+ value: TEAM_MEMBERS_ID,
870
+ });
888
871
 
889
872
  chooseTeam(view, "Support");
890
873
 
@@ -913,26 +896,6 @@ describe("BulkAddUsersToProjectModal", () => {
913
896
  );
914
897
  });
915
898
 
916
- /*
917
- * The modal owns the footer button, and BasicForm's own submit button is
918
- * hidden, so the two have to be kept in step by hand. A button still reading
919
- * "next" on the last step is the one that looks like it did nothing.
920
- */
921
- test("labels the footer button for the step it is on", async () => {
922
- const view: ReturnType<typeof render> = renderModal();
923
-
924
- expect(view.getByTestId("modal-footer-submit-button")).toHaveTextContent(
925
- "pages.users.bulkAddToProjectNext",
926
- );
927
-
928
- chooseProject(view);
929
- await goToTeamStep(view);
930
-
931
- expect(view.getByTestId("modal-footer-submit-button")).toHaveTextContent(
932
- "pages.users.bulkAddToProjectSubmit",
933
- );
934
- });
935
-
936
899
  /*
937
900
  * How many users this is about is the one thing the admin cannot see from
938
901
  * inside the modal - the table's selection is behind it. The count is passed
@@ -1002,7 +965,7 @@ describe("BulkAddUsersToProjectModal", () => {
1002
965
  const view: ReturnType<typeof render> = renderModal();
1003
966
 
1004
967
  chooseProject(view);
1005
- await goToTeamStep(view);
968
+ await waitForSelectedTeam(view, "Members");
1006
969
 
1007
970
  const localeStrings: unknown = JSON.parse(
1008
971
  fs.readFileSync(LOCALE_FILE_PATH, "utf8"),
@@ -1047,5 +1010,15 @@ describe("BulkAddUsersToProjectModal", () => {
1047
1010
  );
1048
1011
 
1049
1012
  expect(unresolvedKeys).toEqual([]);
1013
+
1014
+ // The step names and the Next of the old two-step form are gone for good.
1015
+ for (const retired of [
1016
+ "pages.users.bulkAddToProjectNext",
1017
+ "pages.users.bulkAddToProjectStepProject",
1018
+ "pages.users.bulkAddToProjectStepTeam",
1019
+ ]) {
1020
+ expect(requestedKeys).not.toContain(retired);
1021
+ expect(resolveKey(retired)).toBeUndefined();
1022
+ }
1050
1023
  });
1051
1024
  });