@oneuptime/common 12.0.2 → 12.0.4

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 (384) hide show
  1. package/Models/DatabaseModels/CephCluster.ts +14 -0
  2. package/Models/DatabaseModels/CodeRepository.ts +14 -6
  3. package/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.ts +14 -0
  4. package/Models/DatabaseModels/DockerHost.ts +14 -0
  5. package/Models/DatabaseModels/GlobalOidcProject.ts +18 -0
  6. package/Models/DatabaseModels/GlobalSsoProject.ts +18 -0
  7. package/Models/DatabaseModels/Index.ts +2 -0
  8. package/Models/DatabaseModels/IoTFleet.ts +14 -0
  9. package/Models/DatabaseModels/KubernetesCluster.ts +14 -0
  10. package/Models/DatabaseModels/LogDropFilter.ts +9 -20
  11. package/Models/DatabaseModels/NetworkDevice.ts +14 -0
  12. package/Models/DatabaseModels/NetworkInterface.ts +18 -0
  13. package/Models/DatabaseModels/Project.ts +16 -2
  14. package/Models/DatabaseModels/ProxmoxCluster.ts +14 -0
  15. package/Models/DatabaseModels/Service.ts +30 -0
  16. package/Models/DatabaseModels/StatusPageMonitorRule.ts +911 -0
  17. package/Models/DatabaseModels/StatusPagePrivateUser.ts +30 -0
  18. package/Models/DatabaseModels/StatusPageResource.ts +73 -0
  19. package/Models/DatabaseModels/TraceDropFilter.ts +9 -20
  20. package/Models/DatabaseModels/User.ts +30 -0
  21. package/Server/API/AIAgentDataAPI.ts +31 -0
  22. package/Server/API/BaseAPI.ts +13 -2
  23. package/Server/API/DashboardAPI.ts +458 -12
  24. package/Server/API/GitHubAPI.ts +119 -283
  25. package/Server/API/UserAPI.ts +263 -1
  26. package/Server/EnvironmentConfig.ts +38 -4
  27. package/Server/Infrastructure/GlobalCache.ts +152 -0
  28. package/Server/Infrastructure/Postgres/DataSourceOptions.ts +16 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.ts +123 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.ts +21 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.ts +68 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +100 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +214 -0
  34. package/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.ts +69 -0
  35. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +12 -0
  36. package/Server/Services/AlertStateTimelineService.ts +20 -0
  37. package/Server/Services/AnalyticsDatabaseService.ts +72 -1
  38. package/Server/Services/CephClusterService.ts +26 -86
  39. package/Server/Services/CloudResourceService.ts +23 -83
  40. package/Server/Services/CodeRepositoryService.ts +105 -2
  41. package/Server/Services/DatabaseService.ts +296 -2
  42. package/Server/Services/DockerHostService.ts +19 -79
  43. package/Server/Services/DockerSwarmClusterService.ts +27 -88
  44. package/Server/Services/HostService.ts +46 -99
  45. package/Server/Services/IncidentStateTimelineService.ts +20 -0
  46. package/Server/Services/Index.ts +2 -0
  47. package/Server/Services/IoTFleetService.ts +19 -79
  48. package/Server/Services/KubernetesClusterService.ts +17 -78
  49. package/Server/Services/LabelService.ts +57 -10
  50. package/Server/Services/MetricTypeService.ts +84 -0
  51. package/Server/Services/MonitorService.ts +89 -14
  52. package/Server/Services/MonitorStatusTimelineService.ts +29 -0
  53. package/Server/Services/MonitorTemplateService.ts +65 -0
  54. package/Server/Services/OpenTelemetryIngestService.ts +230 -26
  55. package/Server/Services/PodmanHostService.ts +19 -79
  56. package/Server/Services/ProxmoxClusterService.ts +23 -83
  57. package/Server/Services/RumApplicationService.ts +19 -80
  58. package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +21 -0
  59. package/Server/Services/ServerlessFunctionService.ts +24 -85
  60. package/Server/Services/ServiceService.ts +299 -73
  61. package/Server/Services/StatusPageMonitorRuleEngineService.ts +752 -0
  62. package/Server/Services/StatusPageMonitorRuleService.ts +471 -0
  63. package/Server/Services/TelemetryEntityRelationshipService.ts +1 -0
  64. package/Server/Services/TelemetryEntityService.ts +1 -0
  65. package/Server/Services/UserService.ts +184 -0
  66. package/Server/Utils/AI/Toolbox/CodeTools.ts +45 -4
  67. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +13 -0
  68. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +157 -4
  69. package/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.ts +130 -0
  70. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +170 -39
  71. package/Server/Utils/Monitor/MonitorResource.ts +63 -36
  72. package/Server/Utils/Monitor/MonitorStatusTimeline.ts +36 -0
  73. package/Server/Utils/Monitor/MonitorStepsProjectValidator.ts +148 -127
  74. package/Server/Utils/Monitor/MonitorStepsReferenceExtractor.ts +434 -0
  75. package/Server/Utils/PasswordHash.ts +306 -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/OverviewCustomFields.test.tsx +333 -0
  82. package/Tests/App/Dashboard/UserCustomFields.test.tsx +392 -0
  83. package/Tests/App/Dashboard/WidgetCatalog.test.ts +2 -0
  84. package/Tests/Models/DatabaseModels/ColumnTransformerInvariants.test.ts +306 -0
  85. package/Tests/Models/DatabaseModels/NumberColumnDeserialization.test.ts +333 -0
  86. package/Tests/Models/DatabaseModels/StatusPageMonitorRuleModel.test.ts +190 -0
  87. package/Tests/Server/API/AIAgentDataRepositoryToken.test.ts +381 -0
  88. package/Tests/Server/API/DashboardPublicAttributeValuesAPI.test.ts +943 -0
  89. package/Tests/Server/API/DashboardPublicMetricsAggregateAPI.test.ts +1296 -0
  90. package/Tests/Server/API/DashboardPublicResourceListAPI.test.ts +26 -0
  91. package/Tests/Server/API/DashboardPublicTemplatePayloads.test.ts +598 -0
  92. package/Tests/Server/API/GitHubAppInstallationBindingAPI.test.ts +539 -0
  93. package/Tests/Server/API/Helpers.ts +6 -1
  94. package/Tests/Server/API/UserProjectsAPI.test.ts +852 -0
  95. package/Tests/Server/Infrastructure/GlobalCache.test.ts +354 -0
  96. package/Tests/Server/Infrastructure/PostgresLockTimeoutOptions.test.ts +181 -0
  97. package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +215 -0
  98. package/Tests/Server/Services/AddPerUserPasswordSaltMigration.test.ts +178 -0
  99. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +582 -0
  100. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +5 -0
  101. package/Tests/Server/Services/CodeRepositoryInstallationBinding.test.ts +305 -0
  102. package/Tests/Server/Services/CodeRepositoryResolutionBinding.test.ts +147 -0
  103. package/Tests/Server/Services/DatabaseServicePerUserPasswordSalt.test.ts +870 -0
  104. package/Tests/Server/Services/DatabaseServiceUpdateColumnsIfUnlocked.test.ts +342 -0
  105. package/Tests/Server/Services/DropFilterSaveValidation.test.ts +245 -0
  106. package/Tests/Server/Services/HostServiceUpdateLastSeen.test.ts +163 -15
  107. package/Tests/Server/Services/MetricTypeAttachServices.test.ts +222 -0
  108. package/Tests/Server/Services/MissingReferenceWriteGuard.test.ts +614 -0
  109. package/Tests/Server/Services/MonitorStatusTimelineFastPath.test.ts +23 -0
  110. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +568 -0
  111. package/Tests/Server/Services/ResourceUpdateLastSeenLivenessFallback.test.ts +305 -56
  112. package/Tests/Server/Services/RestoreDroppedUniqueIndexesMigration.test.ts +386 -0
  113. package/Tests/Server/Services/RestoreServiceLowerNameIndexMigration.test.ts +240 -0
  114. package/Tests/Server/Services/ServiceUpdateLastSeenSplitGates.test.ts +705 -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/UserServiceFirstMasterAdminElection.test.ts +885 -0
  119. package/Tests/Server/Services/WidenHashedStringColumnsForScryptMigration.test.ts +220 -0
  120. package/Tests/Server/Utils/AI/CodeTools.test.ts +47 -1
  121. package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +10 -0
  122. package/Tests/Server/Utils/APIKey/AccessPermission.test.ts +267 -0
  123. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +120 -0
  124. package/Tests/Server/Utils/CodeRepository/GitHubInstallationBinding.test.ts +292 -0
  125. package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +260 -13
  126. package/Tests/Server/Utils/EntityRegistryRowFence.test.ts +302 -0
  127. package/Tests/Server/Utils/GitHubInstallationOwnershipVerification.test.ts +340 -0
  128. package/Tests/Server/Utils/GitHubWebhookAndTreeCacheIsolation.test.ts +250 -0
  129. package/Tests/Server/Utils/MetricTypeIndexConvergence.test.ts +598 -0
  130. package/Tests/Server/Utils/Monitor/MonitorStatusTimelineUnusableStatus.test.ts +154 -0
  131. package/Tests/Server/Utils/Monitor/MonitorStepsProjectValidator.test.ts +638 -92
  132. package/Tests/Server/Utils/Monitor/MonitorStepsReferenceExtractor.test.ts +724 -0
  133. package/Tests/Server/Utils/PasswordHash.test.ts +555 -0
  134. package/Tests/Server/Utils/SingleFlight.test.ts +221 -0
  135. package/Tests/Types/Dashboard/NetworkDashboardTemplate.test.ts +793 -0
  136. package/Tests/Types/Database/BigIntColumnTransformer.test.ts +147 -0
  137. package/Tests/Types/Database/ColumnLength.test.ts +7 -1
  138. package/Tests/Types/Database/DatabasePropertyTransformer.test.ts +140 -0
  139. package/Tests/Types/Database/NumericColumnValue.test.ts +127 -0
  140. package/Tests/Types/Decimal.test.ts +37 -0
  141. package/Tests/Types/HashedStringPerUserSalt.test.ts +476 -0
  142. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +293 -0
  143. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +249 -0
  144. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +320 -0
  145. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +271 -0
  146. package/Tests/Types/Monitor/SnmpVersionParsing.test.ts +152 -0
  147. package/Tests/Types/Port.test.ts +38 -0
  148. package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +696 -0
  149. package/Tests/UI/Components/LogsHistogram.test.tsx +276 -0
  150. package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +489 -0
  151. package/Tests/UI/Components/UseLogsHistogram.test.tsx +500 -0
  152. package/Tests/UI/Utils/UserProjectsModelAPI.test.ts +714 -0
  153. package/Tests/Utils/Dashboard/Components/DashboardComponentsUtil.test.ts +120 -0
  154. package/Tests/Utils/Dashboard/DashboardNetworkMapComponent.test.ts +327 -0
  155. package/Tests/Utils/TeamMembersByProject.test.ts +655 -0
  156. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  157. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  158. package/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.ts +40 -0
  159. package/Types/Dashboard/DashboardTemplates.ts +397 -0
  160. package/Types/Database/BigIntColumnTransformer.ts +74 -0
  161. package/Types/Database/ColumnLength.ts +9 -1
  162. package/Types/Database/DatabaseProperty.ts +26 -0
  163. package/Types/Database/NumericColumnValue.ts +128 -0
  164. package/Types/Database/TableColumn.ts +11 -0
  165. package/Types/Database/UnsynchronizedIndex.ts +48 -0
  166. package/Types/Decimal.ts +16 -4
  167. package/Types/HashedString.ts +139 -4
  168. package/Types/Permission.ts +48 -0
  169. package/Types/Port.ts +16 -4
  170. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +85 -11
  171. package/UI/Components/LogsViewer/useLiveLogsRefresh.ts +86 -0
  172. package/UI/Components/LogsViewer/useLogsHistogram.ts +113 -0
  173. package/UI/Components/Navbar/NavBar.tsx +12 -2
  174. package/UI/Components/Navbar/NavBarMenuModal.tsx +19 -7
  175. package/UI/Utils/ModelAPI/UserProjectsModelAPI.ts +257 -0
  176. package/Utils/Dashboard/Components/DashboardNetworkMapComponent.ts +136 -0
  177. package/Utils/Dashboard/Components/Index.ts +7 -0
  178. package/Utils/TeamMembersByProject.ts +237 -0
  179. package/build/dist/Models/DatabaseModels/CephCluster.js +16 -1
  180. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  181. package/build/dist/Models/DatabaseModels/CodeRepository.js +14 -6
  182. package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
  183. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js +12 -0
  184. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel.js.map +1 -1
  185. package/build/dist/Models/DatabaseModels/DockerHost.js +16 -1
  186. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  187. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +16 -1
  188. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
  189. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +16 -1
  190. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
  191. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  192. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  193. package/build/dist/Models/DatabaseModels/IoTFleet.js +16 -1
  194. package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
  195. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +16 -1
  196. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  197. package/build/dist/Models/DatabaseModels/LogDropFilter.js +9 -20
  198. package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
  199. package/build/dist/Models/DatabaseModels/NetworkDevice.js +16 -1
  200. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  201. package/build/dist/Models/DatabaseModels/NetworkInterface.js +16 -1
  202. package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
  203. package/build/dist/Models/DatabaseModels/Project.js +16 -2
  204. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  205. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +16 -1
  206. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  207. package/build/dist/Models/DatabaseModels/Service.js +28 -1
  208. package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
  209. package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js +925 -0
  210. package/build/dist/Models/DatabaseModels/StatusPageMonitorRule.js.map +1 -0
  211. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js +32 -0
  212. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js.map +1 -1
  213. package/build/dist/Models/DatabaseModels/StatusPageResource.js +72 -0
  214. package/build/dist/Models/DatabaseModels/StatusPageResource.js.map +1 -1
  215. package/build/dist/Models/DatabaseModels/TraceDropFilter.js +9 -20
  216. package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
  217. package/build/dist/Models/DatabaseModels/User.js +32 -0
  218. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  219. package/build/dist/Server/API/AIAgentDataAPI.js +21 -2
  220. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  221. package/build/dist/Server/API/BaseAPI.js +11 -1
  222. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  223. package/build/dist/Server/API/DashboardAPI.js +343 -10
  224. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  225. package/build/dist/Server/API/GitHubAPI.js +94 -167
  226. package/build/dist/Server/API/GitHubAPI.js.map +1 -1
  227. package/build/dist/Server/API/UserAPI.js +187 -2
  228. package/build/dist/Server/API/UserAPI.js.map +1 -1
  229. package/build/dist/Server/EnvironmentConfig.js +34 -4
  230. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  231. package/build/dist/Server/Infrastructure/GlobalCache.js +120 -0
  232. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  233. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js +5 -3
  234. package/build/dist/Server/Infrastructure/Postgres/DataSourceOptions.js.map +1 -1
  235. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js +48 -0
  236. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786005052769-AddStatusPageMonitorRule.js.map +1 -0
  237. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js +14 -0
  238. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js.map +1 -0
  239. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js +59 -0
  240. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js.map +1 -0
  241. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +93 -0
  242. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js.map +1 -0
  243. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js +101 -0
  244. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js.map +1 -0
  245. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js +66 -0
  246. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js.map +1 -0
  247. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +12 -0
  248. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  249. package/build/dist/Server/Services/AlertStateTimelineService.js +19 -0
  250. package/build/dist/Server/Services/AlertStateTimelineService.js.map +1 -1
  251. package/build/dist/Server/Services/AnalyticsDatabaseService.js +57 -1
  252. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  253. package/build/dist/Server/Services/CephClusterService.js +26 -76
  254. package/build/dist/Server/Services/CephClusterService.js.map +1 -1
  255. package/build/dist/Server/Services/CloudResourceService.js +23 -73
  256. package/build/dist/Server/Services/CloudResourceService.js.map +1 -1
  257. package/build/dist/Server/Services/CodeRepositoryService.js +90 -2
  258. package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
  259. package/build/dist/Server/Services/DatabaseService.js +246 -2
  260. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  261. package/build/dist/Server/Services/DockerHostService.js +19 -69
  262. package/build/dist/Server/Services/DockerHostService.js.map +1 -1
  263. package/build/dist/Server/Services/DockerSwarmClusterService.js +27 -78
  264. package/build/dist/Server/Services/DockerSwarmClusterService.js.map +1 -1
  265. package/build/dist/Server/Services/HostService.js +58 -102
  266. package/build/dist/Server/Services/HostService.js.map +1 -1
  267. package/build/dist/Server/Services/IncidentStateTimelineService.js +19 -0
  268. package/build/dist/Server/Services/IncidentStateTimelineService.js.map +1 -1
  269. package/build/dist/Server/Services/Index.js +2 -0
  270. package/build/dist/Server/Services/Index.js.map +1 -1
  271. package/build/dist/Server/Services/IoTFleetService.js +19 -69
  272. package/build/dist/Server/Services/IoTFleetService.js.map +1 -1
  273. package/build/dist/Server/Services/KubernetesClusterService.js +17 -68
  274. package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
  275. package/build/dist/Server/Services/LabelService.js +42 -7
  276. package/build/dist/Server/Services/LabelService.js.map +1 -1
  277. package/build/dist/Server/Services/MetricTypeService.js +74 -0
  278. package/build/dist/Server/Services/MetricTypeService.js.map +1 -1
  279. package/build/dist/Server/Services/MonitorService.js +81 -9
  280. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  281. package/build/dist/Server/Services/MonitorStatusTimelineService.js +28 -0
  282. package/build/dist/Server/Services/MonitorStatusTimelineService.js.map +1 -1
  283. package/build/dist/Server/Services/MonitorTemplateService.js +60 -0
  284. package/build/dist/Server/Services/MonitorTemplateService.js.map +1 -1
  285. package/build/dist/Server/Services/OpenTelemetryIngestService.js +155 -25
  286. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  287. package/build/dist/Server/Services/PodmanHostService.js +19 -69
  288. package/build/dist/Server/Services/PodmanHostService.js.map +1 -1
  289. package/build/dist/Server/Services/ProxmoxClusterService.js +23 -73
  290. package/build/dist/Server/Services/ProxmoxClusterService.js.map +1 -1
  291. package/build/dist/Server/Services/RumApplicationService.js +19 -70
  292. package/build/dist/Server/Services/RumApplicationService.js.map +1 -1
  293. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +20 -0
  294. package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
  295. package/build/dist/Server/Services/ServerlessFunctionService.js +24 -75
  296. package/build/dist/Server/Services/ServerlessFunctionService.js.map +1 -1
  297. package/build/dist/Server/Services/ServiceService.js +236 -61
  298. package/build/dist/Server/Services/ServiceService.js.map +1 -1
  299. package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js +603 -0
  300. package/build/dist/Server/Services/StatusPageMonitorRuleEngineService.js.map +1 -0
  301. package/build/dist/Server/Services/StatusPageMonitorRuleService.js +401 -0
  302. package/build/dist/Server/Services/StatusPageMonitorRuleService.js.map +1 -0
  303. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +1 -0
  304. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
  305. package/build/dist/Server/Services/TelemetryEntityService.js +1 -0
  306. package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
  307. package/build/dist/Server/Services/UserService.js +165 -0
  308. package/build/dist/Server/Services/UserService.js.map +1 -1
  309. package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js +31 -1
  310. package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js.map +1 -1
  311. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +13 -0
  312. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  313. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +126 -4
  314. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  315. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js +136 -0
  316. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js.map +1 -0
  317. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +105 -29
  318. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -1
  319. package/build/dist/Server/Utils/Monitor/MonitorResource.js +56 -32
  320. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  321. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js +30 -3
  322. package/build/dist/Server/Utils/Monitor/MonitorStatusTimeline.js.map +1 -1
  323. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js +110 -98
  324. package/build/dist/Server/Utils/Monitor/MonitorStepsProjectValidator.js.map +1 -1
  325. package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js +312 -0
  326. package/build/dist/Server/Utils/Monitor/MonitorStepsReferenceExtractor.js.map +1 -0
  327. package/build/dist/Server/Utils/PasswordHash.js +237 -0
  328. package/build/dist/Server/Utils/PasswordHash.js.map +1 -0
  329. package/build/dist/Server/Utils/SingleFlight.js +76 -0
  330. package/build/dist/Server/Utils/SingleFlight.js.map +1 -0
  331. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js +29 -0
  332. package/build/dist/Server/Utils/StatusPage/MonitorRulePatternValidator.js.map +1 -0
  333. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js +78 -19
  334. package/build/dist/Server/Utils/Telemetry/EntityRegistry.js.map +1 -1
  335. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js +160 -0
  336. package/build/dist/Server/Utils/Telemetry/ResourceHeartbeat.js.map +1 -0
  337. package/build/dist/Server/Utils/Telemetry/Telemetry.js +279 -104
  338. package/build/dist/Server/Utils/Telemetry/Telemetry.js.map +1 -1
  339. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  340. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  341. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  342. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  343. package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js +2 -0
  344. package/build/dist/Types/Dashboard/DashboardComponents/DashboardNetworkMapComponent.js.map +1 -0
  345. package/build/dist/Types/Dashboard/DashboardTemplates.js +368 -0
  346. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  347. package/build/dist/Types/Database/BigIntColumnTransformer.js +66 -0
  348. package/build/dist/Types/Database/BigIntColumnTransformer.js.map +1 -0
  349. package/build/dist/Types/Database/ColumnLength.js +9 -1
  350. package/build/dist/Types/Database/ColumnLength.js.map +1 -1
  351. package/build/dist/Types/Database/DatabaseProperty.js +25 -0
  352. package/build/dist/Types/Database/DatabaseProperty.js.map +1 -1
  353. package/build/dist/Types/Database/NumericColumnValue.js +97 -0
  354. package/build/dist/Types/Database/NumericColumnValue.js.map +1 -0
  355. package/build/dist/Types/Database/TableColumn.js.map +1 -1
  356. package/build/dist/Types/Database/UnsynchronizedIndex.js +46 -0
  357. package/build/dist/Types/Database/UnsynchronizedIndex.js.map +1 -0
  358. package/build/dist/Types/Decimal.js +14 -3
  359. package/build/dist/Types/Decimal.js.map +1 -1
  360. package/build/dist/Types/HashedString.js +95 -5
  361. package/build/dist/Types/HashedString.js.map +1 -1
  362. package/build/dist/Types/Permission.js +42 -0
  363. package/build/dist/Types/Permission.js.map +1 -1
  364. package/build/dist/Types/Port.js +15 -5
  365. package/build/dist/Types/Port.js.map +1 -1
  366. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +51 -10
  367. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  368. package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js +44 -0
  369. package/build/dist/UI/Components/LogsViewer/useLiveLogsRefresh.js.map +1 -0
  370. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js +75 -0
  371. package/build/dist/UI/Components/LogsViewer/useLogsHistogram.js.map +1 -0
  372. package/build/dist/UI/Components/Navbar/NavBar.js +3 -1
  373. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  374. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +19 -7
  375. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  376. package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js +156 -0
  377. package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js.map +1 -0
  378. package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js +114 -0
  379. package/build/dist/Utils/Dashboard/Components/DashboardNetworkMapComponent.js.map +1 -0
  380. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  381. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  382. package/build/dist/Utils/TeamMembersByProject.js +145 -0
  383. package/build/dist/Utils/TeamMembersByProject.js.map +1 -0
  384. package/package.json +1 -1
