@oneuptime/common 11.7.3 → 11.7.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 (365) hide show
  1. package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +1 -0
  2. package/Models/DatabaseModels/AlertStateTimeline.ts +1 -0
  3. package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
  4. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
  5. package/Models/DatabaseModels/Index.ts +5 -0
  6. package/Models/DatabaseModels/LogDropFilter.ts +89 -0
  7. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +13 -3
  8. package/Models/DatabaseModels/RecommendationDismissal.ts +463 -0
  9. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
  10. package/Models/DatabaseModels/StatusPageGroup.ts +95 -0
  11. package/Models/DatabaseModels/TraceDropFilter.ts +89 -0
  12. package/Models/DatabaseModels/WorkflowVariable.ts +5 -1
  13. package/Server/API/AlertAPI.ts +32 -17
  14. package/Server/API/BaseAPI.ts +31 -2
  15. package/Server/API/BaseAnalyticsAPI.ts +36 -2
  16. package/Server/API/CommonAPI.ts +57 -0
  17. package/Server/API/IncidentAPI.ts +60 -33
  18. package/Server/API/IncidentEpisodeAPI.ts +31 -16
  19. package/Server/API/MonitorAPI.ts +30 -0
  20. package/Server/API/MonitorTemplateAPI.ts +8 -0
  21. package/Server/API/ProbeAPI.ts +196 -15
  22. package/Server/API/ProjectAPI.ts +79 -1
  23. package/Server/API/ScheduledMaintenanceAPI.ts +33 -18
  24. package/Server/API/StatusPageAPI.ts +74 -37
  25. package/Server/API/WorkspaceNotificationRuleAPI.ts +34 -4
  26. package/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.ts +527 -0
  27. package/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.ts +31 -0
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.ts +55 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.ts +53 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +8 -0
  31. package/Server/Services/AlertEpisodeService.ts +47 -0
  32. package/Server/Services/AlertService.ts +125 -0
  33. package/Server/Services/BillingService.ts +98 -0
  34. package/Server/Services/DatabaseService.ts +184 -20
  35. package/Server/Services/IncidentEpisodeService.ts +47 -0
  36. package/Server/Services/IncidentService.ts +123 -0
  37. package/Server/Services/IncidentTemplateService.ts +123 -1
  38. package/Server/Services/Index.ts +2 -0
  39. package/Server/Services/LogDropFilterService.ts +133 -0
  40. package/Server/Services/MonitorProbeService.ts +94 -4
  41. package/Server/Services/MonitorService.ts +48 -43
  42. package/Server/Services/NetworkDeviceDiscoveryScanService.ts +70 -0
  43. package/Server/Services/ProbeService.ts +66 -0
  44. package/Server/Services/ProjectService.ts +131 -7
  45. package/Server/Services/RecommendationDismissalService.ts +52 -0
  46. package/Server/Services/RunbookAgentJobService.ts +68 -7
  47. package/Server/Services/ScheduledMaintenanceService.ts +103 -0
  48. package/Server/Services/ScheduledMaintenanceTemplateService.ts +90 -0
  49. package/Server/Services/StatusPageGroupService.ts +186 -0
  50. package/Server/Services/TraceDropFilterService.ts +133 -0
  51. package/Server/Types/Workflow/Components/API/Delete.ts +12 -0
  52. package/Server/Types/Workflow/Components/API/Get.ts +12 -0
  53. package/Server/Types/Workflow/Components/API/Patch.ts +12 -0
  54. package/Server/Types/Workflow/Components/API/Post.ts +12 -0
  55. package/Server/Types/Workflow/Components/API/Put.ts +13 -0
  56. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +212 -0
  57. package/Server/Utils/DropFilterValidation.ts +127 -0
  58. package/Server/Utils/Errors.ts +5 -0
  59. package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
  60. package/Server/Utils/Monitor/MonitorIncident.ts +31 -2
  61. package/Server/Utils/Telemetry/AppMetrics.ts +31 -0
  62. package/Tests/Models/DatabaseModels/MonitorProbeColumnAccessControl.test.ts +196 -0
  63. package/Tests/Models/RecommendationDismissalModel.test.ts +269 -0
  64. package/Tests/Server/API/BaseAPIUpdatePayloadValidation.test.ts +320 -0
  65. package/Tests/Server/API/BaseAnalyticsAPIUpdatePayloadValidation.test.ts +293 -0
  66. package/Tests/Server/API/CommonAPIAuthGuard.test.ts +164 -0
  67. package/Tests/Server/API/ProbeAPI.test.ts +422 -53
  68. package/Tests/Server/API/ProjectAPI.test.ts +180 -0
  69. package/Tests/Server/API/ProjectAPIExtendTrialBillingDisabled.test.ts +138 -0
  70. package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +458 -0
  71. package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +359 -0
  72. package/Tests/Server/Infrastructure/ProcessSignalDelivery.test.ts +427 -0
  73. package/Tests/Server/Services/BillingServiceExtendTrial.test.ts +439 -0
  74. package/Tests/Server/Services/CrossProjectReferenceWriteGuard.test.ts +810 -0
  75. package/Tests/Server/Services/DatabaseServiceAtomicAddToColumns.test.ts +269 -0
  76. package/Tests/Server/Services/DatabaseServiceEmptyUpdate.test.ts +277 -0
  77. package/Tests/Server/Services/DatabaseServiceSortColumnSelect.test.ts +201 -0
  78. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +81 -23
  79. package/Tests/Server/Services/DropFilterSaveValidation.test.ts +398 -0
  80. package/Tests/Server/Services/MonitorProbeDeleteHooks.test.ts +280 -0
  81. package/Tests/Server/Services/MonitorProbeServiceProbeTenancy.test.ts +304 -0
  82. package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +262 -0
  83. package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +614 -0
  84. package/Tests/Server/Services/RecommendationDismissalService.test.ts +306 -0
  85. package/Tests/Server/Services/RepairCrossProjectIncidentReferencesMigration.test.ts +528 -0
  86. package/Tests/Server/Services/StatusPageGroupNesting.test.ts +395 -0
  87. package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +26 -21
  88. package/Tests/Server/Types/Database/Permissions/WorkflowVariableColumnPermission.test.ts +227 -0
  89. package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +285 -0
  90. package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +463 -0
  91. package/Tests/Server/Utils/DropFilterValidation.test.ts +269 -0
  92. package/Tests/Server/Utils/Telemetry/SpanUtil.test.ts +94 -0
  93. package/Tests/Types/DateUserTimezone.test.ts +52 -0
  94. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +177 -9
  95. package/Tests/Types/Monitor/MonitorStepDnsMonitor.test.ts +105 -0
  96. package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +131 -0
  97. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +60 -0
  98. package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +82 -0
  99. package/Tests/Types/Monitor/MonitorStepInfrastructureMonitors.test.ts +268 -0
  100. package/Tests/Types/Monitor/MonitorStepMetricMonitor.test.ts +386 -0
  101. package/Tests/Types/Monitor/MonitorStepProfileMonitor.test.ts +185 -0
  102. package/Tests/Types/Monitor/MonitorStepSnmpMonitor.test.ts +156 -0
  103. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +371 -0
  104. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +901 -0
  105. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +607 -0
  106. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +754 -0
  107. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +960 -0
  108. package/Tests/Types/RollingTime/RollingTimeUtil.test.ts +186 -0
  109. package/Tests/Types/Runbook/RunbookStepTimeout.test.ts +410 -0
  110. package/Tests/Types/Telemetry/DropFilterSampling.test.ts +241 -0
  111. package/Tests/Types/Workspace/NotificationRuleConditionUtil.test.ts +353 -0
  112. package/Tests/Types/Workspace/NotificationRuleUtil.test.ts +566 -0
  113. package/Tests/UI/Components/CodeEditor.test.tsx +174 -0
  114. package/Tests/UI/Components/ErrorBoundary.test.tsx +555 -24
  115. package/Tests/UI/Components/InfoCard.test.tsx +358 -0
  116. package/Tests/UI/Components/LogTimeRangePicker.test.tsx +138 -0
  117. package/Tests/UI/Components/Modal.test.tsx +43 -5
  118. package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +397 -0
  119. package/Tests/UI/Components/ModelTable/ColumnCustomizationModal.test.tsx +427 -0
  120. package/Tests/UI/Components/Runbook/StepTimeoutInput.test.tsx +386 -0
  121. package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +671 -0
  122. package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +404 -0
  123. package/Tests/UI/Utils/DropdownAlignment.test.ts +306 -0
  124. package/Tests/UI/Utils/TableFilterUrlState.test.ts +292 -0
  125. package/Tests/Utils/Monitor/MonitorSummaryProbeUtil.test.ts +263 -0
  126. package/Tests/Utils/NetworkDiscovery/ScanTargetUtil.test.ts +583 -0
  127. package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +1072 -0
  128. package/Tests/Utils/StatusPage/GroupTree.test.ts +583 -0
  129. package/Tests/Utils/StatusPage/ResourceUptime.test.ts +411 -0
  130. package/Types/Date.ts +15 -6
  131. package/Types/Monitor/KubernetesAlertTemplates.ts +205 -0
  132. package/Types/Monitor/MonitorStep.ts +10 -1
  133. package/Types/Monitor/MonitorStepMetricMonitor.ts +46 -1
  134. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +413 -0
  135. package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +168 -0
  136. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +175 -0
  137. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +743 -0
  138. package/Types/Permission.ts +45 -0
  139. package/Types/Recommendation/RecommendationType.ts +20 -0
  140. package/Types/Runbook/RunbookExecutionDeadline.ts +129 -0
  141. package/Types/Runbook/RunbookStepTimeout.ts +202 -0
  142. package/Types/Telemetry/DropFilterSampling.ts +92 -0
  143. package/UI/Components/AI/GenerateFromAIModal.tsx +0 -2
  144. package/UI/Components/Accordion/Accordion.tsx +10 -2
  145. package/UI/Components/BulkUpdate/BulkLabelActions.tsx +0 -1
  146. package/UI/Components/CodeEditor/CodeEditor.tsx +34 -20
  147. package/UI/Components/Date/RangeStartAndEndDateView.tsx +0 -1
  148. package/UI/Components/EditionLabel/EditionLabel.tsx +1 -27
  149. package/UI/Components/Error/PageError.tsx +0 -4
  150. package/UI/Components/ErrorBoundary.tsx +252 -15
  151. package/UI/Components/InfoCard/InfoCard.tsx +58 -1
  152. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +34 -1
  153. package/UI/Components/Modal/Modal.tsx +16 -60
  154. package/UI/Components/ModelFormModal/ModelFormModal.tsx +0 -8
  155. package/UI/Components/ModelTable/BaseModelTable.tsx +116 -67
  156. package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +150 -47
  157. package/UI/Components/Runbook/StepTimeoutInput.tsx +173 -0
  158. package/UI/Components/StatusPage/ResourceGroupSection.tsx +231 -0
  159. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +34 -1
  160. package/UI/Utils/DropdownAlignment.ts +162 -0
  161. package/UI/Utils/TableFilterUrlState.ts +59 -20
  162. package/Utils/API.ts +106 -2
  163. package/Utils/Monitor/MonitorSummaryProbeUtil.ts +130 -0
  164. package/Utils/NetworkDiscovery/ScanTargetUtil.ts +434 -0
  165. package/Utils/StatusPage/GroupNestingLayout.ts +343 -0
  166. package/Utils/StatusPage/GroupTree.ts +307 -0
  167. package/Utils/StatusPage/ResourceUptime.ts +90 -17
  168. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +1 -0
  169. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -1
  170. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +1 -0
  171. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
  172. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
  173. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
  174. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
  175. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  176. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  177. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  178. package/build/dist/Models/DatabaseModels/LogDropFilter.js +91 -0
  179. package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
  180. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +14 -4
  181. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  182. package/build/dist/Models/DatabaseModels/RecommendationDismissal.js +484 -0
  183. package/build/dist/Models/DatabaseModels/RecommendationDismissal.js.map +1 -0
  184. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
  185. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  186. package/build/dist/Models/DatabaseModels/StatusPageGroup.js +94 -0
  187. package/build/dist/Models/DatabaseModels/StatusPageGroup.js.map +1 -1
  188. package/build/dist/Models/DatabaseModels/TraceDropFilter.js +91 -0
  189. package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
  190. package/build/dist/Models/DatabaseModels/WorkflowVariable.js +5 -1
  191. package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
  192. package/build/dist/Server/API/AlertAPI.js +22 -13
  193. package/build/dist/Server/API/AlertAPI.js.map +1 -1
  194. package/build/dist/Server/API/BaseAPI.js +22 -1
  195. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  196. package/build/dist/Server/API/BaseAnalyticsAPI.js +24 -1
  197. package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
  198. package/build/dist/Server/API/CommonAPI.js +42 -0
  199. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  200. package/build/dist/Server/API/IncidentAPI.js +43 -26
  201. package/build/dist/Server/API/IncidentAPI.js.map +1 -1
  202. package/build/dist/Server/API/IncidentEpisodeAPI.js +21 -12
  203. package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
  204. package/build/dist/Server/API/MonitorAPI.js +23 -0
  205. package/build/dist/Server/API/MonitorAPI.js.map +1 -1
  206. package/build/dist/Server/API/MonitorTemplateAPI.js +4 -0
  207. package/build/dist/Server/API/MonitorTemplateAPI.js.map +1 -1
  208. package/build/dist/Server/API/ProbeAPI.js +131 -15
  209. package/build/dist/Server/API/ProbeAPI.js.map +1 -1
  210. package/build/dist/Server/API/ProjectAPI.js +62 -3
  211. package/build/dist/Server/API/ProjectAPI.js.map +1 -1
  212. package/build/dist/Server/API/ScheduledMaintenanceAPI.js +23 -14
  213. package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
  214. package/build/dist/Server/API/StatusPageAPI.js +61 -33
  215. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  216. package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js +26 -2
  217. package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js.map +1 -1
  218. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js +397 -0
  219. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js.map +1 -0
  220. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js +16 -0
  221. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js.map +1 -0
  222. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js +30 -0
  223. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js.map +1 -0
  224. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js +34 -0
  225. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js.map +1 -0
  226. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +8 -0
  227. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  228. package/build/dist/Server/Services/AlertEpisodeService.js +39 -0
  229. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
  230. package/build/dist/Server/Services/AlertService.js +95 -0
  231. package/build/dist/Server/Services/AlertService.js.map +1 -1
  232. package/build/dist/Server/Services/BillingService.js +71 -0
  233. package/build/dist/Server/Services/BillingService.js.map +1 -1
  234. package/build/dist/Server/Services/DatabaseService.js +140 -17
  235. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  236. package/build/dist/Server/Services/IncidentEpisodeService.js +39 -0
  237. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  238. package/build/dist/Server/Services/IncidentService.js +100 -0
  239. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  240. package/build/dist/Server/Services/IncidentTemplateService.js +97 -0
  241. package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
  242. package/build/dist/Server/Services/Index.js +2 -0
  243. package/build/dist/Server/Services/Index.js.map +1 -1
  244. package/build/dist/Server/Services/LogDropFilterService.js +93 -0
  245. package/build/dist/Server/Services/LogDropFilterService.js.map +1 -1
  246. package/build/dist/Server/Services/MonitorProbeService.js +73 -5
  247. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  248. package/build/dist/Server/Services/MonitorService.js +34 -39
  249. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  250. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +71 -0
  251. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
  252. package/build/dist/Server/Services/ProbeService.js +64 -0
  253. package/build/dist/Server/Services/ProbeService.js.map +1 -1
  254. package/build/dist/Server/Services/ProjectService.js +103 -7
  255. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  256. package/build/dist/Server/Services/RecommendationDismissalService.js +50 -0
  257. package/build/dist/Server/Services/RecommendationDismissalService.js.map +1 -0
  258. package/build/dist/Server/Services/RunbookAgentJobService.js +63 -5
  259. package/build/dist/Server/Services/RunbookAgentJobService.js.map +1 -1
  260. package/build/dist/Server/Services/ScheduledMaintenanceService.js +83 -0
  261. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  262. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +65 -0
  263. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
  264. package/build/dist/Server/Services/StatusPageGroupService.js +136 -0
  265. package/build/dist/Server/Services/StatusPageGroupService.js.map +1 -1
  266. package/build/dist/Server/Services/TraceDropFilterService.js +93 -0
  267. package/build/dist/Server/Services/TraceDropFilterService.js.map +1 -1
  268. package/build/dist/Server/Types/Workflow/Components/API/Delete.js +11 -0
  269. package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
  270. package/build/dist/Server/Types/Workflow/Components/API/Get.js +11 -0
  271. package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
  272. package/build/dist/Server/Types/Workflow/Components/API/Patch.js +11 -0
  273. package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
  274. package/build/dist/Server/Types/Workflow/Components/API/Post.js +11 -0
  275. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  276. package/build/dist/Server/Types/Workflow/Components/API/Put.js +12 -0
  277. package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
  278. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +132 -0
  279. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -0
  280. package/build/dist/Server/Utils/DropFilterValidation.js +80 -0
  281. package/build/dist/Server/Utils/DropFilterValidation.js.map +1 -0
  282. package/build/dist/Server/Utils/Errors.js +3 -0
  283. package/build/dist/Server/Utils/Errors.js.map +1 -1
  284. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +30 -12
  285. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  286. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +38 -18
  287. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  288. package/build/dist/Server/Utils/Telemetry/AppMetrics.js +26 -0
  289. package/build/dist/Server/Utils/Telemetry/AppMetrics.js.map +1 -1
  290. package/build/dist/Types/Date.js +14 -4
  291. package/build/dist/Types/Date.js.map +1 -1
  292. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +192 -0
  293. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  294. package/build/dist/Types/Monitor/MonitorStep.js +6 -1
  295. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  296. package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js +32 -1
  297. package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js.map +1 -1
  298. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +294 -0
  299. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -0
  300. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +110 -0
  301. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -0
  302. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +58 -0
  303. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -0
  304. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +451 -0
  305. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -0
  306. package/build/dist/Types/Permission.js +40 -0
  307. package/build/dist/Types/Permission.js.map +1 -1
  308. package/build/dist/Types/Recommendation/RecommendationType.js +21 -0
  309. package/build/dist/Types/Recommendation/RecommendationType.js.map +1 -0
  310. package/build/dist/Types/Runbook/RunbookExecutionDeadline.js +93 -0
  311. package/build/dist/Types/Runbook/RunbookExecutionDeadline.js.map +1 -0
  312. package/build/dist/Types/Runbook/RunbookStepTimeout.js +142 -0
  313. package/build/dist/Types/Runbook/RunbookStepTimeout.js.map +1 -0
  314. package/build/dist/Types/Telemetry/DropFilterSampling.js +75 -0
  315. package/build/dist/Types/Telemetry/DropFilterSampling.js.map +1 -0
  316. package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -2
  317. package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
  318. package/build/dist/UI/Components/Accordion/Accordion.js +9 -2
  319. package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
  320. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +1 -1
  321. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
  322. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +27 -14
  323. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  324. package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js +1 -1
  325. package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js.map +1 -1
  326. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +2 -20
  327. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  328. package/build/dist/UI/Components/Error/PageError.js +1 -3
  329. package/build/dist/UI/Components/Error/PageError.js.map +1 -1
  330. package/build/dist/UI/Components/ErrorBoundary.js +145 -11
  331. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  332. package/build/dist/UI/Components/InfoCard/InfoCard.js +28 -1
  333. package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
  334. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +13 -2
  335. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  336. package/build/dist/UI/Components/Modal/Modal.js +4 -32
  337. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  338. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  339. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +69 -33
  340. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  341. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +73 -32
  342. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -1
  343. package/build/dist/UI/Components/Runbook/StepTimeoutInput.js +101 -0
  344. package/build/dist/UI/Components/Runbook/StepTimeoutInput.js.map +1 -0
  345. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +73 -0
  346. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -0
  347. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +13 -2
  348. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  349. package/build/dist/UI/Utils/DropdownAlignment.js +98 -0
  350. package/build/dist/UI/Utils/DropdownAlignment.js.map +1 -0
  351. package/build/dist/UI/Utils/TableFilterUrlState.js +48 -15
  352. package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
  353. package/build/dist/Utils/API.js +39 -2
  354. package/build/dist/Utils/API.js.map +1 -1
  355. package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js +97 -0
  356. package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js.map +1 -0
  357. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +330 -0
  358. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -0
  359. package/build/dist/Utils/StatusPage/GroupNestingLayout.js +280 -0
  360. package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -0
  361. package/build/dist/Utils/StatusPage/GroupTree.js +214 -0
  362. package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -0
  363. package/build/dist/Utils/StatusPage/ResourceUptime.js +60 -16
  364. package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
  365. package/package.json +1 -1
