@oneuptime/common 11.6.1 → 11.6.2

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 (397) hide show
  1. package/Models/AnalyticsModels/Index.ts +4 -0
  2. package/Models/AnalyticsModels/KubernetesCostAllocation.ts +842 -0
  3. package/Models/AnalyticsModels/NetworkFlow.ts +54 -0
  4. package/Models/AnalyticsModels/SloHistory.ts +240 -0
  5. package/Models/DatabaseModels/Index.ts +20 -0
  6. package/Models/DatabaseModels/NetworkDevice.ts +453 -6
  7. package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +7 -6
  8. package/Models/DatabaseModels/NetworkEndpoint.ts +753 -0
  9. package/Models/DatabaseModels/NetworkSite.ts +1155 -0
  10. package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +517 -0
  11. package/Models/DatabaseModels/NetworkSiteLink.ts +611 -0
  12. package/Models/DatabaseModels/NetworkSiteStatusTimeline.ts +520 -0
  13. package/Models/DatabaseModels/NetworkSiteType.ts +499 -0
  14. package/Models/DatabaseModels/ServiceLevelObjective.ts +1106 -0
  15. package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +762 -0
  16. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +444 -0
  17. package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +443 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.ts +359 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.ts +48 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.ts +65 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.ts +88 -0
  22. package/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.ts +391 -0
  23. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  24. package/Server/Services/AnalyticsDatabaseService.ts +25 -9
  25. package/Server/Services/Index.ts +24 -0
  26. package/Server/Services/KubernetesCostAllocationService.ts +14 -0
  27. package/Server/Services/MetricService.ts +21 -2
  28. package/Server/Services/MonitorService.ts +22 -0
  29. package/Server/Services/NetworkDeviceService.ts +438 -2
  30. package/Server/Services/NetworkEndpointService.ts +414 -0
  31. package/Server/Services/NetworkSiteAssignmentRuleService.ts +98 -0
  32. package/Server/Services/NetworkSiteLinkService.ts +10 -0
  33. package/Server/Services/NetworkSiteService.ts +1254 -0
  34. package/Server/Services/NetworkSiteStatusTimelineService.ts +10 -0
  35. package/Server/Services/NetworkSiteTypeService.ts +10 -0
  36. package/Server/Services/ProjectService.ts +122 -2
  37. package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +457 -0
  38. package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +10 -0
  39. package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +10 -0
  40. package/Server/Services/ServiceLevelObjectiveService.ts +677 -0
  41. package/Server/Services/SloHistoryService.ts +101 -0
  42. package/Server/Services/UserNotificationSettingService.ts +37 -0
  43. package/Server/Types/AnalyticsDatabase/AggregateBy.ts +9 -0
  44. package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +15 -0
  45. package/Server/Utils/AnalyticsDatabase/Statement.ts +39 -3
  46. package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +87 -48
  47. package/Server/Utils/Memory.ts +9 -1
  48. package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +190 -12
  49. package/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  50. package/Server/Utils/Monitor/DnsResolutionCache.ts +129 -0
  51. package/Server/Utils/Monitor/MonitorResource.ts +4 -30
  52. package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +214 -39
  53. package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +343 -0
  54. package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +251 -0
  55. package/Server/Utils/Monitor/NetworkInventoryUtil.ts +176 -142
  56. package/Server/Utils/Monitor/OuiLookupUtil.ts +49 -0
  57. package/Server/Utils/Monitor/SnmpInterfaceRateUtil.ts +17 -13
  58. package/Server/Utils/WhatsAppTemplateUtil.ts +7 -3
  59. package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +135 -0
  60. package/Tests/Models/NetworkSiteHierarchy.test.ts +134 -0
  61. package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +239 -0
  62. package/Tests/Server/Services/KubernetesCostAllocationAggregate.test.ts +338 -0
  63. package/Tests/Server/Services/MetricServiceAggregate.test.ts +142 -0
  64. package/Tests/Server/Services/NetworkDeviceSiteAssignment.test.ts +484 -0
  65. package/Tests/Server/Services/NetworkEndpointServiceUpsert.test.ts +686 -0
  66. package/Tests/Server/Services/NetworkSiteAssignmentRuleService.test.ts +185 -0
  67. package/Tests/Server/Services/NetworkSiteService.test.ts +1354 -0
  68. package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +1313 -0
  69. package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +1988 -0
  70. package/Tests/Server/Utils/AnalyticsDatabase/Statement.test.ts +22 -0
  71. package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +404 -0
  72. package/Tests/Server/Utils/Encryption.test.ts +70 -0
  73. package/Tests/Server/Utils/FileAttachmentMarkdownUtil.test.ts +225 -0
  74. package/Tests/Server/Utils/JsonWebToken.test.ts +175 -0
  75. package/Tests/Server/Utils/LocalFile.test.ts +258 -0
  76. package/Tests/Server/Utils/Memory.test.ts +213 -0
  77. package/Tests/Server/Utils/Monitor/Criteria/LogMonitorCriteria.test.ts +30 -0
  78. package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +385 -0
  79. package/Tests/Server/Utils/Monitor/DnsResolutionCache.test.ts +194 -0
  80. package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +155 -0
  81. package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +600 -0
  82. package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +151 -124
  83. package/Tests/Server/Utils/Monitor/SnmpInterfaceRateUtil.test.ts +496 -0
  84. package/Tests/Server/Utils/MonitorCriteriaDataExtractor.test.ts +175 -0
  85. package/Tests/Server/Utils/MonitorCriteriaMessageFormatter.test.ts +282 -0
  86. package/Tests/Server/Utils/OuiLookupUtil.test.ts +59 -0
  87. package/Tests/Server/Utils/SeriesResourceLabels.test.ts +117 -0
  88. package/Tests/Server/Utils/StackTraceParser.test.ts +370 -0
  89. package/Tests/Server/Utils/Stream.test.ts +87 -0
  90. package/Tests/Server/Utils/ValidateGlobalProviderProjectTeams.test.ts +221 -0
  91. package/Tests/Server/Utils/WhatsAppTemplateUtil.test.ts +199 -0
  92. package/Tests/Types/Database/CompareOperatorWireSerialization.test.ts +33 -0
  93. package/Tests/Types/Email.test.ts +198 -0
  94. package/Tests/Types/Kubernetes/KubernetesObjectParser.test.ts +177 -0
  95. package/Tests/Types/Log/LogQueryToFilter.test.ts +111 -0
  96. package/Tests/Types/Monitor/MonitorStepNetworkDeviceMonitor.test.ts +141 -1
  97. package/Tests/Types/Monitor/MonitorType.test.ts +59 -1
  98. package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +97 -0
  99. package/Tests/Types/Monitor/SnmpEndpointDiscovery.test.ts +151 -0
  100. package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +110 -6
  101. package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +129 -0
  102. package/Tests/Types/SerializableObjectDictionary.test.ts +166 -0
  103. package/Tests/Types/Time/RangeStartAndEndDateTime.test.ts +98 -0
  104. package/Tests/Types/WebsiteRequest.test.ts +230 -0
  105. package/Tests/UI/Components/EntityFilterRoundTrip.test.tsx +103 -0
  106. package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +612 -0
  107. package/Tests/UI/Components/ModelTable/FilterDataToQuery.test.ts +275 -0
  108. package/Tests/UI/Utils/LogExport.test.ts +159 -0
  109. package/Tests/UI/Utils/Navigation.test.ts +183 -0
  110. package/Tests/UI/Utils/TableFilterUrlState.test.ts +539 -0
  111. package/Tests/UI/Utils/TableViewUrlState.test.ts +272 -0
  112. package/Tests/Utils/Base64.test.ts +51 -0
  113. package/Tests/Utils/Boolean.test.ts +76 -0
  114. package/Tests/Utils/Crypto.test.ts +48 -0
  115. package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +259 -0
  116. package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +162 -0
  117. package/Tests/Utils/Enum.test.ts +54 -0
  118. package/Tests/Utils/IpCanonicalUtil.test.ts +85 -0
  119. package/Tests/Utils/Metrics/MetricSeriesFingerprint.test.ts +160 -0
  120. package/Tests/Utils/Monitor/EndpointAttachmentUtil.test.ts +836 -0
  121. package/Tests/Utils/Monitor/MonitorMetricType.test.ts +218 -0
  122. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +447 -0
  123. package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +440 -0
  124. package/Tests/Utils/NetworkSite/MaterializedPathUtil.test.ts +205 -0
  125. package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +221 -0
  126. package/Tests/Utils/NetworkSite/SiteUptimeUtil.test.ts +283 -0
  127. package/Tests/Utils/ObjectUtil.test.ts +30 -0
  128. package/Tests/Utils/Slo/SloStatusColor.test.ts +89 -0
  129. package/Tests/Utils/Slo/SloUtil.test.ts +1980 -0
  130. package/Tests/Utils/Slo/SloWidgetFormat.test.ts +605 -0
  131. package/Tests/Utils/TechStack.test.ts +50 -0
  132. package/Tests/Utils/Traces/CriticalPath.test.ts +178 -0
  133. package/Types/AnalyticsDatabase/AnalyticsTableName.ts +10 -0
  134. package/Types/BaseDatabase/EqualTo.ts +9 -1
  135. package/Types/BaseDatabase/EqualToOrNull.ts +9 -1
  136. package/Types/BaseDatabase/NotEqual.ts +9 -1
  137. package/Types/Dashboard/DashboardComponentType.ts +1 -0
  138. package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
  139. package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +42 -0
  140. package/Types/Dashboard/DashboardTemplates.ts +214 -0
  141. package/Types/Email/EmailTemplateType.ts +2 -0
  142. package/Types/Kubernetes/KubernetesCostIngest.ts +79 -0
  143. package/Types/Monitor/CriteriaFilter.ts +9 -0
  144. package/Types/Monitor/MonitorStep.ts +5 -8
  145. package/Types/Monitor/MonitorStepNetworkDeviceMonitor.ts +27 -5
  146. package/Types/Monitor/MonitorType.ts +15 -5
  147. package/Types/Monitor/SnmpMonitor/ArpEntry.ts +14 -0
  148. package/Types/Monitor/SnmpMonitor/FdbEntry.ts +18 -0
  149. package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +10 -3
  150. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -5
  151. package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +12 -0
  152. package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +231 -3
  153. package/Types/NetworkSite/DefaultNetworkSiteType.ts +20 -0
  154. package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
  155. package/Types/Permission.ts +449 -0
  156. package/Types/ServiceLevelObjective/SliType.ts +6 -0
  157. package/Types/ServiceLevelObjective/SloMultiMonitorMode.ts +6 -0
  158. package/Types/ServiceLevelObjective/SloStatus.ts +9 -0
  159. package/Types/ServiceLevelObjective/SloWindowType.ts +6 -0
  160. package/Types/Telemetry/ServiceType.ts +1 -0
  161. package/UI/Components/Filters/EntityFilter.tsx +16 -0
  162. package/UI/Components/Filters/FilterViewer.tsx +22 -5
  163. package/UI/Components/List/List.tsx +8 -0
  164. package/UI/Components/ModelTable/BaseModelTable.tsx +309 -106
  165. package/UI/Components/ModelTable/FilterDataToQuery.ts +172 -0
  166. package/UI/Components/Navbar/NavBar.tsx +16 -2
  167. package/UI/Components/Navbar/NavBarMenuModal.tsx +3 -3
  168. package/UI/Utils/Navigation.ts +10 -0
  169. package/UI/Utils/TableFilterUrlState.ts +204 -17
  170. package/UI/Utils/TableViewUrlState.ts +165 -0
  171. package/Utils/Dashboard/Components/DashboardSloComponent.ts +114 -0
  172. package/Utils/Dashboard/Components/Index.ts +7 -0
  173. package/Utils/IpCanonicalUtil.ts +134 -0
  174. package/Utils/Monitor/EndpointAttachmentUtil.ts +508 -0
  175. package/Utils/Monitor/NetworkTopologyUtil.ts +157 -5
  176. package/Utils/NetworkSite/CidrMatchUtil.ts +296 -0
  177. package/Utils/NetworkSite/MaterializedPathUtil.ts +115 -0
  178. package/Utils/NetworkSite/SiteStatusRollupUtil.ts +97 -0
  179. package/Utils/NetworkSite/SiteUptimeUtil.ts +111 -0
  180. package/Utils/Slo/SloStatusColor.ts +54 -0
  181. package/Utils/Slo/SloUtil.ts +637 -0
  182. package/Utils/Slo/SloWidgetFormat.ts +383 -0
  183. package/build/dist/Models/AnalyticsModels/Index.js +4 -0
  184. package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
  185. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +713 -0
  186. package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -0
  187. package/build/dist/Models/AnalyticsModels/NetworkFlow.js +44 -0
  188. package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -1
  189. package/build/dist/Models/AnalyticsModels/SloHistory.js +215 -0
  190. package/build/dist/Models/AnalyticsModels/SloHistory.js.map +1 -0
  191. package/build/dist/Models/DatabaseModels/Index.js +20 -0
  192. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  193. package/build/dist/Models/DatabaseModels/NetworkDevice.js +458 -6
  194. package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
  195. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +0 -6
  196. package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
  197. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js +779 -0
  198. package/build/dist/Models/DatabaseModels/NetworkEndpoint.js.map +1 -0
  199. package/build/dist/Models/DatabaseModels/NetworkSite.js +1180 -0
  200. package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -0
  201. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +534 -0
  202. package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -0
  203. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js +629 -0
  204. package/build/dist/Models/DatabaseModels/NetworkSiteLink.js.map +1 -0
  205. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js +538 -0
  206. package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js.map +1 -0
  207. package/build/dist/Models/DatabaseModels/NetworkSiteType.js +522 -0
  208. package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -0
  209. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +1124 -0
  210. package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -0
  211. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +769 -0
  212. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -0
  213. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +460 -0
  214. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -0
  215. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +459 -0
  216. package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -0
  217. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js +130 -0
  218. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js.map +1 -0
  219. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js +31 -0
  220. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js.map +1 -0
  221. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js +36 -0
  222. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js.map +1 -0
  223. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js +49 -0
  224. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js.map +1 -0
  225. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js +140 -0
  226. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js.map +1 -0
  227. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  228. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  229. package/build/dist/Server/Services/AnalyticsDatabaseService.js +23 -6
  230. package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
  231. package/build/dist/Server/Services/Index.js +24 -0
  232. package/build/dist/Server/Services/Index.js.map +1 -1
  233. package/build/dist/Server/Services/KubernetesCostAllocationService.js +12 -0
  234. package/build/dist/Server/Services/KubernetesCostAllocationService.js.map +1 -0
  235. package/build/dist/Server/Services/MetricService.js +21 -3
  236. package/build/dist/Server/Services/MetricService.js.map +1 -1
  237. package/build/dist/Server/Services/MonitorService.js +19 -0
  238. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  239. package/build/dist/Server/Services/NetworkDeviceService.js +351 -1
  240. package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
  241. package/build/dist/Server/Services/NetworkEndpointService.js +319 -0
  242. package/build/dist/Server/Services/NetworkEndpointService.js.map +1 -0
  243. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js +90 -0
  244. package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js.map +1 -0
  245. package/build/dist/Server/Services/NetworkSiteLinkService.js +9 -0
  246. package/build/dist/Server/Services/NetworkSiteLinkService.js.map +1 -0
  247. package/build/dist/Server/Services/NetworkSiteService.js +1038 -0
  248. package/build/dist/Server/Services/NetworkSiteService.js.map +1 -0
  249. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js +9 -0
  250. package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js.map +1 -0
  251. package/build/dist/Server/Services/NetworkSiteTypeService.js +9 -0
  252. package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -0
  253. package/build/dist/Server/Services/ProjectService.js +98 -2
  254. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  255. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +358 -0
  256. package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -0
  257. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +9 -0
  258. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -0
  259. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +9 -0
  260. package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -0
  261. package/build/dist/Server/Services/ServiceLevelObjectiveService.js +582 -0
  262. package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -0
  263. package/build/dist/Server/Services/SloHistoryService.js +77 -0
  264. package/build/dist/Server/Services/SloHistoryService.js.map +1 -0
  265. package/build/dist/Server/Services/UserNotificationSettingService.js +20 -0
  266. package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
  267. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +9 -0
  268. package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
  269. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +15 -0
  270. package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
  271. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +31 -0
  272. package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
  273. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +76 -48
  274. package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
  275. package/build/dist/Server/Utils/Memory.js +9 -1
  276. package/build/dist/Server/Utils/Memory.js.map +1 -1
  277. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +132 -10
  278. package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
  279. package/build/dist/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
  280. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js +77 -0
  281. package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js.map +1 -0
  282. package/build/dist/Server/Utils/Monitor/MonitorResource.js +21 -41
  283. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  284. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +152 -40
  285. package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
  286. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +262 -0
  287. package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -0
  288. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +201 -0
  289. package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -0
  290. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +152 -120
  291. package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
  292. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js +44 -0
  293. package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js.map +1 -0
  294. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js +10 -10
  295. package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js.map +1 -1
  296. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +5 -0
  297. package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
  298. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +10 -0
  299. package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
  300. package/build/dist/Types/BaseDatabase/EqualTo.js +9 -1
  301. package/build/dist/Types/BaseDatabase/EqualTo.js.map +1 -1
  302. package/build/dist/Types/BaseDatabase/EqualToOrNull.js +9 -1
  303. package/build/dist/Types/BaseDatabase/EqualToOrNull.js.map +1 -1
  304. package/build/dist/Types/BaseDatabase/NotEqual.js +9 -1
  305. package/build/dist/Types/BaseDatabase/NotEqual.js.map +1 -1
  306. package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
  307. package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
  308. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
  309. package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
  310. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js +23 -0
  311. package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js.map +1 -0
  312. package/build/dist/Types/Dashboard/DashboardTemplates.js +205 -0
  313. package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
  314. package/build/dist/Types/Email/EmailTemplateType.js +1 -0
  315. package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
  316. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js +21 -0
  317. package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -0
  318. package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
  319. package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
  320. package/build/dist/Types/Monitor/MonitorStep.js +5 -5
  321. package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
  322. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js +8 -0
  323. package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js.map +1 -1
  324. package/build/dist/Types/Monitor/MonitorType.js +15 -5
  325. package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
  326. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js +2 -0
  327. package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js.map +1 -0
  328. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js +2 -0
  329. package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js.map +1 -0
  330. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +9 -3
  331. package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
  332. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +217 -3
  333. package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
  334. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js +21 -0
  335. package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js.map +1 -0
  336. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
  337. package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
  338. package/build/dist/Types/Permission.js +409 -0
  339. package/build/dist/Types/Permission.js.map +1 -1
  340. package/build/dist/Types/ServiceLevelObjective/SliType.js +7 -0
  341. package/build/dist/Types/ServiceLevelObjective/SliType.js.map +1 -0
  342. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js +7 -0
  343. package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js.map +1 -0
  344. package/build/dist/Types/ServiceLevelObjective/SloStatus.js +10 -0
  345. package/build/dist/Types/ServiceLevelObjective/SloStatus.js.map +1 -0
  346. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js +7 -0
  347. package/build/dist/Types/ServiceLevelObjective/SloWindowType.js.map +1 -0
  348. package/build/dist/Types/Telemetry/ServiceType.js +1 -0
  349. package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
  350. package/build/dist/UI/Components/Filters/EntityFilter.js +15 -0
  351. package/build/dist/UI/Components/Filters/EntityFilter.js.map +1 -1
  352. package/build/dist/UI/Components/Filters/FilterViewer.js +19 -4
  353. package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
  354. package/build/dist/UI/Components/List/List.js +1 -1
  355. package/build/dist/UI/Components/List/List.js.map +1 -1
  356. package/build/dist/UI/Components/ModelTable/BaseModelTable.js +235 -89
  357. package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
  358. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js +96 -0
  359. package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js.map +1 -0
  360. package/build/dist/UI/Components/Navbar/NavBar.js +14 -2
  361. package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
  362. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +3 -2
  363. package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
  364. package/build/dist/UI/Utils/Navigation.js +9 -0
  365. package/build/dist/UI/Utils/Navigation.js.map +1 -1
  366. package/build/dist/UI/Utils/TableFilterUrlState.js +159 -15
  367. package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
  368. package/build/dist/UI/Utils/TableViewUrlState.js +103 -0
  369. package/build/dist/UI/Utils/TableViewUrlState.js.map +1 -0
  370. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +93 -0
  371. package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -0
  372. package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
  373. package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
  374. package/build/dist/Utils/IpCanonicalUtil.js +110 -0
  375. package/build/dist/Utils/IpCanonicalUtil.js.map +1 -0
  376. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js +311 -0
  377. package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js.map +1 -0
  378. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +98 -5
  379. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  380. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +222 -0
  381. package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -0
  382. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js +89 -0
  383. package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js.map +1 -0
  384. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +60 -0
  385. package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -0
  386. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js +76 -0
  387. package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js.map +1 -0
  388. package/build/dist/Utils/Slo/SloStatusColor.js +18 -0
  389. package/build/dist/Utils/Slo/SloStatusColor.js.map +1 -0
  390. package/build/dist/Utils/Slo/SloUtil.js +393 -0
  391. package/build/dist/Utils/Slo/SloUtil.js.map +1 -0
  392. package/build/dist/Utils/Slo/SloWidgetFormat.js +174 -0
  393. package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -0
  394. package/package.json +2 -2
  395. package/Types/Dashboard/DashboardComponents/Index.ts +0 -7
  396. package/build/dist/Types/Dashboard/DashboardComponents/Index.js +0 -8
  397. package/build/dist/Types/Dashboard/DashboardComponents/Index.js.map +0 -1