@@ -0,0 +1,392 @@
1
+ import { afterEach, describe, expect, jest, test } from "@jest/globals";
2
+ import "@testing-library/jest-dom";
3
+ import { cleanup, render, screen, waitFor } from "@testing-library/react";
4
+ import * as React from "react";
5
+ import getJestMockFunction, { MockFunction } from "../../MockType";
6
+
7
+ /*
8
+ * Users are the one resource whose custom field answers are not on the record
9
+ * being viewed: User is global, so the per-project values live on the
10
+ * ProjectUserProfile row for (project, user). Nothing can be rendered until
11
+ * that row has been found, which is why the user pages go through this
12
+ * wrapper instead of mounting CustomFieldsDetail directly.
13
+ *
14
+ * The same component backs two very different call sites - the dedicated
15
+ * Custom Fields page, which owes the reader an explanation when there is
16
+ * nothing to show, and the user overview, where it must simply not appear.
17
+ * Both halves are pinned here.
18
+ */
19
+
20
+ const getListMock: MockFunction = getJestMockFunction();
21
+ const getItemMock: MockFunction = getJestMockFunction();
22
+ const getCurrentProjectIdMock: MockFunction = getJestMockFunction();
23
+
24
+ /*
25
+ * The arrow wrappers are load bearing: jest.mock is hoisted above the compiled
26
+ * requires, so naming the mocks directly would capture them before their
27
+ * initializers have run.
28
+ */
29
+ jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
30
+ return {
31
+ __esModule: true,
32
+ default: {
33
+ getList: (...args: Array<any>) => {
34
+ return getListMock(...args);
35
+ },
36
+ getItem: (...args: Array<any>) => {
37
+ return getItemMock(...args);
38
+ },
39
+ updateById: () => {
40
+ return Promise.resolve();
41
+ },
42
+ },
43
+ };
44
+ });
45
+
46
+ jest.mock("../../../UI/Utils/Project", () => {
47
+ return {
48
+ __esModule: true,
49
+ default: {
50
+ getCurrentProjectId: (...args: Array<any>) => {
51
+ return getCurrentProjectIdMock(...args);
52
+ },
53
+ },
54
+ };
55
+ });
56
+
57
+ import UserCustomFields from "../../../../App/FeatureSet/Dashboard/src/Components/CustomFields/UserCustomFields";
58
+ import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
59
+ import ProjectUserProfile from "../../../Models/DatabaseModels/ProjectUserProfile";
60
+ import TeamMemberCustomField from "../../../Models/DatabaseModels/TeamMemberCustomField";
61
+ import CustomFieldType from "../../../Types/CustomField/CustomFieldType";
62
+ import { JSONObject } from "../../../Types/JSON";
63
+ import ObjectID from "../../../Types/ObjectID";
64
+
65
+ const PROJECT_ID: ObjectID = new ObjectID(
66
+ "11111111-1111-4111-8111-111111111111",
67
+ );
68
+ const USER_ID: ObjectID = new ObjectID("22222222-2222-4222-8222-222222222222");
69
+ const PROFILE_ID: ObjectID = new ObjectID(
70
+ "33333333-3333-4333-8333-333333333333",
71
+ );
72
+
73
+ type ListResultShape = {
74
+ data: Array<BaseModel>;
75
+ count: number;
76
+ skip: number;
77
+ limit: number;
78
+ };
79
+
80
+ type ToListResultFunction = (data: Array<BaseModel>) => ListResultShape;
81
+
82
+ const toListResult: ToListResultFunction = (
83
+ data: Array<BaseModel>,
84
+ ): ListResultShape => {
85
+ return { data: data, count: data.length, skip: 0, limit: data.length };
86
+ };
87
+
88
+ type BuildSchemaFunction = (
89
+ names: Array<string>,
90
+ ) => Array<TeamMemberCustomField>;
91
+
92
+ const buildSchema: BuildSchemaFunction = (
93
+ names: Array<string>,
94
+ ): Array<TeamMemberCustomField> => {
95
+ return names.map((name: string) => {
96
+ const schemaItem: TeamMemberCustomField = new TeamMemberCustomField();
97
+ schemaItem.name = name;
98
+ schemaItem.customFieldType = CustomFieldType.Text;
99
+ return schemaItem;
100
+ });
101
+ };
102
+
103
+ type BuildProfileFunction = () => ProjectUserProfile;
104
+
105
+ const buildProfile: BuildProfileFunction = (): ProjectUserProfile => {
106
+ const profile: ProjectUserProfile = new ProjectUserProfile();
107
+ profile.id = PROFILE_ID;
108
+ return profile;
109
+ };
110
+
111
+ /*
112
+ * getList is called for two different models: first the schema, then (only if
113
+ * the project has any) the profile row. Dispatch on modelType rather than call
114
+ * order so a test that expects the second call to be SKIPPED still reads
115
+ * naturally.
116
+ */
117
+ interface ListPlan {
118
+ schema: Array<BaseModel>;
119
+ profiles: Array<BaseModel>;
120
+ }
121
+
122
+ type PlanListsFunction = (plan: ListPlan) => void;
123
+
124
+ const planLists: PlanListsFunction = (plan: ListPlan): void => {
125
+ getListMock.mockImplementation((args: any) => {
126
+ if (args.modelType === TeamMemberCustomField) {
127
+ return Promise.resolve(toListResult(plan.schema));
128
+ }
129
+
130
+ return Promise.resolve(toListResult(plan.profiles));
131
+ });
132
+ };
133
+
134
+ type ResolveProfileItemFunction = (customFields: JSONObject) => void;
135
+
136
+ const resolveProfileItemWith: ResolveProfileItemFunction = (
137
+ customFields: JSONObject,
138
+ ): void => {
139
+ const profile: ProjectUserProfile = buildProfile();
140
+ profile.customFields = customFields;
141
+ getItemMock.mockResolvedValue(profile as never);
142
+ };
143
+
144
+ afterEach(() => {
145
+ cleanup();
146
+ getListMock.mockReset();
147
+ getItemMock.mockReset();
148
+ getCurrentProjectIdMock.mockReset();
149
+ });
150
+
151
+ describe("UserCustomFields - the user overview (hideIfEmpty)", () => {
152
+ test("shows the member's values once a profile row exists", async () => {
153
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
154
+ planLists({
155
+ schema: buildSchema(["Employee ID", "Desk"]),
156
+ profiles: [buildProfile()],
157
+ });
158
+ resolveProfileItemWith({ "Employee ID": "E-4711", Desk: "3rd floor" });
159
+
160
+ render(<UserCustomFields userId={USER_ID} hideIfEmpty={true} />);
161
+
162
+ expect(await screen.findByText("E-4711")).toBeInTheDocument();
163
+ expect(screen.getByText("3rd floor")).toBeInTheDocument();
164
+ expect(screen.getByText("Employee ID")).toBeInTheDocument();
165
+ });
166
+
167
+ test("renders nothing when the project defined no member fields", async () => {
168
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
169
+ planLists({ schema: [], profiles: [buildProfile()] });
170
+
171
+ const { container } = render(
172
+ <UserCustomFields userId={USER_ID} hideIfEmpty={true} />,
173
+ );
174
+
175
+ await waitFor(() => {
176
+ expect(getListMock).toHaveBeenCalled();
177
+ });
178
+
179
+ expect(container).toBeEmptyDOMElement();
180
+ });
181
+
182
+ /*
183
+ * The profile row is created lazily, the first time someone saves their own
184
+ * custom fields. Until then there is genuinely nothing to point the card at.
185
+ */
186
+ test("renders nothing when the member has no profile row yet", async () => {
187
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
188
+ planLists({ schema: buildSchema(["Employee ID"]), profiles: [] });
189
+
190
+ const { container } = render(
191
+ <UserCustomFields userId={USER_ID} hideIfEmpty={true} />,
192
+ );
193
+
194
+ await waitFor(() => {
195
+ expect(getListMock.mock.calls.length).toBeGreaterThan(1);
196
+ });
197
+
198
+ expect(container).toBeEmptyDOMElement();
199
+ });
200
+
201
+ test("renders nothing when the lookup fails", async () => {
202
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
203
+ getListMock.mockRejectedValue(new Error("Upgrade your plan"));
204
+
205
+ const { container } = render(
206
+ <UserCustomFields userId={USER_ID} hideIfEmpty={true} />,
207
+ );
208
+
209
+ await waitFor(() => {
210
+ expect(getListMock).toHaveBeenCalled();
211
+ });
212
+
213
+ expect(screen.queryByText(/Upgrade your plan/i)).not.toBeInTheDocument();
214
+ expect(container).toBeEmptyDOMElement();
215
+ });
216
+
217
+ test("renders nothing, and asks for nothing, without a current project", async () => {
218
+ getCurrentProjectIdMock.mockReturnValue(null);
219
+
220
+ const { container } = render(
221
+ <UserCustomFields userId={USER_ID} hideIfEmpty={true} />,
222
+ );
223
+
224
+ await waitFor(() => {
225
+ expect(container).toBeEmptyDOMElement();
226
+ });
227
+
228
+ expect(getListMock).not.toHaveBeenCalled();
229
+ });
230
+
231
+ test("does not look for a profile row when there are no fields to fill", async () => {
232
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
233
+ planLists({ schema: [], profiles: [buildProfile()] });
234
+
235
+ render(<UserCustomFields userId={USER_ID} hideIfEmpty={true} />);
236
+
237
+ await waitFor(() => {
238
+ expect(getListMock).toHaveBeenCalledTimes(1);
239
+ });
240
+
241
+ expect((getListMock.mock.calls[0]![0] as JSONObject)["modelType"]).toBe(
242
+ TeamMemberCustomField,
243
+ );
244
+ });
245
+
246
+ test("looks the profile up by both project and user", async () => {
247
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
248
+ planLists({
249
+ schema: buildSchema(["Employee ID"]),
250
+ profiles: [buildProfile()],
251
+ });
252
+ resolveProfileItemWith({ "Employee ID": "E-4711" });
253
+
254
+ render(<UserCustomFields userId={USER_ID} hideIfEmpty={true} />);
255
+
256
+ await screen.findByText("E-4711");
257
+
258
+ const profileArgs: JSONObject = getListMock.mock.calls[1]![0] as JSONObject;
259
+ expect(profileArgs["modelType"]).toBe(ProjectUserProfile);
260
+ expect((profileArgs["query"] as JSONObject)["projectId"]).toBe(PROJECT_ID);
261
+ expect((profileArgs["query"] as JSONObject)["userId"]).toBe(USER_ID);
262
+ });
263
+
264
+ /*
265
+ * The wrapper's own two lookups are not the only requests involved: the
266
+ * card it mounts then fetches the schema and the profile row again for
267
+ * itself. Hiding only the wrapper's half left the card's half free to paint
268
+ * "No custom fields have been added" - and then an error box - onto the
269
+ * overview of a user who plainly has custom fields.
270
+ */
271
+ test("renders nothing when the card's own read of the profile fails", async () => {
272
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
273
+ planLists({
274
+ schema: buildSchema(["Employee ID"]),
275
+ profiles: [buildProfile()],
276
+ });
277
+ getItemMock.mockRejectedValue(new Error("Upgrade your plan"));
278
+
279
+ const { container } = render(
280
+ <UserCustomFields userId={USER_ID} hideIfEmpty={true} />,
281
+ );
282
+
283
+ await waitFor(() => {
284
+ expect(getItemMock).toHaveBeenCalled();
285
+ });
286
+
287
+ expect(screen.queryByText(/Upgrade your plan/i)).not.toBeInTheDocument();
288
+ expect(container).toBeEmptyDOMElement();
289
+ });
290
+
291
+ test("renders nothing when the profile row disappears between the two reads", async () => {
292
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
293
+ planLists({
294
+ schema: buildSchema(["Employee ID"]),
295
+ profiles: [buildProfile()],
296
+ });
297
+ getItemMock.mockResolvedValue(null as never);
298
+
299
+ const { container } = render(
300
+ <UserCustomFields userId={USER_ID} hideIfEmpty={true} />,
301
+ );
302
+
303
+ await waitFor(() => {
304
+ expect(getItemMock).toHaveBeenCalled();
305
+ });
306
+
307
+ expect(screen.queryByText("Item not found")).not.toBeInTheDocument();
308
+ expect(container).toBeEmptyDOMElement();
309
+ });
310
+
311
+ /*
312
+ * Someone else's answers, on someone else's profile page. Reading them is
313
+ * the point; editing them from here is not.
314
+ */
315
+ test("is read only", async () => {
316
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
317
+ planLists({
318
+ schema: buildSchema(["Employee ID"]),
319
+ profiles: [buildProfile()],
320
+ });
321
+ resolveProfileItemWith({ "Employee ID": "E-4711" });
322
+
323
+ render(<UserCustomFields userId={USER_ID} hideIfEmpty={true} />);
324
+
325
+ expect(await screen.findByText("E-4711")).toBeInTheDocument();
326
+ expect(screen.queryByText("Edit Fields")).not.toBeInTheDocument();
327
+ });
328
+ });
329
+
330
+ describe("UserCustomFields - the dedicated page (no hideIfEmpty)", () => {
331
+ test("explains that the project defined no member fields", async () => {
332
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
333
+ planLists({ schema: [], profiles: [buildProfile()] });
334
+
335
+ render(<UserCustomFields userId={USER_ID} />);
336
+
337
+ expect(
338
+ await screen.findByText("No custom fields defined"),
339
+ ).toBeInTheDocument();
340
+ });
341
+
342
+ test("explains that this member has not filled anything in", async () => {
343
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
344
+ planLists({ schema: buildSchema(["Employee ID"]), profiles: [] });
345
+
346
+ render(<UserCustomFields userId={USER_ID} />);
347
+
348
+ expect(
349
+ await screen.findByText("No custom field values"),
350
+ ).toBeInTheDocument();
351
+ });
352
+
353
+ test("surfaces a failed lookup rather than hiding it", async () => {
354
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
355
+ getListMock.mockRejectedValue(new Error("Upgrade your plan"));
356
+
357
+ render(<UserCustomFields userId={USER_ID} />);
358
+
359
+ expect(await screen.findByText(/Upgrade your plan/i)).toBeInTheDocument();
360
+ });
361
+
362
+ /*
363
+ * The other half of the pair above: here the card's own read is the one
364
+ * that fails, and this page is the one place that has to say so.
365
+ */
366
+ test("surfaces a failure of the card's own read too", async () => {
367
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
368
+ planLists({
369
+ schema: buildSchema(["Employee ID"]),
370
+ profiles: [buildProfile()],
371
+ });
372
+ getItemMock.mockRejectedValue(new Error("Upgrade your plan"));
373
+
374
+ render(<UserCustomFields userId={USER_ID} />);
375
+
376
+ expect(await screen.findByText(/Upgrade your plan/i)).toBeInTheDocument();
377
+ });
378
+
379
+ test("still shows the values when there is something to show", async () => {
380
+ getCurrentProjectIdMock.mockReturnValue(PROJECT_ID);
381
+ planLists({
382
+ schema: buildSchema(["Employee ID"]),
383
+ profiles: [buildProfile()],
384
+ });
385
+ resolveProfileItemWith({ "Employee ID": "E-4711" });
386
+
387
+ render(<UserCustomFields userId={USER_ID} />);
388
+
389
+ expect(await screen.findByText("E-4711")).toBeInTheDocument();
390
+ expect(screen.getByText("Custom Fields")).toBeInTheDocument();
391
+ });
392
+ });
@@ -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