@@ -665,6 +665,66 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
665
665
  const [error, setError] = useState<string>("");
666
666
  const [tableFilterError, setTableFilterError] = useState<string>("");
667
667
 
668
+ /*
669
+ * Auto-detect label support from the existing filters array. We look for
670
+ * the filter whose `filterEntityType` class name is "Label" and reuse its
671
+ * dropdown wiring (entity type, fetch query, label/value field names) so
672
+ * search inherits whatever scoping the filter popup already had.
673
+ *
674
+ * Computed before the search state below because the `labels` slice of a
675
+ * restored URL is only meaningful when this is non-null.
676
+ */
677
+ type LabelFilterConfig = {
678
+ fieldKey: string;
679
+ entityType: any;
680
+ fetchQuery: any;
681
+ labelField: string;
682
+ };
683
+
684
+ const labelFilterConfig: LabelFilterConfig | null = useMemo(() => {
685
+ const filter: Filter<TBaseModel> | undefined = props.filters.find(
686
+ (f: Filter<TBaseModel>) => {
687
+ return (
688
+ f.filterEntityType &&
689
+ (f.filterEntityType as any).name === "Label" &&
690
+ f.field &&
691
+ f.filterDropdownField
692
+ );
693
+ },
694
+ );
695
+ if (!filter || !filter.field || !filter.filterDropdownField) {
696
+ return null;
697
+ }
698
+ const fieldKey: string | undefined = Object.keys(filter.field)[0];
699
+ if (!fieldKey) {
700
+ return null;
701
+ }
702
+ return {
703
+ fieldKey,
704
+ entityType: filter.filterEntityType,
705
+ fetchQuery: filter.filterQuery || {},
706
+ labelField: filter.filterDropdownField.label,
707
+ };
708
+ }, [props.filters]);
709
+
710
+ /*
711
+ * The label chips are a feature of the in-search Label filter, so a table
712
+ * without one has to ignore the URL's `labels` slice entirely.
713
+ *
714
+ * Tables that have since moved Labels out to a facet chip (Monitors,
715
+ * Network Devices) still receive `labels` from older shared/bookmarked
716
+ * links. Seeding those ids anyway produced a chip the table could neither
717
+ * name (`availableLabels` is only fetched when there *is* a config) nor
718
+ * apply (`buildSearchQueryFragment` skips the constraint for the same
719
+ * reason): a force-expanded search box with a raw-UUID pill sitting above a
720
+ * completely unfiltered list, re-persisted on every write until the user
721
+ * clicked its ×. Dropping it here also means the next view write omits the
722
+ * key, so the URL heals itself.
723
+ */
724
+ const restoredLabelIds: Array<string> = labelFilterConfig
725
+ ? initialUrlState.view.labels || []
726
+ : [];
727
+
668
728
  const [searchText, setSearchText] = useState<string>(
669
729
  initialUrlState.view.search || "",
670
730
  );
