@oneuptime/common 12.0.9 → 12.0.11

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 (262) hide show
  1. package/Models/DatabaseModels/NetworkDevice.ts +44 -0
  2. package/Models/DatabaseModels/NetworkDeviceLink.ts +116 -0
  3. package/Models/DatabaseModels/RunnerJob.ts +17 -2
  4. package/Server/API/LlmProviderAPI.ts +8 -0
  5. package/Server/Infrastructure/Postgres/SchemaMigrations/1787400000000-AddDeviceRoleAndDeclaredLinkParent.ts +52 -0
  6. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
  7. package/Server/Services/NetworkDeviceLabelRuleEngineService.ts +240 -0
  8. package/Server/Services/NetworkDeviceLinkService.ts +338 -2
  9. package/Server/Services/NetworkDeviceService.ts +265 -12
  10. package/Server/Services/RunnerJobService.ts +24 -1
  11. package/Server/Types/Billing/MeteredPlan/AllMeteredPlans.ts +19 -5
  12. package/Server/Types/Database/JSONColumnQuery.ts +42 -4
  13. package/Server/Utils/LLM/LLMService.ts +108 -19
  14. package/Server/Utils/Monitor/MonitorAlert.ts +22 -115
  15. package/Server/Utils/Monitor/MonitorIncident.ts +7 -337
  16. package/Server/Utils/Monitor/MonitorMaintenanceSuppression.ts +27 -2
  17. package/Server/Utils/Monitor/SeriesResourceLabels.ts +32 -0
  18. package/Server/Utils/Monitor/SeriesResourceLinker.ts +469 -0
  19. package/Server/Utils/SSRFProtection.ts +5 -4
  20. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +186 -38
  21. package/Tests/App/AdminDashboard/AdminUsersBulkAddToProject.test.tsx +955 -0
  22. package/Tests/App/AdminDashboard/BulkAddUsersToProject.test.ts +778 -0
  23. package/Tests/App/AdminDashboard/BulkAddUsersToProjectModal.test.tsx +1051 -0
  24. package/Tests/App/Dashboard/AdminNotificationRulesPage.test.tsx +420 -112
  25. package/Tests/App/Dashboard/OnCallReadinessSurfaces.test.tsx +81 -6
  26. package/Tests/App/Dashboard/PayAsYouGoConsentGate.test.tsx +543 -0
  27. package/Tests/App/Dashboard/PayAsYouGoFreePlan.test.ts +125 -0
  28. package/Tests/App/Dashboard/PayAsYouGoNotices.test.tsx +612 -0
  29. package/Tests/App/Dashboard/SloWidgetChartRendering.test.tsx +536 -0
  30. package/Tests/App/Dashboard/UserElementEmail.test.tsx +447 -0
  31. package/Tests/App/Dashboard/UserEmailCallSites.test.tsx +284 -0
  32. package/Tests/Models/AnalyticsModels/CommonModel.test.ts +312 -0
  33. package/Tests/Server/Infrastructure/Postgres/DeviceRoleAndDeclaredLinkParentMigration.test.ts +250 -0
  34. package/Tests/Server/Infrastructure/Postgres/EpisodeMemberNotifyIndexesMigration.test.ts +46 -18
  35. package/Tests/Server/Services/NetworkDeviceLabelRuleRun.test.ts +618 -0
  36. package/Tests/Server/Services/NetworkDeviceLinkParentValidation.test.ts +1043 -0
  37. package/Tests/Server/Services/NetworkSiteAssignmentRuleRun.test.ts +706 -0
  38. package/Tests/Server/Services/RunnerJobEnqueue.test.ts +412 -0
  39. package/Tests/Server/Types/Billing/PayAsYouGoMeteredPricing.test.ts +125 -0
  40. package/Tests/Server/Types/Database/JSONColumnQuery.test.ts +508 -0
  41. package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +2 -2
  42. package/Tests/Server/Utils/AI/LLMServiceRetryPolicy.test.ts +450 -0
  43. package/Tests/Server/Utils/Monitor/MonitorAlertResourceLinking.test.ts +556 -0
  44. package/Tests/Server/Utils/Monitor/MonitorIncidentResourceLinking.test.ts +547 -0
  45. package/Tests/Server/Utils/Monitor/MonitorMaintenanceSuppression.test.ts +30 -0
  46. package/Tests/Server/Utils/Monitor/SeriesResourceLinker.test.ts +699 -0
  47. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +55 -0
  48. package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +668 -0
  49. package/Tests/Types/API/URLMalformedTolerance.test.ts +301 -0
  50. package/Tests/Types/API/URLTelScheme.test.ts +261 -0
  51. package/Tests/Types/API/URLUnsupportedScheme.test.ts +148 -0
  52. package/Tests/Types/Billing/PayAsYouGoPricing.test.ts +64 -0
  53. package/Tests/Types/CustomField/CustomFieldTypeCorrespondence.test.ts +107 -0
  54. package/Tests/Types/Monitor/MonitorType.test.ts +62 -0
  55. package/Tests/Types/NetworkAutomation/RuleRunResult.test.ts +184 -0
  56. package/Tests/Types/Runbook/RunbookStepType.test.ts +124 -0
  57. package/Tests/Types/Workflow/BaseModelComponents.test.ts +17 -0
  58. package/Tests/UI/Components/Button.test.tsx +279 -0
  59. package/Tests/UI/Components/Charts/ChartXAxisDataKey.test.tsx +256 -0
  60. package/Tests/UI/Components/Charts/DataPointUtil.test.ts +323 -0
  61. package/Tests/UI/Components/DictionaryValuePlaceholderAndSuggestions.test.tsx +595 -0
  62. package/Tests/UI/Components/Icon.test.tsx +57 -0
  63. package/Tests/UI/Components/List.test.tsx +20 -3
  64. package/Tests/UI/Components/LogsSavedViewsDropdown.test.tsx +304 -0
  65. package/Tests/UI/Components/LogsViewerClearSavedView.test.tsx +179 -0
  66. package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +349 -1
  67. package/Tests/UI/Components/Pagination.test.tsx +721 -146
  68. package/Tests/UI/Components/PaginationIntegration.test.tsx +386 -0
  69. package/Tests/UI/Components/PaginationUtil.test.ts +417 -0
  70. package/Tests/UI/Components/TelemetrySavedViewsDropdown.test.tsx +343 -0
  71. package/Tests/UI/Components/Workflow/ColumnEditor/ColumnControl.test.ts +289 -0
  72. package/Tests/UI/Components/Workflow/ColumnEditor/ColumnOperators.test.ts +271 -0
  73. package/Tests/UI/Components/Workflow/ColumnEditor/ColumnRow.test.ts +119 -0
  74. package/Tests/UI/Components/Workflow/ColumnEditor/ColumnRowSerialization.test.ts +968 -0
  75. package/Tests/UI/Components/Workflow/ModelColumnEditor.render.test.tsx +766 -0
  76. package/Tests/UI/Utils/RunNetworkRule.test.ts +320 -0
  77. package/Tests/Utils/APIRetryPolicy.test.ts +823 -0
  78. package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +502 -0
  79. package/Tests/Utils/Monitor/NetworkTopologyDeclaredHierarchy.test.ts +759 -0
  80. package/Tests/Utils/NetworkAutomation/RuleRunSummary.test.ts +286 -0
  81. package/Tests/Utils/Schema/BaseSchema.test.ts +651 -0
  82. package/Types/API/Protocol.ts +9 -0
  83. package/Types/API/URL.ts +286 -20
  84. package/Types/Billing/PayAsYouGoPricing.ts +47 -0
  85. package/Types/CustomField/CustomFieldType.ts +28 -0
  86. package/Types/Monitor/MonitorType.ts +11 -0
  87. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +13 -0
  88. package/Types/NetworkAutomation/RuleRunResult.ts +121 -0
  89. package/Types/Runbook/RunbookStepType.ts +23 -0
  90. package/UI/Components/AutocompleteTextInput/AutocompleteTextInput.tsx +7 -0
  91. package/UI/Components/Button/Button.tsx +14 -22
  92. package/UI/Components/Charts/Area/AreaChart.tsx +4 -2
  93. package/UI/Components/Charts/Bar/BarChart.tsx +4 -2
  94. package/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.ts +13 -0
  95. package/UI/Components/Charts/Line/LineChart.tsx +4 -2
  96. package/UI/Components/Charts/Types/XAxis/XAxis.ts +6 -0
  97. package/UI/Components/Charts/Utils/DataPoint.ts +15 -12
  98. package/UI/Components/Dictionary/Dictionary.tsx +4 -39
  99. package/UI/Components/Icon/Icon.tsx +1 -1
  100. package/UI/Components/LogsViewer/LogsViewer.tsx +5 -1
  101. package/UI/Components/LogsViewer/components/LogsFacetSidebar.tsx +8 -0
  102. package/UI/Components/LogsViewer/components/LogsPagination.tsx +29 -91
  103. package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +2 -0
  104. package/UI/Components/LogsViewer/components/SavedViewsDropdown.tsx +66 -1
  105. package/UI/Components/ModelTable/CustomFieldColumns.tsx +55 -0
  106. package/UI/Components/Pagination/Pagination.tsx +373 -328
  107. package/UI/Components/Pagination/PaginationUtil.ts +263 -0
  108. package/UI/Components/Pagination/Screenshots/README.md +15 -0
  109. package/UI/Components/Pagination/Screenshots/pagination-before-after.png +0 -0
  110. package/UI/Components/Pagination/Screenshots/pagination-go-to-page-modal.png +0 -0
  111. package/UI/Components/Pagination/Screenshots/pagination-long-list.png +0 -0
  112. package/UI/Components/Pagination/Screenshots/pagination-mobile.png +0 -0
  113. package/UI/Components/Pagination/Screenshots/pagination-telemetry.png +0 -0
  114. package/UI/Components/TelemetryViewer/components/SavedViewsDropdown.tsx +66 -1
  115. package/UI/Components/TelemetryViewer/components/TelemetryPagination.tsx +38 -92
  116. package/UI/Components/TextArea/TextArea.tsx +3 -0
  117. package/UI/Components/Workflow/ArgumentsForm.tsx +18 -1
  118. package/UI/Components/Workflow/ColumnEditor/AddColumnDropdown.tsx +177 -0
  119. package/UI/Components/Workflow/ColumnEditor/ColumnConditionRow.tsx +243 -0
  120. package/UI/Components/Workflow/ColumnEditor/ColumnControl.ts +255 -0
  121. package/UI/Components/Workflow/ColumnEditor/ColumnFieldRow.tsx +178 -0
  122. package/UI/Components/Workflow/ColumnEditor/ColumnOperators.ts +206 -0
  123. package/UI/Components/Workflow/ColumnEditor/ColumnRow.ts +157 -0
  124. package/UI/Components/Workflow/ColumnEditor/ColumnRowSerialization.ts +517 -0
  125. package/UI/Components/Workflow/ColumnEditor/ColumnValueInput.tsx +482 -0
  126. package/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.tsx +131 -0
  127. package/UI/Components/Workflow/ColumnEditor/ModelRecordForm.tsx +163 -0
  128. package/UI/Components/Workflow/ModelColumnEditor.tsx +284 -100
  129. package/UI/Utils/NetworkAutomation/RunNetworkRule.ts +122 -0
  130. package/Utils/API.ts +243 -36
  131. package/Utils/Monitor/NetworkDeviceRoleUtil.ts +45 -0
  132. package/Utils/Monitor/NetworkTopologyUtil.ts +42 -2
  133. package/Utils/NetworkAutomation/RuleRunSummary.ts +147 -0
  134. package/build/dist/Models/DatabaseModels/NetworkDevice.js +45 -0
  135. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  136. package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js +115 -0
  137. package/build/dist/Models/DatabaseModels/NetworkDeviceLink.js.map +1 -1
  138. package/build/dist/Models/DatabaseModels/RunnerJob.js +17 -2
  139. package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
  140. package/build/dist/Server/API/LlmProviderAPI.js +9 -1
  141. package/build/dist/Server/API/LlmProviderAPI.js.map +1 -1
  142. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787400000000-AddDeviceRoleAndDeclaredLinkParent.js +33 -0
  143. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1787400000000-AddDeviceRoleAndDeclaredLinkParent.js.map +1 -0
  144. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
  145. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  146. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js +202 -0
  147. package/build/dist/Server/Services/NetworkDeviceLabelRuleEngineService.js.map +1 -1
  148. package/build/dist/Server/Services/NetworkDeviceLinkService.js +253 -1
  149. package/build/dist/Server/Services/NetworkDeviceLinkService.js.map +1 -1
  150. package/build/dist/Server/Services/NetworkDeviceService.js +223 -12
  151. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  152. package/build/dist/Server/Services/RunnerJobService.js +20 -2
  153. package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
  154. package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js +12 -5
  155. package/build/dist/Server/Types/Billing/MeteredPlan/AllMeteredPlans.js.map +1 -1
  156. package/build/dist/Server/Types/Database/JSONColumnQuery.js +40 -4
  157. package/build/dist/Server/Types/Database/JSONColumnQuery.js.map +1 -1
  158. package/build/dist/Server/Utils/LLM/LLMService.js +78 -22
  159. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  160. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +22 -98
  161. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  162. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +7 -254
  163. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  164. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js +14 -2
  165. package/build/dist/Server/Utils/Monitor/MonitorMaintenanceSuppression.js.map +1 -1
  166. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js +27 -0
  167. package/build/dist/Server/Utils/Monitor/SeriesResourceLabels.js.map +1 -1
  168. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js +285 -0
  169. package/build/dist/Server/Utils/Monitor/SeriesResourceLinker.js.map +1 -0
  170. package/build/dist/Server/Utils/SSRFProtection.js +5 -4
  171. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  172. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +128 -35
  173. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
  174. package/build/dist/Types/API/Protocol.js +9 -0
  175. package/build/dist/Types/API/Protocol.js.map +1 -1
  176. package/build/dist/Types/API/URL.js +241 -18
  177. package/build/dist/Types/API/URL.js.map +1 -1
  178. package/build/dist/Types/Billing/PayAsYouGoPricing.js +41 -0
  179. package/build/dist/Types/Billing/PayAsYouGoPricing.js.map +1 -0
  180. package/build/dist/Types/CustomField/CustomFieldType.js +26 -0
  181. package/build/dist/Types/CustomField/CustomFieldType.js.map +1 -1
  182. package/build/dist/Types/Monitor/MonitorType.js +10 -0
  183. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  184. package/build/dist/Types/NetworkAutomation/RuleRunResult.js +39 -0
  185. package/build/dist/Types/NetworkAutomation/RuleRunResult.js.map +1 -0
  186. package/build/dist/Types/Runbook/RunbookStepType.js +21 -0
  187. package/build/dist/Types/Runbook/RunbookStepType.js.map +1 -1
  188. package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js +1 -1
  189. package/build/dist/UI/Components/AutocompleteTextInput/AutocompleteTextInput.js.map +1 -1
  190. package/build/dist/UI/Components/Button/Button.js +10 -16
  191. package/build/dist/UI/Components/Button/Button.js.map +1 -1
  192. package/build/dist/UI/Components/Charts/Area/AreaChart.js +2 -1
  193. package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
  194. package/build/dist/UI/Components/Charts/Bar/BarChart.js +2 -1
  195. package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
  196. package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js +12 -0
  197. package/build/dist/UI/Components/Charts/ChartLibrary/Types/ChartDataPoint.js.map +1 -1
  198. package/build/dist/UI/Components/Charts/Line/LineChart.js +2 -1
  199. package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
  200. package/build/dist/UI/Components/Charts/Utils/DataPoint.js +17 -10
  201. package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
  202. package/build/dist/UI/Components/Dictionary/Dictionary.js +4 -18
  203. package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
  204. package/build/dist/UI/Components/Icon/Icon.js +1 -1
  205. package/build/dist/UI/Components/Icon/Icon.js.map +1 -1
  206. package/build/dist/UI/Components/LogsViewer/LogsViewer.js +3 -3
  207. package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
  208. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js +5 -1
  209. package/build/dist/UI/Components/LogsViewer/components/LogsFacetSidebar.js.map +1 -1
  210. package/build/dist/UI/Components/LogsViewer/components/LogsPagination.js +14 -44
  211. package/build/dist/UI/Components/LogsViewer/components/LogsPagination.js.map +1 -1
  212. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
  213. package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
  214. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js +20 -2
  215. package/build/dist/UI/Components/LogsViewer/components/SavedViewsDropdown.js.map +1 -1
  216. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +42 -0
  217. package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -1
  218. package/build/dist/UI/Components/Pagination/Pagination.js +174 -199
  219. package/build/dist/UI/Components/Pagination/Pagination.js.map +1 -1
  220. package/build/dist/UI/Components/Pagination/PaginationUtil.js +160 -0
  221. package/build/dist/UI/Components/Pagination/PaginationUtil.js.map +1 -0
  222. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js +20 -2
  223. package/build/dist/UI/Components/TelemetryViewer/components/SavedViewsDropdown.js.map +1 -1
  224. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryPagination.js +23 -47
  225. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryPagination.js.map +1 -1
  226. package/build/dist/UI/Components/TextArea/TextArea.js +1 -1
  227. package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
  228. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +14 -2
  229. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  230. package/build/dist/UI/Components/Workflow/ColumnEditor/AddColumnDropdown.js +86 -0
  231. package/build/dist/UI/Components/Workflow/ColumnEditor/AddColumnDropdown.js.map +1 -0
  232. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnConditionRow.js +119 -0
  233. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnConditionRow.js.map +1 -0
  234. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnControl.js +206 -0
  235. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnControl.js.map +1 -0
  236. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnFieldRow.js +57 -0
  237. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnFieldRow.js.map +1 -0
  238. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnOperators.js +150 -0
  239. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnOperators.js.map +1 -0
  240. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnRow.js +67 -0
  241. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnRow.js.map +1 -0
  242. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnRowSerialization.js +309 -0
  243. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnRowSerialization.js.map +1 -0
  244. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnValueInput.js +204 -0
  245. package/build/dist/UI/Components/Workflow/ColumnEditor/ColumnValueInput.js.map +1 -0
  246. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js +66 -0
  247. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelQueryBuilder.js.map +1 -0
  248. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelRecordForm.js +83 -0
  249. package/build/dist/UI/Components/Workflow/ColumnEditor/ModelRecordForm.js.map +1 -0
  250. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +187 -68
  251. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -1
  252. package/build/dist/UI/Utils/NetworkAutomation/RunNetworkRule.js +75 -0
  253. package/build/dist/UI/Utils/NetworkAutomation/RunNetworkRule.js.map +1 -0
  254. package/build/dist/Utils/API.js +175 -34
  255. package/build/dist/Utils/API.js.map +1 -1
  256. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +37 -0
  257. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -1
  258. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +25 -3
  259. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  260. package/build/dist/Utils/NetworkAutomation/RuleRunSummary.js +78 -0
  261. package/build/dist/Utils/NetworkAutomation/RuleRunSummary.js.map +1 -0
  262. package/package.json +1 -1
