@oneuptime/common 12.0.3 → 12.0.5

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 (516) hide show
  1. package/Models/DatabaseModels/AIRun.ts +38 -1
  2. package/Models/DatabaseModels/AlertFeed.ts +30 -0
  3. package/Models/DatabaseModels/CephCluster.ts +14 -0
  4. package/Models/DatabaseModels/CodeRepository.ts +14 -6
  5. package/Models/DatabaseModels/Dashboard.ts +28 -0
  6. package/Models/DatabaseModels/DockerHost.ts +14 -0
  7. package/Models/DatabaseModels/GlobalOidcProject.ts +18 -0
  8. package/Models/DatabaseModels/GlobalSsoProject.ts +18 -0
  9. package/Models/DatabaseModels/Incident.ts +2 -0
  10. package/Models/DatabaseModels/IncidentEpisode.ts +1 -0
  11. package/Models/DatabaseModels/IncidentEpisodePublicNote.ts +1 -0
  12. package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
  13. package/Models/DatabaseModels/IncidentFeed.ts +30 -0
  14. package/Models/DatabaseModels/IncidentPublicNote.ts +1 -0
  15. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
  16. package/Models/DatabaseModels/IoTFleet.ts +14 -0
  17. package/Models/DatabaseModels/KubernetesCluster.ts +14 -0
  18. package/Models/DatabaseModels/LogSavedView.ts +33 -0
  19. package/Models/DatabaseModels/NetworkDevice.ts +14 -0
  20. package/Models/DatabaseModels/NetworkInterface.ts +18 -0
  21. package/Models/DatabaseModels/Project.ts +247 -11
  22. package/Models/DatabaseModels/ProxmoxCluster.ts +14 -0
  23. package/Models/DatabaseModels/ScheduledMaintenance.ts +1 -0
  24. package/Models/DatabaseModels/ScheduledMaintenancePublicNote.ts +1 -0
  25. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
  26. package/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.ts +4 -4
  27. package/Models/DatabaseModels/Service.ts +30 -0
  28. package/Models/DatabaseModels/StatusPage.ts +28 -0
  29. package/Models/DatabaseModels/StatusPageAnnouncement.ts +1 -0
  30. package/Models/DatabaseModels/StatusPagePrivateUser.ts +30 -0
  31. package/Models/DatabaseModels/User.ts +30 -0
  32. package/Server/API/AIAgentDataAPI.ts +75 -55
  33. package/Server/API/AIInvestigationAPI.ts +175 -17
  34. package/Server/API/DashboardAPI.ts +429 -22
  35. package/Server/API/GitHubAPI.ts +119 -283
  36. package/Server/API/StatusPageAPI.ts +38 -19
  37. package/Server/API/UserAPI.ts +263 -1
  38. package/Server/EnvironmentConfig.ts +23 -3
  39. package/Server/Infrastructure/ClickhouseConfig.ts +15 -1
  40. package/Server/Infrastructure/ClickhouseDatabase.ts +1 -1
  41. package/Server/Infrastructure/GlobalCache.ts +37 -0
  42. package/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.ts +21 -0
  43. package/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.ts +68 -0
  44. package/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.ts +27 -0
  45. package/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.ts +100 -0
  46. package/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.ts +89 -0
  47. package/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.ts +27 -0
  48. package/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.ts +214 -0
  49. package/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.ts +69 -0
  50. package/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.ts +40 -0
  51. package/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.ts +26 -0
  52. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +20 -0
  53. package/Server/Services/AIRunService.ts +78 -10
  54. package/Server/Services/AIService.ts +94 -22
  55. package/Server/Services/AlertFeedService.ts +5 -0
  56. package/Server/Services/AnalyticsDatabaseService.ts +101 -1
  57. package/Server/Services/CodeRepositoryService.ts +105 -2
  58. package/Server/Services/DatabaseService.ts +227 -3
  59. package/Server/Services/IncidentFeedService.ts +5 -0
  60. package/Server/Services/LlmLogService.ts +46 -2
  61. package/Server/Services/OpenTelemetryIngestService.ts +230 -26
  62. package/Server/Services/UserService.ts +184 -0
  63. package/Server/Utils/AI/Chat/ObservabilityAssistant.ts +6 -0
  64. package/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.ts +4 -0
  65. package/Server/Utils/AI/CodeFix/CodeFixReadiness.ts +8 -5
  66. package/Server/Utils/AI/CodeFix/FixRunBudget.ts +90 -16
  67. package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +2 -0
  68. package/Server/Utils/AI/Remediation/RemediationPlanRunner.ts +2 -0
  69. package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +223 -22
  70. package/Server/Utils/AI/SRE/AlertInvestigationRunner.ts +25 -24
  71. package/Server/Utils/AI/SRE/ConfidenceSignal.ts +182 -71
  72. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +252 -43
  73. package/Server/Utils/AI/SRE/IncidentInvestigationRunner.ts +25 -24
  74. package/Server/Utils/AI/SRE/InstrumentationTaskTrigger.ts +47 -13
  75. package/Server/Utils/AI/SRE/InvestigationGrader.ts +9 -5
  76. package/Server/Utils/AI/SRE/InvestigationQueue.ts +141 -24
  77. package/Server/Utils/AI/SRE/InvestigationSubjectLock.ts +66 -0
  78. package/Server/Utils/AI/SRE/PostedRootCause.ts +94 -3
  79. package/Server/Utils/AI/SRE/README.md +1 -1
  80. package/Server/Utils/AI/SRE/SubjectCodeFixRun.ts +132 -10
  81. package/Server/Utils/AI/Toolbox/CodeTools.ts +45 -4
  82. package/Server/Utils/AnalyticsDatabase/ClusterConfig.ts +24 -0
  83. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +13 -0
  84. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +157 -4
  85. package/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.ts +130 -0
  86. package/Server/Utils/Monitor/Criteria/APIRequestCriteria.ts +29 -0
  87. package/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.ts +56 -0
  88. package/Server/Utils/Monitor/MonitorMetricUtil.ts +46 -0
  89. package/Server/Utils/Monitor/MonitorTemplateUtil.ts +1 -0
  90. package/Server/Utils/PasswordHash.ts +330 -0
  91. package/Tests/App/Dashboard/AIInvestigationHeaderStatus.test.tsx +251 -0
  92. package/Tests/App/Dashboard/EventStatusPanel.test.tsx +747 -0
  93. package/Tests/App/Dashboard/InvestigationFeedRefresh.test.tsx +480 -0
  94. package/Tests/App/Dashboard/InvestigationPanel.test.tsx +1184 -0
  95. package/Tests/App/Dashboard/InvestigationPanelStatus.test.tsx +500 -0
  96. package/Tests/App/Dashboard/OverviewCustomFields.test.tsx +333 -0
  97. package/Tests/App/Dashboard/PortMonitorCriteriaFilter.test.ts +93 -0
  98. package/Tests/App/Dashboard/UserCustomFields.test.tsx +392 -0
  99. package/Tests/App/StatusPage/PublicStatusPageAPIErrorHandling.test.ts +117 -0
  100. package/Tests/App/StatusPage/StatusPageModelAPIPolymorphism.test.ts +223 -0
  101. package/Tests/Models/DatabaseModels/PermissionCatalogueCoverage.test.ts +243 -0
  102. package/Tests/Server/API/AIAgentDataFixFromIncidentContext.test.ts +266 -0
  103. package/Tests/Server/API/AIAgentDataRepositoryToken.test.ts +381 -0
  104. package/Tests/Server/API/AIInvestigationAPI.test.ts +594 -0
  105. package/Tests/Server/API/AIInvestigationCreateFixTask.test.ts +80 -0
  106. package/Tests/Server/API/DashboardMasterPasswordAPI.test.ts +172 -1
  107. package/Tests/Server/API/DashboardPublicAttributeValuesAPI.test.ts +943 -0
  108. package/Tests/Server/API/DashboardPublicMetricsAggregateAPI.test.ts +1296 -0
  109. package/Tests/Server/API/DashboardPublicTemplatePayloads.test.ts +598 -0
  110. package/Tests/Server/API/GitHubAppInstallationBindingAPI.test.ts +539 -0
  111. package/Tests/Server/API/Helpers.ts +6 -1
  112. package/Tests/Server/API/StatusPageMasterPasswordAPI.test.ts +335 -0
  113. package/Tests/Server/API/UserProjectsAPI.test.ts +852 -0
  114. package/Tests/Server/Infrastructure/GlobalCache.test.ts +128 -0
  115. package/Tests/Server/Infrastructure/SemaphoreMutex.test.ts +215 -0
  116. package/Tests/Server/Services/AIRunCodeFixClaim.test.ts +59 -5
  117. package/Tests/Server/Services/AIRunHumanVerdict.test.ts +127 -58
  118. package/Tests/Server/Services/AIServiceDailyBudget.test.ts +396 -20
  119. package/Tests/Server/Services/AddMasterPasswordSaltMigration.test.ts +283 -0
  120. package/Tests/Server/Services/AddPerUserPasswordSaltMigration.test.ts +178 -0
  121. package/Tests/Server/Services/AnalyticsDatabasePaginationStability.test.ts +582 -0
  122. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +30 -1
  123. package/Tests/Server/Services/CodeRepositoryInstallationBinding.test.ts +305 -0
  124. package/Tests/Server/Services/CodeRepositoryResolutionBinding.test.ts +147 -0
  125. package/Tests/Server/Services/DatabaseServicePerUserPasswordSalt.test.ts +880 -0
  126. package/Tests/Server/Services/DatabaseServiceUpdateColumnsWithoutHooks.test.ts +54 -0
  127. package/Tests/Server/Services/FeedAIRunAssociation.test.ts +125 -0
  128. package/Tests/Server/Services/FixFromIncidentTaskTrigger.test.ts +418 -57
  129. package/Tests/Server/Services/InstrumentationTaskTrigger.test.ts +173 -14
  130. package/Tests/Server/Services/MasterPasswordScrypt.test.ts +567 -0
  131. package/Tests/Server/Services/OpenTelemetryServiceResolutionCache.test.ts +568 -0
  132. package/Tests/Server/Services/RestoreDroppedUniqueIndexesMigration.test.ts +386 -0
  133. package/Tests/Server/Services/RestoreServiceLowerNameIndexMigration.test.ts +240 -0
  134. package/Tests/Server/Services/SeparateIncidentAlertAiSettingsMigration.test.ts +194 -0
  135. package/Tests/Server/Services/UserServiceFirstMasterAdminElection.test.ts +885 -0
  136. package/Tests/Server/Services/WidenHashedStringColumnsForScryptMigration.test.ts +220 -0
  137. package/Tests/Server/Utils/AI/AIAlertGating.test.ts +37 -4
  138. package/Tests/Server/Utils/AI/AIConfidenceSignal.test.ts +330 -29
  139. package/Tests/Server/Utils/AI/AIIncidentGating.test.ts +25 -0
  140. package/Tests/Server/Utils/AI/AIInvestigationQueue.test.ts +293 -5
  141. package/Tests/Server/Utils/AI/CodeFixAgentCompletion.test.ts +59 -1
  142. package/Tests/Server/Utils/AI/CodeTools.test.ts +47 -1
  143. package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +10 -0
  144. package/Tests/Server/Utils/AI/FixFromIncidentAutoTrigger.test.ts +342 -19
  145. package/Tests/Server/Utils/AI/FixRunBudget.test.ts +214 -30
  146. package/Tests/Server/Utils/AI/Insights/InvestigationQueueInsightSubject.test.ts +2 -0
  147. package/Tests/Server/Utils/AI/InvestigationGrader.test.ts +65 -17
  148. package/Tests/Server/Utils/AI/InvestigationQueueRemediationExecution.test.ts +3 -0
  149. package/Tests/Server/Utils/AI/InvestigationSettlement.test.ts +313 -20
  150. package/Tests/Server/Utils/AI/PostedRootCause.test.ts +254 -0
  151. package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +4 -0
  152. package/Tests/Server/Utils/AI/RemediationPlanRunner.test.ts +2 -0
  153. package/Tests/Server/Utils/AI/SubjectCodeFixRunDedupe.test.ts +44 -0
  154. package/Tests/Server/Utils/AnalyticsDatabase/ClusterAwareSchema.test.ts +30 -0
  155. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +120 -0
  156. package/Tests/Server/Utils/CodeRepository/GitHubInstallationBinding.test.ts +292 -0
  157. package/Tests/Server/Utils/GitHubInstallationOwnershipVerification.test.ts +340 -0
  158. package/Tests/Server/Utils/GitHubWebhookAndTreeCacheIsolation.test.ts +250 -0
  159. package/Tests/Server/Utils/Monitor/Criteria/APIRequestCriteriaPortTimings.test.ts +212 -0
  160. package/Tests/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.test.ts +401 -0
  161. package/Tests/Server/Utils/Monitor/MonitorMetricUtilPortTimings.test.ts +243 -0
  162. package/Tests/Server/Utils/PasswordHash.test.ts +585 -0
  163. package/Tests/Types/Dashboard/DashboardTemplates.test.ts +111 -0
  164. package/Tests/Types/Database/ColumnLength.test.ts +7 -1
  165. package/Tests/Types/HashedStringPerUserSalt.test.ts +476 -0
  166. package/Tests/Types/Monitor/CephMetricCatalog.test.ts +104 -0
  167. package/Tests/Types/Monitor/CriteriaFilter.test.ts +4 -0
  168. package/Tests/Types/Monitor/DockerAlertTemplates.test.ts +293 -0
  169. package/Tests/Types/Monitor/DockerMetricCatalog.test.ts +109 -0
  170. package/Tests/Types/Monitor/DockerSwarmMetricCatalog.test.ts +118 -0
  171. package/Tests/Types/Monitor/HostAlertTemplates.test.ts +249 -0
  172. package/Tests/Types/Monitor/HostMetricCatalog.test.ts +104 -0
  173. package/Tests/Types/Monitor/IotAlertTemplates.test.ts +320 -0
  174. package/Tests/Types/Monitor/IotMetricCatalog.test.ts +104 -0
  175. package/Tests/Types/Monitor/KubernetesMetricCatalog.test.ts +118 -0
  176. package/Tests/Types/Monitor/MonitorCriteriaInstance.test.ts +42 -0
  177. package/Tests/Types/Monitor/MonitorStep.test.ts +38 -0
  178. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +75 -0
  179. package/Tests/Types/Monitor/PodmanAlertTemplates.test.ts +271 -0
  180. package/Tests/Types/Monitor/PodmanMetricCatalog.test.ts +109 -0
  181. package/Tests/Types/Monitor/ProxmoxMetricCatalog.test.ts +107 -0
  182. package/Tests/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.test.ts +151 -0
  183. package/Tests/Types/Permission.test.ts +137 -0
  184. package/Tests/Types/Rum/SessionReplayMaskingMode.test.ts +101 -0
  185. package/Tests/UI/Components/AiInvestigationSettingsCard.test.tsx +5 -5
  186. package/Tests/UI/Components/CardModelDetailEdit.test.tsx +3 -5
  187. package/Tests/UI/Components/CustomFields/CustomFieldsDetail.test.tsx +696 -0
  188. package/Tests/UI/Components/ErrorBoundary.test.tsx +158 -0
  189. package/Tests/UI/Components/FeedItemSafeMode.test.tsx +74 -0
  190. package/Tests/UI/Components/MoreMenu.test.tsx +756 -0
  191. package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +62 -0
  192. package/Tests/UI/Monitor/PortMonitorView.test.tsx +237 -0
  193. package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +91 -0
  194. package/Tests/UI/Utils/DownloadFile.test.ts +103 -0
  195. package/Tests/UI/Utils/ErrorSupportBundle.test.ts +582 -0
  196. package/Tests/UI/Utils/Project.test.ts +31 -0
  197. package/Tests/UI/Utils/StatusPageModelAPIInjection.test.ts +245 -0
  198. package/Tests/UI/Utils/UseDashboardGridDnd.test.tsx +820 -0
  199. package/Tests/UI/Utils/UserProjectsModelAPI.test.ts +714 -0
  200. package/Tests/Utils/Dashboard/DashboardViewConfig.test.ts +329 -0
  201. package/Tests/Utils/Dashboard/GridLayout.test.ts +951 -0
  202. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +117 -0
  203. package/Tests/Utils/RecordingRuleExpression.test.ts +327 -0
  204. package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +186 -0
  205. package/Tests/Utils/StatusPage/GroupTree.test.ts +456 -0
  206. package/Tests/Utils/StatusPage/OverviewGroupHierarchyVisibility.test.ts +588 -0
  207. package/Tests/Utils/TeamMembersByProject.test.ts +655 -0
  208. package/Tests/Utils/Telemetry/SavedViewTimeRange.test.ts +244 -0
  209. package/Tests/Utils/Telemetry/TelemetryQueryTimeRange.test.ts +825 -0
  210. package/Types/AI/AIRunCodeFixRecommendation.ts +17 -0
  211. package/Types/AI/CodeFixTaskContext.ts +63 -3
  212. package/Types/AI/CodeFixTaskType.ts +3 -3
  213. package/Types/Database/ColumnLength.ts +9 -1
  214. package/Types/Database/TableColumn.ts +11 -0
  215. package/Types/Database/UnsynchronizedIndex.ts +48 -0
  216. package/Types/HashedString.ts +140 -4
  217. package/Types/Monitor/CriteriaFilter.ts +4 -0
  218. package/Types/Monitor/DomainMonitor/DomainLookupMethod.ts +23 -0
  219. package/Types/Monitor/DomainMonitor/DomainMonitorResponse.ts +7 -0
  220. package/Types/Monitor/MonitorCriteriaInstance.ts +24 -7
  221. package/Types/Monitor/MonitorMetricType.ts +8 -0
  222. package/Types/Monitor/MonitorStep.ts +10 -1
  223. package/Types/Monitor/MonitorStepDomainMonitor.ts +21 -0
  224. package/Types/Monitor/PortMonitor/PortMonitorTimings.ts +10 -0
  225. package/Types/Permission.ts +23 -175
  226. package/Types/Probe/ProbeMonitorResponse.ts +6 -0
  227. package/UI/Components/BulkUpdate/BulkUpdateForm.tsx +2 -3
  228. package/UI/Components/CustomFields/CustomFieldsDetail.tsx +85 -11
  229. package/UI/Components/ErrorBoundary.tsx +138 -11
  230. package/UI/Components/Feed/FeedItem.tsx +9 -2
  231. package/UI/Components/ModelDetail/CardModelDetail.tsx +0 -12
  232. package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
  233. package/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.ts +12 -2
  234. package/UI/Components/MoreMenu/MoreMenu.tsx +285 -97
  235. package/UI/Components/MoreMenu/MoreMenuItem.tsx +8 -5
  236. package/UI/Components/Navbar/NavBar.tsx +12 -2
  237. package/UI/Components/Navbar/NavBarMenuModal.tsx +19 -7
  238. package/UI/Utils/DownloadFile.ts +16 -8
  239. package/UI/Utils/ErrorSupportBundle.ts +805 -0
  240. package/UI/Utils/ModelAPI/ModelAPI.ts +19 -8
  241. package/UI/Utils/ModelAPI/UserProjectsModelAPI.ts +257 -0
  242. package/UI/Utils/Project.ts +4 -0
  243. package/UI/Utils/StatusPage.ts +8 -2
  244. package/UI/Utils/UseDashboardGridDnd.ts +917 -0
  245. package/Utils/Dashboard/DashboardViewConfig.ts +80 -36
  246. package/Utils/Dashboard/GridLayout.ts +523 -0
  247. package/Utils/Metrics/RecordingRuleExpression.ts +19 -17
  248. package/Utils/Monitor/MonitorMetricType.ts +44 -2
  249. package/Utils/StatusPage/GroupNestingLayout.ts +69 -0
  250. package/Utils/StatusPage/GroupTree.ts +157 -66
  251. package/Utils/StatusPage/ResourceUptime.ts +37 -2
  252. package/Utils/TeamMembersByProject.ts +237 -0
  253. package/Utils/Telemetry/SavedViewTimeRange.ts +114 -0
  254. package/Utils/Telemetry/TelemetryQueryTimeRange.ts +334 -0
  255. package/build/dist/Models/DatabaseModels/AIRun.js +39 -1
  256. package/build/dist/Models/DatabaseModels/AIRun.js.map +1 -1
  257. package/build/dist/Models/DatabaseModels/AlertFeed.js +32 -0
  258. package/build/dist/Models/DatabaseModels/AlertFeed.js.map +1 -1
  259. package/build/dist/Models/DatabaseModels/CephCluster.js +16 -1
  260. package/build/dist/Models/DatabaseModels/CephCluster.js.map +1 -1
  261. package/build/dist/Models/DatabaseModels/CodeRepository.js +14 -6
  262. package/build/dist/Models/DatabaseModels/CodeRepository.js.map +1 -1
  263. package/build/dist/Models/DatabaseModels/Dashboard.js +29 -0
  264. package/build/dist/Models/DatabaseModels/Dashboard.js.map +1 -1
  265. package/build/dist/Models/DatabaseModels/DockerHost.js +16 -1
  266. package/build/dist/Models/DatabaseModels/DockerHost.js.map +1 -1
  267. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js +16 -1
  268. package/build/dist/Models/DatabaseModels/GlobalOidcProject.js.map +1 -1
  269. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js +16 -1
  270. package/build/dist/Models/DatabaseModels/GlobalSsoProject.js.map +1 -1
  271. package/build/dist/Models/DatabaseModels/Incident.js +2 -0
  272. package/build/dist/Models/DatabaseModels/Incident.js.map +1 -1
  273. package/build/dist/Models/DatabaseModels/IncidentEpisode.js +1 -0
  274. package/build/dist/Models/DatabaseModels/IncidentEpisode.js.map +1 -1
  275. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js +1 -0
  276. package/build/dist/Models/DatabaseModels/IncidentEpisodePublicNote.js.map +1 -1
  277. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
  278. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
  279. package/build/dist/Models/DatabaseModels/IncidentFeed.js +32 -0
  280. package/build/dist/Models/DatabaseModels/IncidentFeed.js.map +1 -1
  281. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js +1 -0
  282. package/build/dist/Models/DatabaseModels/IncidentPublicNote.js.map +1 -1
  283. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
  284. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  285. package/build/dist/Models/DatabaseModels/IoTFleet.js +16 -1
  286. package/build/dist/Models/DatabaseModels/IoTFleet.js.map +1 -1
  287. package/build/dist/Models/DatabaseModels/KubernetesCluster.js +16 -1
  288. package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
  289. package/build/dist/Models/DatabaseModels/LogSavedView.js +33 -0
  290. package/build/dist/Models/DatabaseModels/LogSavedView.js.map +1 -1
  291. package/build/dist/Models/DatabaseModels/NetworkDevice.js +16 -1
  292. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  293. package/build/dist/Models/DatabaseModels/NetworkInterface.js +16 -1
  294. package/build/dist/Models/DatabaseModels/NetworkInterface.js.map +1 -1
  295. package/build/dist/Models/DatabaseModels/Project.js +257 -13
  296. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  297. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js +16 -1
  298. package/build/dist/Models/DatabaseModels/ProxmoxCluster.js.map +1 -1
  299. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js +1 -0
  300. package/build/dist/Models/DatabaseModels/ScheduledMaintenance.js.map +1 -1
  301. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js +1 -0
  302. package/build/dist/Models/DatabaseModels/ScheduledMaintenancePublicNote.js.map +1 -1
  303. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
  304. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  305. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplateOwnerUser.js +4 -4
  306. package/build/dist/Models/DatabaseModels/Service.js +28 -1
  307. package/build/dist/Models/DatabaseModels/Service.js.map +1 -1
  308. package/build/dist/Models/DatabaseModels/StatusPage.js +29 -0
  309. package/build/dist/Models/DatabaseModels/StatusPage.js.map +1 -1
  310. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +1 -0
  311. package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
  312. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js +32 -0
  313. package/build/dist/Models/DatabaseModels/StatusPagePrivateUser.js.map +1 -1
  314. package/build/dist/Models/DatabaseModels/User.js +32 -0
  315. package/build/dist/Models/DatabaseModels/User.js.map +1 -1
  316. package/build/dist/Server/API/AIAgentDataAPI.js +49 -48
  317. package/build/dist/Server/API/AIAgentDataAPI.js.map +1 -1
  318. package/build/dist/Server/API/AIInvestigationAPI.js +111 -11
  319. package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
  320. package/build/dist/Server/API/DashboardAPI.js +312 -15
  321. package/build/dist/Server/API/DashboardAPI.js.map +1 -1
  322. package/build/dist/Server/API/GitHubAPI.js +94 -167
  323. package/build/dist/Server/API/GitHubAPI.js.map +1 -1
  324. package/build/dist/Server/API/StatusPageAPI.js +29 -11
  325. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  326. package/build/dist/Server/API/UserAPI.js +187 -2
  327. package/build/dist/Server/API/UserAPI.js.map +1 -1
  328. package/build/dist/Server/EnvironmentConfig.js +21 -3
  329. package/build/dist/Server/EnvironmentConfig.js.map +1 -1
  330. package/build/dist/Server/Infrastructure/ClickhouseConfig.js +12 -1
  331. package/build/dist/Server/Infrastructure/ClickhouseConfig.js.map +1 -1
  332. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js +1 -1
  333. package/build/dist/Server/Infrastructure/ClickhouseDatabase.js.map +1 -1
  334. package/build/dist/Server/Infrastructure/GlobalCache.js +29 -0
  335. package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
  336. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js +14 -0
  337. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786018109307-AddPerUserPasswordSalt.js.map +1 -0
  338. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js +59 -0
  339. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786023262402-WidenHashedStringColumnsForScrypt.js.map +1 -0
  340. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js +22 -0
  341. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786096660558-AddTimeRangeToLogSavedView.js.map +1 -0
  342. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js +93 -0
  343. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786100000000-RestoreServiceLowerNameIndex.js.map +1 -0
  344. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js +36 -0
  345. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786101798351-MigrationName.js.map +1 -0
  346. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js +18 -0
  347. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786105470826-MigrationName.js.map +1 -0
  348. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js +101 -0
  349. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786200000000-RestoreDroppedUniqueIndexes.js.map +1 -0
  350. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js +66 -0
  351. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786300000000-QuarantineUnboundGitHubInstallations.js.map +1 -0
  352. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js +19 -0
  353. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786400000000-AddMasterPasswordSalt.js.map +1 -0
  354. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js +19 -0
  355. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786500000000-AddInvestigationCodeFixRecommendation.js.map +1 -0
  356. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +20 -0
  357. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  358. package/build/dist/Server/Services/AIRunService.js +58 -12
  359. package/build/dist/Server/Services/AIRunService.js.map +1 -1
  360. package/build/dist/Server/Services/AIService.js +74 -21
  361. package/build/dist/Server/Services/AIService.js.map +1 -1
  362. package/build/dist/Server/Services/AlertFeedService.js +3 -0
  363. package/build/dist/Server/Services/AlertFeedService.js.map +1 -1
  364. package/build/dist/Server/Services/AnalyticsDatabaseService.js +86 -2
  365. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  366. package/build/dist/Server/Services/CodeRepositoryService.js +90 -2
  367. package/build/dist/Server/Services/CodeRepositoryService.js.map +1 -1
  368. package/build/dist/Server/Services/DatabaseService.js +180 -3
  369. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  370. package/build/dist/Server/Services/IncidentFeedService.js +3 -0
  371. package/build/dist/Server/Services/IncidentFeedService.js.map +1 -1
  372. package/build/dist/Server/Services/LlmLogService.js +22 -1
  373. package/build/dist/Server/Services/LlmLogService.js.map +1 -1
  374. package/build/dist/Server/Services/OpenTelemetryIngestService.js +155 -25
  375. package/build/dist/Server/Services/OpenTelemetryIngestService.js.map +1 -1
  376. package/build/dist/Server/Services/UserService.js +165 -0
  377. package/build/dist/Server/Services/UserService.js.map +1 -1
  378. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js +3 -0
  379. package/build/dist/Server/Utils/AI/Chat/ObservabilityAssistant.js.map +1 -1
  380. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js +4 -0
  381. package/build/dist/Server/Utils/AI/CodeFix/CodeFixAgentCompletion.js.map +1 -1
  382. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js +8 -5
  383. package/build/dist/Server/Utils/AI/CodeFix/CodeFixReadiness.js.map +1 -1
  384. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js +63 -24
  385. package/build/dist/Server/Utils/AI/CodeFix/FixRunBudget.js.map +1 -1
  386. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +2 -0
  387. package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
  388. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js +2 -0
  389. package/build/dist/Server/Utils/AI/Remediation/RemediationPlanRunner.js.map +1 -1
  390. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +156 -28
  391. package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
  392. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js +21 -19
  393. package/build/dist/Server/Utils/AI/SRE/AlertInvestigationRunner.js.map +1 -1
  394. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js +128 -49
  395. package/build/dist/Server/Utils/AI/SRE/ConfidenceSignal.js.map +1 -1
  396. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js +170 -31
  397. package/build/dist/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.js.map +1 -1
  398. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js +21 -19
  399. package/build/dist/Server/Utils/AI/SRE/IncidentInvestigationRunner.js.map +1 -1
  400. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js +33 -9
  401. package/build/dist/Server/Utils/AI/SRE/InstrumentationTaskTrigger.js.map +1 -1
  402. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +9 -5
  403. package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js.map +1 -1
  404. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js +121 -41
  405. package/build/dist/Server/Utils/AI/SRE/InvestigationQueue.js.map +1 -1
  406. package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js +46 -0
  407. package/build/dist/Server/Utils/AI/SRE/InvestigationSubjectLock.js.map +1 -0
  408. package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js +61 -14
  409. package/build/dist/Server/Utils/AI/SRE/PostedRootCause.js.map +1 -1
  410. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js +79 -1
  411. package/build/dist/Server/Utils/AI/SRE/SubjectCodeFixRun.js.map +1 -1
  412. package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js +31 -1
  413. package/build/dist/Server/Utils/AI/Toolbox/CodeTools.js.map +1 -1
  414. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js +21 -0
  415. package/build/dist/Server/Utils/AnalyticsDatabase/ClusterConfig.js.map +1 -1
  416. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +13 -0
  417. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  418. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +126 -4
  419. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  420. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js +136 -0
  421. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHubInstallationBinding.js.map +1 -0
  422. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js +20 -3
  423. package/build/dist/Server/Utils/Monitor/Criteria/APIRequestCriteria.js.map +1 -1
  424. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js +43 -0
  425. package/build/dist/Server/Utils/Monitor/Criteria/DomainMonitorCriteria.js.map +1 -1
  426. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js +33 -0
  427. package/build/dist/Server/Utils/Monitor/MonitorMetricUtil.js.map +1 -1
  428. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js +1 -0
  429. package/build/dist/Server/Utils/Monitor/MonitorTemplateUtil.js.map +1 -1
  430. package/build/dist/Server/Utils/PasswordHash.js +258 -0
  431. package/build/dist/Server/Utils/PasswordHash.js.map +1 -0
  432. package/build/dist/Types/AI/AIRunCodeFixRecommendation.js +18 -0
  433. package/build/dist/Types/AI/AIRunCodeFixRecommendation.js.map +1 -0
  434. package/build/dist/Types/AI/CodeFixTaskContext.js +23 -3
  435. package/build/dist/Types/AI/CodeFixTaskContext.js.map +1 -1
  436. package/build/dist/Types/AI/CodeFixTaskType.js +3 -3
  437. package/build/dist/Types/Database/ColumnLength.js +9 -1
  438. package/build/dist/Types/Database/ColumnLength.js.map +1 -1
  439. package/build/dist/Types/Database/TableColumn.js.map +1 -1
  440. package/build/dist/Types/Database/UnsynchronizedIndex.js +46 -0
  441. package/build/dist/Types/Database/UnsynchronizedIndex.js.map +1 -0
  442. package/build/dist/Types/HashedString.js +96 -5
  443. package/build/dist/Types/HashedString.js.map +1 -1
  444. package/build/dist/Types/Monitor/CriteriaFilter.js +4 -0
  445. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  446. package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js +24 -0
  447. package/build/dist/Types/Monitor/DomainMonitor/DomainLookupMethod.js.map +1 -0
  448. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js +24 -7
  449. package/build/dist/Types/Monitor/MonitorCriteriaInstance.js.map +1 -1
  450. package/build/dist/Types/Monitor/MonitorMetricType.js +7 -0
  451. package/build/dist/Types/Monitor/MonitorMetricType.js.map +1 -1
  452. package/build/dist/Types/Monitor/MonitorStep.js +6 -1
  453. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  454. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js +15 -0
  455. package/build/dist/Types/Monitor/MonitorStepDomainMonitor.js.map +1 -1
  456. package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js +2 -0
  457. package/build/dist/Types/Monitor/PortMonitor/PortMonitorTimings.js.map +1 -0
  458. package/build/dist/Types/Permission.js +23 -155
  459. package/build/dist/Types/Permission.js.map +1 -1
  460. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js +2 -5
  461. package/build/dist/UI/Components/BulkUpdate/BulkUpdateForm.js.map +1 -1
  462. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +51 -10
  463. package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
  464. package/build/dist/UI/Components/ErrorBoundary.js +67 -8
  465. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  466. package/build/dist/UI/Components/Feed/FeedItem.js +2 -2
  467. package/build/dist/UI/Components/Feed/FeedItem.js.map +1 -1
  468. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js +0 -12
  469. package/build/dist/UI/Components/ModelDetail/CardModelDetail.js.map +1 -1
  470. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
  471. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  472. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js +12 -2
  473. package/build/dist/UI/Components/MonitorTemplateVariables/TemplateVariablesCatalog.js.map +1 -1
  474. package/build/dist/UI/Components/MoreMenu/MoreMenu.js +193 -65
  475. package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
  476. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +1 -1
  477. package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
  478. package/build/dist/UI/Components/Navbar/NavBar.js +3 -1
  479. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  480. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +19 -7
  481. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  482. package/build/dist/UI/Utils/DownloadFile.js +15 -8
  483. package/build/dist/UI/Utils/DownloadFile.js.map +1 -1
  484. package/build/dist/UI/Utils/ErrorSupportBundle.js +476 -0
  485. package/build/dist/UI/Utils/ErrorSupportBundle.js.map +1 -0
  486. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js +18 -8
  487. package/build/dist/UI/Utils/ModelAPI/ModelAPI.js.map +1 -1
  488. package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js +156 -0
  489. package/build/dist/UI/Utils/ModelAPI/UserProjectsModelAPI.js.map +1 -0
  490. package/build/dist/UI/Utils/Project.js +3 -0
  491. package/build/dist/UI/Utils/Project.js.map +1 -1
  492. package/build/dist/UI/Utils/StatusPage.js +4 -4
  493. package/build/dist/UI/Utils/StatusPage.js.map +1 -1
  494. package/build/dist/UI/Utils/UseDashboardGridDnd.js +551 -0
  495. package/build/dist/UI/Utils/UseDashboardGridDnd.js.map +1 -0
  496. package/build/dist/Utils/Dashboard/DashboardViewConfig.js +42 -26
  497. package/build/dist/Utils/Dashboard/DashboardViewConfig.js.map +1 -1
  498. package/build/dist/Utils/Dashboard/GridLayout.js +338 -0
  499. package/build/dist/Utils/Dashboard/GridLayout.js.map +1 -0
  500. package/build/dist/Utils/Metrics/RecordingRuleExpression.js +19 -17
  501. package/build/dist/Utils/Metrics/RecordingRuleExpression.js.map +1 -1
  502. package/build/dist/Utils/Monitor/MonitorMetricType.js +38 -6
  503. package/build/dist/Utils/Monitor/MonitorMetricType.js.map +1 -1
  504. package/build/dist/Utils/StatusPage/GroupNestingLayout.js +46 -0
  505. package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -1
  506. package/build/dist/Utils/StatusPage/GroupTree.js +79 -34
  507. package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -1
  508. package/build/dist/Utils/StatusPage/ResourceUptime.js +22 -1
  509. package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
  510. package/build/dist/Utils/TeamMembersByProject.js +145 -0
  511. package/build/dist/Utils/TeamMembersByProject.js.map +1 -0
  512. package/build/dist/Utils/Telemetry/SavedViewTimeRange.js +79 -0
  513. package/build/dist/Utils/Telemetry/SavedViewTimeRange.js.map +1 -0
  514. package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js +236 -0
  515. package/build/dist/Utils/Telemetry/TelemetryQueryTimeRange.js.map +1 -0
  516. package/package.json +1 -1