@@ -673,9 +733,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
673
733
  );
674
734
  const [isSearchFocused, setIsSearchFocused] = useState<boolean>(false);
675
735
  const [isSearchExpanded, setIsSearchExpanded] = useState<boolean>(
676
- Boolean(
677
- initialUrlState.view.search || (initialUrlState.view.labels || []).length,
678
- ),
736
+ Boolean(initialUrlState.view.search || restoredLabelIds.length),
679
737
  );
680
738
  const searchInputRef: React.RefObject<HTMLInputElement> =
681
739
  React.useRef<HTMLInputElement>(null!);
@@ -697,7 +755,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
697
755
  const [selectedLabels, setSelectedLabels] = useState<
698
756
  Array<SearchLabelOption>
699
757
  >(() => {
700
- return (initialUrlState.view.labels || []).map((id: string) => {
758
+ return restoredLabelIds.map((id: string) => {
701
759
  return { id: id, name: id, color: "#94a3b8" };
702
760
  });
703
761
  });
@@ -793,43 +851,24 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
793
851
  }, [debouncedSearchText, selectedLabelIdsKey]);
794
852
 
795
853
  /*
796
- * Auto-detect label support from the existing filters array. We look for
797
- * the filter whose `filterEntityType` class name is "Label" and reuse its
798
- * dropdown wiring (entity type, fetch query, label/value field names) so
799
- * search inherits whatever scoping the filter popup already had.
854
+ * `props.filters` is not frozen a page can rebuild it after mount, and
855
+ * that is exactly how a Labels filter leaves the popup for the facet bar.
856
+ * Chips left over from a config that no longer exists are unnameable and
857
+ * unappliable, so drop them here too rather than only at mount.
800
858
  */
