@oneuptime/common 11.7.2 → 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 (414) hide show
  1. package/Models/AnalyticsModels/KubernetesCostAllocation.ts +103 -0
  2. package/Models/DatabaseModels/AlertEpisodeStateTimeline.ts +1 -0
  3. package/Models/DatabaseModels/AlertStateTimeline.ts +1 -0
  4. package/Models/DatabaseModels/IncidentEpisodeStateTimeline.ts +1 -0
  5. package/Models/DatabaseModels/IncidentStateTimeline.ts +1 -0
  6. package/Models/DatabaseModels/Index.ts +5 -0
  7. package/Models/DatabaseModels/LogDropFilter.ts +89 -0
  8. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +13 -3
  9. package/Models/DatabaseModels/RecommendationDismissal.ts +463 -0
  10. package/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.ts +1 -0
  11. package/Models/DatabaseModels/StatusPageGroup.ts +95 -0
  12. package/Models/DatabaseModels/TableView.ts +40 -0
  13. package/Models/DatabaseModels/TraceDropFilter.ts +89 -0
  14. package/Models/DatabaseModels/WorkflowVariable.ts +5 -1
  15. package/Server/API/AlertAPI.ts +32 -17
  16. package/Server/API/BaseAPI.ts +31 -2
  17. package/Server/API/BaseAnalyticsAPI.ts +36 -2
  18. package/Server/API/CommonAPI.ts +57 -0
  19. package/Server/API/IncidentAPI.ts +60 -33
  20. package/Server/API/IncidentEpisodeAPI.ts +31 -16
  21. package/Server/API/MonitorAPI.ts +30 -0
  22. package/Server/API/MonitorTemplateAPI.ts +8 -0
  23. package/Server/API/ProbeAPI.ts +196 -15
  24. package/Server/API/ProjectAPI.ts +79 -1
  25. package/Server/API/ScheduledMaintenanceAPI.ts +33 -18
  26. package/Server/API/StatusPageAPI.ts +74 -37
  27. package/Server/API/WorkspaceNotificationRuleAPI.ts +34 -4
  28. package/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.ts +13 -0
  29. package/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.ts +527 -0
  30. package/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.ts +31 -0
  31. package/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.ts +55 -0
  32. package/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.ts +53 -0
  33. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  34. package/Server/Services/AlertEpisodeService.ts +47 -0
  35. package/Server/Services/AlertService.ts +125 -0
  36. package/Server/Services/BillingService.ts +98 -0
  37. package/Server/Services/DatabaseService.ts +184 -20
  38. package/Server/Services/IncidentEpisodeService.ts +47 -0
  39. package/Server/Services/IncidentService.ts +123 -0
  40. package/Server/Services/IncidentTemplateService.ts +123 -1
  41. package/Server/Services/Index.ts +2 -0
  42. package/Server/Services/LogDropFilterService.ts +133 -0
  43. package/Server/Services/MonitorProbeService.ts +94 -4
  44. package/Server/Services/MonitorService.ts +48 -43
  45. package/Server/Services/NetworkDeviceDiscoveryScanService.ts +70 -0
  46. package/Server/Services/ProbeService.ts +66 -0
  47. package/Server/Services/ProjectService.ts +131 -7
  48. package/Server/Services/RecommendationDismissalService.ts +52 -0
  49. package/Server/Services/RunbookAgentJobService.ts +68 -7
  50. package/Server/Services/ScheduledMaintenanceService.ts +103 -0
  51. package/Server/Services/ScheduledMaintenanceTemplateService.ts +90 -0
  52. package/Server/Services/StatusPageGroupService.ts +186 -0
  53. package/Server/Services/TraceDropFilterService.ts +133 -0
  54. package/Server/Types/Workflow/Components/API/Delete.ts +12 -0
  55. package/Server/Types/Workflow/Components/API/Get.ts +12 -0
  56. package/Server/Types/Workflow/Components/API/Patch.ts +12 -0
  57. package/Server/Types/Workflow/Components/API/Post.ts +12 -0
  58. package/Server/Types/Workflow/Components/API/Put.ts +13 -0
  59. package/Server/Utils/Database/ProjectScopedReferenceValidator.ts +212 -0
  60. package/Server/Utils/DropFilterValidation.ts +127 -0
  61. package/Server/Utils/Errors.ts +5 -0
  62. package/Server/Utils/Monitor/MonitorAlert.ts +28 -1
  63. package/Server/Utils/Monitor/MonitorIncident.ts +31 -2
  64. package/Server/Utils/Telemetry/AppMetrics.ts +31 -0
  65. package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +16 -0
  66. package/Tests/Models/DatabaseModels/MonitorProbeColumnAccessControl.test.ts +196 -0
  67. package/Tests/Models/RecommendationDismissalModel.test.ts +269 -0
  68. package/Tests/Server/API/BaseAPIUpdatePayloadValidation.test.ts +320 -0
  69. package/Tests/Server/API/BaseAnalyticsAPIUpdatePayloadValidation.test.ts +293 -0
  70. package/Tests/Server/API/CommonAPIAuthGuard.test.ts +164 -0
  71. package/Tests/Server/API/ProbeAPI.test.ts +422 -53
  72. package/Tests/Server/API/ProjectAPI.test.ts +180 -0
  73. package/Tests/Server/API/ProjectAPIExtendTrialBillingDisabled.test.ts +138 -0
  74. package/Tests/Server/API/ProjectScopedCustomRouteAuth.test.ts +458 -0
  75. package/Tests/Server/Infrastructure/ContainerBootConfiguration.test.ts +359 -0
  76. package/Tests/Server/Infrastructure/ProcessSignalDelivery.test.ts +427 -0
  77. package/Tests/Server/Services/BillingServiceExtendTrial.test.ts +439 -0
  78. package/Tests/Server/Services/CrossProjectReferenceWriteGuard.test.ts +810 -0
  79. package/Tests/Server/Services/DatabaseServiceAtomicAddToColumns.test.ts +269 -0
  80. package/Tests/Server/Services/DatabaseServiceEmptyUpdate.test.ts +277 -0
  81. package/Tests/Server/Services/DatabaseServiceSortColumnSelect.test.ts +201 -0
  82. package/Tests/Server/Services/DiscoveryScanClaimHookFreeSafety.test.ts +81 -23
  83. package/Tests/Server/Services/DropFilterSaveValidation.test.ts +398 -0
  84. package/Tests/Server/Services/MonitorProbeDeleteHooks.test.ts +280 -0
  85. package/Tests/Server/Services/MonitorProbeServiceProbeTenancy.test.ts +304 -0
  86. package/Tests/Server/Services/NetworkDeviceDiscoveryScanService.test.ts +262 -0
  87. package/Tests/Server/Services/ProjectServiceExtendTrial.test.ts +614 -0
  88. package/Tests/Server/Services/RecommendationDismissalService.test.ts +306 -0
  89. package/Tests/Server/Services/RepairCrossProjectIncidentReferencesMigration.test.ts +528 -0
  90. package/Tests/Server/Services/StatusPageGroupNesting.test.ts +395 -0
  91. package/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +26 -21
  92. package/Tests/Server/Types/Database/Permissions/WorkflowVariableColumnPermission.test.ts +227 -0
  93. package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +285 -0
  94. package/Tests/Server/Utils/Database/ProjectScopedReferenceValidator.test.ts +463 -0
  95. package/Tests/Server/Utils/DropFilterValidation.test.ts +269 -0
  96. package/Tests/Server/Utils/Telemetry/SpanUtil.test.ts +94 -0
  97. package/Tests/Types/DateUserTimezone.test.ts +52 -0
  98. package/Tests/Types/JSONFunctions.test.ts +103 -1
  99. package/Tests/Types/Monitor/KubernetesAlertTemplates.test.ts +177 -9
  100. package/Tests/Types/Monitor/MonitorStepDnsMonitor.test.ts +105 -0
  101. package/Tests/Types/Monitor/MonitorStepDnssecMonitor.test.ts +131 -0
  102. package/Tests/Types/Monitor/MonitorStepDomainMonitor.test.ts +60 -0
  103. package/Tests/Types/Monitor/MonitorStepExternalStatusPageMonitor.test.ts +82 -0
  104. package/Tests/Types/Monitor/MonitorStepInfrastructureMonitors.test.ts +268 -0
  105. package/Tests/Types/Monitor/MonitorStepMetricMonitor.test.ts +386 -0
  106. package/Tests/Types/Monitor/MonitorStepProfileMonitor.test.ts +185 -0
  107. package/Tests/Types/Monitor/MonitorStepSnmpMonitor.test.ts +156 -0
  108. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCatalog.test.ts +371 -0
  109. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationCoverage.test.ts +901 -0
  110. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationNotificationMode.test.ts +607 -0
  111. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.test.ts +754 -0
  112. package/Tests/Types/Monitor/Recommendation/MonitorRecommendationUtil.test.ts +960 -0
  113. package/Tests/Types/RollingTime/RollingTimeUtil.test.ts +186 -0
  114. package/Tests/Types/Runbook/RunbookStepTimeout.test.ts +410 -0
  115. package/Tests/Types/Telemetry/DropFilterSampling.test.ts +241 -0
  116. package/Tests/Types/Workspace/NotificationRuleConditionUtil.test.ts +353 -0
  117. package/Tests/Types/Workspace/NotificationRuleUtil.test.ts +566 -0
  118. package/Tests/UI/Components/CodeEditor.test.tsx +174 -0
  119. package/Tests/UI/Components/ErrorBoundary.test.tsx +555 -24
  120. package/Tests/UI/Components/InfoCard.test.tsx +358 -0
  121. package/Tests/UI/Components/LogTimeRangePicker.test.tsx +138 -0
  122. package/Tests/UI/Components/Modal.test.tsx +43 -5
  123. package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +679 -0
  124. package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +397 -0
  125. package/Tests/UI/Components/ModelTable/ColumnCustomizationModal.test.tsx +999 -0
  126. package/Tests/UI/Components/ModelTable/ColumnPreference.test.ts +1678 -0
  127. package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1094 -0
  128. package/Tests/UI/Components/Runbook/StepTimeoutInput.test.tsx +386 -0
  129. package/Tests/UI/Components/StatusPage/ResourceGroupSection.test.tsx +671 -0
  130. package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +404 -0
  131. package/Tests/UI/Utils/DropdownAlignment.test.ts +306 -0
  132. package/Tests/UI/Utils/TableFilterUrlState.test.ts +292 -0
  133. package/Tests/Utils/Monitor/MonitorSummaryProbeUtil.test.ts +263 -0
  134. package/Tests/Utils/NetworkDiscovery/ScanTargetUtil.test.ts +583 -0
  135. package/Tests/Utils/StatusPage/GroupNestingLayout.test.ts +1072 -0
  136. package/Tests/Utils/StatusPage/GroupTree.test.ts +583 -0
  137. package/Tests/Utils/StatusPage/ResourceUptime.test.ts +411 -0
  138. package/Tests/Utils/UserPreferences.test.ts +563 -0
  139. package/Types/Date.ts +15 -6
  140. package/Types/JSONFunctions.ts +7 -2
  141. package/Types/Kubernetes/KubernetesCostIngest.ts +37 -1
  142. package/Types/Monitor/KubernetesAlertTemplates.ts +205 -0
  143. package/Types/Monitor/MonitorStep.ts +10 -1
  144. package/Types/Monitor/MonitorStepMetricMonitor.ts +46 -1
  145. package/Types/Monitor/Recommendation/MonitorRecommendationCatalog.ts +413 -0
  146. package/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.ts +168 -0
  147. package/Types/Monitor/Recommendation/MonitorRecommendationTypes.ts +175 -0
  148. package/Types/Monitor/Recommendation/MonitorRecommendationUtil.ts +743 -0
  149. package/Types/Permission.ts +45 -0
  150. package/Types/Recommendation/RecommendationType.ts +20 -0
  151. package/Types/Runbook/RunbookExecutionDeadline.ts +129 -0
  152. package/Types/Runbook/RunbookStepTimeout.ts +202 -0
  153. package/Types/Telemetry/DropFilterSampling.ts +92 -0
  154. package/UI/Components/AI/GenerateFromAIModal.tsx +0 -2
  155. package/UI/Components/Accordion/Accordion.tsx +10 -2
  156. package/UI/Components/BulkUpdate/BulkLabelActions.tsx +0 -1
  157. package/UI/Components/CodeEditor/CodeEditor.tsx +34 -20
  158. package/UI/Components/Date/RangeStartAndEndDateView.tsx +0 -1
  159. package/UI/Components/EditionLabel/EditionLabel.tsx +1 -27
  160. package/UI/Components/Error/PageError.tsx +0 -4
  161. package/UI/Components/ErrorBoundary.tsx +252 -15
  162. package/UI/Components/InfoCard/InfoCard.tsx +58 -1
  163. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +34 -1
  164. package/UI/Components/MasterPage/MasterPage.tsx +65 -0
  165. package/UI/Components/Modal/Modal.tsx +16 -60
  166. package/UI/Components/ModelFormModal/ModelFormModal.tsx +0 -8
  167. package/UI/Components/ModelTable/BaseModelTable.tsx +503 -71
  168. package/UI/Components/ModelTable/Column.ts +17 -0
  169. package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +523 -0
  170. package/UI/Components/ModelTable/ColumnPreference.ts +482 -0
  171. package/UI/Components/ModelTable/CustomFieldColumns.tsx +326 -0
  172. package/UI/Components/ModelTable/TableView.tsx +24 -2
  173. package/UI/Components/ModelTable/useCustomFieldColumns.ts +150 -0
  174. package/UI/Components/Runbook/StepTimeoutInput.tsx +173 -0
  175. package/UI/Components/SideMenu/SideMenu.tsx +24 -4
  176. package/UI/Components/StatusPage/ResourceGroupSection.tsx +231 -0
  177. package/UI/Components/Table/Table.tsx +14 -1
  178. package/UI/Components/Table/TableRow.tsx +180 -175
  179. package/UI/Components/Table/Types/Column.ts +2 -0
  180. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +34 -1
  181. package/UI/Utils/DropdownAlignment.ts +162 -0
  182. package/UI/Utils/TableFilterUrlState.ts +59 -20
  183. package/Utils/API.ts +106 -2
  184. package/Utils/Monitor/MonitorSummaryProbeUtil.ts +130 -0
  185. package/Utils/NetworkDiscovery/ScanTargetUtil.ts +434 -0
  186. package/Utils/StatusPage/GroupNestingLayout.ts +343 -0
  187. package/Utils/StatusPage/GroupTree.ts +307 -0
  188. package/Utils/StatusPage/ResourceUptime.ts +90 -17
  189. package/Utils/UserPreferences.ts +53 -0
  190. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +86 -0
  191. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -1
  192. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js +1 -0
  193. package/build/dist/Models/DatabaseModels/AlertEpisodeStateTimeline.js.map +1 -1
  194. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js +1 -0
  195. package/build/dist/Models/DatabaseModels/AlertStateTimeline.js.map +1 -1
  196. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js +1 -0
  197. package/build/dist/Models/DatabaseModels/IncidentEpisodeStateTimeline.js.map +1 -1
  198. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js +1 -0
  199. package/build/dist/Models/DatabaseModels/IncidentStateTimeline.js.map +1 -1
  200. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  201. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  202. package/build/dist/Models/DatabaseModels/LogDropFilter.js +91 -0
  203. package/build/dist/Models/DatabaseModels/LogDropFilter.js.map +1 -1
  204. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +14 -4
  205. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  206. package/build/dist/Models/DatabaseModels/RecommendationDismissal.js +484 -0
  207. package/build/dist/Models/DatabaseModels/RecommendationDismissal.js.map +1 -0
  208. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js +1 -0
  209. package/build/dist/Models/DatabaseModels/ScheduledMaintenanceStateTimeline.js.map +1 -1
  210. package/build/dist/Models/DatabaseModels/StatusPageGroup.js +94 -0
  211. package/build/dist/Models/DatabaseModels/StatusPageGroup.js.map +1 -1
  212. package/build/dist/Models/DatabaseModels/TableView.js +40 -0
  213. package/build/dist/Models/DatabaseModels/TableView.js.map +1 -1
  214. package/build/dist/Models/DatabaseModels/TraceDropFilter.js +91 -0
  215. package/build/dist/Models/DatabaseModels/TraceDropFilter.js.map +1 -1
  216. package/build/dist/Models/DatabaseModels/WorkflowVariable.js +5 -1
  217. package/build/dist/Models/DatabaseModels/WorkflowVariable.js.map +1 -1
  218. package/build/dist/Server/API/AlertAPI.js +22 -13
  219. package/build/dist/Server/API/AlertAPI.js.map +1 -1
  220. package/build/dist/Server/API/BaseAPI.js +22 -1
  221. package/build/dist/Server/API/BaseAPI.js.map +1 -1
  222. package/build/dist/Server/API/BaseAnalyticsAPI.js +24 -1
  223. package/build/dist/Server/API/BaseAnalyticsAPI.js.map +1 -1
  224. package/build/dist/Server/API/CommonAPI.js +42 -0
  225. package/build/dist/Server/API/CommonAPI.js.map +1 -1
  226. package/build/dist/Server/API/IncidentAPI.js +43 -26
  227. package/build/dist/Server/API/IncidentAPI.js.map +1 -1
  228. package/build/dist/Server/API/IncidentEpisodeAPI.js +21 -12
  229. package/build/dist/Server/API/IncidentEpisodeAPI.js.map +1 -1
  230. package/build/dist/Server/API/MonitorAPI.js +23 -0
  231. package/build/dist/Server/API/MonitorAPI.js.map +1 -1
  232. package/build/dist/Server/API/MonitorTemplateAPI.js +4 -0
  233. package/build/dist/Server/API/MonitorTemplateAPI.js.map +1 -1
  234. package/build/dist/Server/API/ProbeAPI.js +131 -15
  235. package/build/dist/Server/API/ProbeAPI.js.map +1 -1
  236. package/build/dist/Server/API/ProjectAPI.js +62 -3
  237. package/build/dist/Server/API/ProjectAPI.js.map +1 -1
  238. package/build/dist/Server/API/ScheduledMaintenanceAPI.js +23 -14
  239. package/build/dist/Server/API/ScheduledMaintenanceAPI.js.map +1 -1
  240. package/build/dist/Server/API/StatusPageAPI.js +61 -33
  241. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  242. package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js +26 -2
  243. package/build/dist/Server/API/WorkspaceNotificationRuleAPI.js.map +1 -1
  244. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js +12 -0
  245. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js.map +1 -0
  246. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js +397 -0
  247. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785320000000-RepairCrossProjectIncidentReferences.js.map +1 -0
  248. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js +16 -0
  249. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785329453269-AddParentGroupToStatusPageGroup.js.map +1 -0
  250. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js +30 -0
  251. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785397674289-AddRecommendationDismissalTable.js.map +1 -0
  252. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js +34 -0
  253. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785405581596-AddDroppedCountersToDropFilters.js.map +1 -0
  254. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  255. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  256. package/build/dist/Server/Services/AlertEpisodeService.js +39 -0
  257. package/build/dist/Server/Services/AlertEpisodeService.js.map +1 -1
  258. package/build/dist/Server/Services/AlertService.js +95 -0
  259. package/build/dist/Server/Services/AlertService.js.map +1 -1
  260. package/build/dist/Server/Services/BillingService.js +71 -0
  261. package/build/dist/Server/Services/BillingService.js.map +1 -1
  262. package/build/dist/Server/Services/DatabaseService.js +140 -17
  263. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  264. package/build/dist/Server/Services/IncidentEpisodeService.js +39 -0
  265. package/build/dist/Server/Services/IncidentEpisodeService.js.map +1 -1
  266. package/build/dist/Server/Services/IncidentService.js +100 -0
  267. package/build/dist/Server/Services/IncidentService.js.map +1 -1
  268. package/build/dist/Server/Services/IncidentTemplateService.js +97 -0
  269. package/build/dist/Server/Services/IncidentTemplateService.js.map +1 -1
  270. package/build/dist/Server/Services/Index.js +2 -0
  271. package/build/dist/Server/Services/Index.js.map +1 -1
  272. package/build/dist/Server/Services/LogDropFilterService.js +93 -0
  273. package/build/dist/Server/Services/LogDropFilterService.js.map +1 -1
  274. package/build/dist/Server/Services/MonitorProbeService.js +73 -5
  275. package/build/dist/Server/Services/MonitorProbeService.js.map +1 -1
  276. package/build/dist/Server/Services/MonitorService.js +34 -39
  277. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  278. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js +71 -0
  279. package/build/dist/Server/Services/NetworkDeviceDiscoveryScanService.js.map +1 -1
  280. package/build/dist/Server/Services/ProbeService.js +64 -0
  281. package/build/dist/Server/Services/ProbeService.js.map +1 -1
  282. package/build/dist/Server/Services/ProjectService.js +103 -7
  283. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  284. package/build/dist/Server/Services/RecommendationDismissalService.js +50 -0
  285. package/build/dist/Server/Services/RecommendationDismissalService.js.map +1 -0
  286. package/build/dist/Server/Services/RunbookAgentJobService.js +63 -5
  287. package/build/dist/Server/Services/RunbookAgentJobService.js.map +1 -1
  288. package/build/dist/Server/Services/ScheduledMaintenanceService.js +83 -0
  289. package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
  290. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js +65 -0
  291. package/build/dist/Server/Services/ScheduledMaintenanceTemplateService.js.map +1 -1
  292. package/build/dist/Server/Services/StatusPageGroupService.js +136 -0
  293. package/build/dist/Server/Services/StatusPageGroupService.js.map +1 -1
  294. package/build/dist/Server/Services/TraceDropFilterService.js +93 -0
  295. package/build/dist/Server/Services/TraceDropFilterService.js.map +1 -1
  296. package/build/dist/Server/Types/Workflow/Components/API/Delete.js +11 -0
  297. package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
  298. package/build/dist/Server/Types/Workflow/Components/API/Get.js +11 -0
  299. package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
  300. package/build/dist/Server/Types/Workflow/Components/API/Patch.js +11 -0
  301. package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
  302. package/build/dist/Server/Types/Workflow/Components/API/Post.js +11 -0
  303. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  304. package/build/dist/Server/Types/Workflow/Components/API/Put.js +12 -0
  305. package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
  306. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js +132 -0
  307. package/build/dist/Server/Utils/Database/ProjectScopedReferenceValidator.js.map +1 -0
  308. package/build/dist/Server/Utils/DropFilterValidation.js +80 -0
  309. package/build/dist/Server/Utils/DropFilterValidation.js.map +1 -0
  310. package/build/dist/Server/Utils/Errors.js +3 -0
  311. package/build/dist/Server/Utils/Errors.js.map +1 -1
  312. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +30 -12
  313. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  314. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +38 -18
  315. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  316. package/build/dist/Server/Utils/Telemetry/AppMetrics.js +26 -0
  317. package/build/dist/Server/Utils/Telemetry/AppMetrics.js.map +1 -1
  318. package/build/dist/Types/Date.js +14 -4
  319. package/build/dist/Types/Date.js.map +1 -1
  320. package/build/dist/Types/JSONFunctions.js +8 -3
  321. package/build/dist/Types/JSONFunctions.js.map +1 -1
  322. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -1
  323. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js +192 -0
  324. package/build/dist/Types/Monitor/KubernetesAlertTemplates.js.map +1 -1
  325. package/build/dist/Types/Monitor/MonitorStep.js +6 -1
  326. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  327. package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js +32 -1
  328. package/build/dist/Types/Monitor/MonitorStepMetricMonitor.js.map +1 -1
  329. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js +294 -0
  330. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationCatalog.js.map +1 -0
  331. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js +110 -0
  332. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationSeverityMapper.js.map +1 -0
  333. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js +58 -0
  334. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationTypes.js.map +1 -0
  335. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js +451 -0
  336. package/build/dist/Types/Monitor/Recommendation/MonitorRecommendationUtil.js.map +1 -0
  337. package/build/dist/Types/Permission.js +40 -0
  338. package/build/dist/Types/Permission.js.map +1 -1
  339. package/build/dist/Types/Recommendation/RecommendationType.js +21 -0
  340. package/build/dist/Types/Recommendation/RecommendationType.js.map +1 -0
  341. package/build/dist/Types/Runbook/RunbookExecutionDeadline.js +93 -0
  342. package/build/dist/Types/Runbook/RunbookExecutionDeadline.js.map +1 -0
  343. package/build/dist/Types/Runbook/RunbookStepTimeout.js +142 -0
  344. package/build/dist/Types/Runbook/RunbookStepTimeout.js.map +1 -0
  345. package/build/dist/Types/Telemetry/DropFilterSampling.js +75 -0
  346. package/build/dist/Types/Telemetry/DropFilterSampling.js.map +1 -0
  347. package/build/dist/UI/Components/AI/GenerateFromAIModal.js +1 -2
  348. package/build/dist/UI/Components/AI/GenerateFromAIModal.js.map +1 -1
  349. package/build/dist/UI/Components/Accordion/Accordion.js +9 -2
  350. package/build/dist/UI/Components/Accordion/Accordion.js.map +1 -1
  351. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js +1 -1
  352. package/build/dist/UI/Components/BulkUpdate/BulkLabelActions.js.map +1 -1
  353. package/build/dist/UI/Components/CodeEditor/CodeEditor.js +27 -14
  354. package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
  355. package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js +1 -1
  356. package/build/dist/UI/Components/Date/RangeStartAndEndDateView.js.map +1 -1
  357. package/build/dist/UI/Components/EditionLabel/EditionLabel.js +2 -20
  358. package/build/dist/UI/Components/EditionLabel/EditionLabel.js.map +1 -1
  359. package/build/dist/UI/Components/Error/PageError.js +1 -3
  360. package/build/dist/UI/Components/Error/PageError.js.map +1 -1
  361. package/build/dist/UI/Components/ErrorBoundary.js +145 -11
  362. package/build/dist/UI/Components/ErrorBoundary.js.map +1 -1
  363. package/build/dist/UI/Components/InfoCard/InfoCard.js +28 -1
  364. package/build/dist/UI/Components/InfoCard/InfoCard.js.map +1 -1
  365. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +13 -2
  366. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  367. package/build/dist/UI/Components/MasterPage/MasterPage.js +50 -1
  368. package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
  369. package/build/dist/UI/Components/Modal/Modal.js +4 -32
  370. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  371. package/build/dist/UI/Components/ModelFormModal/ModelFormModal.js.map +1 -1
  372. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +308 -40
  373. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  374. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +230 -0
  375. package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -0
  376. package/build/dist/UI/Components/ModelTable/ColumnPreference.js +258 -0
  377. package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -0
  378. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +168 -0
  379. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -0
  380. package/build/dist/UI/Components/ModelTable/TableView.js +13 -2
  381. package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
  382. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +84 -0
  383. package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -0
  384. package/build/dist/UI/Components/Runbook/StepTimeoutInput.js +101 -0
  385. package/build/dist/UI/Components/Runbook/StepTimeoutInput.js.map +1 -0
  386. package/build/dist/UI/Components/SideMenu/SideMenu.js +15 -5
  387. package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
  388. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js +73 -0
  389. package/build/dist/UI/Components/StatusPage/ResourceGroupSection.js.map +1 -0
  390. package/build/dist/UI/Components/Table/Table.js +15 -2
  391. package/build/dist/UI/Components/Table/Table.js.map +1 -1
  392. package/build/dist/UI/Components/Table/TableRow.js +11 -6
  393. package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
  394. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +13 -2
  395. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  396. package/build/dist/UI/Utils/DropdownAlignment.js +98 -0
  397. package/build/dist/UI/Utils/DropdownAlignment.js.map +1 -0
  398. package/build/dist/UI/Utils/TableFilterUrlState.js +48 -15
  399. package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
  400. package/build/dist/Utils/API.js +39 -2
  401. package/build/dist/Utils/API.js.map +1 -1
  402. package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js +97 -0
  403. package/build/dist/Utils/Monitor/MonitorSummaryProbeUtil.js.map +1 -0
  404. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js +330 -0
  405. package/build/dist/Utils/NetworkDiscovery/ScanTargetUtil.js.map +1 -0
  406. package/build/dist/Utils/StatusPage/GroupNestingLayout.js +280 -0
  407. package/build/dist/Utils/StatusPage/GroupNestingLayout.js.map +1 -0
  408. package/build/dist/Utils/StatusPage/GroupTree.js +214 -0
  409. package/build/dist/Utils/StatusPage/GroupTree.js.map +1 -0
  410. package/build/dist/Utils/StatusPage/ResourceUptime.js +60 -16
  411. package/build/dist/Utils/StatusPage/ResourceUptime.js.map +1 -1
  412. package/build/dist/Utils/UserPreferences.js +33 -0
  413. package/build/dist/Utils/UserPreferences.js.map +1 -1
  414. package/package.json +1 -1