@@ -0,0 +1,304 @@
1
+ import SavedViewsDropdown, {
2
+ SavedViewsDropdownProps,
3
+ } from "../../../UI/Components/LogsViewer/components/SavedViewsDropdown";
4
+ import LogsViewerToolbar from "../../../UI/Components/LogsViewer/components/LogsViewerToolbar";
5
+ import LogsFacetSidebar from "../../../UI/Components/LogsViewer/components/LogsFacetSidebar";
6
+ import { LogsSavedViewOption } from "../../../UI/Components/LogsViewer/types";
7
+ import "@testing-library/jest-dom";
8
+ import {
9
+ cleanup,
10
+ fireEvent,
11
+ render,
12
+ screen,
13
+ RenderResult,
14
+ } from "@testing-library/react";
15
+ import React from "react";
16
+ import { afterEach, describe, expect, jest, test } from "@jest/globals";
17
+
18
+ /*
19
+ * The logs explorer grew its saved views before the shared telemetry viewer
20
+ * did, so it carries its own copy of the dropdown — and its own copy of the
21
+ * bug in issue 3189: a view could be applied but never taken back off.
22
+ *
23
+ * Everything the telemetry dropdown gained is pinned here for the logs one
24
+ * too, plus the two extra surfaces logs has that traces does not: the toolbar
25
+ * that mounts the dropdown, and the facet sidebar, which lists the same views
26
+ * again down the left-hand side and re-applied them on click.
27
+ */
28
+
29
+ const VIEWS: Array<LogsSavedViewOption> = [
30
+ { id: "errors", name: "Errors only" },
31
+ { id: "checkout", name: "Checkout service", isDefault: true },
32
+ ];
33
+
34
+ const CLEAR_LABEL: string = "Clear view";
35
+ const MENU_PROBE: string = "+ Save Current View";
36
+
37
+ interface Handlers {
38
+ onSelect: (viewId: string) => void;
39
+ onClear: () => void;
40
+ onCreate: () => void;
41
+ onEdit: (viewId: string) => void;
42
+ onDelete: (viewId: string) => void;
43
+ onUpdateCurrent: () => void;
44
+ }
45
+
46
+ function makeHandlers(): Handlers {
47
+ return {
48
+ onSelect: jest.fn(),
49
+ onClear: jest.fn(),
50
+ onCreate: jest.fn(),
51
+ onEdit: jest.fn(),
52
+ onDelete: jest.fn(),
53
+ onUpdateCurrent: jest.fn(),
54
+ };
55
+ }
56
+
57
+ function renderDropdown(
58
+ overrides: Partial<SavedViewsDropdownProps> = {},
59
+ handlers: Handlers = makeHandlers(),
60
+ ): { handlers: Handlers; result: RenderResult } {
61
+ const props: SavedViewsDropdownProps = {
62
+ savedViews: VIEWS,
63
+ selectedSavedViewId: null,
64
+ ...handlers,
65
+ ...overrides,
66
+ };
67
+
68
+ return { handlers, result: render(<SavedViewsDropdown {...props} />) };
69
+ }
70
+
71
+ function trigger(): HTMLElement {
72
+ return screen.getAllByRole("button")[0]!;
73
+ }
74
+
75
+ function openMenu(): void {
76
+ fireEvent.click(trigger());
77
+ }
78
+
79
+ function isMenuOpen(): boolean {
80
+ return screen.queryByText(MENU_PROBE) !== null;
81
+ }
82
+
83
+ function rowFor(name: string): HTMLElement {
84
+ return screen.getByRole("button", { name: name });
85
+ }
86
+
87
+ describe("LogsViewer SavedViewsDropdown — clearing the applied view", () => {
88
+ afterEach(() => {
89
+ cleanup();
90
+ });
91
+
92
+ test("clicking the applied view clears it instead of re-applying it", () => {
93
+ const { handlers } = renderDropdown({ selectedSavedViewId: "errors" });
94
+
95
+ openMenu();
96
+ fireEvent.click(rowFor("Errors only"));
97
+
98
+ expect(handlers.onClear).toHaveBeenCalledTimes(1);
99
+ expect(handlers.onSelect).not.toHaveBeenCalled();
100
+ expect(isMenuOpen()).toBe(false);
101
+ });
102
+
103
+ test("the explicit Clear view row clears and closes the menu", () => {
104
+ const { handlers } = renderDropdown({ selectedSavedViewId: "errors" });
105
+
106
+ openMenu();
107
+ fireEvent.click(rowFor(CLEAR_LABEL));
108
+
109
+ expect(handlers.onClear).toHaveBeenCalledTimes(1);
110
+ expect(handlers.onSelect).not.toHaveBeenCalled();
111
+ expect(isMenuOpen()).toBe(false);
112
+ });
113
+
114
+ test("the Clear view row is offered only while a view is applied", () => {
115
+ renderDropdown({ selectedSavedViewId: null });
116
+
117
+ openMenu();
118
+
119
+ expect(screen.queryByText(CLEAR_LABEL)).toBeNull();
120
+ });
121
+
122
+ test("a selection pointing at a view that no longer exists offers no clear row", () => {
123
+ renderDropdown({ selectedSavedViewId: "deleted-view" });
124
+
125
+ openMenu();
126
+
127
+ expect(screen.queryByText(CLEAR_LABEL)).toBeNull();
128
+ });
129
+
130
+ test("clicking a different view still applies it", () => {
131
+ const { handlers } = renderDropdown({ selectedSavedViewId: "errors" });
132
+
133
+ openMenu();
134
+ fireEvent.click(rowFor("Checkout service (default)"));
135
+
136
+ expect(handlers.onSelect).toHaveBeenCalledWith("checkout");
137
+ expect(handlers.onClear).not.toHaveBeenCalled();
138
+ });
139
+
140
+ test("aria-pressed tracks which view is applied", () => {
141
+ renderDropdown({ selectedSavedViewId: "errors" });
142
+
143
+ openMenu();
144
+
145
+ expect(rowFor("Errors only")).toHaveAttribute("aria-pressed", "true");
146
+ expect(rowFor("Checkout service (default)")).toHaveAttribute(
147
+ "aria-pressed",
148
+ "false",
149
+ );
150
+ });
151
+
152
+ test("without onClear the applied view is still merely re-applied", () => {
153
+ const { handlers } = renderDropdown({
154
+ selectedSavedViewId: "errors",
155
+ onClear: undefined,
156
+ });
157
+
158
+ openMenu();
159
+
160
+ expect(screen.queryByText(CLEAR_LABEL)).toBeNull();
161
+
162
+ fireEvent.click(rowFor("Errors only"));
163
+
164
+ expect(handlers.onSelect).toHaveBeenCalledWith("errors");
165
+ expect(handlers.onClear).not.toHaveBeenCalled();
166
+ });
167
+
168
+ test("Edit and Delete on the applied row do not clear it", () => {
169
+ const { handlers } = renderDropdown({ selectedSavedViewId: "errors" });
170
+
171
+ openMenu();
172
+ fireEvent.click(screen.getAllByRole("button", { name: "Edit" })[0]!);
173
+
174
+ expect(handlers.onEdit).toHaveBeenCalledWith("errors");
175
+
176
+ openMenu();
177
+ fireEvent.click(screen.getAllByRole("button", { name: "Delete" })[0]!);
178
+
179
+ expect(handlers.onDelete).toHaveBeenCalledWith("errors");
180
+ expect(handlers.onClear).not.toHaveBeenCalled();
181
+ });
182
+ });
183
+
184
+ /*
185
+ * The toolbar is the only thing that mounts the dropdown in the real logs
186
+ * explorer, so a clear handler that never reaches it is the same bug wearing
187
+ * a different hat. This renders the real toolbar rather than asserting on
188
+ * prop names.
189
+ */
190
+ describe("LogsViewerToolbar hands the clear handler to the dropdown", () => {
191
+ afterEach(() => {
192
+ cleanup();
193
+ });
194
+
195
+ test("Clear view appears in the toolbar's dropdown and fires the host handler", () => {
196
+ const onClearSavedView: () => void = jest.fn();
197
+ const onSavedViewSelect: (viewId: string) => void = jest.fn();
198
+
199
+ render(
200
+ <LogsViewerToolbar
201
+ resultCount={12}
202
+ savedViews={VIEWS}
203
+ selectedSavedViewId="errors"
204
+ onSavedViewSelect={onSavedViewSelect}
205
+ onClearSavedView={onClearSavedView}
206
+ />,
207
+ );
208
+
209
+ fireEvent.click(screen.getByRole("button", { name: /Errors only/ }));
210
+ fireEvent.click(screen.getByRole("button", { name: CLEAR_LABEL }));
211
+
212
+ expect(onClearSavedView).toHaveBeenCalledTimes(1);
213
+ expect(onSavedViewSelect).not.toHaveBeenCalled();
214
+ });
215
+
216
+ test("a toolbar without a clear handler shows no Clear view row", () => {
217
+ render(
218
+ <LogsViewerToolbar
219
+ resultCount={12}
220
+ savedViews={VIEWS}
221
+ selectedSavedViewId="errors"
222
+ onSavedViewSelect={jest.fn()}
223
+ />,
224
+ );
225
+
226
+ fireEvent.click(screen.getByRole("button", { name: /Errors only/ }));
227
+
228
+ expect(screen.queryByText(CLEAR_LABEL)).toBeNull();
229
+ });
230
+ });
231
+
232
+ /*
233
+ * The sidebar lists the same saved views a second time. It has no room for a
234
+ * "Clear view" row, so the toggle is the whole affordance there — and without
235
+ * it the sidebar quietly stayed a one-way door even after the dropdown was
236
+ * fixed.
237
+ */
238
+ describe("LogsFacetSidebar toggles the applied view off", () => {
239
+ afterEach(() => {
240
+ cleanup();
241
+ });
242
+
243
+ function renderSidebar(
244
+ onClearSavedView: (() => void) | undefined,
245
+ onSavedViewSelect: (viewId: string) => void,
246
+ ): void {
247
+ render(
248
+ <LogsFacetSidebar
249
+ facetData={{}}
250
+ isLoading={false}
251
+ serviceMap={{}}
252
+ onIncludeFilter={jest.fn()}
253
+ onExcludeFilter={jest.fn()}
254
+ savedViews={VIEWS}
255
+ selectedSavedViewId="errors"
256
+ onSavedViewSelect={onSavedViewSelect}
257
+ onClearSavedView={onClearSavedView}
258
+ />,
259
+ );
260
+ }
261
+
262
+ test("clicking the applied view clears it", () => {
263
+ const onClearSavedView: () => void = jest.fn();
264
+ const onSavedViewSelect: (viewId: string) => void = jest.fn();
265
+
266
+ renderSidebar(onClearSavedView, onSavedViewSelect);
267
+ fireEvent.click(screen.getByRole("button", { name: /Errors only/ }));
268
+
269
+ expect(onClearSavedView).toHaveBeenCalledTimes(1);
270
+ expect(onSavedViewSelect).not.toHaveBeenCalled();
271
+ });
272
+
273
+ test("clicking another view still applies it", () => {
274
+ const onClearSavedView: () => void = jest.fn();
275
+ const onSavedViewSelect: (viewId: string) => void = jest.fn();
276
+
277
+ renderSidebar(onClearSavedView, onSavedViewSelect);
278
+ fireEvent.click(screen.getByRole("button", { name: /Checkout service/ }));
279
+
280
+ expect(onSavedViewSelect).toHaveBeenCalledWith("checkout");
281
+ expect(onClearSavedView).not.toHaveBeenCalled();
282
+ });
283
+
284
+ test("the applied row reports itself as pressed", () => {
285
+ renderSidebar(jest.fn(), jest.fn());
286
+
287
+ expect(screen.getByRole("button", { name: /Errors only/ })).toHaveAttribute(
288
+ "aria-pressed",
289
+ "true",
290
+ );
291
+ expect(
292
+ screen.getByRole("button", { name: /Checkout service/ }),
293
+ ).toHaveAttribute("aria-pressed", "false");
294
+ });
295
+
296
+ test("a sidebar without a clear handler re-applies as before", () => {
297
+ const onSavedViewSelect: (viewId: string) => void = jest.fn();
298
+
299
+ renderSidebar(undefined, onSavedViewSelect);
300
+ fireEvent.click(screen.getByRole("button", { name: /Errors only/ }));
301
+
302
+ expect(onSavedViewSelect).toHaveBeenCalledWith("errors");
303
+ });
304
+ });
@@ -0,0 +1,179 @@
1
+ import { LogsSavedViewOption } from "../../../UI/Components/LogsViewer/types";
2
+ import "@testing-library/jest-dom";
3
+ import {
4
+ cleanup,
5
+ fireEvent,
6
+ render,
7
+ screen,
8
+ waitFor,
9
+ } from "@testing-library/react";
10
+ import React from "react";
11
+ import { afterEach, describe, expect, jest, test } from "@jest/globals";
12
+ import getJestMockFunction, { MockFunction } from "../../MockType";
13
+
14
+ /*
15
+ * LogsViewer is the container between the logs explorer and the two places a
16
+ * saved view can be picked — the toolbar dropdown and the facet sidebar. Both
17
+ * of those are covered directly in LogsSavedViewsDropdown.test.tsx, and the
18
+ * host's clearSavedView is covered in App/Tests/Dashboard. This file is the
19
+ * middle link: the passthrough that connects them.
20
+ *
21
+ * It is worth its own file because that link is invisible when it breaks.
22
+ * Deleting `onClearSavedView: props.onClearSavedView` from the toolbar props
23
+ * object leaves the dropdown rendering, the host handler defined, every other
24
+ * test green — and the "Clear view" row simply never appears again, which is
25
+ * the original bug back in place.
26
+ *
27
+ * The container loads services and log attributes on mount, so both API
28
+ * surfaces are mocked out; nothing here depends on what they return beyond
29
+ * their resolving.
30
+ */
31
+
32
+ /*
33
+ * Declared before jest.mock but dereferenced inside the factories: ts-jest
34
+ * hoists the jest.mock calls above these initializers, so naming the mocks
35
+ * directly in a factory would capture undefined.
36
+ */
37
+ const getListMock: MockFunction = getJestMockFunction();
38
+ const postMock: MockFunction = getJestMockFunction();
39
+
40
+ jest.mock("../../../UI/Utils/ModelAPI/ModelAPI", () => {
41
+ return {
42
+ __esModule: true,
43
+ default: {
44
+ getList: (...args: Array<any>) => {
45
+ return getListMock(...args);
46
+ },
47
+ getCommonHeaders: () => {
48
+ return {};
49
+ },
50
+ },
51
+ };
52
+ });
53
+
54
+ jest.mock("../../../UI/Utils/API/API", () => {
55
+ return {
56
+ __esModule: true,
57
+ default: {
58
+ post: (...args: Array<any>) => {
59
+ return postMock(...args);
60
+ },
61
+ getFriendlyErrorMessage: (error: Error) => {
62
+ return error.message;
63
+ },
64
+ getFriendlyMessage: (error: Error) => {
65
+ return error.message;
66
+ },
67
+ },
68
+ };
69
+ });
70
+
71
+ getListMock.mockImplementation(() => {
72
+ return Promise.resolve({ data: [], count: 0, skip: 0, limit: 0 });
73
+ });
74
+
75
+ postMock.mockImplementation(() => {
76
+ return Promise.resolve({ data: {} });
77
+ });
78
+
79
+ // Imported after the mock so the container picks the mocked ModelAPI up.
80
+ import LogsViewer from "../../../UI/Components/LogsViewer/LogsViewer";
81
+
82
+ const VIEWS: Array<LogsSavedViewOption> = [
83
+ { id: "errors", name: "Errors only" },
84
+ { id: "checkout", name: "Checkout service", isDefault: true },
85
+ ];
86
+
87
+ const CLEAR_LABEL: string = "Clear view";
88
+
89
+ interface RenderedViewer {
90
+ onClearSavedView: () => void;
91
+ onSavedViewSelect: (viewId: string) => void;
92
+ }
93
+
94
+ async function renderViewer(
95
+ withClearHandler: boolean,
96
+ ): Promise<RenderedViewer> {
97
+ const onClearSavedView: () => void = jest.fn();
98
+ const onSavedViewSelect: (viewId: string) => void = jest.fn();
99
+
100
+ render(
101
+ <LogsViewer
102
+ logs={[]}
103
+ isLoading={false}
104
+ filterData={{}}
105
+ onFilterChanged={jest.fn()}
106
+ facetData={{}}
107
+ savedViews={VIEWS}
108
+ selectedSavedViewId="errors"
109
+ onSavedViewSelect={onSavedViewSelect}
110
+ {...(withClearHandler ? { onClearSavedView: onClearSavedView } : {})}
111
+ />,
112
+ );
113
+
114
+ // The container renders a loader until its service lookup resolves.
115
+ await waitFor(() => {
116
+ expect(screen.getAllByRole("button").length).toBeGreaterThan(0);
117
+ });
118
+
119
+ return {
120
+ onClearSavedView: onClearSavedView,
121
+ onSavedViewSelect: onSavedViewSelect,
122
+ };
123
+ }
124
+
125
+ function savedViewButtons(): Array<HTMLElement> {
126
+ return screen.getAllByRole("button", { name: /Errors only/ });
127
+ }
128
+
129
+ describe("LogsViewer forwards the clear handler to both saved-view surfaces", () => {
130
+ afterEach(() => {
131
+ cleanup();
132
+ });
133
+
134
+ test("the toolbar dropdown offers Clear view and it reaches the host", async () => {
135
+ const { onClearSavedView, onSavedViewSelect } = await renderViewer(true);
136
+
137
+ /*
138
+ * The sidebar lists the view too, so the trigger is picked by its
139
+ * dropdown, not by name alone: the toolbar's trigger is the one that
140
+ * opens a panel containing the clear row.
141
+ */
142
+ for (const button of savedViewButtons()) {
143
+ fireEvent.click(button);
144
+ }
145
+
146
+ const clearRow: HTMLElement = screen.getByRole("button", {
147
+ name: CLEAR_LABEL,
148
+ });
149
+
150
+ fireEvent.click(clearRow);
151
+
152
+ expect(onClearSavedView).toHaveBeenCalled();
153
+ expect(onSavedViewSelect).not.toHaveBeenCalled();
154
+ });
155
+
156
+ test("the facet sidebar's applied row toggles off through the same handler", async () => {
157
+ const { onClearSavedView, onSavedViewSelect } = await renderViewer(true);
158
+
159
+ /*
160
+ * The sidebar's entry is a plain row rather than a dropdown trigger, so
161
+ * clicking it is the clear. It is the first of the two matches because
162
+ * the sidebar renders before the table column.
163
+ */
164
+ fireEvent.click(savedViewButtons()[0]!);
165
+
166
+ expect(onClearSavedView).toHaveBeenCalled();
167
+ expect(onSavedViewSelect).not.toHaveBeenCalled();
168
+ });
169
+
170
+ test("a host that passes no clear handler still gets the old behaviour", async () => {
171
+ const { onClearSavedView, onSavedViewSelect } = await renderViewer(false);
172
+
173
+ fireEvent.click(savedViewButtons()[0]!);
174
+
175
+ expect(screen.queryByText(CLEAR_LABEL)).toBeNull();
176
+ expect(onClearSavedView).not.toHaveBeenCalled();
177
+ expect(onSavedViewSelect).toHaveBeenCalledWith("errors");
178
+ });
179
+ });