801
- type LabelFilterConfig = {
802
- fieldKey: string;
803
- entityType: any;
804
- fetchQuery: any;
805
- labelField: string;
806
- };
807
-
808
- const labelFilterConfig: LabelFilterConfig | null = useMemo(() => {
809
- const filter: Filter<TBaseModel> | undefined = props.filters.find(
810
- (f: Filter<TBaseModel>) => {
811
- return (
812
- f.filterEntityType &&
813
- (f.filterEntityType as any).name === "Label" &&
814
- f.field &&
815
- f.filterDropdownField
816
- );
817
- },
818
- );
819
- if (!filter || !filter.field || !filter.filterDropdownField) {
820
- return null;
821
- }
822
- const fieldKey: string | undefined = Object.keys(filter.field)[0];
823
- if (!fieldKey) {
824
- return null;
859
+ useEffect(() => {
860
+ if (labelFilterConfig) {
861
+ return;
825
862
  }
826
- return {
827
- fieldKey,
828
- entityType: filter.filterEntityType,
829
- fetchQuery: filter.filterQuery || {},
830
- labelField: filter.filterDropdownField.label,
831
- };
832
- }, [props.filters]);
863
+
864
+ setSelectedLabels((existing: Array<SearchLabelOption>) => {
865
+ /*
866
+ * Same array when there is nothing to clear, so this costs an idle table
867
+ * no re-render.
868
+ */
869
+ return existing.length === 0 ? existing : [];
870
+ });
871
+ }, [labelFilterConfig]);
833
872
 
834
873
  // Fetch labels on first search expansion if this resource supports them.
835
874
  useEffect(() => {
@@ -3263,36 +3302,46 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
3263
3302
  />
3264
3303
  {/* Pills + input wrap row */}
3265
3304
  <div className="flex min-w-0 flex-1 flex-wrap items-center gap-1.5">
3266
- {selectedLabels.map((label: SearchLabelOption) => {
3267
- return (
3268
- <span
3269
- key={label.id}
3270
- className="inline-flex items-center gap-1 rounded-full bg-gray-50 py-0.5 pl-2 pr-1 text-xs font-medium text-gray-700 ring-1 ring-inset ring-gray-200 transition-all hover:bg-gray-100"
3271
- title={`Label: ${label.name}`}
3272
- >
3305
+ {/*
3306
+ * Gated on label support as well as on the chips themselves: a
3307
+ * pill this table cannot name, apply or refill is never worth
3308
+ * drawing, whatever left it in state.
3309
+ */}
3310
+ {hasLabelSupport &&
3311
+ selectedLabels.map((label: SearchLabelOption) => {
3312
+ return (
3273
3313
  <span
3274
- className="h-2 w-2 flex-none rounded-full"
3275
- style={{ backgroundColor: label.color }}
3276
- aria-hidden="true"
3277
- />
3278
- <span className="max-w-[8rem] truncate">{label.name}</span>
3279
- <button
3280
- type="button"
3281
- onMouseDown={(e: React.MouseEvent<HTMLButtonElement>) => {
3282
- e.preventDefault();
3283
- }}
3284
- onClick={() => {
3285
- removeLabel(label.id);
3286
- }}
3287
- title="Remove label"
3288
- aria-label={`Remove ${label.name}`}
3289
- className="ml-0.5 flex-none rounded-full p-0.5 text-gray-400 transition-colors hover:bg-gray-200 hover:text-gray-700"
3314
+ key={label.id}
3315
+ className="inline-flex items-center gap-1 rounded-full bg-gray-50 py-0.5 pl-2 pr-1 text-xs font-medium text-gray-700 ring-1 ring-inset ring-gray-200 transition-all hover:bg-gray-100"
3316
+ title={`Label: ${label.name}`}
3290
3317
  >
3291
- <Icon icon={IconProp.Close} className="h-3 w-3" />
3292
- </button>
3293
- </span>
3294
- );
3295
- })}
3318
+ <span
3319
+ className="h-2 w-2 flex-none rounded-full"
3320
+ style={{ backgroundColor: label.color }}
3321
+ aria-hidden="true"
3322
+ />
3323
+ <span className="max-w-[8rem] truncate">
3324
+ {label.name}
3325
+ </span>
3326
+ <button
3327
+ type="button"
3328
+ onMouseDown={(
3329
+ e: React.MouseEvent<HTMLButtonElement>,
3330
+ ) => {
3331
+ e.preventDefault();
3332
+ }}
3333
+ onClick={() => {
3334
+ removeLabel(label.id);
3335
+ }}
3336
+ title="Remove label"
3337
+ aria-label={`Remove ${label.name}`}
3338
+ className="ml-0.5 flex-none rounded-full p-0.5 text-gray-400 transition-colors hover:bg-gray-200 hover:text-gray-700"
3339
+ >
3340
+ <Icon icon={IconProp.Close} className="h-3 w-3" />
3341
+ </button>
3342
+ </span>
3343
+ );
3344
+ })}
3296
3345
  <input
3297
3346
  ref={searchInputRef}
3298
3347
  type="text"
@@ -12,6 +12,7 @@ import {
12
12
  DragDropContext,
13
13
  Draggable,
14
14
  DraggableProvided,
15
+ DraggableStateSnapshot,
15
16
  Droppable,
16
17
  DroppableProvided,
17
18
  DropResult,
@@ -88,6 +89,14 @@ const ColumnCustomizationModal: ColumnCustomizationModalFunction = <
88
89
  });
89
90
  }, [entries, normalizedSearch, isSearching]);
