@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,271 @@
1
+ /*
2
+ * Which comparisons each kind of column offers.
3
+ *
4
+ * The rule that matters most here is the one about REPRESENTABLE_OPERATOR_TYPES:
5
+ * an operator the editor offers but cannot read back would lock the whole value
6
+ * to the JSON editor the next time the step is opened, which is the worst kind
7
+ * of bug in this file because it only shows up on the second visit.
8
+ */
9
+
10
+ import { ObjectType } from "../../../../../Types/JSON";
11
+ import {
12
+ DICTIONARY_FILTER_OPERATOR_OPTIONS,
13
+ DictionaryFilterOperator,
14
+ DictionaryFilterOperatorOption,
15
+ } from "../../../../../UI/Components/Dictionary/DictionaryFilterOperator";
16
+ import {
17
+ defaultOperatorForControl,
18
+ isKnownOperator,
19
+ operatorLabelFor,
20
+ operatorsForControl,
21
+ } from "../../../../../UI/Components/Workflow/ColumnEditor/ColumnOperators";
22
+ import { ModelColumnControl } from "../../../../../UI/Components/Workflow/ColumnEditor/ColumnRow";
23
+ import { describe, expect, test } from "@jest/globals";
24
+
25
+ /*
26
+ * A copy of the private list in ModelColumnEditor, kept here deliberately: if
27
+ * the two ever disagree this test is the thing that notices.
28
+ */
29
+ const REPRESENTABLE_OBJECT_TYPES: Array<string> = [
30
+ ObjectType.EqualTo,
31
+ ObjectType.NotEqual,
32
+ ObjectType.Search,
33
+ ObjectType.NotContains,
34
+ ObjectType.StartsWith,
35
+ ObjectType.EndsWith,
36
+ ObjectType.GreaterThan,
37
+ ObjectType.GreaterThanOrEqual,
38
+ ObjectType.LessThan,
39
+ ObjectType.LessThanOrEqual,
40
+ ObjectType.IsNull,
41
+ ObjectType.NotNull,
42
+ ObjectType.Includes,
43
+ ObjectType.IncludesNone,
44
+ ];
45
+
46
+ /*
47
+ * The UI operator names and the wire object types are separate vocabularies:
48
+ * "Contains" serializes as a Search, and the two null checks are named for what
49
+ * they show rather than for the class behind them.
50
+ */
51
+ const WIRE_TYPE_FOR_OPERATOR: Record<string, string> = {
52
+ [DictionaryFilterOperator.EqualTo]: ObjectType.EqualTo,
53
+ [DictionaryFilterOperator.NotEqual]: ObjectType.NotEqual,
54
+ [DictionaryFilterOperator.Contains]: ObjectType.Search,
55
+ [DictionaryFilterOperator.NotContains]: ObjectType.NotContains,
56
+ [DictionaryFilterOperator.StartsWith]: ObjectType.StartsWith,
57
+ [DictionaryFilterOperator.EndsWith]: ObjectType.EndsWith,
58
+ [DictionaryFilterOperator.GreaterThan]: ObjectType.GreaterThan,
59
+ [DictionaryFilterOperator.GreaterThanOrEqual]: ObjectType.GreaterThanOrEqual,
60
+ [DictionaryFilterOperator.LessThan]: ObjectType.LessThan,
61
+ [DictionaryFilterOperator.LessThanOrEqual]: ObjectType.LessThanOrEqual,
62
+ [DictionaryFilterOperator.IsEmpty]: ObjectType.IsNull,
63
+ [DictionaryFilterOperator.IsNotEmpty]: ObjectType.NotNull,
64
+ [DictionaryFilterOperator.IsAnyOf]: ObjectType.Includes,
65
+ [DictionaryFilterOperator.IsNoneOf]: ObjectType.IncludesNone,
66
+ };
67
+
68
+ describe("operatorsForControl — nothing offered that cannot be read back", () => {
69
+ test("every operator offered for every control round-trips through the editor", () => {
70
+ for (const control of Object.values(ModelColumnControl)) {
71
+ for (const operator of operatorsForControl(control)) {
72
+ const wireType: string | undefined = WIRE_TYPE_FOR_OPERATOR[operator];
73
+
74
+ expect(wireType).toBeDefined();
75
+ expect(REPRESENTABLE_OBJECT_TYPES).toContain(wireType);
76
+ }
77
+ }
78
+ });
79
+
80
+ test("every operator offered is one the dictionary layer knows how to build", () => {
81
+ for (const control of Object.values(ModelColumnControl)) {
82
+ for (const operator of operatorsForControl(control)) {
83
+ expect(isKnownOperator(operator)).toBe(true);
84
+ }
85
+ }
86
+ });
87
+
88
+ test("equals is offered by every control, and is the default", () => {
89
+ for (const control of Object.values(ModelColumnControl)) {
90
+ expect(operatorsForControl(control)).toContain(
91
+ DictionaryFilterOperator.EqualTo,
92
+ );
93
+ expect(defaultOperatorForControl(control)).toBe(
94
+ DictionaryFilterOperator.EqualTo,
95
+ );
96
+ }
97
+ });
98
+ });
99
+
100
+ describe("operatorsForControl — filtered by what the column can mean", () => {
101
+ test("a number offers the ordering comparisons and no substring ones", () => {
102
+ const operators: Array<DictionaryFilterOperator> = operatorsForControl(
103
+ ModelColumnControl.Number,
104
+ );
105
+
106
+ expect(operators).toContain(DictionaryFilterOperator.GreaterThan);
107
+ expect(operators).toContain(DictionaryFilterOperator.LessThanOrEqual);
108
+ expect(operators).not.toContain(DictionaryFilterOperator.Contains);
109
+ expect(operators).not.toContain(DictionaryFilterOperator.StartsWith);
110
+ });
111
+
112
+ test("an ID offers neither substring nor ordering — both are footguns on a uuid", () => {
113
+ const operators: Array<DictionaryFilterOperator> = operatorsForControl(
114
+ ModelColumnControl.ObjectId,
115
+ );
116
+
117
+ expect(operators).toContain(DictionaryFilterOperator.EqualTo);
118
+ expect(operators).toContain(DictionaryFilterOperator.IsAnyOf);
119
+ expect(operators).not.toContain(DictionaryFilterOperator.Contains);
120
+ expect(operators).not.toContain(DictionaryFilterOperator.GreaterThan);
121
+ });
122
+
123
+ test("a boolean offers only the four comparisons that mean anything", () => {
124
+ expect(operatorsForControl(ModelColumnControl.Boolean)).toEqual([
125
+ DictionaryFilterOperator.EqualTo,
126
+ DictionaryFilterOperator.NotEqual,
127
+ DictionaryFilterOperator.IsEmpty,
128
+ DictionaryFilterOperator.IsNotEmpty,
129
+ ]);
130
+ });
131
+
132
+ test("a date offers ordering but not membership lists", () => {
133
+ const operators: Array<DictionaryFilterOperator> = operatorsForControl(
134
+ ModelColumnControl.Date,
135
+ );
136
+
137
+ expect(operators).toContain(DictionaryFilterOperator.GreaterThan);
138
+ expect(operators).not.toContain(DictionaryFilterOperator.IsAnyOf);
139
+ expect(operators).not.toContain(DictionaryFilterOperator.Contains);
140
+ });
141
+
142
+ test("text keeps every operator it had before this filter existed", () => {
143
+ const operators: Array<DictionaryFilterOperator> = operatorsForControl(
144
+ ModelColumnControl.Text,
145
+ );
146
+
147
+ expect(operators).toContain(DictionaryFilterOperator.Contains);
148
+ expect(operators).toContain(DictionaryFilterOperator.NotContains);
149
+ expect(operators).toContain(DictionaryFilterOperator.StartsWith);
150
+ expect(operators).toContain(DictionaryFilterOperator.EndsWith);
151
+ expect(operators).toContain(DictionaryFilterOperator.IsAnyOf);
152
+ });
153
+
154
+ test("a column no row can hold still gets the widest list, not the narrowest", () => {
155
+ /*
156
+ * It is never offered in the picker, but a condition stored against one
157
+ * still renders, and narrowing that row would rewrite what it does.
158
+ */
159
+ expect(operatorsForControl(ModelColumnControl.Unsupported)).toEqual(
160
+ operatorsForControl(ModelColumnControl.Text),
161
+ );
162
+ });
163
+ });
164
+
165
+ describe("operatorsForControl — the operator already saved is never dropped", () => {
166
+ test("a contains saved against an ID column stays in that row's list", () => {
167
+ const operators: Array<DictionaryFilterOperator> = operatorsForControl(
168
+ ModelColumnControl.ObjectId,
169
+ DictionaryFilterOperator.Contains,
170
+ );
171
+
172
+ expect(operators).toContain(DictionaryFilterOperator.Contains);
173
+ });
174
+
175
+ test("an operator that is already in the list is not listed twice", () => {
176
+ const operators: Array<DictionaryFilterOperator> = operatorsForControl(
177
+ ModelColumnControl.Number,
178
+ DictionaryFilterOperator.GreaterThan,
179
+ );
180
+
181
+ expect(
182
+ operators.filter((operator: DictionaryFilterOperator) => {
183
+ return operator === DictionaryFilterOperator.GreaterThan;
184
+ }).length,
185
+ ).toBe(1);
186
+ });
187
+
188
+ test("the returned array is a copy — a caller cannot mutate the shared list", () => {
189
+ const first: Array<DictionaryFilterOperator> = operatorsForControl(
190
+ ModelColumnControl.Text,
191
+ );
192
+ first.push(DictionaryFilterOperator.GreaterThan);
193
+
194
+ expect(operatorsForControl(ModelColumnControl.Text)).not.toContain(
195
+ DictionaryFilterOperator.GreaterThan,
196
+ );
197
+ });
198
+ });
199
+
200
+ describe("operatorLabelFor", () => {
201
+ test("a date reads in date language", () => {
202
+ expect(
203
+ operatorLabelFor(
204
+ DictionaryFilterOperator.GreaterThan,
205
+ ModelColumnControl.Date,
206
+ ),
207
+ ).toBe("is after");
208
+ expect(
209
+ operatorLabelFor(
210
+ DictionaryFilterOperator.LessThanOrEqual,
211
+ ModelColumnControl.Date,
212
+ ),
213
+ ).toBe("is on or before");
214
+ });
215
+
216
+ test("a boolean reads as is / is not", () => {
217
+ expect(
218
+ operatorLabelFor(
219
+ DictionaryFilterOperator.EqualTo,
220
+ ModelColumnControl.Boolean,
221
+ ),
222
+ ).toBe("is");
223
+ expect(
224
+ operatorLabelFor(
225
+ DictionaryFilterOperator.NotEqual,
226
+ ModelColumnControl.Boolean,
227
+ ),
228
+ ).toBe("is not");
229
+ });
230
+
231
+ test("the null checks are worded as set / not set on every control", () => {
232
+ for (const control of Object.values(ModelColumnControl)) {
233
+ expect(operatorLabelFor(DictionaryFilterOperator.IsEmpty, control)).toBe(
234
+ "is not set",
235
+ );
236
+ expect(
237
+ operatorLabelFor(DictionaryFilterOperator.IsNotEmpty, control),
238
+ ).toBe("is set");
239
+ }
240
+ });
241
+
242
+ test("anything without an override keeps the shared wording", () => {
243
+ for (const option of DICTIONARY_FILTER_OPERATOR_OPTIONS) {
244
+ const label: string = operatorLabelFor(
245
+ option.operator,
246
+ ModelColumnControl.Text,
247
+ );
248
+
249
+ expect(label.length).toBeGreaterThan(0);
250
+ }
251
+
252
+ expect(
253
+ operatorLabelFor(
254
+ DictionaryFilterOperator.Contains,
255
+ ModelColumnControl.Text,
256
+ ),
257
+ ).toBe("contains");
258
+ });
259
+
260
+ test("an unknown operator falls back rather than rendering blank", () => {
261
+ const label: string = operatorLabelFor(
262
+ "SomethingElse" as DictionaryFilterOperator,
263
+ ModelColumnControl.Text,
264
+ );
265
+
266
+ const first: DictionaryFilterOperatorOption =
267
+ DICTIONARY_FILTER_OPERATOR_OPTIONS[0]!;
268
+
269
+ expect(label).toBe(first.label);
270
+ });
271
+ });
@@ -0,0 +1,119 @@
1
+ /*
2
+ * The row model, and the one function every edit goes through.
3
+ *
4
+ * changeColumnRow exists because the alternative — a callback per field — is
5
+ * silently broken in React: two of them fired from one event both close over
6
+ * the same render's row, and the second overwrites the first. That is not a
7
+ * theoretical hazard; it made a raw cell impossible to type into while the box
8
+ * on screen showed the new text, which is the worst shape a bug can take.
9
+ */
10
+
11
+ import { DictionaryFilterOperator } from "../../../../../UI/Components/Dictionary/DictionaryFilterOperator";
12
+ import {
13
+ ColumnValueMode,
14
+ ModelColumnRow,
15
+ changeColumnRow,
16
+ makeColumnRow,
17
+ } from "../../../../../UI/Components/Workflow/ColumnEditor/ColumnRow";
18
+ import { describe, expect, test } from "@jest/globals";
19
+
20
+ describe("makeColumnRow", () => {
21
+ test("fills in the defaults an untouched row has", () => {
22
+ const row: ModelColumnRow = makeColumnRow({ columnId: "name" });
23
+
24
+ expect(row.columnId).toBe("name");
25
+ expect(row.operator).toBe(DictionaryFilterOperator.EqualTo);
26
+ expect(row.valueMode).toBe(ColumnValueMode.Literal);
27
+ expect(row.text).toBe("");
28
+ expect(row.values).toEqual([]);
29
+ expect(row.isSeeded).toBe(false);
30
+ });
31
+
32
+ test("gives every row an identity of its own", () => {
33
+ /*
34
+ * React keys rows by this. Keyed by column name instead, a row whose name
35
+ * is being typed would be unmounted and remounted on every keystroke, and
36
+ * the focused input would go with it.
37
+ */
38
+ const first: ModelColumnRow = makeColumnRow({ columnId: "name" });
39
+ const second: ModelColumnRow = makeColumnRow({ columnId: "name" });
40
+
41
+ expect(first.key).not.toBe(second.key);
42
+ expect(first.key.length).toBeGreaterThan(0);
43
+ });
44
+
45
+ test("keeps a raw value only when it was given one", () => {
46
+ expect(makeColumnRow({ columnId: "a" }).rawValue).toBeUndefined();
47
+ expect(
48
+ makeColumnRow({
49
+ columnId: "a",
50
+ valueMode: ColumnValueMode.Raw,
51
+ rawValue: null,
52
+ }).rawValue,
53
+ ).toBeNull();
54
+ });
55
+ });
56
+
57
+ describe("changeColumnRow", () => {
58
+ const raw: ModelColumnRow = makeColumnRow({
59
+ columnId: "port",
60
+ valueMode: ColumnValueMode.Raw,
61
+ text: "8080",
62
+ rawValue: "8080",
63
+ });
64
+
65
+ test("carries several changes at once, which is the whole point", () => {
66
+ const next: ModelColumnRow = changeColumnRow(raw, {
67
+ text: "9090",
68
+ valueMode: ColumnValueMode.Literal,
69
+ });
70
+
71
+ expect(next.text).toBe("9090");
72
+ expect(next.valueMode).toBe(ColumnValueMode.Literal);
73
+ });
74
+
75
+ test("drops the stored original once the row stops being raw", () => {
76
+ /*
77
+ * Otherwise serialization keeps emitting the value that was read, and the
78
+ * builder's own typing never reaches the workflow.
79
+ */
80
+ const next: ModelColumnRow = changeColumnRow(raw, {
81
+ text: "9090",
82
+ valueMode: ColumnValueMode.Literal,
83
+ });
84
+
85
+ expect(next.rawValue).toBeUndefined();
86
+ });
87
+
88
+ test("keeps the stored original while the row is still raw", () => {
89
+ const next: ModelColumnRow = changeColumnRow(raw, {
90
+ columnId: "portNumber",
91
+ });
92
+
93
+ expect(next.valueMode).toBe(ColumnValueMode.Raw);
94
+ expect(next.rawValue).toBe("8080");
95
+ });
96
+
97
+ test("a row that has been edited is no longer a blank the editor opened with", () => {
98
+ const seeded: ModelColumnRow = makeColumnRow({
99
+ columnId: "name",
100
+ isSeeded: true,
101
+ });
102
+
103
+ expect(changeColumnRow(seeded, { text: "Acknowledged" }).isSeeded).toBe(
104
+ false,
105
+ );
106
+ });
107
+
108
+ test("the row keeps its identity through an edit", () => {
109
+ expect(changeColumnRow(raw, { text: "9090" }).key).toBe(raw.key);
110
+ });
111
+
112
+ test("does not mutate the row it was given", () => {
113
+ changeColumnRow(raw, { text: "9090", valueMode: ColumnValueMode.Literal });
114
+
115
+ expect(raw.text).toBe("8080");
116
+ expect(raw.valueMode).toBe(ColumnValueMode.Raw);
117
+ expect(raw.rawValue).toBe("8080");
118
+ });
119
+ });