@@ -1,11 +1,12 @@
1
1
  import Includes from "../../../Types/BaseDatabase/Includes";
2
- import QueryOperator from "../../../Types/BaseDatabase/QueryOperator";
3
2
  import { API_DOCS_URL, BILLING_ENABLED, getAllEnvVars } from "../../Config";
4
3
  import API from "../../Utils/API/API";
5
4
  import useTranslateValue from "../../Utils/Translation";
6
5
  import { Logger } from "../../Utils/Logger";
7
6
  import Navigation from "../../Utils/Navigation";
8
7
  import TableFilterUrlState from "../../Utils/TableFilterUrlState";
8
+ import TableViewUrlState from "../../Utils/TableViewUrlState";
9
+ import buildQueryFromFilterData, { sanitizeFilterData, } from "./FilterDataToQuery";
9
10
  import PermissionUtil from "../../Utils/Permission";
10
11
  import ProjectUtil from "../../Utils/Project";
11
12
  import User from "../../Utils/User";
@@ -29,8 +30,6 @@ import AnalyticsBaseModel from "../../../Models/AnalyticsModels/AnalyticsBaseMod
29
30
  import BaseModel from "../../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
30
31
  import Route from "../../../Types/API/Route";
31
32
  import URL from "../../../Types/API/URL";
