@oneuptime/common 12.0.1 → 12.0.3

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 (385) hide show
  1. package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +14 -0
  2. package/Models/DatabaseModels/Host.ts +12 -4
  3. package/Models/DatabaseModels/Index.ts +2 -0
  4. package/Models/DatabaseModels/KubernetesContainer.ts +5 -4
  5. package/Models/DatabaseModels/KubernetesResource.ts +8 -7
  6. package/Models/DatabaseModels/LogDropFilter.ts +9 -20
  7. package/Models/DatabaseModels/PodmanResource.ts +6 -6
  8. package/Models/DatabaseModels/ServiceLevelObjective.ts +91 -0
  9. package/Models/DatabaseModels/StatusPage.ts +95 -0
  10. package/Models/DatabaseModels/StatusPageMonitorRule.ts +911 -0
  11. package/Models/DatabaseModels/StatusPageResource.ts +73 -0
  12. package/Models/DatabaseModels/TraceDropFilter.ts +9 -20
  13. package/Server/API/BaseAPI.ts +13 -2
  14. package/Server/API/DashboardAPI.ts +39 -0
  15. package/Server/API/TeamMemberAPI.ts +85 -0
  16. package/Server/EnvironmentConfig.ts +31 -1
  17. package/Server/Infrastructure/GlobalCache.ts +115 -0
  18. package/Server/Infrastructure/Postgres/DataSourceOptions.ts +16 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.ts +84 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.ts +40 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.ts +131 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.ts +25 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.ts +123 -0
  24. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  25. package/Server/Middleware/ProjectAuthorization.ts +66 -4
  26. package/Server/Services/AlertStateTimelineService.ts +20 -0
  27. package/Server/Services/BillingService.ts +600 -51
  28. package/Server/Services/CephClusterService.ts +27 -45
  29. package/Server/Services/CephResourceService.ts +43 -4
  30. package/Server/Services/CloudResourceService.ts +24 -42
  31. package/Server/Services/DatabaseService.ts +198 -6
  32. package/Server/Services/DockerHostService.ts +20 -38
  33. package/Server/Services/DockerResourceService.ts +62 -8
  34. package/Server/Services/DockerSwarmClusterService.ts +28 -46
  35. package/Server/Services/DockerSwarmResourceService.ts +53 -4
  36. package/Server/Services/HostService.ts +47 -57
  37. package/Server/Services/IncidentStateTimelineService.ts +20 -0
  38. package/Server/Services/Index.ts +2 -0
  39. package/Server/Services/IoTDeviceService.ts +1 -17
  40. package/Server/Services/IoTFleetService.ts +20 -38
  41. package/Server/Services/KubernetesClusterService.ts +18 -36
  42. package/Server/Services/KubernetesContainerService.ts +50 -9
  43. package/Server/Services/KubernetesResourceService.ts +53 -7
  44. package/Server/Services/LabelService.ts +153 -1
  45. package/Server/Services/MetricTypeService.ts +84 -0
  46. package/Server/Services/MonitorService.ts +146 -14
  47. package/Server/Services/MonitorStatusTimelineService.ts +29 -0
  48. package/Server/Services/MonitorTemplateService.ts +65 -0
  49. package/Server/Services/PodmanHostService.ts +20 -38
  50. package/Server/Services/PodmanResourceService.ts +62 -8
  51. package/Server/Services/ProjectService.ts +165 -35
  52. package/Server/Services/ProxmoxClusterService.ts +24 -42
  53. package/Server/Services/ProxmoxResourceService.ts +43 -4
  54. package/Server/Services/RumApplicationService.ts +20 -38
  55. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +21 -0
  56. package/Server/Services/ServerlessFunctionService.ts +25 -43
  57. package/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.ts +426 -0
  58. package/Server/Services/ServiceLevelObjectiveService.ts +39 -0
  59. package/Server/Services/ServiceService.ts +299 -73
  60. package/Server/Services/StatusPageMonitorRuleEngineService.ts +752 -0
  61. package/Server/Services/StatusPageMonitorRuleService.ts +471 -0
  62. package/Server/Services/StatusPageService.ts +95 -36
  63. package/Server/Services/StatusPageSubscriberNotificationTemplateService.ts +18 -1
  64. package/Server/Services/StatusPageSubscriberService.ts +3 -0
  65. package/Server/Services/TelemetryEntityRelationshipService.ts +1 -0
  66. package/Server/Services/TelemetryEntityService.ts +1 -0
  67. package/Server/Types/Database/JSONColumnQuery.ts +621 -0
  68. package/Server/Types/Database/Permissions/PublicPermission.ts +9 -2
  69. package/Server/Types/Database/QueryHelper.ts +17 -32
  70. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +170 -39
  71. package/Server/Utils/Database/TruncateColumnValue.ts +84 -0
  72. package/Server/Utils/Monitor/MonitorResource.ts +63 -36
  73. package/Server/Utils/Monitor/MonitorStatusTimeline.ts +36 -0
  74. package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +148 -127
  75. package/Server/Utils/Monitor/MonitorStepsReferenceExtractor.ts +434 -0
  76. package/Server/Utils/SingleFlight.ts +83 -0
  77. package/Server/Utils/StatusPage/MonitorRulePatternValidator.ts +46 -0
  78. package/Server/Utils/Telemetry/EntityRegistry.ts +107 -26
  79. package/Server/Utils/Telemetry/ResourceHeartbeat.ts +314 -0
  80. package/Server/Utils/Telemetry/Telemetry.ts +351 -122
  81. package/Tests/App/Dashboard/UsersTableGroupsByPerson.test.tsx +448 -0
  82. package/Tests/App/Dashboard/WidgetCatalog.test.ts +2 -0
  83. package/Tests/Models/DatabaseModels/ColumnTransformerInvariants.test.ts +306 -0
  84. package/Tests/Models/DatabaseModels/NumberColumnDeserialization.test.ts +333 -0
  85. package/Tests/Models/DatabaseModels/StatusPageMonitorRuleModel.test.ts +190 -0
  86. package/Tests/Server/API/BaseAPIApiKeyAuth.test.ts +704 -0
  87. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +26 -0
  88. package/Tests/Server/API/TeamMemberRemoveUserFromProjectAPI.test.ts +303 -0
  89. package/Tests/Server/Infrastructure/GlobalCache.test.ts +226 -0
  90. package/Tests/Server/Infrastructure/PostgresLockTimeoutOptions.test.ts +181 -0
  91. package/Tests/Server/Middleware/MasterAdminAuthorization.test.ts +350 -0
  92. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyHeader.test.ts +362 -0
  93. package/Tests/Server/Middleware/ProjectAuthorizationApiKeyMiddleware.test.ts +687 -0
  94. package/Tests/Server/Services/BillingService.test.ts +78 -3
  95. package/Tests/Server/Services/BillingServiceChangePlanCancel.test.ts +645 -0
  96. package/Tests/Server/Services/BillingServiceTrialPlanChange.test.ts +1005 -0
  97. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlocked.test.ts +342 -0
  98. package/Tests/Server/Services/DropFilterSaveValidation.test.ts +245 -0
  99. package/Tests/Server/Services/HookFreeWriteLengthClamp.test.ts +503 -0
  100. package/Tests/Server/Services/HostIpAddressesColumnWidth.test.ts +198 -0
  101. package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +658 -0
  102. package/Tests/Server/Services/InventoryResourceNameColumnWidth.test.ts +500 -0
  103. package/Tests/Server/Services/InventoryUpsertSchemaParity.test.ts +586 -0
  104. package/Tests/Server/Services/InventoryUpsertTruncationGuard.test.ts +1242 -0
  105. package/Tests/Server/Services/MetricTypeAttachServices.test.ts +222 -0
  106. package/Tests/Server/Services/MissingReferenceWriteGuard.test.ts +614 -0
  107. package/Tests/Server/Services/MonitorStatusTimelineFastPath.test.ts +23 -0
  108. package/Tests/Server/Services/ProjectServiceChangePlan.test.ts +650 -0
  109. package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +1 -0
  110. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +636 -0
  111. package/Tests/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.test.ts +770 -0
  112. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +130 -0
  113. package/Tests/Server/Services/ServiceUpdateLastSeenSplitGates.test.ts +705 -0
  114. package/Tests/Server/Services/SloMonitorLabelRuleHooks.test.ts +352 -0
  115. package/Tests/Server/Services/StatusPageMonitorRuleEngineService.test.ts +1719 -0
  116. package/Tests/Server/Services/StatusPageMonitorRuleHooks.test.ts +1212 -0
  117. package/Tests/Server/Services/StatusPageMonitorRuleMonitorCreateHook.test.ts +228 -0
  118. package/Tests/Server/Services/StatusPageSubscriberReport.test.ts +29 -13
  119. package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +69 -8
  120. package/Tests/Server/Types/Database/JSONColumnQuery.test.ts +593 -0
  121. package/Tests/Server/Types/Database/Permissions/PublicPermission.test.ts +495 -0
  122. package/Tests/Server/Types/Database/QueryUtil.test.ts +113 -0
  123. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +267 -0
  124. package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +260 -13
  125. package/Tests/Server/Utils/Database/TruncateColumnValue.test.ts +179 -0
  126. package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +302 -0
  127. package/Tests/Server/Utils/MetricTypeIndexConvergence.test.ts +598 -0
  128. package/Tests/Server/Utils/Monitor/MonitorStatusTimelineUnusableStatus.test.ts +154 -0
  129. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +638 -92
  130. package/Tests/Server/Utils/Monitor/MonitorStepsReferenceExtractor.test.ts +724 -0
  131. package/Tests/Server/Utils/SingleFlight.test.ts +221 -0
  132. package/Tests/Types/Dashboard/NetworkDashboardTemplate.test.ts +793 -0
  133. package/Tests/Types/Database/BigIntColumnTransformer.test.ts +147 -0
  134. package/Tests/Types/Database/DatabasePropertyTransformer.test.ts +140 -0
  135. package/Tests/Types/Database/NumericColumnValue.test.ts +127 -0
  136. package/Tests/Types/Decimal.test.ts +37 -0
  137. package/Tests/Types/Events/Recurring.test.ts +157 -0
  138. package/Tests/Types/Monitor/SnmpVersionParsing.test.ts +152 -0
  139. package/Tests/Types/Port.test.ts +38 -0
  140. package/Tests/UI/Components/LogsHistogram.test.tsx +276 -0
  141. package/Tests/UI/Components/ModelTable/ModelTableGroupsProjectUsers.test.tsx +375 -0
  142. package/Tests/UI/Components/ModelTable/useCustomFieldColumns.test.tsx +196 -0
  143. package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +489 -0
  144. package/Tests/UI/Components/UseLogsHistogram.test.tsx +500 -0
  145. package/Tests/UI/Utils/ProjectUsersModelAPI.test.ts +739 -0
  146. package/Tests/UI/Utils/TeamMembersByUser.test.ts +633 -0
  147. package/Tests/Utils/Dashboard/Components/DashboardComponentsUtil.test.ts +120 -0
  148. package/Tests/Utils/Dashboard/DashboardNetworkMapComponent.test.ts +327 -0
  149. package/Tests/Utils/StatusPage/ReportPeriod.test.ts +218 -0
  150. package/Tests/Utils/Telemetry/HostIpAddresses.test.ts +291 -0
  151. package/Types/CustomField/CustomFieldDefinition.ts +24 -0
  152. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  153. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  154. package/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.ts +40 -0
  155. package/Types/Dashboard/DashboardTemplates.ts +397 -0
  156. package/Types/Database/BigIntColumnTransformer.ts +74 -0
  157. package/Types/Database/DatabaseProperty.ts +26 -0
  158. package/Types/Database/NumericColumnValue.ts +128 -0
  159. package/Types/Date.ts +112 -0
  160. package/Types/Decimal.ts +16 -4
  161. package/Types/Events/Recurring.ts +99 -1
  162. package/Types/Permission.ts +48 -0
  163. package/Types/Port.ts +16 -4
  164. package/Types/StatusPage/StatusPageReport.ts +11 -0
  165. package/Types/StatusPage/StatusPageReportPeriodType.ts +21 -0
  166. package/UI/Components/LogsViewer/useLiveLogsRefresh.ts +86 -0
  167. package/UI/Components/LogsViewer/useLogsHistogram.ts +113 -0
  168. package/UI/Components/ModelTable/CustomFieldColumns.tsx +2 -6
  169. package/UI/Components/ModelTable/useCustomFieldColumns.ts +21 -2
  170. package/UI/Utils/ModelAPI/ProjectUsersModelAPI.ts +305 -0
  171. package/UI/Utils/TeamMembersByUser.ts +302 -0
  172. package/Utils/Dashboard/Components/DashboardNetworkMapComponent.ts +136 -0
  173. package/Utils/Dashboard/Components/Index.ts +7 -0
  174. package/Utils/StatusPage/ReportPeriod.ts +236 -0
  175. package/Utils/Telemetry/HostIpAddresses.ts +98 -0
  176. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +12 -0
  177. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
  178. package/build/dist/Models/DatabaseModels/Host.js +12 -4
  179. package/build/dist/Models/DatabaseModels/Host.js.map +1 -1
  180. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  181. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  182. package/build/dist/Models/DatabaseModels/KubernetesContainer.js +4 -4
  183. package/build/dist/Models/DatabaseModels/KubernetesContainer.js.map +1 -1
  184. package/build/dist/Models/DatabaseModels/KubernetesResource.js +7 -7
  185. package/build/dist/Models/DatabaseModels/KubernetesResource.js.map +1 -1
  186. package/build/dist/Models/DatabaseModels/LogDropFilter.js +9 -20
  187. package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
  188. package/build/dist/Models/DatabaseModels/PodmanResource.js +6 -6
  189. package/build/dist/Models/DatabaseModels/PodmanResource.js.map +1 -1
  190. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +87 -0
  191. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -1
  192. package/build/dist/Models/DatabaseModels/StatusPage.js +98 -0
  193. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  194. package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js +925 -0
  195. package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js.map +1 -0
  196. package/build/dist/Models/DatabaseModels/StatusPageResource.js +72 -0
  197. package/build/dist/Models/DatabaseModels/StatusPageResource.js.map +1 -1
  198. package/build/dist/Models/DatabaseModels/TraceDropFilter.js +9 -20
  199. package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
  200. package/build/dist/Server/API/BaseAPI.js +11 -1
  201. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  202. package/build/dist/Server/API/DashboardAPI.js +39 -0
  203. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  204. package/build/dist/Server/API/TeamMemberAPI.js +57 -2
  205. package/build/dist/Server/API/TeamMemberAPI.js.map +1 -1
  206. package/build/dist/Server/EnvironmentConfig.js +27 -1
  207. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  208. package/build/dist/Server/Infrastructure/GlobalCache.js +91 -0
  209. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  210. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +5 -3
  211. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
  212. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js +45 -0
  213. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785900000000-AddSloMonitorLabelRule.js.map +1 -0
  214. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js +31 -0
  215. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785915638551-IncreaseHostIpAddressesLength.js.map +1 -0
  216. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js +90 -0
  217. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930000000-WidenInventoryResourceNameColumns.js.map +1 -0
  218. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js +14 -0
  219. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785930709405-AddStatusPageReportPeriod.js.map +1 -0
  220. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js +48 -0
  221. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js.map +1 -0
  222. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  223. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  224. package/build/dist/Server/Middleware/ProjectAuthorization.js +59 -4
  225. package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
  226. package/build/dist/Server/Services/AlertStateTimelineService.js +19 -0
  227. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
  228. package/build/dist/Server/Services/BillingService.js +466 -36
  229. package/build/dist/Server/Services/BillingService.js.map +1 -1
  230. package/build/dist/Server/Services/CephClusterService.js +26 -39
  231. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  232. package/build/dist/Server/Services/CephResourceService.js +28 -3
  233. package/build/dist/Server/Services/CephResourceService.js.map +1 -1
  234. package/build/dist/Server/Services/CloudResourceService.js +23 -36
  235. package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
  236. package/build/dist/Server/Services/DatabaseService.js +155 -2
  237. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  238. package/build/dist/Server/Services/DockerHostService.js +19 -32
  239. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  240. package/build/dist/Server/Services/DockerResourceService.js +34 -4
  241. package/build/dist/Server/Services/DockerResourceService.js.map +1 -1
  242. package/build/dist/Server/Services/DockerSwarmClusterService.js +27 -40
  243. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  244. package/build/dist/Server/Services/DockerSwarmResourceService.js +28 -3
  245. package/build/dist/Server/Services/DockerSwarmResourceService.js.map +1 -1
  246. package/build/dist/Server/Services/HostService.js +58 -64
  247. package/build/dist/Server/Services/HostService.js.map +1 -1
  248. package/build/dist/Server/Services/IncidentStateTimelineService.js +19 -0
  249. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  250. package/build/dist/Server/Services/Index.js +2 -0
  251. package/build/dist/Server/Services/Index.js.map +1 -1
  252. package/build/dist/Server/Services/IoTDeviceService.js +1 -8
  253. package/build/dist/Server/Services/IoTDeviceService.js.map +1 -1
  254. package/build/dist/Server/Services/IoTFleetService.js +19 -32
  255. package/build/dist/Server/Services/IoTFleetService.js.map +1 -1
  256. package/build/dist/Server/Services/KubernetesClusterService.js +17 -30
  257. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  258. package/build/dist/Server/Services/KubernetesContainerService.js +29 -3
  259. package/build/dist/Server/Services/KubernetesContainerService.js.map +1 -1
  260. package/build/dist/Server/Services/KubernetesResourceService.js +32 -4
  261. package/build/dist/Server/Services/KubernetesResourceService.js.map +1 -1
  262. package/build/dist/Server/Services/LabelService.js +127 -0
  263. package/build/dist/Server/Services/LabelService.js.map +1 -1
  264. package/build/dist/Server/Services/MetricTypeService.js +74 -0
  265. package/build/dist/Server/Services/MetricTypeService.js.map +1 -1
  266. package/build/dist/Server/Services/MonitorService.js +128 -9
  267. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  268. package/build/dist/Server/Services/MonitorStatusTimelineService.js +28 -0
  269. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  270. package/build/dist/Server/Services/MonitorTemplateService.js +60 -0
  271. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  272. package/build/dist/Server/Services/PodmanHostService.js +19 -32
  273. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  274. package/build/dist/Server/Services/PodmanResourceService.js +34 -4
  275. package/build/dist/Server/Services/PodmanResourceService.js.map +1 -1
  276. package/build/dist/Server/Services/ProjectService.js +135 -21
  277. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  278. package/build/dist/Server/Services/ProxmoxClusterService.js +23 -36
  279. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  280. package/build/dist/Server/Services/ProxmoxResourceService.js +28 -3
  281. package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
  282. package/build/dist/Server/Services/RumApplicationService.js +19 -32
  283. package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
  284. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +20 -0
  285. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  286. package/build/dist/Server/Services/ServerlessFunctionService.js +24 -37
  287. package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
  288. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js +347 -0
  289. package/build/dist/Server/Services/ServiceLevelObjectiveMonitorRuleEngineService.js.map +1 -0
  290. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +33 -1
  291. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -1
  292. package/build/dist/Server/Services/ServiceService.js +236 -61
  293. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  294. package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js +603 -0
  295. package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js.map +1 -0
  296. package/build/dist/Server/Services/StatusPageMonitorRuleService.js +401 -0
  297. package/build/dist/Server/Services/StatusPageMonitorRuleService.js.map +1 -0
  298. package/build/dist/Server/Services/StatusPageService.js +69 -46
  299. package/build/dist/Server/Services/StatusPageService.js.map +1 -1
  300. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js +17 -1
  301. package/build/dist/Server/Services/StatusPageSubscriberNotificationTemplateService.js.map +1 -1
  302. package/build/dist/Server/Services/StatusPageSubscriberService.js +3 -0
  303. package/build/dist/Server/Services/StatusPageSubscriberService.js.map +1 -1
  304. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +1 -0
  305. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
  306. package/build/dist/Server/Services/TelemetryEntityService.js +1 -0
  307. package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
  308. package/build/dist/Server/Types/Database/JSONColumnQuery.js +402 -0
  309. package/build/dist/Server/Types/Database/JSONColumnQuery.js.map +1 -0
  310. package/build/dist/Server/Types/Database/Permissions/PublicPermission.js +9 -2
  311. package/build/dist/Server/Types/Database/Permissions/PublicPermission.js.map +1 -1
  312. package/build/dist/Server/Types/Database/QueryHelper.js +17 -27
  313. package/build/dist/Server/Types/Database/QueryHelper.js.map +1 -1
  314. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +105 -29
  315. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  316. package/build/dist/Server/Utils/Database/TruncateColumnValue.js +32 -0
  317. package/build/dist/Server/Utils/Database/TruncateColumnValue.js.map +1 -0
  318. package/build/dist/Server/Utils/Monitor/MonitorResource.js +56 -32
  319. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  320. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +30 -3
  321. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -1
  322. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +110 -98
  323. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -1
  324. package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js +312 -0
  325. package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js.map +1 -0
  326. package/build/dist/Server/Utils/SingleFlight.js +76 -0
  327. package/build/dist/Server/Utils/SingleFlight.js.map +1 -0
  328. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js +29 -0
  329. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js.map +1 -0
  330. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +78 -19
  331. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  332. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +160 -0
  333. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -0
  334. package/build/dist/Server/Utils/Telemetry/Telemetry.js +279 -104
  335. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  336. package/build/dist/Types/CustomField/CustomFieldDefinition.js +2 -0
  337. package/build/dist/Types/CustomField/CustomFieldDefinition.js.map +1 -0
  338. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  339. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  340. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  341. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  342. package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js +2 -0
  343. package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js.map +1 -0
  344. package/build/dist/Types/Dashboard/DashboardTemplates.js +368 -0
  345. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  346. package/build/dist/Types/Database/BigIntColumnTransformer.js +66 -0
  347. package/build/dist/Types/Database/BigIntColumnTransformer.js.map +1 -0
  348. package/build/dist/Types/Database/DatabaseProperty.js +25 -0
  349. package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
  350. package/build/dist/Types/Database/NumericColumnValue.js +97 -0
  351. package/build/dist/Types/Database/NumericColumnValue.js.map +1 -0
  352. package/build/dist/Types/Date.js +68 -0
  353. package/build/dist/Types/Date.js.map +1 -1
  354. package/build/dist/Types/Decimal.js +14 -3
  355. package/build/dist/Types/Decimal.js.map +1 -1
  356. package/build/dist/Types/Events/Recurring.js +63 -0
  357. package/build/dist/Types/Events/Recurring.js.map +1 -1
  358. package/build/dist/Types/Permission.js +42 -0
  359. package/build/dist/Types/Permission.js.map +1 -1
  360. package/build/dist/Types/Port.js +15 -5
  361. package/build/dist/Types/Port.js.map +1 -1
  362. package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js +22 -0
  363. package/build/dist/Types/StatusPage/StatusPageReportPeriodType.js.map +1 -0
  364. package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js +44 -0
  365. package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js.map +1 -0
  366. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +75 -0
  367. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -0
  368. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
  369. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +18 -2
  370. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -1
  371. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js +213 -0
  372. package/build/dist/UI/Utils/ModelAPI/ProjectUsersModelAPI.js.map +1 -0
  373. package/build/dist/UI/Utils/TeamMembersByUser.js +195 -0
  374. package/build/dist/UI/Utils/TeamMembersByUser.js.map +1 -0
  375. package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js +114 -0
  376. package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js.map +1 -0
  377. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  378. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  379. package/build/dist/Utils/StatusPage/ReportPeriod.js +131 -0
  380. package/build/dist/Utils/StatusPage/ReportPeriod.js.map +1 -0
  381. package/build/dist/Utils/Telemetry/HostIpAddresses.js +82 -0
  382. package/build/dist/Utils/Telemetry/HostIpAddresses.js.map +1 -0
  383. package/jest.config.json +2 -0
  384. package/package.json +1 -1
  385. package/tsconfig.json +12 -1
