@oneuptime/common 11.6.0 → 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.
- package/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.ts +41 -24
- package/Models/AnalyticsModels/Index.ts +4 -0
- package/Models/AnalyticsModels/KubernetesCostAllocation.ts +842 -0
- package/Models/AnalyticsModels/MetricBaselineHourly.ts +2 -0
- package/Models/AnalyticsModels/MetricItemAggMV1m.ts +5 -2
- package/Models/AnalyticsModels/MetricItemAggMV1mByContainer.ts +5 -2
- package/Models/AnalyticsModels/MetricItemAggMV1mByHostV2.ts +5 -2
- package/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.ts +5 -2
- package/Models/AnalyticsModels/MetricItemAggMV1mByService.ts +5 -2
- package/Models/AnalyticsModels/NetworkFlow.ts +54 -0
- package/Models/AnalyticsModels/SloHistory.ts +240 -0
- package/Models/DatabaseModels/Index.ts +20 -0
- package/Models/DatabaseModels/NetworkDevice.ts +453 -6
- package/Models/DatabaseModels/NetworkDeviceDiscoveryScan.ts +7 -6
- package/Models/DatabaseModels/NetworkEndpoint.ts +753 -0
- package/Models/DatabaseModels/NetworkSite.ts +1155 -0
- package/Models/DatabaseModels/NetworkSiteAssignmentRule.ts +517 -0
- package/Models/DatabaseModels/NetworkSiteLink.ts +611 -0
- package/Models/DatabaseModels/NetworkSiteStatusTimeline.ts +520 -0
- package/Models/DatabaseModels/NetworkSiteType.ts +499 -0
- package/Models/DatabaseModels/ServiceLevelObjective.ts +1106 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.ts +762 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.ts +444 -0
- package/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.ts +443 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.ts +359 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.ts +48 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.ts +65 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.ts +88 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.ts +391 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
- package/Server/Services/AnalyticsDatabaseService.ts +38 -10
- package/Server/Services/Index.ts +24 -0
- package/Server/Services/KubernetesCostAllocationService.ts +14 -0
- package/Server/Services/MetricService.ts +21 -2
- package/Server/Services/MonitorService.ts +22 -0
- package/Server/Services/NetworkDeviceService.ts +438 -2
- package/Server/Services/NetworkEndpointService.ts +414 -0
- package/Server/Services/NetworkSiteAssignmentRuleService.ts +98 -0
- package/Server/Services/NetworkSiteLinkService.ts +10 -0
- package/Server/Services/NetworkSiteService.ts +1254 -0
- package/Server/Services/NetworkSiteStatusTimelineService.ts +10 -0
- package/Server/Services/NetworkSiteTypeService.ts +10 -0
- package/Server/Services/ProjectService.ts +122 -2
- package/Server/Services/ServiceLevelObjectiveBurnRateRuleService.ts +457 -0
- package/Server/Services/ServiceLevelObjectiveOwnerTeamService.ts +10 -0
- package/Server/Services/ServiceLevelObjectiveOwnerUserService.ts +10 -0
- package/Server/Services/ServiceLevelObjectiveService.ts +677 -0
- package/Server/Services/SloHistoryService.ts +101 -0
- package/Server/Services/UserNotificationSettingService.ts +37 -0
- package/Server/Types/AnalyticsDatabase/AggregateBy.ts +9 -0
- package/Server/Types/Database/Permissions/OwnerTableRegistry.ts +15 -0
- package/Server/Utils/AnalyticsDatabase/Statement.ts +39 -3
- package/Server/Utils/AnalyticsDatabase/StatementGenerator.ts +128 -52
- package/Server/Utils/Memory.ts +9 -1
- package/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.ts +190 -12
- package/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
- package/Server/Utils/Monitor/DnsResolutionCache.ts +129 -0
- package/Server/Utils/Monitor/MonitorResource.ts +4 -30
- package/Server/Utils/Monitor/NetworkDeviceHydrationUtil.ts +214 -39
- package/Server/Utils/Monitor/NetworkDeviceMetricUtil.ts +343 -0
- package/Server/Utils/Monitor/NetworkDeviceWalkUtil.ts +251 -0
- package/Server/Utils/Monitor/NetworkInventoryUtil.ts +176 -142
- package/Server/Utils/Monitor/OuiLookupUtil.ts +49 -0
- package/Server/Utils/Monitor/SnmpInterfaceRateUtil.ts +17 -13
- package/Server/Utils/WhatsAppTemplateUtil.ts +7 -3
- package/Tests/Models/AnalyticsModels/AnalyticsBaseModel.test.ts +122 -0
- package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +135 -0
- package/Tests/Models/NetworkSiteHierarchy.test.ts +134 -0
- package/Tests/Server/Services/AnalyticsDatabaseService.test.ts +239 -0
- package/Tests/Server/Services/KubernetesCostAllocationAggregate.test.ts +338 -0
- package/Tests/Server/Services/MetricServiceAggregate.test.ts +142 -0
- package/Tests/Server/Services/NetworkDeviceSiteAssignment.test.ts +484 -0
- package/Tests/Server/Services/NetworkEndpointServiceUpsert.test.ts +686 -0
- package/Tests/Server/Services/NetworkSiteAssignmentRuleService.test.ts +185 -0
- package/Tests/Server/Services/NetworkSiteService.test.ts +1354 -0
- package/Tests/Server/Services/ServiceLevelObjectiveBurnRateRuleService.test.ts +1313 -0
- package/Tests/Server/Services/ServiceLevelObjectiveService.test.ts +1988 -0
- package/Tests/Server/Utils/AnalyticsDatabase/ClusterAwareSchema.test.ts +164 -3
- package/Tests/Server/Utils/AnalyticsDatabase/Statement.test.ts +22 -0
- package/Tests/Server/Utils/AnalyticsDatabase/StatementGenerator.test.ts +503 -0
- package/Tests/Server/Utils/Encryption.test.ts +70 -0
- package/Tests/Server/Utils/FileAttachmentMarkdownUtil.test.ts +225 -0
- package/Tests/Server/Utils/JsonWebToken.test.ts +175 -0
- package/Tests/Server/Utils/LocalFile.test.ts +258 -0
- package/Tests/Server/Utils/Memory.test.ts +213 -0
- package/Tests/Server/Utils/Monitor/Criteria/LogMonitorCriteria.test.ts +30 -0
- package/Tests/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.test.ts +385 -0
- package/Tests/Server/Utils/Monitor/DnsResolutionCache.test.ts +194 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceHydrationUtil.test.ts +155 -0
- package/Tests/Server/Utils/Monitor/NetworkDeviceWalkUtil.test.ts +600 -0
- package/Tests/Server/Utils/Monitor/NetworkInventoryUtil.test.ts +151 -124
- package/Tests/Server/Utils/Monitor/SnmpInterfaceRateUtil.test.ts +496 -0
- package/Tests/Server/Utils/MonitorCriteriaDataExtractor.test.ts +175 -0
- package/Tests/Server/Utils/MonitorCriteriaMessageFormatter.test.ts +282 -0
- package/Tests/Server/Utils/OuiLookupUtil.test.ts +59 -0
- package/Tests/Server/Utils/SeriesResourceLabels.test.ts +117 -0
- package/Tests/Server/Utils/StackTraceParser.test.ts +370 -0
- package/Tests/Server/Utils/Stream.test.ts +87 -0
- package/Tests/Server/Utils/ValidateGlobalProviderProjectTeams.test.ts +221 -0
- package/Tests/Server/Utils/WhatsAppTemplateUtil.test.ts +199 -0
- package/Tests/Types/Database/CompareOperatorWireSerialization.test.ts +33 -0
- package/Tests/Types/Email.test.ts +198 -0
- package/Tests/Types/HashCode.test.ts +41 -0
- package/Tests/Types/Kubernetes/KubernetesObjectParser.test.ts +177 -0
- package/Tests/Types/Log/LogQueryParser.test.ts +186 -0
- package/Tests/Types/Log/LogQueryToFilter.test.ts +111 -0
- package/Tests/Types/Monitor/MonitorStepNetworkDeviceMonitor.test.ts +141 -1
- package/Tests/Types/Monitor/MonitorType.test.ts +59 -1
- package/Tests/Types/Monitor/NetworkDeviceAlertPack.test.ts +97 -0
- package/Tests/Types/Monitor/SnmpEndpointDiscovery.test.ts +151 -0
- package/Tests/Types/Monitor/SnmpVendorTemplate.test.ts +110 -6
- package/Tests/Types/NetworkSite/DefaultNetworkSiteType.test.ts +129 -0
- package/Tests/Types/SerializableObjectDictionary.test.ts +166 -0
- package/Tests/Types/Time/RangeStartAndEndDateTime.test.ts +98 -0
- package/Tests/Types/WebsiteRequest.test.ts +230 -0
- package/Tests/UI/Components/EntityFilterRoundTrip.test.tsx +103 -0
- package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +612 -0
- package/Tests/UI/Components/ModelTable/FilterDataToQuery.test.ts +275 -0
- package/Tests/UI/Utils/LogExport.test.ts +159 -0
- package/Tests/UI/Utils/Navigation.test.ts +183 -0
- package/Tests/UI/Utils/TableFilterUrlState.test.ts +539 -0
- package/Tests/UI/Utils/TableViewUrlState.test.ts +272 -0
- package/Tests/Utils/Base64.test.ts +51 -0
- package/Tests/Utils/Boolean.test.ts +76 -0
- package/Tests/Utils/Crypto.test.ts +48 -0
- package/Tests/Utils/Dashboard/DashboardSloComponent.test.ts +259 -0
- package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +162 -0
- package/Tests/Utils/Dashboard/VariableInterpolation.test.ts +197 -0
- package/Tests/Utils/Enum.test.ts +54 -0
- package/Tests/Utils/IpCanonicalUtil.test.ts +85 -0
- package/Tests/Utils/Metrics/MetricSeriesFingerprint.test.ts +160 -0
- package/Tests/Utils/Monitor/EndpointAttachmentUtil.test.ts +836 -0
- package/Tests/Utils/Monitor/MonitorMetricType.test.ts +218 -0
- package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +447 -0
- package/Tests/Utils/NetworkSite/CidrMatchUtil.test.ts +440 -0
- package/Tests/Utils/NetworkSite/MaterializedPathUtil.test.ts +205 -0
- package/Tests/Utils/NetworkSite/SiteStatusRollupUtil.test.ts +221 -0
- package/Tests/Utils/NetworkSite/SiteUptimeUtil.test.ts +283 -0
- package/Tests/Utils/ObjectUtil.test.ts +30 -0
- package/Tests/Utils/Slo/SloStatusColor.test.ts +89 -0
- package/Tests/Utils/Slo/SloUtil.test.ts +1980 -0
- package/Tests/Utils/Slo/SloWidgetFormat.test.ts +605 -0
- package/Tests/Utils/TechStack.test.ts +50 -0
- package/Tests/Utils/Traces/CriticalPath.test.ts +178 -0
- package/Tests/Utils/ValueFormatter.test.ts +305 -0
- package/Types/AnalyticsDatabase/AnalyticsTableName.ts +10 -0
- package/Types/AnalyticsDatabase/TableColumn.ts +23 -0
- package/Types/BaseDatabase/EqualTo.ts +9 -1
- package/Types/BaseDatabase/EqualToOrNull.ts +9 -1
- package/Types/BaseDatabase/NotEqual.ts +9 -1
- package/Types/Dashboard/DashboardComponentType.ts +1 -0
- package/Types/Dashboard/DashboardComponents/ComponentArgument.ts +1 -0
- package/Types/Dashboard/DashboardComponents/DashboardSloComponent.ts +42 -0
- package/Types/Dashboard/DashboardTemplates.ts +214 -0
- package/Types/Email/EmailTemplateType.ts +2 -0
- package/Types/Kubernetes/KubernetesCostIngest.ts +79 -0
- package/Types/Monitor/CriteriaFilter.ts +9 -0
- package/Types/Monitor/MonitorStep.ts +5 -8
- package/Types/Monitor/MonitorStepNetworkDeviceMonitor.ts +27 -5
- package/Types/Monitor/MonitorType.ts +15 -5
- package/Types/Monitor/SnmpMonitor/ArpEntry.ts +14 -0
- package/Types/Monitor/SnmpMonitor/FdbEntry.ts +18 -0
- package/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.ts +10 -3
- package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -5
- package/Types/Monitor/SnmpMonitor/SnmpMonitorResponse.ts +12 -0
- package/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.ts +231 -3
- package/Types/NetworkSite/DefaultNetworkSiteType.ts +20 -0
- package/Types/NotificationSetting/NotificationSettingEventType.ts +4 -0
- package/Types/Permission.ts +449 -0
- package/Types/ServiceLevelObjective/SliType.ts +6 -0
- package/Types/ServiceLevelObjective/SloMultiMonitorMode.ts +6 -0
- package/Types/ServiceLevelObjective/SloStatus.ts +9 -0
- package/Types/ServiceLevelObjective/SloWindowType.ts +6 -0
- package/Types/Telemetry/ServiceType.ts +1 -0
- package/UI/Components/Filters/EntityFilter.tsx +16 -0
- package/UI/Components/Filters/FilterViewer.tsx +22 -5
- package/UI/Components/List/List.tsx +8 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +309 -106
- package/UI/Components/ModelTable/FilterDataToQuery.ts +172 -0
- package/UI/Components/Navbar/NavBar.tsx +16 -2
- package/UI/Components/Navbar/NavBarMenuModal.tsx +3 -3
- package/UI/Utils/Navigation.ts +10 -0
- package/UI/Utils/TableFilterUrlState.ts +204 -17
- package/UI/Utils/TableViewUrlState.ts +165 -0
- package/Utils/Dashboard/Components/DashboardSloComponent.ts +114 -0
- package/Utils/Dashboard/Components/Index.ts +7 -0
- package/Utils/IpCanonicalUtil.ts +134 -0
- package/Utils/Monitor/EndpointAttachmentUtil.ts +508 -0
- package/Utils/Monitor/NetworkTopologyUtil.ts +157 -5
- package/Utils/NetworkSite/CidrMatchUtil.ts +296 -0
- package/Utils/NetworkSite/MaterializedPathUtil.ts +115 -0
- package/Utils/NetworkSite/SiteStatusRollupUtil.ts +97 -0
- package/Utils/NetworkSite/SiteUptimeUtil.ts +111 -0
- package/Utils/Slo/SloStatusColor.ts +54 -0
- package/Utils/Slo/SloUtil.ts +637 -0
- package/Utils/Slo/SloWidgetFormat.ts +383 -0
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.js +25 -20
- package/build/dist/Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/Index.js +4 -0
- package/build/dist/Models/AnalyticsModels/Index.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +713 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -0
- package/build/dist/Models/AnalyticsModels/MetricBaselineHourly.js +2 -0
- package/build/dist/Models/AnalyticsModels/MetricBaselineHourly.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1m.js +5 -2
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1m.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js +5 -2
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByContainer.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByHostV2.js +5 -2
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByHostV2.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js +5 -2
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByK8sCluster.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js +5 -2
- package/build/dist/Models/AnalyticsModels/MetricItemAggMV1mByService.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js +44 -0
- package/build/dist/Models/AnalyticsModels/NetworkFlow.js.map +1 -1
- package/build/dist/Models/AnalyticsModels/SloHistory.js +215 -0
- package/build/dist/Models/AnalyticsModels/SloHistory.js.map +1 -0
- package/build/dist/Models/DatabaseModels/Index.js +20 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDevice.js +458 -6
- package/build/dist/Models/DatabaseModels/NetworkDevice.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js +0 -6
- package/build/dist/Models/DatabaseModels/NetworkDeviceDiscoveryScan.js.map +1 -1
- package/build/dist/Models/DatabaseModels/NetworkEndpoint.js +779 -0
- package/build/dist/Models/DatabaseModels/NetworkEndpoint.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSite.js +1180 -0
- package/build/dist/Models/DatabaseModels/NetworkSite.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js +534 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteAssignmentRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteLink.js +629 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteLink.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js +538 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteStatusTimeline.js.map +1 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js +522 -0
- package/build/dist/Models/DatabaseModels/NetworkSiteType.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js +1124 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjective.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js +769 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveBurnRateRule.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js +460 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerTeam.js.map +1 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js +459 -0
- package/build/dist/Models/DatabaseModels/ServiceLevelObjectiveOwnerUser.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js +130 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784757142154-AddNetworkSiteHierarchyAndEndpoints.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js +31 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784897317860-AddNetworkSiteAlerting.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js +36 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784970388777-AddNetworkDevicePollingColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js +49 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784986826214-AddNetworkSiteTypeTable.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js +140 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1784987015619-AddServiceLevelObjective.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Services/AnalyticsDatabaseService.js +32 -7
- package/build/dist/Server/Services/AnalyticsDatabaseService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +24 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/KubernetesCostAllocationService.js +12 -0
- package/build/dist/Server/Services/KubernetesCostAllocationService.js.map +1 -0
- package/build/dist/Server/Services/MetricService.js +21 -3
- package/build/dist/Server/Services/MetricService.js.map +1 -1
- package/build/dist/Server/Services/MonitorService.js +19 -0
- package/build/dist/Server/Services/MonitorService.js.map +1 -1
- package/build/dist/Server/Services/NetworkDeviceService.js +351 -1
- package/build/dist/Server/Services/NetworkDeviceService.js.map +1 -1
- package/build/dist/Server/Services/NetworkEndpointService.js +319 -0
- package/build/dist/Server/Services/NetworkEndpointService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js +90 -0
- package/build/dist/Server/Services/NetworkSiteAssignmentRuleService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteLinkService.js +9 -0
- package/build/dist/Server/Services/NetworkSiteLinkService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteService.js +1038 -0
- package/build/dist/Server/Services/NetworkSiteService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js +9 -0
- package/build/dist/Server/Services/NetworkSiteStatusTimelineService.js.map +1 -0
- package/build/dist/Server/Services/NetworkSiteTypeService.js +9 -0
- package/build/dist/Server/Services/NetworkSiteTypeService.js.map +1 -0
- package/build/dist/Server/Services/ProjectService.js +98 -2
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js +358 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveBurnRateRuleService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js +9 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerTeamService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js +9 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveOwnerUserService.js.map +1 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js +582 -0
- package/build/dist/Server/Services/ServiceLevelObjectiveService.js.map +1 -0
- package/build/dist/Server/Services/SloHistoryService.js +77 -0
- package/build/dist/Server/Services/SloHistoryService.js.map +1 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js +20 -0
- package/build/dist/Server/Services/UserNotificationSettingService.js.map +1 -1
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js +9 -0
- package/build/dist/Server/Types/AnalyticsDatabase/AggregateBy.js.map +1 -1
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js +15 -0
- package/build/dist/Server/Types/Database/Permissions/OwnerTableRegistry.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js +31 -0
- package/build/dist/Server/Utils/AnalyticsDatabase/Statement.js.map +1 -1
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js +105 -52
- package/build/dist/Server/Utils/AnalyticsDatabase/StatementGenerator.js.map +1 -1
- package/build/dist/Server/Utils/Memory.js +9 -1
- package/build/dist/Server/Utils/Memory.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js +132 -10
- package/build/dist/Server/Utils/Monitor/Criteria/SnmpMonitorCriteria.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/Data/OuiVendors.json +6920 -0
- package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js +77 -0
- package/build/dist/Server/Utils/Monitor/DnsResolutionCache.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/MonitorResource.js +21 -41
- package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js +152 -40
- package/build/dist/Server/Utils/Monitor/NetworkDeviceHydrationUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js +262 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceMetricUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js +201 -0
- package/build/dist/Server/Utils/Monitor/NetworkDeviceWalkUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js +152 -120
- package/build/dist/Server/Utils/Monitor/NetworkInventoryUtil.js.map +1 -1
- package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js +44 -0
- package/build/dist/Server/Utils/Monitor/OuiLookupUtil.js.map +1 -0
- package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js +10 -10
- package/build/dist/Server/Utils/Monitor/SnmpInterfaceRateUtil.js.map +1 -1
- package/build/dist/Server/Utils/WhatsAppTemplateUtil.js +5 -0
- package/build/dist/Server/Utils/WhatsAppTemplateUtil.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js +10 -0
- package/build/dist/Types/AnalyticsDatabase/AnalyticsTableName.js.map +1 -1
- package/build/dist/Types/AnalyticsDatabase/TableColumn.js +7 -0
- package/build/dist/Types/AnalyticsDatabase/TableColumn.js.map +1 -1
- package/build/dist/Types/BaseDatabase/EqualTo.js +9 -1
- package/build/dist/Types/BaseDatabase/EqualTo.js.map +1 -1
- package/build/dist/Types/BaseDatabase/EqualToOrNull.js +9 -1
- package/build/dist/Types/BaseDatabase/EqualToOrNull.js.map +1 -1
- package/build/dist/Types/BaseDatabase/NotEqual.js +9 -1
- package/build/dist/Types/BaseDatabase/NotEqual.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponentType.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponentType.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js +1 -0
- package/build/dist/Types/Dashboard/DashboardComponents/ComponentArgument.js.map +1 -1
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js +23 -0
- package/build/dist/Types/Dashboard/DashboardComponents/DashboardSloComponent.js.map +1 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js +205 -0
- package/build/dist/Types/Dashboard/DashboardTemplates.js.map +1 -1
- package/build/dist/Types/Email/EmailTemplateType.js +1 -0
- package/build/dist/Types/Email/EmailTemplateType.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesCostIngest.js +21 -0
- package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js +1 -0
- package/build/dist/Types/Monitor/CriteriaFilter.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStep.js +5 -5
- package/build/dist/Types/Monitor/MonitorStep.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js +8 -0
- package/build/dist/Types/Monitor/MonitorStepNetworkDeviceMonitor.js.map +1 -1
- package/build/dist/Types/Monitor/MonitorType.js +15 -5
- package/build/dist/Types/Monitor/MonitorType.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/ArpEntry.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js +2 -0
- package/build/dist/Types/Monitor/SnmpMonitor/FdbEntry.js.map +1 -0
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js +9 -3
- package/build/dist/Types/Monitor/SnmpMonitor/NetworkDeviceAlertPack.js.map +1 -1
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js +217 -3
- package/build/dist/Types/Monitor/SnmpMonitor/SnmpVendorTemplate.js.map +1 -1
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js +21 -0
- package/build/dist/Types/NetworkSite/DefaultNetworkSiteType.js.map +1 -0
- package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js +3 -0
- package/build/dist/Types/NotificationSetting/NotificationSettingEventType.js.map +1 -1
- package/build/dist/Types/Permission.js +409 -0
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/Types/ServiceLevelObjective/SliType.js +7 -0
- package/build/dist/Types/ServiceLevelObjective/SliType.js.map +1 -0
- package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js +7 -0
- package/build/dist/Types/ServiceLevelObjective/SloMultiMonitorMode.js.map +1 -0
- package/build/dist/Types/ServiceLevelObjective/SloStatus.js +10 -0
- package/build/dist/Types/ServiceLevelObjective/SloStatus.js.map +1 -0
- package/build/dist/Types/ServiceLevelObjective/SloWindowType.js +7 -0
- package/build/dist/Types/ServiceLevelObjective/SloWindowType.js.map +1 -0
- package/build/dist/Types/Telemetry/ServiceType.js +1 -0
- package/build/dist/Types/Telemetry/ServiceType.js.map +1 -1
- package/build/dist/UI/Components/Filters/EntityFilter.js +15 -0
- package/build/dist/UI/Components/Filters/EntityFilter.js.map +1 -1
- package/build/dist/UI/Components/Filters/FilterViewer.js +19 -4
- package/build/dist/UI/Components/Filters/FilterViewer.js.map +1 -1
- package/build/dist/UI/Components/List/List.js +1 -1
- package/build/dist/UI/Components/List/List.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +235 -89
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js +96 -0
- package/build/dist/UI/Components/ModelTable/FilterDataToQuery.js.map +1 -0
- package/build/dist/UI/Components/Navbar/NavBar.js +14 -2
- package/build/dist/UI/Components/Navbar/NavBar.js.map +1 -1
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js +3 -2
- package/build/dist/UI/Components/Navbar/NavBarMenuModal.js.map +1 -1
- package/build/dist/UI/Utils/Navigation.js +9 -0
- package/build/dist/UI/Utils/Navigation.js.map +1 -1
- package/build/dist/UI/Utils/TableFilterUrlState.js +159 -15
- package/build/dist/UI/Utils/TableFilterUrlState.js.map +1 -1
- package/build/dist/UI/Utils/TableViewUrlState.js +103 -0
- package/build/dist/UI/Utils/TableViewUrlState.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js +93 -0
- package/build/dist/Utils/Dashboard/Components/DashboardSloComponent.js.map +1 -0
- package/build/dist/Utils/Dashboard/Components/Index.js +4 -0
- package/build/dist/Utils/Dashboard/Components/Index.js.map +1 -1
- package/build/dist/Utils/IpCanonicalUtil.js +110 -0
- package/build/dist/Utils/IpCanonicalUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js +311 -0
- package/build/dist/Utils/Monitor/EndpointAttachmentUtil.js.map +1 -0
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +98 -5
- package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
- package/build/dist/Utils/NetworkSite/CidrMatchUtil.js +222 -0
- package/build/dist/Utils/NetworkSite/CidrMatchUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js +89 -0
- package/build/dist/Utils/NetworkSite/MaterializedPathUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js +60 -0
- package/build/dist/Utils/NetworkSite/SiteStatusRollupUtil.js.map +1 -0
- package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js +76 -0
- package/build/dist/Utils/NetworkSite/SiteUptimeUtil.js.map +1 -0
- package/build/dist/Utils/Slo/SloStatusColor.js +18 -0
- package/build/dist/Utils/Slo/SloStatusColor.js.map +1 -0
- package/build/dist/Utils/Slo/SloUtil.js +393 -0
- package/build/dist/Utils/Slo/SloUtil.js.map +1 -0
- package/build/dist/Utils/Slo/SloWidgetFormat.js +174 -0
- package/build/dist/Utils/Slo/SloWidgetFormat.js.map +1 -0
- package/package.json +2 -2
- package/Types/Dashboard/DashboardComponents/Index.ts +0 -7
- package/build/dist/Types/Dashboard/DashboardComponents/Index.js +0 -8
- package/build/dist/Types/Dashboard/DashboardComponents/Index.js.map +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
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 { GetReactElementFunction } from "../../Types/FunctionTypes";
|
|
5
4
|
import SelectEntityField from "../../Types/SelectEntityField";
|
|
@@ -13,6 +12,12 @@ import Select from "../../../Types/BaseDatabase/Select";
|
|
|
13
12
|
import { Logger } from "../../Utils/Logger";
|
|
14
13
|
import Navigation from "../../Utils/Navigation";
|
|
15
14
|
import TableFilterUrlState from "../../Utils/TableFilterUrlState";
|
|
15
|
+
import TableViewUrlState, {
|
|
16
|
+
TableViewUrlStateData,
|
|
17
|
+
} from "../../Utils/TableViewUrlState";
|
|
18
|
+
import buildQueryFromFilterData, {
|
|
19
|
+
sanitizeFilterData,
|
|
20
|
+
} from "./FilterDataToQuery";
|
|
16
21
|
import PermissionUtil from "../../Utils/Permission";
|
|
17
22
|
import ProjectUtil from "../../Utils/Project";
|
|
18
23
|
import User from "../../Utils/User";
|
|
@@ -67,8 +72,6 @@ import AccessControlModel from "../../../Models/DatabaseModels/DatabaseBaseModel
|
|
|
67
72
|
import Route from "../../../Types/API/Route";
|
|
68
73
|
import URL from "../../../Types/API/URL";
|
|
69
74
|
import { ColumnAccessControl } from "../../../Types/BaseDatabase/AccessControl";
|
|
70
|
-
import InBetween from "../../../Types/BaseDatabase/InBetween";
|
|
71
|
-
import Search from "../../../Types/BaseDatabase/Search";
|
|
72
75
|
import MultiSearch from "../../../Types/BaseDatabase/MultiSearch";
|
|
73
76
|
import SortOrder from "../../../Types/BaseDatabase/SortOrder";
|
|
74
77
|
import SubscriptionPlan, {
|
|
@@ -91,7 +94,6 @@ import Permission, {
|
|
|
91
94
|
PermissionHelper,
|
|
92
95
|
UserPermission,
|
|
93
96
|
} from "../../../Types/Permission";
|
|
94
|
-
import Typeof from "../../../Types/Typeof";
|
|
95
97
|
import React, {
|
|
96
98
|
MutableRefObject,
|
|
97
99
|
ReactElement,
|
|
@@ -287,6 +289,24 @@ export interface BaseTableProps<
|
|
|
287
289
|
* If you do not provide this key, the table will not save the user preferences in local storage.
|
|
288
290
|
*/
|
|
289
291
|
userPreferencesKey: string;
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* Namespace for this table's filter/facet/view state in the URL query
|
|
295
|
+
* string. Defaults to `saveFilterProps.tableId`, falling back to
|
|
296
|
+
* `userPreferencesKey` — both of which are already unique per table, which
|
|
297
|
+
* is what lets several tables share a page without clobbering each other.
|
|
298
|
+
*
|
|
299
|
+
* Only set this explicitly when the same table component is mounted more
|
|
300
|
+
* than once on one route and the two instances must keep separate state.
|
|
301
|
+
*/
|
|
302
|
+
urlStateKey?: string | undefined;
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Opt out of mirroring this table's filters into the URL. Use for tables
|
|
306
|
+
* inside modals/side-overs, or transient tables whose filters shouldn't
|
|
307
|
+
* outlive the page.
|
|
308
|
+
*/
|
|
309
|
+
disableUrlState?: boolean | undefined;
|
|
290
310
|
}
|
|
291
311
|
|
|
292
312
|
export interface ComponentProps<
|
|
@@ -377,6 +397,61 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
377
397
|
return props.initialItemsOnPage || 10;
|
|
378
398
|
};
|
|
379
399
|
|
|
400
|
+
/*
|
|
401
|
+
* ---------------------------------------------------------------------
|
|
402
|
+
* URL-persisted view state
|
|
403
|
+
* ---------------------------------------------------------------------
|
|
404
|
+
*
|
|
405
|
+
* The table mirrors its filters, facets, search, sort and page into the URL
|
|
406
|
+
* query string so that (a) navigating into a row and pressing Back brings
|
|
407
|
+
* the same filtered view back, and (b) the URL can be pasted to a teammate.
|
|
408
|
+
*
|
|
409
|
+
* The snapshot is read *once, synchronously, during the first render* and
|
|
410
|
+
* fed to the `useState` initializers below. Restoring in an effect instead
|
|
411
|
+
* would fire the first fetch against the unfiltered defaults and then throw
|
|
412
|
+
* that response away — a visible flash of the wrong rows plus a wasted
|
|
413
|
+
* request.
|
|
414
|
+
*/
|
|
415
|
+
const urlStateKey: string | undefined = props.disableUrlState
|
|
416
|
+
? undefined
|
|
417
|
+
: props.urlStateKey ||
|
|
418
|
+
props.saveFilterProps?.tableId ||
|
|
419
|
+
props.userPreferencesKey ||
|
|
420
|
+
undefined;
|
|
421
|
+
|
|
422
|
+
const initialUrlState: {
|
|
423
|
+
filter: FilterData<TBaseModel> | null;
|
|
424
|
+
view: TableViewUrlStateData;
|
|
425
|
+
} = useMemo(() => {
|
|
426
|
+
const restoredFilter: JSONObject | null = TableFilterUrlState.read(
|
|
427
|
+
urlStateKey,
|
|
428
|
+
"filter",
|
|
429
|
+
);
|
|
430
|
+
|
|
431
|
+
/*
|
|
432
|
+
* Anything on the URL is user-editable, so keep only the fields this table
|
|
433
|
+
* actually offers a filter for before it reaches the outgoing query.
|
|
434
|
+
*/
|
|
435
|
+
const sanitized: FilterData<TBaseModel> | null = restoredFilter
|
|
436
|
+
? sanitizeFilterData<TBaseModel>({
|
|
437
|
+
filterData: restoredFilter as unknown as FilterData<TBaseModel>,
|
|
438
|
+
filters: props.filters,
|
|
439
|
+
})
|
|
440
|
+
: null;
|
|
441
|
+
|
|
442
|
+
return {
|
|
443
|
+
filter: sanitized && Object.keys(sanitized).length > 0 ? sanitized : null,
|
|
444
|
+
view: TableViewUrlState.fromJSON(
|
|
445
|
+
TableFilterUrlState.read(urlStateKey, "view"),
|
|
446
|
+
),
|
|
447
|
+
};
|
|
448
|
+
}, []);
|
|
449
|
+
|
|
450
|
+
// Surfaces two tables on one page accidentally sharing a URL namespace.
|
|
451
|
+
useEffect(() => {
|
|
452
|
+
return TableFilterUrlState.claimKey(urlStateKey);
|
|
453
|
+
}, [urlStateKey]);
|
|
454
|
+
|
|
380
455
|
const [orderedStatesListNewItemOrder, setOrderedStatesListNewItemOrder] =
|
|
381
456
|
useState<number | null>(null);
|
|
382
457
|
|
|
@@ -384,8 +459,15 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
384
459
|
TBaseModel | undefined
|
|
385
460
|
>(undefined);
|
|
386
461
|
const [data, setData] = useState<Array<TBaseModel>>([]);
|
|
387
|
-
const [query, setQuery] = useState<Query<TBaseModel>>({
|
|
388
|
-
|
|
462
|
+
const [query, setQuery] = useState<Query<TBaseModel>>(() => {
|
|
463
|
+
return buildQueryFromFilterData<TBaseModel>({
|
|
464
|
+
filterData: initialUrlState.filter || props.initialFilterData || {},
|
|
465
|
+
filters: props.filters,
|
|
466
|
+
});
|
|
467
|
+
});
|
|
468
|
+
const [currentPageNumber, setCurrentPageNumber] = useState<number>(
|
|
469
|
+
initialUrlState.view.page || 1,
|
|
470
|
+
);
|
|
389
471
|
const [totalItemsCount, setTotalItemsCount] = useState<number>(0);
|
|
390
472
|
/*
|
|
391
473
|
* Analytics endpoints (Log/Span/Metric/...) skip COUNT(*) for
|
|
@@ -399,10 +481,18 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
399
481
|
const [error, setError] = useState<string>("");
|
|
400
482
|
const [tableFilterError, setTableFilterError] = useState<string>("");
|
|
401
483
|
|
|
402
|
-
const [searchText, setSearchText] = useState<string>(
|
|
403
|
-
|
|
484
|
+
const [searchText, setSearchText] = useState<string>(
|
|
485
|
+
initialUrlState.view.search || "",
|
|
486
|
+
);
|
|
487
|
+
const [debouncedSearchText, setDebouncedSearchText] = useState<string>(
|
|
488
|
+
initialUrlState.view.search || "",
|
|
489
|
+
);
|
|
404
490
|
const [isSearchFocused, setIsSearchFocused] = useState<boolean>(false);
|
|
405
|
-
const [isSearchExpanded, setIsSearchExpanded] = useState<boolean>(
|
|
491
|
+
const [isSearchExpanded, setIsSearchExpanded] = useState<boolean>(
|
|
492
|
+
Boolean(
|
|
493
|
+
initialUrlState.view.search || (initialUrlState.view.labels || []).length,
|
|
494
|
+
),
|
|
495
|
+
);
|
|
406
496
|
const searchInputRef: React.RefObject<HTMLInputElement> =
|
|
407
497
|
React.useRef<HTMLInputElement>(null!);
|
|
408
498
|
|
|
@@ -415,13 +505,36 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
415
505
|
const [availableLabels, setAvailableLabels] = useState<
|
|
416
506
|
Array<SearchLabelOption>
|
|
417
507
|
>([]);
|
|
508
|
+
/*
|
|
509
|
+
* Restored label chips start as bare IDs — the id is all the query needs, so
|
|
510
|
+
* rows are correct on the very first fetch. The human-readable name/colour
|
|
511
|
+
* are filled in by the hydration effect below once the label list loads.
|
|
512
|
+
*/
|
|
418
513
|
const [selectedLabels, setSelectedLabels] = useState<
|
|
419
514
|
Array<SearchLabelOption>
|
|
420
|
-
>(
|
|
515
|
+
>(() => {
|
|
516
|
+
return (initialUrlState.view.labels || []).map((id: string) => {
|
|
517
|
+
return { id: id, name: id, color: "#94a3b8" };
|
|
518
|
+
});
|
|
519
|
+
});
|
|
421
520
|
const [isLabelsLoading, setIsLabelsLoading] = useState<boolean>(false);
|
|
422
521
|
const [labelsFetched, setLabelsFetched] = useState<boolean>(false);
|
|
423
522
|
const [labelDropdownIndex, setLabelDropdownIndex] = useState<number>(0);
|
|
424
523
|
|
|
524
|
+
/*
|
|
525
|
+
* Only the *ids* affect the query, so effects key off this instead of the
|
|
526
|
+
* array itself. Without it, merely re-labelling a chip (which happens when
|
|
527
|
+
* URL-restored chips get their display name hydrated) would look like a
|
|
528
|
+
* filter change and trigger a refetch + a jump back to page 1.
|
|
529
|
+
*/
|
|
530
|
+
const selectedLabelIds: Array<string> = useMemo(() => {
|
|
531
|
+
return selectedLabels.map((l: SearchLabelOption) => {
|
|
532
|
+
return l.id;
|
|
533
|
+
});
|
|
534
|
+
}, [selectedLabels]);
|
|
535
|
+
|
|
536
|
+
const selectedLabelIdsKey: string = selectedLabelIds.join(",");
|
|
537
|
+
|
|
425
538
|
useEffect(() => {
|
|
426
539
|
const handle: ReturnType<typeof setTimeout> = setTimeout(() => {
|
|
427
540
|
setDebouncedSearchText(searchText);
|
|
@@ -477,12 +590,23 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
477
590
|
) {
|
|
478
591
|
setIsSearchExpanded(true);
|
|
479
592
|
}
|
|
480
|
-
}, [debouncedSearchText,
|
|
593
|
+
}, [debouncedSearchText, selectedLabelIdsKey]);
|
|
594
|
+
|
|
595
|
+
/*
|
|
596
|
+
* Effects run on mount too, so without this guard the very first pass would
|
|
597
|
+
* stomp a page number restored from the URL back to 1.
|
|
598
|
+
*/
|
|
599
|
+
const isFirstRenderRef: MutableRefObject<boolean> = React.useRef(true);
|
|
481
600
|
|
|
482
601
|
useEffect(() => {
|
|
602
|
+
if (isFirstRenderRef.current) {
|
|
603
|
+
isFirstRenderRef.current = false;
|
|
604
|
+
return;
|
|
605
|
+
}
|
|
606
|
+
|
|
483
607
|
// reset to first page whenever the active search term or labels change
|
|
484
608
|
setCurrentPageNumber(1);
|
|
485
|
-
}, [debouncedSearchText,
|
|
609
|
+
}, [debouncedSearchText, selectedLabelIdsKey]);
|
|
486
610
|
|
|
487
611
|
/*
|
|
488
612
|
* Auto-detect label support from the existing filters array. We look for
|
|
@@ -582,14 +706,52 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
582
706
|
};
|
|
583
707
|
}, [isSearchExpanded, labelFilterConfig, labelsFetched]);
|
|
584
708
|
|
|
709
|
+
/*
|
|
710
|
+
* Chips restored from the URL only carry an id. Once the label list lands,
|
|
711
|
+
* swap in the real name and colour so the chip reads "Production" rather
|
|
712
|
+
* than a raw ObjectID. Labels that no longer exist (deleted, or not visible
|
|
713
|
+
* to this user) keep their id — the filter still applies, it just isn't
|
|
714
|
+
* pretty, which beats silently dropping a constraint from a shared link.
|
|
715
|
+
*/
|
|
716
|
+
useEffect(() => {
|
|
717
|
+
if (availableLabels.length === 0 || selectedLabels.length === 0) {
|
|
718
|
+
return;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
let didHydrate: boolean = false;
|
|
722
|
+
|
|
723
|
+
const hydrated: Array<SearchLabelOption> = selectedLabels.map(
|
|
724
|
+
(selected: SearchLabelOption) => {
|
|
725
|
+
const match: SearchLabelOption | undefined = availableLabels.find(
|
|
726
|
+
(available: SearchLabelOption) => {
|
|
727
|
+
return available.id === selected.id;
|
|
728
|
+
},
|
|
729
|
+
);
|
|
730
|
+
|
|
731
|
+
if (!match || match.name === selected.name) {
|
|
732
|
+
return selected;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
didHydrate = true;
|
|
736
|
+
return match;
|
|
737
|
+
},
|
|
738
|
+
);
|
|
739
|
+
|
|
740
|
+
if (didHydrate) {
|
|
741
|
+
setSelectedLabels(hydrated);
|
|
742
|
+
}
|
|
743
|
+
}, [availableLabels]);
|
|
744
|
+
|
|
585
745
|
const [showModel, setShowModal] = useState<boolean>(false);
|
|
586
746
|
const [showFilterModal, setShowFilterModal] = useState<boolean>(false);
|
|
587
747
|
const [modalType, setModalType] = useState<ModalType>(ModalType.Create);
|
|
588
748
|
const [sortBy, setSortBy] = useState<keyof TBaseModel | null>(
|
|
589
|
-
|
|
749
|
+
(initialUrlState.view.sortBy as keyof TBaseModel | undefined) ||
|
|
750
|
+
props.sortBy ||
|
|
751
|
+
null,
|
|
590
752
|
);
|
|
591
753
|
const [sortOrder, setSortOrder] = useState<SortOrder>(
|
|
592
|
-
props.sortOrder || SortOrder.Ascending,
|
|
754
|
+
initialUrlState.view.sortOrder || props.sortOrder || SortOrder.Ascending,
|
|
593
755
|
);
|
|
594
756
|
const [showDeleteConfirmModal, setShowDeleteConfirmModal] =
|
|
595
757
|
useState<boolean>(false);
|
|
@@ -598,7 +760,24 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
598
760
|
const [currentDeleteableItem, setCurrentDeleteableItem] =
|
|
599
761
|
useState<TBaseModel | null>(null);
|
|
600
762
|
|
|
601
|
-
|
|
763
|
+
/*
|
|
764
|
+
* A page size that came in on the URL wins over the viewer's own stored
|
|
765
|
+
* preference — a shared link should render the same slice of rows for
|
|
766
|
+
* everyone who opens it.
|
|
767
|
+
*/
|
|
768
|
+
const [itemsOnPage, setItemsOnPage] = useState<number>(
|
|
769
|
+
initialUrlState.view.itemsOnPage || getItemsOnPage(),
|
|
770
|
+
);
|
|
771
|
+
|
|
772
|
+
/*
|
|
773
|
+
* Page size is a personal preference (it already lives in localStorage), so
|
|
774
|
+
* it is only put on the URL once it is explicitly part of *this* view —
|
|
775
|
+
* either it arrived on the link, or the viewer changed it here. Otherwise
|
|
776
|
+
* every table would carry a redundant `itemsOnPage` param.
|
|
777
|
+
*/
|
|
778
|
+
const isItemsOnPageExplicitRef: MutableRefObject<boolean> = React.useRef(
|
|
779
|
+
Boolean(initialUrlState.view.itemsOnPage),
|
|
780
|
+
);
|
|
602
781
|
|
|
603
782
|
useEffect(() => {
|
|
604
783
|
// update items on page in localstorage.
|
|
@@ -624,6 +803,24 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
624
803
|
// only update if the query has changed.
|
|
625
804
|
if (JSON.stringify(currentQuery) !== JSON.stringify(newQuery)) {
|
|
626
805
|
propsQueryRef.current = newQuery;
|
|
806
|
+
|
|
807
|
+
/*
|
|
808
|
+
* This is how facet-bar selections reach the API, so narrowing the
|
|
809
|
+
* result set has to send the user back to page 1 — exactly like the
|
|
810
|
+
* column-filter path does in `onFilterChanged`. Without it, changing a
|
|
811
|
+
* facet while on page 5 re-queries page 5 of a now-shorter list and
|
|
812
|
+
* lands on an empty page (and, since the page number is mirrored into
|
|
813
|
+
* the URL, shares that empty page too).
|
|
814
|
+
*
|
|
815
|
+
* When the page is already 1, `setCurrentPageNumber` is a no-op and the
|
|
816
|
+
* explicit fetch below is what refreshes the list; when it isn't, the
|
|
817
|
+
* state change re-runs the main fetch effect.
|
|
818
|
+
*/
|
|
819
|
+
if (currentPageNumber !== 1) {
|
|
820
|
+
setCurrentPageNumber(1);
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
|
|
627
824
|
fetchItems().catch((err: Error) => {
|
|
628
825
|
setError(API.getFriendlyMessage(err));
|
|
629
826
|
});
|
|
@@ -1204,6 +1401,31 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
1204
1401
|
}
|
|
1205
1402
|
}, [showFilterModal, props.filters]);
|
|
1206
1403
|
|
|
1404
|
+
/*
|
|
1405
|
+
* A table restored from the URL is already filtered, so its chips have to
|
|
1406
|
+
* render immediately — and entity/dropdown chips can only resolve their
|
|
1407
|
+
* labels from `filterDropdownOptions`, which are otherwise fetched lazily
|
|
1408
|
+
* when the filter popup opens. Without this, a shared link (or a Back
|
|
1409
|
+
* navigation) showed a filtered list with no visible indication of *why*,
|
|
1410
|
+
* and no "Clear Filters" button to escape it.
|
|
1411
|
+
*/
|
|
1412
|
+
useEffect(() => {
|
|
1413
|
+
if (!initialUrlState.filter) {
|
|
1414
|
+
return;
|
|
1415
|
+
}
|
|
1416
|
+
|
|
1417
|
+
/*
|
|
1418
|
+
* Callers use this to render their own "filters active" affordance. It is
|
|
1419
|
+
* otherwise only fired by the filter form, so a restored view would show a
|
|
1420
|
+
* clean banner over a filtered table.
|
|
1421
|
+
*/
|
|
1422
|
+
props.onFilterApplied?.(true);
|
|
1423
|
+
|
|
1424
|
+
getFilterDropdownItems().catch((err: Error) => {
|
|
1425
|
+
setTableFilterError(API.getFriendlyMessage(err));
|
|
1426
|
+
});
|
|
1427
|
+
}, []);
|
|
1428
|
+
|
|
1207
1429
|
type GetSelectFunction = () => Select<TBaseModel>;
|
|
1208
1430
|
|
|
1209
1431
|
const getSelect: GetSelectFunction = (): Select<TBaseModel> => {
|
|
@@ -1284,6 +1506,8 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
1284
1506
|
// then set query, sort and items on the page
|
|
1285
1507
|
setQuery(tableView.query || {});
|
|
1286
1508
|
setFilterData(tableView.query || {});
|
|
1509
|
+
// a saved view pins its own page size, so it belongs on the URL
|
|
1510
|
+
isItemsOnPageExplicitRef.current = true;
|
|
1287
1511
|
setItemsOnPage(tableView.itemsOnPage || 10);
|
|
1288
1512
|
setSortBy((sortBy as keyof TBaseModel) || null);
|
|
1289
1513
|
setSortOrder(sortOrder);
|
|
@@ -1300,6 +1524,13 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
1300
1524
|
}
|
|
1301
1525
|
} else {
|
|
1302
1526
|
setQuery({});
|
|
1527
|
+
/*
|
|
1528
|
+
* Also clear the filter chips. Leaving `filterData` behind kept
|
|
1529
|
+
* the chips on screen and the `-filter` param in the URL, so the
|
|
1530
|
+
* next visit re-applied the very filters the user just cleared.
|
|
1531
|
+
*/
|
|
1532
|
+
setFilterData({});
|
|
1533
|
+
props.onFilterApplied?.(false);
|
|
1303
1534
|
setSortBy(null);
|
|
1304
1535
|
setSortOrder(SortOrder.Descending);
|
|
1305
1536
|
setItemsOnPage(10);
|
|
@@ -1427,7 +1658,13 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
1427
1658
|
buttonSize: ButtonSize.Small,
|
|
1428
1659
|
className: "",
|
|
1429
1660
|
onClick: () => {
|
|
1430
|
-
|
|
1661
|
+
/*
|
|
1662
|
+
* Just open the popup. This used to `setQuery({})` first, which
|
|
1663
|
+
* dropped the active filters (and refetched everything) the moment
|
|
1664
|
+
* the user opened the filter UI — while the chips and the URL still
|
|
1665
|
+
* advertised them. Filters now change only when the form applies
|
|
1666
|
+
* them.
|
|
1667
|
+
*/
|
|
1431
1668
|
setShowFilterModal(true);
|
|
1432
1669
|
},
|
|
1433
1670
|
disabled: isFilterFetchLoading,
|
|
@@ -1449,7 +1686,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
1449
1686
|
itemsOnPage,
|
|
1450
1687
|
query,
|
|
1451
1688
|
debouncedSearchText,
|
|
1452
|
-
|
|
1689
|
+
selectedLabelIdsKey,
|
|
1453
1690
|
props.refreshToggle,
|
|
1454
1691
|
]);
|
|
1455
1692
|
|
|
@@ -1766,7 +2003,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
1766
2003
|
};
|
|
1767
2004
|
|
|
1768
2005
|
const [filterData, setFilterData] = useState<FilterData<TBaseModel>>(
|
|
1769
|
-
props.initialFilterData || {},
|
|
2006
|
+
initialUrlState.filter || props.initialFilterData || {},
|
|
1770
2007
|
);
|
|
1771
2008
|
|
|
1772
2009
|
type OnFilterChangedFunction = (filterData: FilterData<TBaseModel>) => void;
|
|
@@ -1774,100 +2011,56 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
1774
2011
|
const onFilterChanged: OnFilterChangedFunction = (
|
|
1775
2012
|
filterData: FilterData<TBaseModel>,
|
|
1776
2013
|
): void => {
|
|
1777
|
-
const newQuery: Query<TBaseModel> = {};
|
|
1778
|
-
|
|
1779
2014
|
setFilterData(filterData);
|
|
1780
2015
|
setCurrentPageNumber(1);
|
|
1781
2016
|
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
newQuery[key as keyof TBaseModel] = Boolean(filterData[key]);
|
|
1789
|
-
}
|
|
1790
|
-
|
|
1791
|
-
if (typeof filterData[key] === Typeof.Number) {
|
|
1792
|
-
newQuery[key as keyof TBaseModel] = filterData[key];
|
|
1793
|
-
}
|
|
1794
|
-
|
|
1795
|
-
if (filterData[key] instanceof Date) {
|
|
1796
|
-
newQuery[key as keyof TBaseModel] = filterData[key];
|
|
1797
|
-
}
|
|
1798
|
-
|
|
1799
|
-
if (filterData[key] instanceof Search) {
|
|
1800
|
-
newQuery[key as keyof TBaseModel] = filterData[key];
|
|
1801
|
-
}
|
|
1802
|
-
|
|
1803
|
-
if (filterData[key] instanceof InBetween) {
|
|
1804
|
-
newQuery[key as keyof TBaseModel] = filterData[key];
|
|
1805
|
-
}
|
|
1806
|
-
|
|
1807
|
-
if (
|
|
1808
|
-
props.filters.find((f: Filter<TBaseModel>) => {
|
|
1809
|
-
return f.field && f.field[key];
|
|
1810
|
-
})?.type === FieldType.JSON &&
|
|
1811
|
-
typeof filterData[key] === Typeof.Object
|
|
1812
|
-
) {
|
|
1813
|
-
newQuery[key as keyof TBaseModel] = filterData[key];
|
|
1814
|
-
}
|
|
1815
|
-
|
|
1816
|
-
if (Array.isArray(filterData[key])) {
|
|
1817
|
-
newQuery[key as keyof TBaseModel] = new Includes(
|
|
1818
|
-
filterData[key] as Array<string>,
|
|
1819
|
-
);
|
|
1820
|
-
}
|
|
1821
|
-
|
|
1822
|
-
/*
|
|
1823
|
-
* Pass any QueryOperator instance (IncludesAll, IncludesNone, StartsWith,
|
|
1824
|
-
* EndsWith, NotContains, EqualTo, NotEqual, GreaterThan, LessThan,
|
|
1825
|
-
* InBetween, IsNull, NotNull, ...) through to the query as-is.
|
|
1826
|
-
*/
|
|
1827
|
-
if (filterData[key] instanceof QueryOperator) {
|
|
1828
|
-
newQuery[key as keyof TBaseModel] = filterData[key];
|
|
1829
|
-
}
|
|
1830
|
-
}
|
|
1831
|
-
|
|
1832
|
-
setQuery({ ...newQuery });
|
|
2017
|
+
setQuery(
|
|
2018
|
+
buildQueryFromFilterData<TBaseModel>({
|
|
2019
|
+
filterData: filterData,
|
|
2020
|
+
filters: props.filters,
|
|
2021
|
+
}),
|
|
2022
|
+
);
|
|
1833
2023
|
};
|
|
1834
2024
|
|
|
1835
2025
|
/*
|
|
1836
|
-
*
|
|
1837
|
-
*
|
|
1838
|
-
*
|
|
1839
|
-
*
|
|
1840
|
-
*
|
|
1841
|
-
*
|
|
2026
|
+
* Mirror the table's view into the URL so Back restores it and the link can
|
|
2027
|
+
* be handed to a teammate. Restoring happens in the `useState` initializers
|
|
2028
|
+
* above (synchronously, before the first fetch), so there is nothing to gate
|
|
2029
|
+
* here: the first write after mount already carries the restored values.
|
|
2030
|
+
*
|
|
2031
|
+
* `replaceState` is used under the hood, so dragging a filter around doesn't
|
|
2032
|
+
* flood the back stack.
|
|
1842
2033
|
*/
|
|
1843
|
-
const [hasRestoredUrlFilters, setHasRestoredUrlFilters] =
|
|
1844
|
-
useState<boolean>(false);
|
|
1845
|
-
|
|
1846
2034
|
useEffect(() => {
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
2035
|
+
TableFilterUrlState.writeMany(urlStateKey, {
|
|
2036
|
+
filter: filterData as unknown as JSONObject,
|
|
2037
|
+
view: TableViewUrlState.toJSON(
|
|
2038
|
+
{
|
|
2039
|
+
search: debouncedSearchText,
|
|
2040
|
+
labels: selectedLabelIds,
|
|
2041
|
+
sortBy: sortBy as string | undefined,
|
|
2042
|
+
sortOrder: sortOrder,
|
|
2043
|
+
page: currentPageNumber,
|
|
2044
|
+
itemsOnPage: isItemsOnPageExplicitRef.current
|
|
2045
|
+
? itemsOnPage
|
|
2046
|
+
: undefined,
|
|
2047
|
+
},
|
|
2048
|
+
{
|
|
2049
|
+
sortBy: props.sortBy as string | undefined,
|
|
2050
|
+
sortOrder: props.sortOrder,
|
|
2051
|
+
},
|
|
2052
|
+
),
|
|
2053
|
+
});
|
|
2054
|
+
}, [
|
|
2055
|
+
urlStateKey,
|
|
2056
|
+
filterData,
|
|
2057
|
+
debouncedSearchText,
|
|
2058
|
+
selectedLabelIdsKey,
|
|
2059
|
+
sortBy,
|
|
2060
|
+
sortOrder,
|
|
2061
|
+
currentPageNumber,
|
|
2062
|
+
itemsOnPage,
|
|
2063
|
+
]);
|
|
1871
2064
|
|
|
1872
2065
|
type GetDeleteBulkActionFunction = () => BulkActionButtonSchema<TBaseModel>;
|
|
1873
2066
|
|
|
@@ -2161,6 +2354,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
2161
2354
|
|
|
2162
2355
|
if (newItemsOnPage !== itemsOnPage) {
|
|
2163
2356
|
setTableView(null);
|
|
2357
|
+
isItemsOnPageExplicitRef.current = true;
|
|
2164
2358
|
}
|
|
2165
2359
|
|
|
2166
2360
|
setItemsOnPage(newItemsOnPage);
|
|
@@ -2252,6 +2446,7 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
2252
2446
|
await getFilterDropdownItems();
|
|
2253
2447
|
}}
|
|
2254
2448
|
filters={classicTableFilters}
|
|
2449
|
+
filterData={filterData}
|
|
2255
2450
|
filterError={tableFilterError}
|
|
2256
2451
|
isFilterLoading={isFilterFetchLoading}
|
|
2257
2452
|
showFilterModal={showFilterModal}
|
|
@@ -2294,9 +2489,17 @@ const BaseModelTable: <TBaseModel extends BaseModel | AnalyticsBaseModel>(
|
|
|
2294
2489
|
fields={fields}
|
|
2295
2490
|
itemsOnPage={itemsOnPage}
|
|
2296
2491
|
disablePagination={props.disablePagination || false}
|
|
2297
|
-
onNavigateToPage={async (
|
|
2492
|
+
onNavigateToPage={async (
|
|
2493
|
+
pageNumber: number,
|
|
2494
|
+
newItemsOnPage: number,
|
|
2495
|
+
) => {
|
|
2298
2496
|
setCurrentPageNumber(pageNumber);
|
|
2299
|
-
|
|
2497
|
+
|
|
2498
|
+
if (newItemsOnPage !== itemsOnPage) {
|
|
2499
|
+
isItemsOnPageExplicitRef.current = true;
|
|
2500
|
+
}
|
|
2501
|
+
|
|
2502
|
+
setItemsOnPage(newItemsOnPage);
|
|
2300
2503
|
}}
|
|
2301
2504
|
noItemsMessage={props.noItemsMessage || ""}
|
|
2302
2505
|
onRefreshClick={async () => {
|