@@ -24,6 +24,7 @@ export interface FeedItemProps {
24
24
  itemDateTime: Date;
25
25
  icon: IconProp;
26
26
  color: Color;
27
+ safeMode?: boolean | undefined;
27
28
  }
28
29
 
29
30
  export interface ComponentProps extends FeedItemProps {
@@ -43,7 +44,10 @@ const FeedItem: FunctionComponent<ComponentProps> = (
43
44
  title={`More Information`}
44
45
  description={
45
46
  <div>
46
- <MarkdownViewer text={props.moreTextInMarkdown || ""} />
47
+ <MarkdownViewer
48
+ text={props.moreTextInMarkdown || ""}
49
+ safeMode={props.safeMode === true}
50
+ />
47
51
  </div>
48
52
  }
49
53
  isLoading={false}
@@ -123,7 +127,10 @@ const FeedItem: FunctionComponent<ComponentProps> = (
123
127
  <div className="mt-2 text-sm text-gray-700">
124
128
  {props.textInMarkdown && (
125
129
  <div>
126
- <MarkdownViewer text={props.textInMarkdown} />
130
+ <MarkdownViewer
131
+ text={props.textInMarkdown}
132
+ safeMode={props.safeMode === true}
133
+ />
127
134
  </div>
128
135
  )}
129
136
  {props.element && <div>{props.element}</div>}
@@ -12,8 +12,6 @@ import Fields from "../Forms/Types/Fields";
12
12
  import { FormStep } from "../Forms/Types/FormStep";
13
13
  import { ModalWidth } from "../Modal/Modal";
14
14
  import ModelFormModal from "../ModelFormModal/ModelFormModal";
15
- import { ToastType } from "../Toast/Toast";
16
- import { ShowToastNotification } from "../Toast/ToastInit";
17
15
  import ModelDetail, { ComponentProps as ModeDetailProps } from "./ModelDetail";
18
16
  import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
19
17
  import IconProp from "../../../Types/Icon/IconProp";
@@ -167,16 +165,6 @@ const CardModelDetail: <TBaseModel extends BaseModel>(
167
165
  onSuccess={(item: TBaseModel) => {
168
166
  setShowModal(false);
169
167
  setRefresher(!refresher);
170
- /*
171
- * The modal just disappears otherwise, which reads as "nothing
172
- * happened" - especially on cards that do not display every field
173
- * the edit form exposes.
174
- */
175
- ShowToastNotification({
176
- title: "Changes saved",
177
- description: `${model.singularName || "Item"} updated successfully.`,
178
- type: ToastType.SUCCESS,
179
- });
180
168
  if (props.onSaveSuccess) {
181
169
  props.onSaveSuccess(item);
182
170
  }
@@ -3707,7 +3707,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
3707
3707
  b.onClick?.();
3708
3708
  }
3709
3709
  }}
3710
- className={b.disabled ? "opacity-40 pointer-events-none" : ""}
3710
+ isDisabled={b.disabled}
3711
3711
  />
3712
3712
  );
3713
3713
  },
@@ -463,11 +463,21 @@ export default class TemplateVariablesCatalog {
463
463
  return {
464
464
  title: "Domain",
465
465
  variables: [
466
- { key: "isOnline", description: "True if WHOIS lookup succeeded." },
466
+ {
467
+ key: "isOnline",
468
+ description: "True if the registration lookup succeeded.",
469
+ },
467
470
  { key: "domainName", description: "Domain queried." },
471
+ {
472
+ key: "lookupMethod",
473
+ description: "Protocol that answered - RDAP or WHOIS.",
474
+ },
468
475
  { key: "registrar", description: "Registrar name." },
469
476
  { key: "createdDate", description: "Domain registration date." },
470
- { key: "updatedDate", description: "Last WHOIS update." },
477
+ {
478
+ key: "updatedDate",
479
+ description: "Last change to the registration.",
480
+ },
471
481
  { key: "expiresDate", description: "Expiration date." },
472
482
  { key: "nameServers", description: "Array of nameservers." },
473
483
  { key: "domainStatus", description: "EPP status codes." },
@@ -5,7 +5,6 @@ import React, {
5
5
  useEffect,
6
6
  useId,
7
7
  useImperativeHandle,
8
- useRef,
9
8
  useState,
10
9
  } from "react";
11
10
  import IconProp from "../../../Types/Icon/IconProp";
@@ -23,8 +22,18 @@ export interface ComponentProps {
23
22
  triggerClassName?: string | undefined;
24
23
  menuIcon?: IconProp | undefined;
25
24
  text?: string | undefined;
25
+ isDisabled?: boolean | undefined;
26
26
  }
27
27
 
28
+ const isMenuItemDisabled: (item: HTMLElement) => boolean = (
29
+ item: HTMLElement,
30
+ ): boolean => {
31
+ return (
32
+ item.getAttribute("aria-disabled") === "true" ||
33
+ (item instanceof HTMLButtonElement && item.disabled)
34
+ );
35
+ };
36
+
28
37
  const MoreMenu: React.ForwardRefExoticComponent<
29
38
  ComponentProps & React.RefAttributes<unknown>
30
39
  > = forwardRef(
@@ -32,11 +41,53 @@ const MoreMenu: React.ForwardRefExoticComponent<
32
41
  const uniqueId: string = useId();
33
42
  const menuId: string = `menu-${uniqueId}`;
34
43
  const buttonId: string = `menu-button-${uniqueId}`;
44
+ const customTrigger: ReactElement | undefined =
45
+ props.elementToBeShownInsteadOfButton;
46
+ const isNativeButtonTrigger: boolean = Boolean(
47
+ customTrigger && customTrigger.type === "button",
48
+ );
35
49
  const { ref, isComponentVisible, setIsComponentVisible } =
36
50
  useComponentOutsideClick(false);
37
51
  const [focusedIndex, setFocusedIndex] = useState<number>(-1);
38
- const menuItemRefs: React.MutableRefObject<(HTMLDivElement | null)[]> =
39
- useRef<(HTMLDivElement | null)[]>([]);
52
+
53
+ /*
54
+ * Menu sections and dividers are valid top-level children, so the list of
55
+ * keyboard targets cannot be derived from props.children. Read the actual
56
+ * rendered menuitem descendants instead; this also supports arbitrarily
57
+ * nested sections while skipping non-action content.
58
+ */
59
+ const getMenuItems: () => Array<HTMLElement> =
60
+ useCallback((): Array<HTMLElement> => {
61
+ const menuElement: HTMLElement | null =
62
+ ref.current as HTMLElement | null;
63
+
64
+ if (!menuElement) {
65
+ return [];
66
+ }
67
+
68
+ /*
69
+ * Some established callers pass their own button as a menu child
70
+ * (usually wrapped for spacing) instead of MoreMenuItem. Promote that
71
+ * existing interactive element to a menuitem so it remains reachable
72
+ * by roving focus and participates in delegated dismissal. Explicit
73
+ * menuitems and anything nested inside one are left untouched.
74
+ */
75
+ Array.from(
76
+ menuElement.querySelectorAll<HTMLElement>(
77
+ 'button, a[href], [role="button"]',
78
+ ),
79
+ ).forEach((item: HTMLElement) => {
80
+ if (!item.closest('[role="menuitem"]')) {
81
+ item.setAttribute("role", "menuitem");
82
+ }
83
+ });
84
+
85
+ return Array.from(
86
+ menuElement.querySelectorAll<HTMLElement>('[role="menuitem"]'),
87
+ ).filter((item: HTMLElement) => {
88
+ return !isMenuItemDisabled(item);
89
+ });
90
+ }, [ref]);
40
91
 
41
92
  useImperativeHandle(componentRef, () => {
42
93
  return {
@@ -64,19 +115,40 @@ const MoreMenu: React.ForwardRefExoticComponent<
64
115
  }, [isComponentVisible]);
65
116
 
66
117
  useEffect(() => {
67
- if (focusedIndex >= 0 && menuItemRefs.current[focusedIndex]) {
68
- menuItemRefs.current[focusedIndex]?.focus();
118
+ if (props.isDisabled && isComponentVisible) {
119
+ setIsComponentVisible(false);
69
120
  }
70
- }, [focusedIndex]);
121
+ }, [props.isDisabled, isComponentVisible, setIsComponentVisible]);
122
+
123
+ useEffect(() => {
124
+ const menuItems: Array<HTMLElement> = getMenuItems();
125
+
126
+ menuItems.forEach((item: HTMLElement, index: number) => {
127
+ item.tabIndex = index === focusedIndex ? 0 : -1;
128
+ });
129
+
130
+ if (focusedIndex >= 0 && menuItems.length > 0) {
131
+ const safeFocusedIndex: number = Math.min(
132
+ focusedIndex,
133
+ menuItems.length - 1,
134
+ );
135
+
136
+ if (safeFocusedIndex !== focusedIndex) {
137
+ setFocusedIndex(safeFocusedIndex);
138
+ } else {
139
+ menuItems[safeFocusedIndex]?.focus();
140
+ }
141
+ }
142
+ }, [focusedIndex, getMenuItems, isComponentVisible, props.children]);
71
143
 
72
144
  const restoreFocusToTrigger: () => void = useCallback((): void => {
73
145
  /*
74
- * Return focus to the trigger after the menu closes via Escape or item
75
- * selection (WAI-ARIA menu-button pattern). Deferred to the next frame so
76
- * the menu has unmounted, and only reclaimed if focus fell back to
77
- * <body> so we never steal focus that the activated item intentionally
78
- * moved elsewhere (e.g. into a dialog it opened). Not called on
79
- * outside-click dismissal, which should leave focus where the user clicked.
146
+ * Return focus after item selection (WAI-ARIA menu-button pattern).
147
+ * Deferred to the next frame so the menu has unmounted, and only reclaimed
148
+ * if focus fell back to <body> so we never steal focus that the activated
149
+ * item intentionally moved elsewhere (e.g. into a dialog it opened). Escape
150
+ * has a separate unconditional path below; outside-click dismissal leaves
151
+ * focus where the user clicked.
80
152
  */
81
153
  requestAnimationFrame(() => {
82
154
  const activeElement: Element | null = document.activeElement;
@@ -86,50 +158,174 @@ const MoreMenu: React.ForwardRefExoticComponent<
86
158
  });
87
159
  }, [buttonId]);
88
160
 
161
+ const focusTrigger: () => void = useCallback((): void => {
162
+ document.getElementById(buttonId)?.focus();
163
+ }, [buttonId]);
164
+
89
165
  const handleKeyDown: (event: React.KeyboardEvent) => void = useCallback(
90
166
  (event: React.KeyboardEvent): void => {
91
167
  if (!isComponentVisible) {
92
168
  return;
93
169
  }
94
170
 
95
- const itemCount: number = props.children.length;
171
+ if (event.key === "Escape") {
172
+ event.preventDefault();
173
+ setIsComponentVisible(false);
174
+ /*
175
+ * Escape always returns focus to the menu button. Do this immediately:
176
+ * a deferred callback can run before React unmounts the focused menu
177
+ * item and incorrectly decide that focus should be left alone.
178
+ */
179
+ focusTrigger();
180
+ return;
181
+ }
182
+
183
+ if (event.key === "Tab") {
184
+ setIsComponentVisible(false);
185
+ return;
186
+ }
187
+
188
+ const menuItems: Array<HTMLElement> = getMenuItems();
189
+ const itemCount: number = menuItems.length;
190
+
191
+ if (itemCount === 0) {
192
+ return;
193
+ }
194
+
195
+ const activeElement: Element | null = document.activeElement;
196
+ const activeIndex: number = menuItems.findIndex((item: HTMLElement) => {
197
+ return item === activeElement || item.contains(activeElement);
198
+ });
199
+ const currentIndex: number =
200
+ activeIndex >= 0
201
+ ? activeIndex
202
+ : focusedIndex >= 0 && focusedIndex < itemCount
203
+ ? focusedIndex
204
+ : 0;
205
+ const moveFocusToItem: (index: number) => void = (
206
+ index: number,
207
+ ): void => {
208
+ setFocusedIndex(index);
209
+ /*
210
+ * Move DOM focus in the same keyboard event as well as recording the
211
+ * roving index. React may batch consecutive keyboard events, so the
212
+ * next Enter/Space must target the newly selected item immediately.
213
+ */
214
+ menuItems[index]?.focus();
215
+ };
96
216
 
97
217
  switch (event.key) {
98
- case "Escape":
99
- event.preventDefault();
100
- setIsComponentVisible(false);
101
- restoreFocusToTrigger();
102
- break;
103
218
  case "ArrowDown":
104
219
  event.preventDefault();
105
- setFocusedIndex((prev: number) => {
106
- return (prev + 1) % itemCount;
107
- });
220
+ moveFocusToItem((currentIndex + 1) % itemCount);
108
221
  break;
109
222
  case "ArrowUp":
110
223
  event.preventDefault();
111
- setFocusedIndex((prev: number) => {
112
- return (prev - 1 + itemCount) % itemCount;
113
- });
224
+ moveFocusToItem((currentIndex - 1 + itemCount) % itemCount);
114
225
  break;
115
226
  case "Home":
116
227
  event.preventDefault();
117
- setFocusedIndex(0);
228
+ moveFocusToItem(0);
118
229
  break;
119
230
  case "End":
120
231
  event.preventDefault();
121
- setFocusedIndex(itemCount - 1);
232
+ moveFocusToItem(itemCount - 1);
122
233
  break;
234
+ case "Enter":
235
+ case " ": {
236
+ const eventTarget: EventTarget = event.target;
237
+ const menuItem: HTMLElement | undefined = menuItems.find(
238
+ (item: HTMLElement) => {
239
+ return (
240
+ eventTarget instanceof Node &&
241
+ (item === eventTarget || item.contains(eventTarget))
242
+ );
243
+ },
244
+ );
245
+
246
+ if (menuItem) {
247
+ /*
248
+ * Prevent the native button activation from adding a second
249
+ * click, then use the exact focused item as the activation
250
+ * target. Its own handler runs once and the delegated menu click
251
+ * below closes the menu.
252
+ */
253
+ event.preventDefault();
254
+ menuItem.click();
255
+ }
256
+ break;
257
+ }
123
258
  }
124
259
  },
125
260
  [
261
+ focusedIndex,
262
+ focusTrigger,
263
+ getMenuItems,
126
264
  isComponentVisible,
127
- props.children.length,
128
265
  setIsComponentVisible,
129
- restoreFocusToTrigger,
130
266
  ],
131
267
  );
132
268
 
269
+ const handleMenuClick: (event: React.MouseEvent<HTMLDivElement>) => void = (
270
+ event: React.MouseEvent<HTMLDivElement>,
271
+ ): void => {
272
+ const eventTarget: EventTarget = event.target;
273
+
274
+ if (!(eventTarget instanceof Element)) {
275
+ return;
276
+ }
277
+
278
+ const menuItem: Element | null = eventTarget.closest('[role="menuitem"]');
279
+
280
+ if (
281
+ menuItem instanceof HTMLElement &&
282
+ event.currentTarget.contains(menuItem) &&
283
+ !isMenuItemDisabled(menuItem) &&
284
+ isComponentVisible
285
+ ) {
286
+ setIsComponentVisible(false);
287
+ restoreFocusToTrigger();
288
+ }
289
+ };
290
+
291
+ const getNativeButtonTrigger: () => ReactElement | null =
292
+ (): ReactElement | null => {
293
+ if (!customTrigger || !isNativeButtonTrigger) {
294
+ return null;
295
+ }
296
+
297
+ const trigger: ReactElement<
298
+ React.ButtonHTMLAttributes<HTMLButtonElement>
299
+ > = customTrigger as ReactElement<
300
+ React.ButtonHTMLAttributes<HTMLButtonElement>
301
+ >;
302
+ const isTriggerDisabled: boolean = Boolean(
303
+ props.isDisabled || trigger.props.disabled,
304
+ );
305
+
306
+ return React.cloneElement(trigger, {
307
+ id: buttonId,
308
+ type: trigger.props.type || "button",
309
+ className: [trigger.props.className, props.triggerClassName]
310
+ .filter(Boolean)
311
+ .join(" "),
312
+ disabled: isTriggerDisabled,
313
+ "aria-disabled": isTriggerDisabled,
314
+ "aria-label":
315
+ trigger.props["aria-label"] || props.text || "More options",
316
+ "aria-haspopup": "menu",
317
+ "aria-expanded": isComponentVisible,
318
+ "aria-controls": isComponentVisible ? menuId : undefined,
319
+ onClick: (event: React.MouseEvent<HTMLButtonElement>): void => {
320
+ trigger.props.onClick?.(event);
321
+
322
+ if (!event.defaultPrevented && !isTriggerDisabled) {
323
+ setIsComponentVisible(!isDropdownVisible);
324
+ }
325
+ },
326
+ });
327
+ };
328
+
133
329
  return (
134
330
  <div
135
331
  className="relative inline-block text-left"
@@ -141,6 +337,7 @@ const MoreMenu: React.ForwardRefExoticComponent<
141
337
  icon={props.menuIcon || IconProp.More}
142
338
  title={props.text || ""}
143
339
  buttonStyle={ButtonStyleType.OUTLINE}
340
+ disabled={props.isDisabled}
144
341
  onClick={() => {
145
342
  setIsComponentVisible(!isDropdownVisible);
146
343
  }}
@@ -151,51 +348,65 @@ const MoreMenu: React.ForwardRefExoticComponent<
151
348
  />
152
349
  )}
153
350
 
154
- {props.elementToBeShownInsteadOfButton && (
155
- <div
156
- /*
157
- * The id lets the menu's aria-labelledby resolve and lets focus
158
- * return here on close. But the menu-button ARIA (haspopup/expanded/
159
- * label) is only applied when a caller opts in with triggerClassName
160
- * — callers that pass their own element (some already a real
161
- * <button>) keep a bare wrapper to avoid layering redundant button
162
- * semantics on top.
163
- */
164
- id={buttonId}
165
- className={props.triggerClassName}
166
- onClick={() => {
167
- setIsComponentVisible(!isDropdownVisible);
168
- }}
169
- role="button"
170
- tabIndex={0}
171
- aria-label={
172
- props.triggerClassName ? props.text || "More options" : undefined
173
- }
174
- aria-haspopup={props.triggerClassName ? "menu" : undefined}
175
- aria-expanded={
176
- props.triggerClassName ? isComponentVisible : undefined
177
- }
178
- aria-controls={
179
- props.triggerClassName && isComponentVisible ? menuId : undefined
180
- }
181
- onKeyDown={(e: React.KeyboardEvent) => {
351
+ {getNativeButtonTrigger()}
352
+
353
+ {props.elementToBeShownInsteadOfButton &&
354
+ !isNativeButtonTrigger &&
355
+ props.triggerClassName && (
356
+ <button
357
+ id={buttonId}
358
+ type="button"
359
+ className={props.triggerClassName}
360
+ disabled={props.isDisabled}
361
+ onClick={() => {
362
+ setIsComponentVisible(!isDropdownVisible);
363
+ }}
364
+ aria-label={props.text || "More options"}
365
+ aria-haspopup="menu"
366
+ aria-expanded={isComponentVisible}
367
+ aria-controls={isComponentVisible ? menuId : undefined}
368
+ >
369
+ {props.elementToBeShownInsteadOfButton}
370
+ </button>
371
+ )}
372
+
373
+ {props.elementToBeShownInsteadOfButton &&
374
+ !isNativeButtonTrigger &&
375
+ !props.triggerClassName && (
376
+ <div
182
377
  /*
183
- * Only respond to the wrapper's own keys, never a focusable
184
- * child's (e.g. an input inside a custom trigger), so typing
185
- * isn't hijacked.
378
+ * Keep the legacy keyboard-operable wrapper for unstyled custom
379
+ * triggers. Many callers provide a visual <div>, not an interactive
380
+ * element, so dropping this role/tab stop would make their menu
381
+ * mouse-only. Styled custom triggers use the native button above.
186
382
  */
187
- if (
188
- (e.key === "Enter" || e.key === " ") &&
189
- e.target === e.currentTarget
190
- ) {
191
- e.preventDefault();
192
- setIsComponentVisible(!isDropdownVisible);
193
- }
194
- }}
195
- >
196
- {props.elementToBeShownInsteadOfButton}
197
- </div>
198
- )}
383
+ id={buttonId}
384
+ role="button"
385
+ tabIndex={props.isDisabled ? -1 : 0}
386
+ aria-label={props.text || undefined}
387
+ aria-haspopup="menu"
388
+ aria-expanded={isComponentVisible}
389
+ aria-controls={isComponentVisible ? menuId : undefined}
390
+ aria-disabled={Boolean(props.isDisabled)}
391
+ onClick={() => {
392
+ if (!props.isDisabled) {
393
+ setIsComponentVisible(!isDropdownVisible);
394
+ }
395
+ }}
396
+ onKeyDown={(event: React.KeyboardEvent<HTMLDivElement>) => {
397
+ if (
398
+ !props.isDisabled &&
399
+ event.target === event.currentTarget &&
400
+ (event.key === "Enter" || event.key === " ")
401
+ ) {
402
+ event.preventDefault();
403
+ setIsComponentVisible(!isDropdownVisible);
404
+ }
405
+ }}
406
+ >
407
+ {props.elementToBeShownInsteadOfButton}
408
+ </div>
409
+ )}
199
410
 
200
411
  {isComponentVisible && (
201
412
  <div
@@ -205,36 +416,13 @@ const MoreMenu: React.ForwardRefExoticComponent<
205
416
  role="menu"
206
417
  aria-orientation="vertical"
207
418
  aria-labelledby={buttonId}
419
+ onClick={handleMenuClick}
208
420
  >
209
421
  {props.children.map((child: ReactElement, index: number) => {
210
422
  return (
211
- <div
212
- key={index}
213
- ref={(el: HTMLDivElement | null) => {
214
- menuItemRefs.current[index] = el;
215
- }}
216
- role="menuitem"
217
- tabIndex={focusedIndex === index ? 0 : -1}
218
- onClick={() => {
219
- if (isComponentVisible) {
220
- setIsComponentVisible(false);
221
- restoreFocusToTrigger();
222
- }
223
- }}
224
- onKeyDown={(e: React.KeyboardEvent) => {
225
- if (e.key === "Enter" || e.key === " ") {
226
- e.preventDefault();
227
- setIsComponentVisible(false);
228
- // Trigger child click
229
- const clickEvent: MouseEvent = new MouseEvent("click", {
230
- bubbles: true,
231
- });
232
- e.currentTarget.dispatchEvent(clickEvent);
233
- }
234
- }}
235
- >
423
+ <React.Fragment key={child.key || index}>
236
424
  {child}
237
- </div>
425
+ </React.Fragment>
238
426
  );
239
427
  })}
240
428
  </div>
@@ -9,17 +9,20 @@ export interface ComponentProps {
9
9
  rightElement?: Array<ReactElement> | ReactElement | undefined;
10
10
  className?: string | undefined;
11
11
  iconClassName?: string | undefined;
12
- key: string | number;
12
+ isDisabled?: boolean | undefined;
13
13
  }
14
14
 
15
15
  const MoreMenuItem: FunctionComponent<ComponentProps> = (
16
16
  props: ComponentProps,
17
17
  ): ReactElement => {
18
18
  return (
19
- <a
20
- key={props.key || Math.random()}
21
- className={`cursor-pointer group flex items-center px-3 py-2 mx-1 rounded-md text-sm text-gray-700 hover:text-gray-900 hover:bg-indigo-50 transition-colors duration-100 ${props.className}`}
19
+ <button
20
+ type="button"
21
+ className={`group mx-1 flex items-center rounded-md px-3 py-2 text-left text-sm text-gray-700 transition-colors duration-100 enabled:cursor-pointer enabled:hover:bg-indigo-50 enabled:hover:text-gray-900 disabled:cursor-not-allowed disabled:opacity-50 ${props.className || ""}`}
22
22
  role="menuitem"
23
+ tabIndex={-1}
24
+ disabled={props.isDisabled}
25
+ aria-disabled={Boolean(props.isDisabled)}
23
26
  onClick={() => {
24
27
  props.onClick();
25
28
  }}
@@ -34,7 +37,7 @@ const MoreMenuItem: FunctionComponent<ComponentProps> = (
34
37
  <div className="font-medium">{props.text}</div>
35
38
  <div>{props.rightElement}</div>
36
39
  </div>
37
- </a>
40
+ </button>
38
41
  );
39
42
  };
40
43
 
@@ -13,6 +13,7 @@ import NavBarMenuModal from "./NavBarMenuModal";
13
13
  import Button, { ButtonStyleType } from "../Button/Button";
14
14
  import Navigation from "../../Utils/Navigation";
15
15
  import useComponentOutsideClick from "../../Types/UseComponentOutsideClick";
16
+ import useTranslateValue from "../../Utils/Translation";
16
17
  import Icon, { ThickProp } from "../Icon/Icon";
17
18
 
18
19
  export interface NavItem {
@@ -54,7 +55,7 @@ export interface ComponentProps {
54
55
  items?: NavItem[];
55
56
  rightElement?: NavItem;
56
57
  moreMenuItems?: MoreMenuItem[];
57
- moreMenuTitle?: string; // Title for the more menu (default: "More")
58
+ moreMenuTitle?: string; // Title for the more menu (default: "Products")
58
59
  moreMenuSearchPlaceholder?: string; // Placeholder for the menu search box
59
60
  moreMenuNoResultsText?: string; // Empty-state text when search matches nothing
60
61
  moreMenuKeyboardHint?: string; // Keyboard hint shown in the menu footer
@@ -79,6 +80,7 @@ const MOBILE_MENU_MIN_HEIGHT_IN_PX: number = 160;
79
80
  const Navbar: FunctionComponent<ComponentProps> = (
80
81
  props: ComponentProps,
81
82
  ): ReactElement => {
83
+ const { translateString } = useTranslateValue();
82
84
  const [isMobile, setIsMobile] = useState<boolean>(false);
83
85
  const [isMobileMenuVisible, setIsMobileMenuVisible] =
84
86
  useState<boolean>(false);
@@ -408,7 +410,15 @@ const Navbar: FunctionComponent<ComponentProps> = (
408
410
  className="mr-1.5 h-4 w-4 transition-transform duration-150 group-hover:scale-110 group-hover:text-indigo-600"
409
411
  thick={ThickProp.Thick}
410
412
  />
411
- <span>{props.moreMenuTitle || "Products"}</span>
413
+ {/*
414
+ * Callers pass a plain English literal here (or nothing, and
415
+ * take the default) — run it through the same flat-key lookup
416
+ * the side menu uses so the button is localised like every
417
+ * other label in the nav.
418
+ */}
419
+ <span>
420
+ {translateString(props.moreMenuTitle || "Products")}
421
+ </span>
412
422
  <Icon
413
423
  icon={IconProp.ChevronDown}
414
424
  className={`ml-1.5 h-3 w-3 text-gray-400 transition-transform duration-200 ${