@@ -19,6 +19,23 @@ export default interface Columns<
19
19
  field: SelectEntityField<TEntity>;
20
20
  selectedProperty?: string | undefined;
21
21
  title: string;
22
+ /*
23
+ * Stable identity for this column, used to persist the viewer's show/hide
24
+ * and ordering choices. Leave it unset and one is derived from the declared
25
+ * field (see ColumnPreference.getColumnIds) - set it only when the derived
26
+ * id would be unstable, e.g. a cell rendered entirely through `getElement`
27
+ * off a placeholder `field: { _id: true }` whose title is likely to change.
28
+ */
29
+ id?: string | undefined;
30
+ /*
31
+ * Keep this column out of the "Customize Columns" picker: it is always
32
+ * shown and can never be moved. Use it for the column that identifies the
33
+ * row (usually the name), so a table can never be customized into
34
+ * anonymity.
35
+ */
36
+ isNotCustomizable?: boolean | undefined;
37
+ // Start hidden. The viewer can still switch it on from the picker.
38
+ isHiddenByDefault?: boolean | undefined;
22
39
  contentClassName?: string | undefined;
23
40
  colSpan?: number | undefined;
24
41
  disableSort?: boolean;
@@ -0,0 +1,523 @@
1
+ import { CustomizableColumn } from "./ColumnPreference";
2
+ import Button, { ButtonSize, ButtonStyleType } from "../Button/Button";
3
+ import CheckboxElement from "../Checkbox/Checkbox";
4
+ import Icon from "../Icon/Icon";
5
+ import Input, { InputType } from "../Input/Input";
6
+ import Modal, { ModalWidth } from "../Modal/Modal";
7
+ import AnalyticsBaseModel from "../../../Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel";
8
+ import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
9
+ import IconProp from "../../../Types/Icon/IconProp";
10
+ import React, { ReactElement, useMemo, useState } from "react";
11
+ import {
12
+ DragDropContext,
13
+ Draggable,
14
+ DraggableProvided,
15
+ DraggableStateSnapshot,
16
+ Droppable,
17
+ DroppableProvided,
18
+ DropResult,
19
+ } from "react-beautiful-dnd";
20
+
21
+ export interface ComponentProps<
22
+ TBaseModel extends BaseModel | AnalyticsBaseModel,
23
+ > {
24
+ // Every customizable column, already in the order the table renders them.
25
+ columns: Array<CustomizableColumn<TBaseModel>>;
26
+ onSave: (columns: Array<CustomizableColumn<TBaseModel>>) => void;
27
+ onClose: () => void;
28
+ // Drop the stored layout and go back to what the table ships with.
29
+ onReset: () => void;
30
+ title?: string | undefined;
31
+ description?: string | undefined;
32
+ /*
33
+ * False once the viewer has customized anything, which is when Reset earns
34
+ * its place in the footer.
35
+ */
36
+ isDefaultLayout?: boolean | undefined;
37
+ }
38
+
39
+ type ColumnCustomizationModalFunction = <
40
+ TBaseModel extends BaseModel | AnalyticsBaseModel,
41
+ >(
42
+ props: ComponentProps<TBaseModel>,
43
+ ) => ReactElement;
44
+
45
+ /*
46
+ * The "Customize Columns" picker: a checkbox and a drag handle per column.
47
+ *
48
+ * Two constraints shape it:
49
+ *
50
+ * - The last visible column cannot be switched off. A table with no columns
51
+ * renders as an empty shell with no header row, and the only control that
52
+ * could undo that is the one the viewer just closed.
53
+ *
54
+ * - Reordering is offered through Up/Down buttons as well as drag. Drag alone
55
+ * is unusable with a keyboard or a screen reader, and pointer-only
56
+ * reordering is also the part that cannot be exercised in tests.
57
+ *
58
+ * Changes are staged locally and only handed back on Save, so Cancel really
59
+ * does cancel.
60
+ */
61
+ const ColumnCustomizationModal: ColumnCustomizationModalFunction = <
62
+ TBaseModel extends BaseModel | AnalyticsBaseModel,
63
+ >(
64
+ props: ComponentProps<TBaseModel>,
65
+ ): ReactElement => {
66
+ const [entries, setEntries] = useState<Array<CustomizableColumn<TBaseModel>>>(
67
+ [...props.columns],
68
+ );
69
+ const [searchText, setSearchText] = useState<string>("");
70
+
71
+ const visibleCount: number = useMemo(() => {
72
+ return entries.filter((entry: CustomizableColumn<TBaseModel>) => {
73
+ return entry.isVisible;
74
+ }).length;
75
+ }, [entries]);
76
+
77
+ const normalizedSearch: string = searchText.trim().toLowerCase();
78
+ const isSearching: boolean = normalizedSearch.length > 0;
79
+
80
+ const shownEntries: Array<CustomizableColumn<TBaseModel>> = useMemo(() => {
81
+ if (!isSearching) {
82
+ return entries;
83
+ }
84
+
85
+ return entries.filter((entry: CustomizableColumn<TBaseModel>) => {
86
+ return (entry.column.title || "")
87
+ .toLowerCase()
88
+ .includes(normalizedSearch);
89
+ });
90
+ }, [entries, normalizedSearch, isSearching]);
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
+
100
+ type ToggleFunction = (id: string, isVisible: boolean) => void;
101
+
102
+ const toggleColumn: ToggleFunction = (
103
+ id: string,
104
+ isVisible: boolean,
105
+ ): void => {
106
+ setEntries((current: Array<CustomizableColumn<TBaseModel>>) => {
107
+ const isLastVisible: boolean =
108
+ !isVisible &&
109
+ current.filter((entry: CustomizableColumn<TBaseModel>) => {
110
+ return entry.isVisible;
111
+ }).length <= 1;
112
+
113
+ if (isLastVisible) {
114
+ // Refuse rather than render a table with nothing in it.
115
+ return current;
116
+ }
117
+
118
+ return current.map((entry: CustomizableColumn<TBaseModel>) => {
119
+ return entry.id === id ? { ...entry, isVisible } : entry;
120
+ });
121
+ });
122
+ };
123
+
124
+ type MoveFunction = (fromIndex: number, toIndex: number) => void;
125
+
126
+ const moveColumn: MoveFunction = (
127
+ fromIndex: number,
128
+ toIndex: number,
129
+ ): void => {
130
+ setEntries((current: Array<CustomizableColumn<TBaseModel>>) => {
131
+ if (
132
+ fromIndex === toIndex ||
133
+ fromIndex < 0 ||
134
+ toIndex < 0 ||
135
+ fromIndex >= current.length ||
136
+ toIndex >= current.length
137
+ ) {
138
+ return current;
139
+ }
140
+
141
+ const next: Array<CustomizableColumn<TBaseModel>> = [...current];
142
+ const [moved] = next.splice(fromIndex, 1);
143
+
144
+ if (!moved) {
145
+ return current;
146
+ }
147
+
148
+ next.splice(toIndex, 0, moved);
149
+
150
+ return next;
151
+ });
152
+ };
153
+
154
+ type OnDragEndFunction = (result: DropResult) => void;
155
+
156
+ const onDragEnd: OnDragEndFunction = (result: DropResult): void => {
157
+ /*
158
+ * Guard on the object, not on the index: a drop into the first slot has
159
+ * `index === 0`, which a truthiness check would throw away.
160
+ */
161
+ if (!result.destination) {
162
+ return;
163
+ }
164
+
165
+ moveColumn(result.source.index, result.destination.index);
166
+ };
167
+
168
+ type SetAllVisibleFunction = (isVisible: boolean) => void;
169
+
170
+ const setAllVisible: SetAllVisibleFunction = (isVisible: boolean): void => {
171
+ setEntries((current: Array<CustomizableColumn<TBaseModel>>) => {
172
+ if (!isVisible) {
173
+ /*
174
+ * "Hide all" still has to leave one column standing, so it keeps the
175
+ * first one - the leftmost, which is normally the row's name.
176
+ */
177
+ let isFirstKept: boolean = false;
178
+
179
+ return current.map((entry: CustomizableColumn<TBaseModel>) => {
180
+ if (!isFirstKept) {
181
+ isFirstKept = true;
182
+ return { ...entry, isVisible: true };
183
+ }
184
+
185
+ return { ...entry, isVisible: false };
186
+ });
187
+ }
188
+
189
+ return current.map((entry: CustomizableColumn<TBaseModel>) => {
190
+ return { ...entry, isVisible: true };
191
+ });
192
+ });
193
+ };
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
+
226
+ type GetRowFunction = (data: {
227
+ entry: CustomizableColumn<TBaseModel>;
228
+ index: number;
229
+ dragHandle?: ReactElement | undefined;
230
+ }) => ReactElement;
231
+
232
+ const getRowContents: GetRowFunction = (data: {
233
+ entry: CustomizableColumn<TBaseModel>;
234
+ index: number;
235
+ dragHandle?: ReactElement | undefined;
236
+ }): ReactElement => {
237
+ const { entry, index } = data;
238
+
239
+ const isOnlyVisibleColumn: boolean = entry.isVisible && visibleCount <= 1;
240
+
241
+ return (
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" />}
244
+
245
+ <div className="min-w-0 flex-1">
246
+ <CheckboxElement
247
+ value={entry.isVisible}
248
+ disabled={isOnlyVisibleColumn}
249
+ dataTestId={`column-toggle-${entry.id}`}
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
+ }
262
+ onChange={(value: boolean) => {
263
+ toggleColumn(entry.id, value);
264
+ }}
265
+ />
266
+ </div>
267
+
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">
278
+ <Button
279
+ buttonSize={ButtonSize.Small}
280
+ buttonStyle={ButtonStyleType.ICON}
281
+ icon={IconProp.ChevronUp}
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"
286
+ dataTestId={`column-move-up-${entry.id}`}
287
+ disabled={isSearching || index === 0}
288
+ onClick={() => {
289
+ moveColumn(index, index - 1);
290
+ }}
291
+ />
292
+ <Button
293
+ buttonSize={ButtonSize.Small}
294
+ buttonStyle={ButtonStyleType.ICON}
295
+ icon={IconProp.ChevronDown}
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"
300
+ dataTestId={`column-move-down-${entry.id}`}
301
+ disabled={isSearching || index === entries.length - 1}
302
+ onClick={() => {
303
+ moveColumn(index, index + 1);
304
+ }}
305
+ />
306
+ </div>
307
+ </div>
308
+ );
309
+ };
310
+
311
+ type GetListFunction = () => ReactElement;
312
+
313
+ const getList: GetListFunction = (): ReactElement => {
314
+ if (shownEntries.length === 0) {
315
+ return (
316
+ <div
317
+ className="flex flex-col items-center gap-2 px-3 py-10 text-center"
318
+ data-testid="column-customization-no-results"
319
+ >
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>
324
+ </div>
325
+ );
326
+ }
327
+
328
+ /*
329
+ * Dragging a filtered list would move a column to a position that only
330
+ * makes sense inside the filter, so while a search is active the list is
331
+ * rendered plain and the reorder controls are disabled.
332
+ */
333
+ if (isSearching) {
334
+ return (
335
+ <div className="divide-y divide-gray-100">
336
+ {shownEntries.map((entry: CustomizableColumn<TBaseModel>) => {
337
+ return (
338
+ <div key={entry.id}>
339
+ {getRowContents({
340
+ entry,
341
+ index: entries.indexOf(entry),
342
+ })}
343
+ </div>
344
+ );
345
+ })}
346
+ </div>
347
+ );
348
+ }
349
+
350
+ return (
351
+ <DragDropContext onDragEnd={onDragEnd}>
352
+ <Droppable droppableId="model-table-columns">
353
+ {(droppableProvided: DroppableProvided) => {
354
+ return (
355
+ <div
356
+ ref={droppableProvided.innerRef}
357
+ {...droppableProvided.droppableProps}
358
+ className="divide-y divide-gray-100"
359
+ aria-label="Columns"
360
+ >
361
+ {shownEntries.map(
362
+ (entry: CustomizableColumn<TBaseModel>, index: number) => {
363
+ return (
364
+ <Draggable
365
+ draggableId={entry.id}
366
+ index={index}
367
+ key={entry.id}
368
+ >
369
+ {(
370
+ draggableProvided: DraggableProvided,
371
+ draggableSnapshot: DraggableStateSnapshot,
372
+ ) => {
373
+ return (
374
+ <div
375
+ ref={draggableProvided.innerRef}
376
+ {...draggableProvided.draggableProps}
377
+ className={
378
+ draggableSnapshot.isDragging
379
+ ? "rounded-md bg-white shadow-lg ring-1 ring-gray-200"
380
+ : "bg-white"
381
+ }
382
+ >
383
+ {getRowContents({
384
+ entry,
385
+ index,
386
+ dragHandle: (
387
+ <div
388
+ {...draggableProvided.dragHandleProps}
389
+ className="flex w-5 flex-none cursor-grab justify-center text-gray-300 transition-colors group-hover:text-gray-500 active:cursor-grabbing"
390
+ aria-label={`Drag to reorder ${entry.column.title}`}
391
+ title="Drag to reorder"
392
+ >
393
+ <Icon
394
+ icon={IconProp.GripVertical}
395
+ className="h-4 w-4"
396
+ />
397
+ </div>
398
+ ),
399
+ })}
400
+ </div>
401
+ );
402
+ }}
403
+ </Draggable>
404
+ );
405
+ },
406
+ )}
407
+ {droppableProvided.placeholder}
408
+ </div>
409
+ );
410
+ }}
411
+ </Droppable>
412
+ </DragDropContext>
413
+ );
414
+ };
415
+
416
+ return (
417
+ <Modal
418
+ title={props.title || "Customize Columns"}
419
+ description={
420
+ props.description ||
421
+ "Choose which columns to show and drag them into the order you want."
422
+ }
423
+ modalWidth={ModalWidth.Medium}
424
+ submitButtonText="Save"
425
+ closeButtonText="Cancel"
426
+ onClose={props.onClose}
427
+ onSubmit={() => {
428
+ props.onSave(entries);
429
+ }}
430
+ leftFooterElement={
431
+ props.isDefaultLayout ? (
432
+ <></>
433
+ ) : (
434
+ <Button
435
+ title="Reset to default"
436
+ icon={IconProp.Refresh}
437
+ buttonSize={ButtonSize.Normal}
438
+ buttonStyle={ButtonStyleType.NORMAL}
439
+ dataTestId="column-customization-reset"
440
+ onClick={() => {
441
+ props.onReset();
442
+ }}
443
+ />
444
+ )
445
+ }
446
+ >
447
+ <div className="space-y-3" data-testid="column-customization-modal">
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" />
451
+ </div>
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"
469
+ onClick={() => {
470
+ setSearchText("");
471
+ }}
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
+ )}
477
+ </div>
478
+
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>
504
+ </div>
505
+
506
+ <div className="max-h-80 overflow-y-auto overscroll-contain rounded-md border border-gray-200 bg-white">
507
+ {getList()}
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>
518
+ </div>
519
+ </Modal>
520
+ );
521
+ };
522
+
523
+ export default ColumnCustomizationModal;