From 6678797e589751b655e26449b1bb0f7f65adc0fa Mon Sep 17 00:00:00 2001 From: ankitaakamai Date: Mon, 17 Nov 2025 11:09:00 +0530 Subject: [PATCH 1/4] upcoming: [DI-28270] - Remove firewall filtering and region filter depdency --- .../CloudPulse/Utils/FilterBuilder.test.ts | 24 ++---- .../CloudPulse/Utils/FilterBuilder.ts | 1 - .../features/CloudPulse/Utils/FilterConfig.ts | 12 +-- .../features/CloudPulse/Utils/utils.test.ts | 2 - .../shared/CloudPulseRegionSelect.test.tsx | 84 ++++--------------- .../shared/CloudPulseRegionSelect.tsx | 60 ++++--------- 6 files changed, 42 insertions(+), 141 deletions(-) diff --git a/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.test.ts b/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.test.ts index 798a0e85fec..dab4641047f 100644 --- a/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.test.ts +++ b/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.test.ts @@ -147,26 +147,20 @@ it('test getResourceSelectionProperties method for linode-firewall', () => { expect(resourceSelectionConfig).toBeDefined(); if (resourceSelectionConfig) { - const { - disabled, - handleResourcesSelection, - label, - savePreferences, - filterFn, - } = getResourcesProperties( - { - config: resourceSelectionConfig, - dashboard: { ...mockDashboard, id: 4 }, - isServiceAnalyticsIntegration: true, - }, - vi.fn() - ); + const { disabled, handleResourcesSelection, label, savePreferences } = + getResourcesProperties( + { + config: resourceSelectionConfig, + dashboard: { ...mockDashboard, id: 4 }, + isServiceAnalyticsIntegration: true, + }, + vi.fn() + ); const { name } = resourceSelectionConfig.configuration; expect(handleResourcesSelection).toBeDefined(); expect(savePreferences).toEqual(false); expect(disabled).toEqual(false); expect(label).toEqual(name); - expect(filterFn).toBeDefined(); } }); diff --git a/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts b/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts index e692d4bb05d..b63fdd76ca7 100644 --- a/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts +++ b/packages/manager/src/features/CloudPulse/Utils/FilterBuilder.ts @@ -143,7 +143,6 @@ export const getRegionProperties = ( dashboard ), xFilter: filterBasedOnConfig(config, dependentFilters ?? {}), - selectedEntities: (dependentFilters?.[RESOURCE_ID] ?? []) as string[], }; }; diff --git a/packages/manager/src/features/CloudPulse/Utils/FilterConfig.ts b/packages/manager/src/features/CloudPulse/Utils/FilterConfig.ts index bb52b6bdb2a..64fcf6f0fd5 100644 --- a/packages/manager/src/features/CloudPulse/Utils/FilterConfig.ts +++ b/packages/manager/src/features/CloudPulse/Utils/FilterConfig.ts @@ -11,10 +11,10 @@ import { RESOURCE_ID, } from './constants'; import { CloudPulseAvailableViews, CloudPulseSelectTypes } from './models'; -import { filterFirewallResources, filterKubernetesClusters } from './utils'; +import { filterKubernetesClusters } from './utils'; import type { CloudPulseServiceTypeFilterMap } from './models'; -import type { Firewall, KubernetesCluster } from '@linode/api-v4'; +import type { KubernetesCluster } from '@linode/api-v4'; const TIME_DURATION = 'Time Range'; @@ -234,7 +234,6 @@ export const FIREWALL_CONFIG: Readonly = { { configuration: { filterKey: 'resource_id', - children: [PARENT_ENTITY_REGION], filterType: 'string', isFilterable: true, isMetricsFilter: true, @@ -244,14 +243,11 @@ export const FIREWALL_CONFIG: Readonly = { placeholder: 'Select Firewalls', priority: 1, associatedEntityType: 'linode', - filterFn: (resources: Firewall[]) => - filterFirewallResources(resources, 'linode'), }, name: 'Firewalls', }, { configuration: { - dependency: ['resource_id'], filterKey: PARENT_ENTITY_REGION, filterType: 'string', isFilterable: true, @@ -339,7 +335,6 @@ export const FIREWALL_NODEBALANCER_CONFIG: Readonly - filterFirewallResources(resources, 'nodebalancer'), }, name: 'Firewall', }, { configuration: { - dependency: [RESOURCE_ID], children: [NODEBALANCER_ID], filterKey: PARENT_ENTITY_REGION, filterType: 'string', diff --git a/packages/manager/src/features/CloudPulse/Utils/utils.test.ts b/packages/manager/src/features/CloudPulse/Utils/utils.test.ts index 3c6d3be0e5f..e2258ec14bd 100644 --- a/packages/manager/src/features/CloudPulse/Utils/utils.test.ts +++ b/packages/manager/src/features/CloudPulse/Utils/utils.test.ts @@ -361,14 +361,12 @@ describe('getEnabledServiceTypes', () => { const resourcesFilterConfig = getResourcesFilterConfig(4); expect(resourcesFilterConfig).toBeDefined(); expect(resourcesFilterConfig?.associatedEntityType).toBe('linode'); - expect(resourcesFilterConfig?.filterFn).toBeDefined(); }); it('should return the resources filter configuration for the nodebalancer-firewall dashboard', () => { const resourcesFilterConfig = getResourcesFilterConfig(8); expect(resourcesFilterConfig).toBeDefined(); expect(resourcesFilterConfig?.associatedEntityType).toBe('nodebalancer'); - expect(resourcesFilterConfig?.filterFn).toBeDefined(); }); }); diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.test.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.test.tsx index 14d53e1a7e8..1b2d232e68d 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.test.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.test.tsx @@ -8,11 +8,7 @@ import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import * as React from 'react'; -import { - dashboardFactory, - databaseInstanceFactory, - firewallFactory, -} from 'src/factories'; +import { dashboardFactory, databaseInstanceFactory } from 'src/factories'; import { renderWithTheme } from 'src/utilities/testHelpers'; import { NO_REGION_MESSAGE } from '../Utils/constants'; @@ -24,7 +20,6 @@ import type { useRegionsQuery } from '@linode/queries'; const props: CloudPulseRegionSelectProps = { filterKey: 'region', - selectedEntities: [], handleRegionChange: vi.fn(), label: 'Region', selectedDashboard: undefined, @@ -327,26 +322,10 @@ describe('CloudPulseRegionSelect', () => { id: 'ap-west', label: 'IN, Mumbai', capabilities: [capabilityServiceTypeMapping['firewall']], - }), - ], - isError: false, - isLoading: false, - }); - queryMocks.useResourcesQuery.mockReturnValue({ - data: [ - firewallFactory.build({ - id: 1, - entities: [{ id: 1, type: 'linode' }], - }), - ], - isError: false, - isLoading: false, - }); - queryMocks.useAllLinodesQuery.mockReturnValue({ - data: [ - linodeFactory.build({ - id: 1, - region: 'ap-west', + monitors: { + metrics: [capabilityServiceTypeMapping['firewall']], + alerts: [], + }, }), ], isError: false, @@ -362,7 +341,6 @@ describe('CloudPulseRegionSelect', () => { service_type: 'firewall', id: 4, })} - selectedEntities={['1']} /> ); await user.click(screen.getByRole('button', { name: 'Open' })); @@ -378,31 +356,16 @@ describe('CloudPulseRegionSelect', () => { id: 'ap-west', label: 'IN, Mumbai', capabilities: [capabilityServiceTypeMapping['firewall']], + monitors: { + metrics: [capabilityServiceTypeMapping['firewall']], + alerts: [], + }, }), ], isError: false, isLoading: false, }); - queryMocks.useResourcesQuery.mockReturnValue({ - data: [ - firewallFactory.build({ - id: 1, - entities: [{ id: 1, type: 'linode' }], - }), - ], - isError: false, - isLoading: false, - }); - queryMocks.useAllLinodesQuery.mockReturnValue({ - data: [ - linodeFactory.build({ - id: 1, - region: 'ap-west', - }), - ], - isError: false, - isLoading: false, - }); + renderWithTheme( { service_type: 'firewall', id: 4, })} - selectedEntities={['1']} /> ); expect(screen.getByDisplayValue('IN, Mumbai (ap-west)')).toBeVisible(); @@ -424,31 +386,16 @@ describe('CloudPulseRegionSelect', () => { id: 'ap-west', label: 'IN, Mumbai', capabilities: [capabilityServiceTypeMapping['firewall']], + monitors: { + metrics: [capabilityServiceTypeMapping['firewall']], + alerts: [], + }, }), ], isError: false, isLoading: false, }); - queryMocks.useResourcesQuery.mockReturnValue({ - data: [ - firewallFactory.build({ - id: 1, - entities: [{ id: 1, type: 'nodebalancer' }], - }), - ], - isError: false, - isLoading: false, - }); - queryMocks.useAllNodeBalancersQuery.mockReturnValue({ - data: [ - nodeBalancerFactory.build({ - id: 1, - region: 'ap-west', - }), - ], - isError: false, - isLoading: false, - }); + renderWithTheme( { service_type: 'firewall', id: 8, })} - selectedEntities={['1']} /> ); expect(screen.getByDisplayValue('IN, Mumbai (ap-west)')).toBeVisible(); diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.tsx index c49ad4c0fd7..11a8c2b11fa 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.tsx @@ -6,7 +6,6 @@ import { RegionSelect } from 'src/components/RegionSelect/RegionSelect'; import { useFlags } from 'src/hooks/useFlags'; import { useResourcesQuery } from 'src/queries/cloudpulse/resources'; -import { useFirewallFetchOptions } from '../Alerts/CreateAlert/Criteria/DimensionFilterValue/useFirewallFetchOptions'; import { filterRegionByServiceType } from '../Alerts/Utils/utils'; import { NO_REGION_MESSAGE, @@ -15,13 +14,9 @@ import { } from '../Utils/constants'; import { deepEqual, filterUsingDependentFilters } from '../Utils/FilterBuilder'; import { FILTER_CONFIG } from '../Utils/FilterConfig'; -import { - getAssociatedEntityType, - getResourcesFilterConfig, -} from '../Utils/utils'; +import { getResourcesFilterConfig } from '../Utils/utils'; import { CLOUD_PULSE_TEXT_FIELD_PROPS } from './styles'; -import type { Item } from '../Alerts/constants'; import type { CloudPulseMetricsFilter } from '../Dashboard/CloudPulseDashboardLanding'; import type { Dashboard, FilterValue, Region } from '@linode/api-v4'; @@ -39,7 +34,6 @@ export interface CloudPulseRegionSelectProps { placeholder?: string; savePreferences?: boolean; selectedDashboard: Dashboard | undefined; - selectedEntities: string[]; xFilter?: CloudPulseMetricsFilter; } @@ -53,7 +47,6 @@ export const CloudPulseRegionSelect = React.memo( placeholder, savePreferences, selectedDashboard, - selectedEntities, disabled = false, xFilter, } = props; @@ -69,7 +62,10 @@ export const CloudPulseRegionSelect = React.memo( isError: isResourcesError, isLoading: isResourcesLoading, } = useResourcesQuery( - !disabled && selectedDashboard !== undefined && Boolean(regions?.length), + filterKey !== PARENT_ENTITY_REGION && + !disabled && + selectedDashboard !== undefined && + Boolean(regions?.length), selectedDashboard?.service_type, {}, { @@ -93,50 +89,20 @@ export const CloudPulseRegionSelect = React.memo( const [selectedRegion, setSelectedRegion] = React.useState(); - // Get the associated entity type for the dashboard - const associatedEntityType = getAssociatedEntityType(dashboardId); - const { - values: linodeRegions, - isLoading: isLinodeRegionIdLoading, - isError: isLinodeRegionIdError, - } = useFirewallFetchOptions({ - dimensionLabel: filterKey, - entities: selectedEntities, - regions, - serviceType, - associatedEntityType, - type: 'metrics', - }); - const linodeRegionIds = linodeRegions.map( - (option: Item) => option.value - ); - - const supportedLinodeRegions = React.useMemo(() => { - return ( - regions?.filter((region) => linodeRegionIds?.includes(region.id)) ?? [] - ); - }, [regions, linodeRegionIds]); - const supportedRegions = React.useMemo(() => { return filterRegionByServiceType('metrics', regions, serviceType); }, [regions, serviceType]); const supportedRegionsFromResources = React.useMemo(() => { if (filterKey === PARENT_ENTITY_REGION) { - return supportedLinodeRegions; + return supportedRegions; } return supportedRegions.filter(({ id }) => filterUsingDependentFilters(resources, xFilter)?.some( ({ region }) => region === id ) ); - }, [ - filterKey, - supportedLinodeRegions, - supportedRegions, - resources, - xFilter, - ]); + }, [supportedRegions, resources, xFilter, filterKey]); const dependencyKey = supportedRegionsFromResources .map((region) => region.id) @@ -192,9 +158,14 @@ export const CloudPulseRegionSelect = React.memo( currentCapability={capability} data-testid="region-select" disableClearable={false} - disabled={!selectedDashboard || !regions || disabled || !resources} + disabled={ + !selectedDashboard || + !regions || + disabled || + (!resources && filterKey !== PARENT_ENTITY_REGION) + } errorText={ - isError || isResourcesError || isLinodeRegionIdError + isError || isResourcesError ? `Failed to fetch ${label || 'Regions'}.` : '' } @@ -203,7 +174,8 @@ export const CloudPulseRegionSelect = React.memo( label={label || 'Region'} loading={ !disabled && - (isLoading || isResourcesLoading || isLinodeRegionIdLoading) + (isLoading || + (isResourcesLoading && filterKey !== PARENT_ENTITY_REGION)) } noMarginTop noOptionsText={ From 383898f17a1e44950515169206524f452c2156c2 Mon Sep 17 00:00:00 2001 From: ankitaakamai Date: Mon, 17 Nov 2025 17:49:30 +0530 Subject: [PATCH 2/4] upcoming: [DI-28270] - Remove typo --- packages/manager/src/features/CloudPulse/Utils/FilterConfig.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/manager/src/features/CloudPulse/Utils/FilterConfig.ts b/packages/manager/src/features/CloudPulse/Utils/FilterConfig.ts index 64fcf6f0fd5..30f8922d5c2 100644 --- a/packages/manager/src/features/CloudPulse/Utils/FilterConfig.ts +++ b/packages/manager/src/features/CloudPulse/Utils/FilterConfig.ts @@ -335,6 +335,7 @@ export const FIREWALL_NODEBALANCER_CONFIG: Readonly Date: Tue, 18 Nov 2025 11:21:10 +0530 Subject: [PATCH 3/4] upcoming: [DI-28270] - Add condition in error text --- .../src/features/CloudPulse/shared/CloudPulseRegionSelect.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.tsx index 11a8c2b11fa..5b385bd2c2f 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.tsx @@ -165,7 +165,7 @@ export const CloudPulseRegionSelect = React.memo( (!resources && filterKey !== PARENT_ENTITY_REGION) } errorText={ - isError || isResourcesError + isError || (isResourcesError && filterKey !== PARENT_ENTITY_REGION) ? `Failed to fetch ${label || 'Regions'}.` : '' } From f4d5def6f66562f47f148d8bed9ebe928797b430 Mon Sep 17 00:00:00 2001 From: ankitaakamai Date: Thu, 20 Nov 2025 10:45:16 +0530 Subject: [PATCH 4/4] upcoming: [DI-28270] - Add changeset --- .../.changeset/pr-13111-upcoming-features-1763615562636.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 packages/manager/.changeset/pr-13111-upcoming-features-1763615562636.md diff --git a/packages/manager/.changeset/pr-13111-upcoming-features-1763615562636.md b/packages/manager/.changeset/pr-13111-upcoming-features-1763615562636.md new file mode 100644 index 00000000000..7fc2ab5ef65 --- /dev/null +++ b/packages/manager/.changeset/pr-13111-upcoming-features-1763615562636.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Upcoming Features +--- + +CloudPulse-Metrics: Remove filtering of firewalls and region filter dependency on firewall-select in Firewalls ([#13111](https://github.com/linode/manager/pull/13111))