@@ -0,0 +1,448 @@
1
+ import "@testing-library/jest-dom";
2
+ import { render, screen, waitFor } from "@testing-library/react";
3
+ import React, { ReactElement } from "react";
4
+ import {
5
+ afterEach,
6
+ beforeEach,
7
+ describe,
8
+ expect,
9
+ jest,
10
+ test,
11
+ } from "@jest/globals";
12
+ import { MemoryRouter } from "react-router-dom";
13
+
14
+ /*
15
+ * The customer-facing bug this whole change exists for: Settings > Users
16
+ * listed TeamMember, a (user, team) join row, so one person on three teams
17
+ * filled three rows with the same name and avatar and read as three different
18
+ * people.
19
+ *
20
+ * The unit suites cover the grouping util and the API class. Neither of them
21
+ * touches the page, and the fix on the page is a single prop -
22
+ * modelAPI={ProjectUsersModelAPI} - whose loss brings every duplicate straight
23
+ * back with no test failing. That prop, the column that now has to render a
24
+ * list of teams rather than one, and the row's derived status are what this
25
+ * file pins.
26
+ */
27
+
28
+ jest.mock("../../../UI/Utils/Permission", () => {
29
+ return {
30
+ __esModule: true,
31
+ default: {
32
+ getAllPermissions: () => {
33
+ return [];
34
+ },
35
+ getProjectPermissions: () => {
36
+ return [];
37
+ },
38
+ getGlobalPermissions: () => {
39
+ return [];
40
+ },
41
+ },
42
+ };
43
+ });
44
+
45
+ jest.mock("../../../UI/Utils/User", () => {
46
+ return {
47
+ __esModule: true,
48
+ default: {
49
+ isMasterAdmin: () => {
50
+ return true;
51
+ },
52
+ getUserId: () => {
53
+ return null;
54
+ },
55
+ },
56
+ };
57
+ });
58
+
59
+ jest.mock("../../../UI/Utils/Translation", () => {
60
+ return {
61
+ __esModule: true,
62
+ default: () => {
63
+ return {
64
+ translateString: (value: string | undefined) => {
65
+ return value;
66
+ },
67
+ translateValue: (value: unknown) => {
68
+ return value;
69
+ },
70
+ };
71
+ },
72
+ };
73
+ });
74
+
75
+ /*
76
+ * The page is rendered through a stand-in ModelTable that records the props it
77
+ * was given. Rendering the real one would drag in the facet bar, the URL
78
+ * state and the pager, none of which this file is about - what matters is
79
+ * which API the page hands the table, and what its columns do with a grouped
80
+ * row.
81
+ */
82
+ type CapturedTableProps = {
83
+ modelAPI?: unknown;
84
+ columns: Array<{
85
+ title: string;
86
+ disableSort?: boolean | undefined;
87
+ getElement?: ((item: TeamMember) => ReactElement) | undefined;
88
+ getExportValue?: ((item: TeamMember) => string) | undefined;
89
+ }>;
90
+ deleteButtonText?: string | undefined;
91
+ singularName?: string | undefined;
92
+ pluralName?: string | undefined;
93
+ isDeleteable?: boolean | undefined;
94
+ };
95
+
96
+ let capturedTableProps: CapturedTableProps | null = null;
97
+
98
+ jest.mock("../../../UI/Components/ModelTable/ModelTable", () => {
99
+ return {
100
+ __esModule: true,
101
+ default: (props: CapturedTableProps) => {
102
+ capturedTableProps = props;
103
+ return null;
104
+ },
105
+ };
106
+ });
107
+
108
+ import Users from "../../../../App/FeatureSet/Dashboard/src/Pages/Users/Index";
109
+ import ProjectUsersModelAPI from "../../../UI/Utils/ModelAPI/ProjectUsersModelAPI";
110
+ import TeamMembersByUser, {
111
+ ProjectUserRow,
112
+ } from "../../../UI/Utils/TeamMembersByUser";
113
+ import ModelAPI from "../../../UI/Utils/ModelAPI/ModelAPI";
114
+ import ProjectUtil from "../../../UI/Utils/Project";
115
+ import Project from "../../../Models/DatabaseModels/Project";
116
+ import Team from "../../../Models/DatabaseModels/Team";
117
+ import TeamMember from "../../../Models/DatabaseModels/TeamMember";
118
+ import User from "../../../Models/DatabaseModels/User";
119
+ import Route from "../../../Types/API/Route";
120
+ import Name from "../../../Types/Name";
121
+ import ObjectID from "../../../Types/ObjectID";
122
+
123
+ const PROJECT_ID: ObjectID = new ObjectID(
124
+ "00000000-0000-4000-8000-000000000001",
125
+ );
126
+
127
+ const currentProject: Project = new Project();
128
+ currentProject._id = PROJECT_ID.toString();
129
+
130
+ type MembershipSpec = {
131
+ id: string;
132
+ userId: string;
133
+ userName?: string | undefined;
134
+ teamId?: string | undefined;
135
+ teamName?: string | undefined;
136
+ hasAcceptedInvitation?: boolean | undefined;
137
+ };
138
+
139
+ const buildMembership: (spec: MembershipSpec) => TeamMember = (
140
+ spec: MembershipSpec,
141
+ ): TeamMember => {
142
+ const teamMember: TeamMember = new TeamMember();
143
+
144
+ teamMember._id = spec.id;
145
+ teamMember.userId = new ObjectID(spec.userId);
146
+ teamMember.projectId = PROJECT_ID;
147
+ teamMember.hasAcceptedInvitation = spec.hasAcceptedInvitation ?? true;
148
+
149
+ const user: User = new User();
150
+ user._id = spec.userId;
151
+
152
+ if (spec.userName) {
153
+ user.name = new Name(spec.userName);
154
+ }
155
+
156
+ teamMember.user = user;
157
+
158
+ if (spec.teamId) {
159
+ teamMember.teamId = new ObjectID(spec.teamId);
160
+
161
+ const team: Team = new Team();
162
+ team._id = spec.teamId;
163
+ team.name = spec.teamName || spec.teamId;
164
+ teamMember.team = team;
165
+ }
166
+
167
+ return teamMember;
168
+ };
169
+
170
+ /*
171
+ * A row exactly as ProjectUsersModelAPI hands it to the table, built by the
172
+ * real grouping code rather than hand-written, so a change in the shape of a
173
+ * grouped row cannot leave these assertions passing against a shape the page
174
+ * never actually receives.
175
+ */
176
+ const buildGroupedRow: (
177
+ memberships: Array<MembershipSpec>,
178
+ ) => ProjectUserRow = (memberships: Array<MembershipSpec>): ProjectUserRow => {
179
+ return TeamMembersByUser.groupByUser(memberships.map(buildMembership))[0]!;
180
+ };
181
+
182
+ type ColumnOf = (title: string) => CapturedTableProps["columns"][0];
183
+
184
+ const columnTitled: ColumnOf = (
185
+ title: string,
186
+ ): CapturedTableProps["columns"][0] => {
187
+ const column: CapturedTableProps["columns"][0] | undefined =
188
+ capturedTableProps?.columns.find(
189
+ (candidate: CapturedTableProps["columns"][0]) => {
190
+ return candidate.title === title;
191
+ },
192
+ );
193
+
194
+ if (!column) {
195
+ throw new Error(
196
+ `No "${title}" column. Columns: ${(capturedTableProps?.columns || [])
197
+ .map((candidate: CapturedTableProps["columns"][0]) => {
198
+ return candidate.title;
199
+ })
200
+ .join(", ")}`,
201
+ );
202
+ }
203
+
204
+ return column;
205
+ };
206
+
207
+ type RenderCellFunction = (title: string, row: ProjectUserRow) => void;
208
+
209
+ const renderCell: RenderCellFunction = (
210
+ title: string,
211
+ row: ProjectUserRow,
212
+ ): void => {
213
+ render(<MemoryRouter>{columnTitled(title).getElement!(row)}</MemoryRouter>);
214
+ };
215
+
216
+ describe("Settings > Users page", () => {
217
+ beforeEach(async () => {
218
+ capturedTableProps = null;
219
+
220
+ jest.spyOn(ProjectUtil, "getCurrentProjectId").mockReturnValue(PROJECT_ID);
221
+ // The page counts SCIM configs on mount to decide whether to warn.
222
+ jest.spyOn(ModelAPI, "count").mockResolvedValue(0);
223
+ jest.spyOn(ModelAPI, "getCommonHeaders").mockReturnValue({});
224
+
225
+ render(
226
+ <MemoryRouter>
227
+ <Users
228
+ pageRoute={new Route("/dashboard/users")}
229
+ currentProject={currentProject}
230
+ hasPaymentMethod={true}
231
+ />
232
+ </MemoryRouter>,
233
+ );
234
+
235
+ await waitFor(() => {
236
+ expect(capturedTableProps).not.toBeNull();
237
+ });
238
+ });
239
+
240
+ afterEach(() => {
241
+ jest.restoreAllMocks();
242
+ });
243
+
244
+ describe("the fix itself", () => {
245
+ /*
246
+ * If this fails, every user on more than one team is back to occupying one
247
+ * row per team - which is the bug customers reported.
248
+ */
249
+ test("lists people, not memberships, by using the grouping API", () => {
250
+ expect(capturedTableProps!.modelAPI).toBe(ProjectUsersModelAPI);
251
+ });
252
+
253
+ test("names its rows after people", () => {
254
+ expect(capturedTableProps!.singularName).toBe("User");
255
+ expect(capturedTableProps!.pluralName).toBe("Users");
256
+ });
257
+ });
258
+
259
+ describe("the Teams column", () => {
260
+ test("shows every team the person belongs to, not just one", () => {
261
+ renderCell(
262
+ "Teams",
263
+ buildGroupedRow([
264
+ {
265
+ id: "m1",
266
+ userId: "u1",
267
+ userName: "Thomas Stock",
268
+ teamId: "t1",
269
+ teamName: "NTW_Online Operations",
270
+ },
271
+ {
272
+ id: "m2",
273
+ userId: "u1",
274
+ userName: "Thomas Stock",
275
+ teamId: "t2",
276
+ teamName: "Owners",
277
+ },
278
+ ]),
279
+ );
280
+
281
+ expect(screen.getByText("NTW_Online Operations")).toBeInTheDocument();
282
+ expect(screen.getByText("Owners")).toBeInTheDocument();
283
+ });
284
+
285
+ test("collapses a long team list behind a 'more' control rather than growing the row", () => {
286
+ renderCell(
287
+ "Teams",
288
+ buildGroupedRow([
289
+ { id: "m1", userId: "u1", teamId: "t1", teamName: "Alpha" },
290
+ { id: "m2", userId: "u1", teamId: "t2", teamName: "Bravo" },
291
+ { id: "m3", userId: "u1", teamId: "t3", teamName: "Charlie" },
292
+ { id: "m4", userId: "u1", teamId: "t4", teamName: "Delta" },
293
+ { id: "m5", userId: "u1", teamId: "t5", teamName: "Echo" },
294
+ ]),
295
+ );
296
+
297
+ expect(screen.getByText("Alpha")).toBeInTheDocument();
298
+ expect(screen.queryByText("Echo")).not.toBeInTheDocument();
299
+ expect(screen.getByText("2 more teams")).toBeInTheDocument();
300
+ });
301
+
302
+ test("says so when the person is on no team at all", () => {
303
+ renderCell(
304
+ "Teams",
305
+ buildGroupedRow([{ id: "m1", userId: "u1", userName: "Nobody" }]),
306
+ );
307
+
308
+ expect(screen.getByText("No team assigned")).toBeInTheDocument();
309
+ });
310
+
311
+ /*
312
+ * The exporter is column-driven and would otherwise fall back to the
313
+ * single `team` on the membership the row was built from, so the CSV would
314
+ * quietly disagree with the cell beside it.
315
+ */
316
+ test("exports every team, not the one the row was built from", () => {
317
+ const row: ProjectUserRow = buildGroupedRow([
318
+ { id: "m1", userId: "u1", teamId: "t1", teamName: "Engineering" },
319
+ { id: "m2", userId: "u1", teamId: "t2", teamName: "On-Call" },
320
+ { id: "m3", userId: "u1", teamId: "t3", teamName: "Admins" },
321
+ ]);
322
+
323
+ expect(columnTitled("Teams").getExportValue!(row)).toBe(
324
+ "Admins; Engineering; On-Call",
325
+ );
326
+ });
327
+
328
+ test("exports an empty cell rather than crashing on a team-less row", () => {
329
+ const row: ProjectUserRow = buildGroupedRow([
330
+ { id: "m1", userId: "u1", userName: "Nobody" },
331
+ ]);
332
+
333
+ expect(columnTitled("Teams").getExportValue!(row)).toBe("");
334
+ });
335
+ });
336
+
337
+ describe("the Status column", () => {
338
+ test("reads Member once any invitation has been accepted", () => {
339
+ renderCell(
340
+ "Status",
341
+ buildGroupedRow([
342
+ {
343
+ id: "m1",
344
+ userId: "u1",
345
+ teamId: "t1",
346
+ hasAcceptedInvitation: true,
347
+ },
348
+ ]),
349
+ );
350
+
351
+ expect(screen.getByText("Member")).toBeInTheDocument();
352
+ expect(screen.queryByText(/Pending/)).not.toBeInTheDocument();
353
+ });
354
+
355
+ test("reads Invitation Sent while nothing has been accepted", () => {
356
+ renderCell(
357
+ "Status",
358
+ buildGroupedRow([
359
+ {
360
+ id: "m1",
361
+ userId: "u1",
362
+ teamId: "t1",
363
+ hasAcceptedInvitation: false,
364
+ },
365
+ {
366
+ id: "m2",
367
+ userId: "u1",
368
+ teamId: "t2",
369
+ hasAcceptedInvitation: false,
370
+ },
371
+ ]),
372
+ );
373
+
374
+ expect(screen.getByText("Invitation Sent")).toBeInTheDocument();
375
+ expect(screen.queryByText("Member")).not.toBeInTheDocument();
376
+ });
377
+
378
+ /*
379
+ * Per-team invitation state used to be visible because each row WAS one
380
+ * team. On a grouped row it would disappear entirely without this.
381
+ */
382
+ test("still surfaces invitations the person has not accepted yet", () => {
383
+ renderCell(
384
+ "Status",
385
+ buildGroupedRow([
386
+ {
387
+ id: "m1",
388
+ userId: "u1",
389
+ teamId: "t1",
390
+ hasAcceptedInvitation: true,
391
+ },
392
+ {
393
+ id: "m2",
394
+ userId: "u1",
395
+ teamId: "t2",
396
+ hasAcceptedInvitation: false,
397
+ },
398
+ {
399
+ id: "m3",
400
+ userId: "u1",
401
+ teamId: "t3",
402
+ hasAcceptedInvitation: false,
403
+ },
404
+ ]),
405
+ );
406
+
407
+ expect(screen.getByText("Member")).toBeInTheDocument();
408
+ expect(screen.getByText("2 Invitations Pending")).toBeInTheDocument();
409
+ });
410
+
411
+ test("counts a single pending invitation in the singular", () => {
412
+ renderCell(
413
+ "Status",
414
+ buildGroupedRow([
415
+ {
416
+ id: "m1",
417
+ userId: "u1",
418
+ teamId: "t1",
419
+ hasAcceptedInvitation: true,
420
+ },
421
+ {
422
+ id: "m2",
423
+ userId: "u1",
424
+ teamId: "t2",
425
+ hasAcceptedInvitation: false,
426
+ },
427
+ ]),
428
+ );
429
+
430
+ expect(screen.getByText("1 Invitation Pending")).toBeInTheDocument();
431
+ });
432
+
433
+ /*
434
+ * The server can only order by the stored per-membership column, which on
435
+ * a grouped row disagrees with the derived one on screen - so the control
436
+ * has to be off rather than visibly not sorting.
437
+ */
438
+ test("offers no sort control, because the value is derived", () => {
439
+ expect(columnTitled("Status").disableSort).toBe(true);
440
+ });
441
+ });
442
+
443
+ describe("removing someone", () => {
444
+ test("labels the action as removal from the project, not from a team", () => {
445
+ expect(capturedTableProps!.deleteButtonText).toBe("Remove from Project");
446
+ });
447
+ });
448
+ });
@@ -207,6 +207,7 @@ describe("WidgetCatalog", () => {
207
207
  "Podman",
208
208
  "Proxmox",
209
209
  "Ceph",
210
+ "Network",
210
211
  ]) {
211
212
  expect(getCategory(name).group).toBe(
212
213
  WidgetCategoryGroup.Infrastructure,
@@ -277,6 +278,7 @@ describe("WidgetCatalog", () => {
277
278
  "Podman",
278
279
  "Proxmox",
279
280
  "Ceph",
281
+ "Network",
280
282
  ]);
281
283
  });
282
284