32
- import InBetween from "../../../Types/BaseDatabase/InBetween";
33
- import Search from "../../../Types/BaseDatabase/Search";
34
33
  import MultiSearch from "../../../Types/BaseDatabase/MultiSearch";
35
34
  import SortOrder from "../../../Types/BaseDatabase/SortOrder";
36
35
  import SubscriptionPlan from "../../../Types/Billing/SubscriptionPlan";
@@ -41,7 +40,6 @@ import Color from "../../../Types/Color";
41
40
  import IconProp from "../../../Types/Icon/IconProp";
42
41
  import ObjectID from "../../../Types/ObjectID";
43
42
  import Permission, { PermissionHelper, } from "../../../Types/Permission";
44
- import Typeof from "../../../Types/Typeof";
45
43
  import React, { useEffect, useMemo, useState, } from "react";
46
44
  import TableViewElement from "./TableView";
47
45
  import UserPreferences, { UserPreferenceType, } from "../../../Utils/UserPreferences";
@@ -61,7 +59,7 @@ export var ModalType;
61
59
  ModalType[ModalType["Edit"] = 1] = "Edit";
62
60
  })(ModalType || (ModalType = {}));
63
61
  const BaseModelTable = (props) => {
64
- var _a, _b;
62
+ var _a, _b, _c;
65
63
  const { translateValue, translateString } = useTranslateValue();
66
64
  const tx = (value) => {
67
65
  var _a;
@@ -106,11 +104,58 @@ const BaseModelTable = (props) => {
106
104
  }
107
105
  return props.initialItemsOnPage || 10;
108
106
  };
107
+ /*
108
+ * ---------------------------------------------------------------------
109
+ * URL-persisted view state
110
+ * ---------------------------------------------------------------------
111
+ *
112
+ * The table mirrors its filters, facets, search, sort and page into the URL
113
+ * query string so that (a) navigating into a row and pressing Back brings
114
+ * the same filtered view back, and (b) the URL can be pasted to a teammate.
115
+ *
116
+ * The snapshot is read *once, synchronously, during the first render* and
117
+ * fed to the `useState` initializers below. Restoring in an effect instead
118
+ * would fire the first fetch against the unfiltered defaults and then throw
119
+ * that response away — a visible flash of the wrong rows plus a wasted
120
+ * request.
121
+ */
122
+ const urlStateKey = props.disableUrlState
123
+ ? undefined
124
+ : props.urlStateKey ||
125
+ ((_b = props.saveFilterProps) === null || _b === void 0 ? void 0 : _b.tableId) ||
126
+ props.userPreferencesKey ||
127
+ undefined;
128
+ const initialUrlState = useMemo(() => {
129
+ const restoredFilter = TableFilterUrlState.read(urlStateKey, "filter");
130
+ /*
131
+ * Anything on the URL is user-editable, so keep only the fields this table
132
+ * actually offers a filter for before it reaches the outgoing query.
133
+ */
134
+ const sanitized = restoredFilter
135
+ ? sanitizeFilterData({
136
+ filterData: restoredFilter,
137
+ filters: props.filters,
138
+ })
139
+ : null;
140
+ return {
141
+ filter: sanitized && Object.keys(sanitized).length > 0 ? sanitized : null,
142
+ view: TableViewUrlState.fromJSON(TableFilterUrlState.read(urlStateKey, "view")),
143
+ };
144
+ }, []);
145
+ // Surfaces two tables on one page accidentally sharing a URL namespace.
146
+ useEffect(() => {
147
+ return TableFilterUrlState.claimKey(urlStateKey);
148
+ }, [urlStateKey]);
109
149
  const [orderedStatesListNewItemOrder, setOrderedStatesListNewItemOrder] = useState(null);
110
150
  const [onBeforeFetchData, setOnBeforeFetchData] = useState(undefined);
111
151
  const [data, setData] = useState([]);
112
- const [query, setQuery] = useState({});
113
- const [currentPageNumber, setCurrentPageNumber] = useState(1);
152
+ const [query, setQuery] = useState(() => {
153
+ return buildQueryFromFilterData({
154
+ filterData: initialUrlState.filter || props.initialFilterData || {},
155
+ filters: props.filters,
156
+ });
157
+ });
158
+ const [currentPageNumber, setCurrentPageNumber] = useState(initialUrlState.view.page || 1);
114
159
  const [totalItemsCount, setTotalItemsCount] = useState(0);
115
160
  /*
116
161
  * Analytics endpoints (Log/Span/Metric/...) skip COUNT(*) for
@@ -122,16 +167,37 @@ const BaseModelTable = (props) => {
122
167
  const [isLoading, setIsLoading] = useState(true);
123
168
  const [error, setError] = useState("");
124
169
  const [tableFilterError, setTableFilterError] = useState("");
125
- const [searchText, setSearchText] = useState("");
126
- const [debouncedSearchText, setDebouncedSearchText] = useState("");
170
+ const [searchText, setSearchText] = useState(initialUrlState.view.search || "");
171
+ const [debouncedSearchText, setDebouncedSearchText] = useState(initialUrlState.view.search || "");
127
172
  const [isSearchFocused, setIsSearchFocused] = useState(false);
128
- const [isSearchExpanded, setIsSearchExpanded] = useState(false);
173
+ const [isSearchExpanded, setIsSearchExpanded] = useState(Boolean(initialUrlState.view.search || (initialUrlState.view.labels || []).length));
129
174
  const searchInputRef = React.useRef(null);
130
175
  const [availableLabels, setAvailableLabels] = useState([]);
131
- const [selectedLabels, setSelectedLabels] = useState([]);
176
+ /*
177
+ * Restored label chips start as bare IDs — the id is all the query needs, so
178
+ * rows are correct on the very first fetch. The human-readable name/colour
179
+ * are filled in by the hydration effect below once the label list loads.
180
+ */
181
+ const [selectedLabels, setSelectedLabels] = useState(() => {
182
+ return (initialUrlState.view.labels || []).map((id) => {
183
+ return { id: id, name: id, color: "#94a3b8" };
184
+ });
185
+ });
132
186
  const [isLabelsLoading, setIsLabelsLoading] = useState(false);
133
187
  const [labelsFetched, setLabelsFetched] = useState(false);
134
188
  const [labelDropdownIndex, setLabelDropdownIndex] = useState(0);
189
+ /*
190
+ * Only the *ids* affect the query, so effects key off this instead of the
191
+ * array itself. Without it, merely re-labelling a chip (which happens when
192
+ * URL-restored chips get their display name hydrated) would look like a
193
+ * filter change and trigger a refetch + a jump back to page 1.
194
+ */
195
+ const selectedLabelIds = useMemo(() => {
196
+ return selectedLabels.map((l) => {
197
+ return l.id;
198
+ });
199
+ }, [selectedLabels]);
200
+ const selectedLabelIdsKey = selectedLabelIds.join(",");
135
201
  useEffect(() => {
136
202
  const handle = setTimeout(() => {
137
203
  setDebouncedSearchText(searchText);
@@ -182,11 +248,20 @@ const BaseModelTable = (props) => {
182
248
  !isSearchExpanded) {
183
249
  setIsSearchExpanded(true);
184
250
  }
185
- }, [debouncedSearchText, selectedLabels]);
251
+ }, [debouncedSearchText, selectedLabelIdsKey]);
252
+ /*
253
+ * Effects run on mount too, so without this guard the very first pass would
254
+ * stomp a page number restored from the URL back to 1.
255
+ */
256
+ const isFirstRenderRef = React.useRef(true);
186
257
  useEffect(() => {
258
+ if (isFirstRenderRef.current) {
259
+ isFirstRenderRef.current = false;
260
+ return;
261
+ }
187
262
  // reset to first page whenever the active search term or labels change
188
263
  setCurrentPageNumber(1);
189
- }, [debouncedSearchText, selectedLabels]);
264
+ }, [debouncedSearchText, selectedLabelIdsKey]);
190
265
  const labelFilterConfig = useMemo(() => {
191
266
  const filter = props.filters.find((f) => {
192
267
  return (f.filterEntityType &&
@@ -268,15 +343,55 @@ const BaseModelTable = (props) => {
268
343
  cancelled = true;
269
344
  };
270
345
  }, [isSearchExpanded, labelFilterConfig, labelsFetched]);
346
+ /*
347
+ * Chips restored from the URL only carry an id. Once the label list lands,
348
+ * swap in the real name and colour so the chip reads "Production" rather
349
+ * than a raw ObjectID. Labels that no longer exist (deleted, or not visible
350
+ * to this user) keep their id — the filter still applies, it just isn't
351
+ * pretty, which beats silently dropping a constraint from a shared link.
352
+ */
353
+ useEffect(() => {
354
+ if (availableLabels.length === 0 || selectedLabels.length === 0) {
355
+ return;
356
+ }
357
+ let didHydrate = false;
358
+ const hydrated = selectedLabels.map((selected) => {
359
+ const match = availableLabels.find((available) => {
360
+ return available.id === selected.id;
361
+ });
362
+ if (!match || match.name === selected.name) {
363
+ return selected;
364
+ }
365
+ didHydrate = true;
366
+ return match;
367
+ });
368
+ if (didHydrate) {
369
+ setSelectedLabels(hydrated);
370
+ }
371
+ }, [availableLabels]);
271
372
  const [showModel, setShowModal] = useState(false);
272
373
  const [showFilterModal, setShowFilterModal] = useState(false);
273
374
  const [modalType, setModalType] = useState(ModalType.Create);
274
- const [sortBy, setSortBy] = useState(props.sortBy || null);
275
- const [sortOrder, setSortOrder] = useState(props.sortOrder || SortOrder.Ascending);
375
+ const [sortBy, setSortBy] = useState(initialUrlState.view.sortBy ||
376
+ props.sortBy ||
377
+ null);
378
+ const [sortOrder, setSortOrder] = useState(initialUrlState.view.sortOrder || props.sortOrder || SortOrder.Ascending);
276
379
  const [showDeleteConfirmModal, setShowDeleteConfirmModal] = useState(false);
277
380
  const [currentEditableItem, setCurrentEditableItem] = useState(null);
278
381
  const [currentDeleteableItem, setCurrentDeleteableItem] = useState(null);
279
- const [itemsOnPage, setItemsOnPage] = useState(getItemsOnPage());
382
+ /*
383
+ * A page size that came in on the URL wins over the viewer's own stored
384
+ * preference — a shared link should render the same slice of rows for
385
+ * everyone who opens it.
386
+ */
387
+ const [itemsOnPage, setItemsOnPage] = useState(initialUrlState.view.itemsOnPage || getItemsOnPage());
388
+ /*
389
+ * Page size is a personal preference (it already lives in localStorage), so
390
+ * it is only put on the URL once it is explicitly part of *this* view —
391
+ * either it arrived on the link, or the viewer changed it here. Otherwise
392
+ * every table would carry a redundant `itemsOnPage` param.
393
+ */
394
+ const isItemsOnPageExplicitRef = React.useRef(Boolean(initialUrlState.view.itemsOnPage));
280
395
  useEffect(() => {
281
396
  // update items on page in localstorage.
282
397
  if (itemsOnPage && props.userPreferencesKey) {
@@ -296,6 +411,22 @@ const BaseModelTable = (props) => {
296
411
  // only update if the query has changed.
297
412
  if (JSON.stringify(currentQuery) !== JSON.stringify(newQuery)) {
298
413
  propsQueryRef.current = newQuery;
414
+ /*
415
+ * This is how facet-bar selections reach the API, so narrowing the
416
+ * result set has to send the user back to page 1 — exactly like the
417
+ * column-filter path does in `onFilterChanged`. Without it, changing a
418
+ * facet while on page 5 re-queries page 5 of a now-shorter list and
419
+ * lands on an empty page (and, since the page number is mirrored into
420
+ * the URL, shares that empty page too).
421
+ *
422
+ * When the page is already 1, `setCurrentPageNumber` is a no-op and the
423
+ * explicit fetch below is what refreshes the list; when it isn't, the
424
+ * state change re-runs the main fetch effect.
425
+ */
426
+ if (currentPageNumber !== 1) {
427
+ setCurrentPageNumber(1);
428
+ return;
429
+ }
299
430
  fetchItems().catch((err) => {
300
431
  setError(API.getFriendlyMessage(err));
301
432
  });
@@ -700,6 +831,29 @@ const BaseModelTable = (props) => {
700
831
  });
701
832
  }
702
833
  }, [showFilterModal, props.filters]);
834
+ /*
835
+ * A table restored from the URL is already filtered, so its chips have to
836
+ * render immediately — and entity/dropdown chips can only resolve their
837
+ * labels from `filterDropdownOptions`, which are otherwise fetched lazily
838
+ * when the filter popup opens. Without this, a shared link (or a Back
839
+ * navigation) showed a filtered list with no visible indication of *why*,
840
+ * and no "Clear Filters" button to escape it.
841
+ */
842
+ useEffect(() => {
843
+ var _a;
844
+ if (!initialUrlState.filter) {
845
+ return;
846
+ }
847
+ /*
848
+ * Callers use this to render their own "filters active" affordance. It is
849
+ * otherwise only fired by the filter form, so a restored view would show a
850
+ * clean banner over a filtered table.
851
+ */
852
+ (_a = props.onFilterApplied) === null || _a === void 0 ? void 0 : _a.call(props, true);
853
+ getFilterDropdownItems().catch((err) => {
854
+ setTableFilterError(API.getFriendlyMessage(err));
855
+ });
856
+ }, []);
703
857
  const getSelect = () => {
704
858
  const selectFields = getSelectFromColumns({
705
859
  columns: props.columns || [],
@@ -739,6 +893,7 @@ const BaseModelTable = (props) => {
739
893
  }
740
894
  if (props.saveFilterProps && props.saveFilterProps.tableId) {
741
895
  return (React.createElement(TableViewElement, { tableId: props.saveFilterProps.tableId, tableView: tableView, currentQuery: query, currentSortBy: sortBy, currentItemsOnPage: itemsOnPage, currentSortOrder: sortOrder, currentFacetState: props.currentFacetState, onViewChange: async (tableView) => {
896
+ var _a;
742
897
  setTableView(tableView);
743
898
  if (tableView) {
744
899
  const sortBy = Object.keys(tableView.sort || {})[0];
@@ -751,6 +906,8 @@ const BaseModelTable = (props) => {
751
906
  // then set query, sort and items on the page
752
907
  setQuery(tableView.query || {});
753
908
  setFilterData(tableView.query || {});
909
+ // a saved view pins its own page size, so it belongs on the URL
910
+ isItemsOnPageExplicitRef.current = true;
754
911
  setItemsOnPage(tableView.itemsOnPage || 10);
755
912
  setSortBy(sortBy || null);
756
913
  setSortOrder(sortOrder);
@@ -764,6 +921,13 @@ const BaseModelTable = (props) => {
764
921
  }
765
922
  else {
766
923
  setQuery({});
924
+ /*
925
+ * Also clear the filter chips. Leaving `filterData` behind kept
926
+ * the chips on screen and the `-filter` param in the URL, so the
927
+ * next visit re-applied the very filters the user just cleared.
928
+ */
929
+ setFilterData({});
930
+ (_a = props.onFilterApplied) === null || _a === void 0 ? void 0 : _a.call(props, false);
767
931
  setSortBy(null);
768
932
  setSortOrder(SortOrder.Descending);
769
933
  setItemsOnPage(10);
@@ -865,7 +1029,13 @@ const BaseModelTable = (props) => {
865
1029
  buttonSize: ButtonSize.Small,
866
1030
  className: "",
867
1031
  onClick: () => {
868
- setQuery({});
1032
+ /*
1033
+ * Just open the popup. This used to `setQuery({})` first, which
1034
+ * dropped the active filters (and refetched everything) the moment
1035
+ * the user opened the filter UI — while the chips and the URL still
1036
+ * advertised them. Filters now change only when the form applies
1037
+ * them.
1038
+ */
869
1039
  setShowFilterModal(true);
870
1040
  },
871
1041
  disabled: isFilterFetchLoading,
@@ -885,7 +1055,7 @@ const BaseModelTable = (props) => {
885
1055
  itemsOnPage,
886
1056
  query,
887
1057
  debouncedSearchText,
888
- selectedLabels,
1058
+ selectedLabelIdsKey,
889
1059
  props.refreshToggle,
890
1060
  ]);
891
1061
  const shouldDisableSort = (columnName) => {
@@ -1084,79 +1254,51 @@ const BaseModelTable = (props) => {
1084
1254
  }
1085
1255
  setActionButtonSchema(actionsSchema);
1086
1256
  };
1087
- const [filterData, setFilterData] = useState(props.initialFilterData || {});
1257
+ const [filterData, setFilterData] = useState(initialUrlState.filter || props.initialFilterData || {});
1088
1258
  const onFilterChanged = (filterData) => {
1089
- var _a;
1090
- const newQuery = {};
1091
1259
  setFilterData(filterData);
1092
1260
  setCurrentPageNumber(1);
1093
- for (const key in filterData) {
1094
- if (filterData[key] && typeof filterData[key] === Typeof.String) {
1095
- newQuery[key] = (filterData[key] || "").toString();
1096
- }
1097
- if (typeof filterData[key] === Typeof.Boolean) {
1098
- newQuery[key] = Boolean(filterData[key]);
1099
- }
1100
- if (typeof filterData[key] === Typeof.Number) {
1101
- newQuery[key] = filterData[key];
1102
- }
1103
- if (filterData[key] instanceof Date) {
1104
- newQuery[key] = filterData[key];
1105
- }
1106
- if (filterData[key] instanceof Search) {
1107
- newQuery[key] = filterData[key];
1108
- }
1109
- if (filterData[key] instanceof InBetween) {
1110
- newQuery[key] = filterData[key];
1111
- }
1112
- if (((_a = props.filters.find((f) => {
1113
- return f.field && f.field[key];
1114
- })) === null || _a === void 0 ? void 0 : _a.type) === FieldType.JSON &&
1115
- typeof filterData[key] === Typeof.Object) {
1116
- newQuery[key] = filterData[key];
1117
- }
1118
- if (Array.isArray(filterData[key])) {
1119
- newQuery[key] = new Includes(filterData[key]);
1120
- }
1121
- /*
1122
- * Pass any QueryOperator instance (IncludesAll, IncludesNone, StartsWith,
1123
- * EndsWith, NotContains, EqualTo, NotEqual, GreaterThan, LessThan,
1124
- * InBetween, IsNull, NotNull, ...) through to the query as-is.
1125
- */
1126
- if (filterData[key] instanceof QueryOperator) {
1127
- newQuery[key] = filterData[key];
1128
- }
1129
- }
1130
- setQuery(Object.assign({}, newQuery));
1261
+ setQuery(buildQueryFromFilterData({
1262
+ filterData: filterData,
1263
+ filters: props.filters,
1264
+ }));
1131
1265
  };
1132
1266
  /*
1133
- * URL persistence for classic (column) filters, keyed by the table's
1134
- * `saveFilterProps.tableId`. Mirrors the facet persistence in
1135
- * `useResourceOwners` so filters survive navigating to a detail page and
1136
- * back, and so a filtered view is shareable. `hasRestoredUrlFilters` is
1137
- * state (not a ref) so the persist effect only runs after the restore has
1138
- * been applied never clobbering the snapshot with the empty default.
1267
+ * Mirror the table's view into the URL so Back restores it and the link can
1268
+ * be handed to a teammate. Restoring happens in the `useState` initializers
1269
+ * above (synchronously, before the first fetch), so there is nothing to gate
1270
+ * here: the first write after mount already carries the restored values.
1271
+ *
1272
+ * `replaceState` is used under the hood, so dragging a filter around doesn't
1273
+ * flood the back stack.
1139
1274
  */
1140
- const [hasRestoredUrlFilters, setHasRestoredUrlFilters] = useState(false);
1141
1275
  useEffect(() => {
1142
- var _a;
1143
- const restored = TableFilterUrlState.read((_a = props.saveFilterProps) === null || _a === void 0 ? void 0 : _a.tableId, "filter");
1144
- if (restored) {
1145
- /*
1146
- * Re-run through onFilterChanged so the derived query is rebuilt and the
1147
- * first fetch uses the restored filters.
1148
- */
1149
- onFilterChanged(restored);
1150
- }
1151
- setHasRestoredUrlFilters(true);
1152
- }, []);
1153
- useEffect(() => {
1154
- var _a;
1155
- if (!hasRestoredUrlFilters) {
1156
- return;
1157
- }
1158
- TableFilterUrlState.write((_a = props.saveFilterProps) === null || _a === void 0 ? void 0 : _a.tableId, "filter", filterData);
1159
- }, [hasRestoredUrlFilters, filterData]);
1276
+ TableFilterUrlState.writeMany(urlStateKey, {
1277
+ filter: filterData,
1278
+ view: TableViewUrlState.toJSON({
1279
+ search: debouncedSearchText,
1280
+ labels: selectedLabelIds,
1281
+ sortBy: sortBy,
1282
+ sortOrder: sortOrder,
1283
+ page: currentPageNumber,
1284
+ itemsOnPage: isItemsOnPageExplicitRef.current
1285
+ ? itemsOnPage
1286
+ : undefined,
1287
+ }, {
1288
+ sortBy: props.sortBy,
1289
+ sortOrder: props.sortOrder,
1290
+ }),
1291
+ });
1292
+ }, [
1293
+ urlStateKey,
1294
+ filterData,
1295
+ debouncedSearchText,
1296
+ selectedLabelIdsKey,
1297
+ sortBy,
1298
+ sortOrder,
1299
+ currentPageNumber,
1300
+ itemsOnPage,
1301
+ ]);
1160
1302
  const getDeleteBulkAction = () => {
1161
1303
  return {
1162
1304
  title: "Delete",
@@ -1330,6 +1472,7 @@ const BaseModelTable = (props) => {
1330
1472
  setCurrentPageNumber(pageNumber);
1331
1473
  if (newItemsOnPage !== itemsOnPage) {
1332
1474
  setTableView(null);
1475
+ isItemsOnPageExplicitRef.current = true;
1333
1476
  }
1334
1477
  setItemsOnPage(newItemsOnPage);
1335
1478
  }, noItemsMessage: props.noItemsMessage || "", onRefreshClick: async () => {
@@ -1367,7 +1510,7 @@ const BaseModelTable = (props) => {
1367
1510
  onFilterChanged(filterData);
1368
1511
  }, onFilterRefreshClick: async () => {
1369
1512
  await getFilterDropdownItems();
1370
- }, filters: classicTableFilters, filterError: tableFilterError, isFilterLoading: isFilterFetchLoading, showFilterModal: showFilterModal, onFilterModalClose: () => {
1513
+ }, filters: classicTableFilters, filterData: filterData, filterError: tableFilterError, isFilterLoading: isFilterFetchLoading, showFilterModal: showFilterModal, onFilterModalClose: () => {
1371
1514
  setShowFilterModal(false);
1372
1515
  }, onFilterModalOpen: () => {
1373
1516
  setShowFilterModal(true);
@@ -1383,9 +1526,12 @@ const BaseModelTable = (props) => {
1383
1526
  },
1384
1527
  });
1385
1528
  await fetchItems();
1386
- }, dragDropIdField: "_id", dragDropIndexField: props.dragDropIndexField, isLoading: getTableLoadingState(), totalItemsCount: totalItemsCount, hasMore: hasMore, data: data, id: props.id, fields: fields, itemsOnPage: itemsOnPage, disablePagination: props.disablePagination || false, onNavigateToPage: async (pageNumber, itemsOnPage) => {
1529
+ }, dragDropIdField: "_id", dragDropIndexField: props.dragDropIndexField, isLoading: getTableLoadingState(), totalItemsCount: totalItemsCount, hasMore: hasMore, data: data, id: props.id, fields: fields, itemsOnPage: itemsOnPage, disablePagination: props.disablePagination || false, onNavigateToPage: async (pageNumber, newItemsOnPage) => {
1387
1530
  setCurrentPageNumber(pageNumber);
1388
- setItemsOnPage(itemsOnPage);
1531
+ if (newItemsOnPage !== itemsOnPage) {
1532
+ isItemsOnPageExplicitRef.current = true;
1533
+ }
1534
+ setItemsOnPage(newItemsOnPage);
1389
1535
  }, noItemsMessage: props.noItemsMessage || "", onRefreshClick: async () => {
1390
1536
  await fetchItems();
1391
1537
  }, actionButtons: actionButtonSchema }));
@@ -1882,9 +2028,9 @@ const BaseModelTable = (props) => {
1882
2028
  ? new ObjectID(currentEditableItem["_id"])
1883
2029
  : undefined,
1884
2030
  })) : (React.createElement(React.Fragment, null)),
1885
- showDeleteConfirmModal && (React.createElement(ConfirmModal, { title: `Delete ${props.singularName || model.singularName}`, description: `Are you sure you want to delete this ${(_b = (props.singularName ||
2031
+ showDeleteConfirmModal && (React.createElement(ConfirmModal, { title: `Delete ${props.singularName || model.singularName}`, description: `Are you sure you want to delete this ${(_c = (props.singularName ||
1886
2032
  model.singularName ||
1887
- "item")) === null || _b === void 0 ? void 0 : _b.toLowerCase()}?`, onClose: () => {
2033
+ "item")) === null || _c === void 0 ? void 0 : _c.toLowerCase()}?`, onClose: () => {
1888
2034
  setShowDeleteConfirmModal(false);
1889
2035
  }, submitButtonText: "Delete", onSubmit: async () => {
1890
2036
  if (currentDeleteableItem && currentDeleteableItem["_id"]) {