90
91
 
92
+ /*
93
+ * Both bulk actions are switched off when they have nothing left to do -
94
+ * "Show all" with everything already on is a no-op, and "Hide all" cannot go
95
+ * below the one column that has to stay.
96
+ */
97
+ const isEverythingVisible: boolean = visibleCount === entries.length;
98
+ const isOnlyOneVisible: boolean = visibleCount <= 1;
99
+
91
100
  type ToggleFunction = (id: string, isVisible: boolean) => void;
92
101
 
93
102
  const toggleColumn: ToggleFunction = (
@@ -183,6 +192,37 @@ const ColumnCustomizationModal: ColumnCustomizationModalFunction = <
183
192
  });
184
193
  };
185
194
 
195
+ type GetBulkActionFunction = (data: {
196
+ title: string;
197
+ dataTestId: string;
198
+ disabled: boolean;
199
+ onClick: () => void;
200
+ }) => ReactElement;
201
+
202
+ /*
203
+ * Rendered as plain buttons rather than through <Button>: these sit inside
204
+ * the body as a compact pair, and the shared button styles are sized for a
205
+ * footer.
206
+ */
207
+ const getBulkAction: GetBulkActionFunction = (data: {
208
+ title: string;
209
+ dataTestId: string;
210
+ disabled: boolean;
211
+ onClick: () => void;
212
+ }): ReactElement => {
213
+ return (
214
+ <button
215
+ type="button"
216
+ data-testid={data.dataTestId}
217
+ disabled={data.disabled}
218
+ onClick={data.onClick}
219
+ className="rounded-md px-2 py-1 text-xs font-medium text-gray-600 transition-colors hover:bg-white hover:text-gray-900 hover:shadow-sm focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 disabled:cursor-not-allowed disabled:text-gray-300 disabled:hover:bg-transparent disabled:hover:shadow-none"
220
+ >
221
+ {data.title}
222
+ </button>
223
+ );
224
+ };
225
+
186
226
  type GetRowFunction = (data: {
187
227
  entry: CustomizableColumn<TBaseModel>;
188
228
  index: number;
@@ -199,27 +239,50 @@ const ColumnCustomizationModal: ColumnCustomizationModalFunction = <
199
239
  const isOnlyVisibleColumn: boolean = entry.isVisible && visibleCount <= 1;
200
240
 
201
241
  return (
202
- <div className="flex items-center gap-3 px-3 py-2">
203
- {data.dragHandle || <div className="w-4" />}
242
+ <div className="group flex items-center gap-2 px-3 py-2 transition-colors hover:bg-gray-50">
243
+ {data.dragHandle || <div className="w-5 flex-none" />}
204
244
 
205
- <div className="flex-1 min-w-0">
245
+ <div className="min-w-0 flex-1">
206
246
  <CheckboxElement
207
247
  value={entry.isVisible}
208
248
  disabled={isOnlyVisibleColumn}
209
249
  dataTestId={`column-toggle-${entry.id}`}
210
- title={entry.column.title}
250
+ outerDivClassName="relative flex items-center"
251
+ title={
252
+ <span
253
+ className={
254
+ entry.isVisible
255
+ ? "text-sm font-medium text-gray-900"
256
+ : "text-sm font-normal text-gray-400"
257
+ }
258
+ >
259
+ {entry.column.title}
260
+ </span>
261
+ }
211
262
  onChange={(value: boolean) => {
212
263
  toggleColumn(entry.id, value);
213
264
  }}
214
265
  />
215
266
  </div>
216
267
 
217
- <div className="flex flex-none items-center gap-1">
268
+ {isOnlyVisibleColumn && (
269
+ <span
270
+ className="flex-none rounded-full bg-gray-100 px-2 py-0.5 text-[11px] font-medium text-gray-500"
271
+ data-testid={`column-locked-${entry.id}`}
272
+ >
273
+ Required
274
+ </span>
275
+ )}
276
+
277
+ <div className="flex flex-none items-center gap-0.5">
218
278
  <Button
219
279
  buttonSize={ButtonSize.Small}
220
280
  buttonStyle={ButtonStyleType.ICON}
221
281
  icon={IconProp.ChevronUp}
222
282
  title=""
283
+ tooltip="Move up"
284
+ ariaLabel={`Move ${entry.column.title} up`}
285
+ className="text-gray-400 hover:bg-gray-200 hover:text-gray-700 disabled:text-gray-200 disabled:hover:bg-transparent"
223
286
  dataTestId={`column-move-up-${entry.id}`}
224
287
  disabled={isSearching || index === 0}
225
288
  onClick={() => {
@@ -231,6 +294,9 @@ const ColumnCustomizationModal: ColumnCustomizationModalFunction = <
231
294
  buttonStyle={ButtonStyleType.ICON}
232
295
  icon={IconProp.ChevronDown}
233
296
  title=""
297
+ tooltip="Move down"
298
+ ariaLabel={`Move ${entry.column.title} down`}
299
+ className="text-gray-400 hover:bg-gray-200 hover:text-gray-700 disabled:text-gray-200 disabled:hover:bg-transparent"
234
300
  dataTestId={`column-move-down-${entry.id}`}
235
301
  disabled={isSearching || index === entries.length - 1}
236
302
  onClick={() => {
@@ -248,10 +314,13 @@ const ColumnCustomizationModal: ColumnCustomizationModalFunction = <
248
314
  if (shownEntries.length === 0) {
249
315
  return (
250
316
  <div
251
- className="px-3 py-6 text-center text-sm text-gray-400"
317
+ className="flex flex-col items-center gap-2 px-3 py-10 text-center"
252
318
  data-testid="column-customization-no-results"
253
319
  >
254
- No columns match &quot;{searchText}&quot;.
320
+ <Icon icon={IconProp.Search} className="h-6 w-6 text-gray-300" />
321
+ <p className="text-sm text-gray-500">
322
+ No columns match &quot;{searchText}&quot;.
323
+ </p>
255
324
  </div>
256
325
  );
257
326
  }
@@ -287,6 +356,7 @@ const ColumnCustomizationModal: ColumnCustomizationModalFunction = <
287
356
  ref={droppableProvided.innerRef}
288
357
  {...droppableProvided.droppableProps}
289
358
  className="divide-y divide-gray-100"
359
+ aria-label="Columns"
290
360
  >
291
361
  {shownEntries.map(
292
362
  (entry: CustomizableColumn<TBaseModel>, index: number) => {
@@ -296,12 +366,19 @@ const ColumnCustomizationModal: ColumnCustomizationModalFunction = <
296
366
  index={index}
297
367
  key={entry.id}
298
368
  >
299
- {(draggableProvided: DraggableProvided) => {
369
+ {(
370
+ draggableProvided: DraggableProvided,
371
+ draggableSnapshot: DraggableStateSnapshot,
372
+ ) => {
300
373
  return (
301
374
  <div
302
375
  ref={draggableProvided.innerRef}
303
376
  {...draggableProvided.draggableProps}
304
- className="bg-white"
377
+ className={
378
+ draggableSnapshot.isDragging
379
+ ? "rounded-md bg-white shadow-lg ring-1 ring-gray-200"
380
+ : "bg-white"
381
+ }
305
382
  >
306
383
  {getRowContents({
307
384
  entry,
@@ -309,7 +386,7 @@ const ColumnCustomizationModal: ColumnCustomizationModalFunction = <
309
386
  dragHandle: (
310
387
  <div
311
388
  {...draggableProvided.dragHandleProps}
312
- className="flex-none cursor-grab text-gray-400 hover:text-gray-600 active:cursor-grabbing"
389
+ className="flex w-5 flex-none cursor-grab justify-center text-gray-300 transition-colors group-hover:text-gray-500 active:cursor-grabbing"
313
390
  aria-label={`Drag to reorder ${entry.column.title}`}
314
391
  title="Drag to reorder"
315
392
  >
@@ -344,7 +421,6 @@ const ColumnCustomizationModal: ColumnCustomizationModalFunction = <
344
421
  "Choose which columns to show and drag them into the order you want."
345
422
  }
346
423
  modalWidth={ModalWidth.Medium}
347
- icon={IconProp.TableCells}
348
424
  submitButtonText="Save"
349
425
  closeButtonText="Cancel"
350
426
  onClose={props.onClose}
@@ -357,8 +433,9 @@ const ColumnCustomizationModal: ColumnCustomizationModalFunction = <
357
433
  ) : (
358
434
  <Button
359
435
  title="Reset to default"
436
+ icon={IconProp.Refresh}
360
437
  buttonSize={ButtonSize.Normal}
361
- buttonStyle={ButtonStyleType.OUTLINE}
438
+ buttonStyle={ButtonStyleType.NORMAL}
362
439
  dataTestId="column-customization-reset"
363
440
  onClick={() => {
364
441
  props.onReset();
@@ -368,50 +445,76 @@ const ColumnCustomizationModal: ColumnCustomizationModalFunction = <
368
445
  }
369
446
  >
370
447
  <div className="space-y-3" data-testid="column-customization-modal">
371
- <div className="flex items-center justify-between gap-3">
372
- <div className="flex-1">
373
- <Input
374
- type={InputType.TEXT}
375
- placeholder="Search columns..."
376
- value={searchText}
377
- dataTestId="column-customization-search"
378
- onChange={(value: string) => {
379
- setSearchText(value);
380
- }}
381
- />
448
+ <div className="relative">
449
+ <div className="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
450
+ <Icon icon={IconProp.Search} className="h-4 w-4 text-gray-400" />
382
451
  </div>
383
- <div className="flex flex-none gap-2">
384
- <Button
385
- title="Show all"
386
- buttonSize={ButtonSize.Small}
387
- buttonStyle={ButtonStyleType.OUTLINE}
388
- dataTestId="column-customization-show-all"
389
- onClick={() => {
390
- setAllVisible(true);
391
- }}
392
- />
393
- <Button
394
- title="Hide all"
395
- buttonSize={ButtonSize.Small}
396
- buttonStyle={ButtonStyleType.OUTLINE}
397
- dataTestId="column-customization-hide-all"
452
+ <Input
453
+ type={InputType.TEXT}
454
+ placeholder="Search columns..."
455
+ value={searchText}
456
+ dataTestId="column-customization-search"
457
+ outerDivClassName="w-full"
458
+ className="block w-full rounded-md border border-gray-300 bg-white py-2 pl-9 pr-9 text-sm placeholder-gray-400 focus:border-indigo-500 focus:outline-none focus:ring-1 focus:ring-indigo-500"
459
+ onChange={(value: string) => {
460
+ setSearchText(value);
461
+ }}
462
+ />
463
+ {searchText.length > 0 && (
464
+ <button
465
+ type="button"
466
+ aria-label="Clear search"
467
+ title="Clear search"
468
+ data-testid="column-customization-search-clear"
398
469
  onClick={() => {
399
- setAllVisible(false);
470
+ setSearchText("");
400
471
  }}
401
- />
402
- </div>
472
+ className="absolute inset-y-0 right-0 flex items-center pr-3 text-gray-400 transition-colors hover:text-gray-600 focus:outline-none focus-visible:text-gray-600"
473
+ >
474
+ <Icon icon={IconProp.Close} className="h-4 w-4" />
475
+ </button>
476
+ )}
403
477
  </div>
404
478
 
405
- <div
406
- className="text-xs text-gray-500"
407
- data-testid="column-customization-count"
408
- >
409
- {visibleCount} of {entries.length} columns shown
479
+ <div className="flex items-center justify-between gap-3">
480
+ <div
481
+ className="text-xs font-medium text-gray-500"
482
+ data-testid="column-customization-count"
483
+ >
484
+ {visibleCount} of {entries.length} columns shown
485
+ </div>
486
+ <div className="flex flex-none items-center gap-1 rounded-md bg-gray-50 p-0.5 ring-1 ring-inset ring-gray-200">
487
+ {getBulkAction({
488
+ title: "Show all",
489
+ dataTestId: "column-customization-show-all",
490
+ disabled: isEverythingVisible,
491
+ onClick: () => {
492
+ setAllVisible(true);
493
+ },
494
+ })}
495
+ {getBulkAction({
496
+ title: "Hide all",
497
+ dataTestId: "column-customization-hide-all",
498
+ disabled: isOnlyOneVisible,
499
+ onClick: () => {
500
+ setAllVisible(false);
501
+ },
502
+ })}
503
+ </div>
410
504
  </div>
411
505
 
412
- <div className="rounded-md border border-gray-200 overflow-hidden">
506
+ <div className="max-h-80 overflow-y-auto overscroll-contain rounded-md border border-gray-200 bg-white">
413
507
  {getList()}
414
508
  </div>
509
+
510
+ <p
511
+ className="text-xs text-gray-400"
512
+ data-testid="column-customization-hint"
513
+ >
514
+ {isSearching
515
+ ? "Clear the search to reorder columns."
516
+ : "Drag a row, or use the arrows, to change the column order."}
517
+ </p>
415
518
  </div>
416
519
  </Modal>
417
520
  );