diff --git a/packages/manager/.changeset/pr-12805-upcoming-features-1756916789818.md b/packages/manager/.changeset/pr-12805-upcoming-features-1756916789818.md new file mode 100644 index 00000000000..e24897263cb --- /dev/null +++ b/packages/manager/.changeset/pr-12805-upcoming-features-1756916789818.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Upcoming Features +--- + +CloudPulse-Metrics: Update CloudPulseRegionSelect.tsx to handle default linode region selection in firewalls contextual view ([#12805](https://github.com/linode/manager/pull/12805)) diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseDashboardFilterBuilder.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseDashboardFilterBuilder.tsx index 9dc771e5c81..34e25625503 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseDashboardFilterBuilder.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseDashboardFilterBuilder.tsx @@ -351,9 +351,7 @@ export const CloudPulseDashboardFilterBuilder = React.memo( dashboard, isServiceAnalyticsIntegration, preferences, - dependentFilters: resource_ids?.length - ? { [RESOURCE_ID]: resource_ids } - : dependentFilterReference.current, + dependentFilters: dependentFilterReference.current, shouldDisable: isError || isLoading, }, handleTextFilterChange diff --git a/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.test.tsx b/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.test.tsx index 5912a0521f3..f6a82a98348 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.test.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.test.tsx @@ -8,7 +8,11 @@ import { screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import * as React from 'react'; -import { dashboardFactory, databaseInstanceFactory } from 'src/factories'; +import { + dashboardFactory, + databaseInstanceFactory, + firewallFactory, +} from 'src/factories'; import { renderWithTheme } from 'src/utilities/testHelpers'; import { NO_REGION_MESSAGE } from '../Utils/constants'; @@ -31,6 +35,7 @@ const props: CloudPulseRegionSelectProps = { const queryMocks = vi.hoisted(() => ({ useRegionsQuery: vi.fn().mockReturnValue({}), useResourcesQuery: vi.fn().mockReturnValue({}), + useAllLinodesQuery: vi.fn().mockReturnValue({}), })); const allRegions: Region[] = [ @@ -80,6 +85,7 @@ const allRegions: Region[] = [ vi.mock('@linode/queries', async (importOriginal) => ({ ...(await importOriginal()), useRegionsQuery: queryMocks.useRegionsQuery, + useAllLinodesQuery: queryMocks.useAllLinodesQuery, })); vi.mock('src/queries/cloudpulse/resources', async () => { @@ -285,4 +291,97 @@ describe('CloudPulseRegionSelect', () => { await user.click(screen.getByRole('button', { name: 'Open' })); expect(screen.getByText(NO_REGION_MESSAGE['firewall'])).toBeVisible(); }); + + it('Should show the correct linode region in the dropdown for firewall service type when savePreferences is true', async () => { + const user = userEvent.setup(); + queryMocks.useRegionsQuery.mockReturnValue({ + data: [ + regionFactory.build({ + 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', + }), + ], + isError: false, + isLoading: false, + }); + + renderWithTheme( + + ); + await user.click(screen.getByRole('button', { name: 'Open' })); + expect( + screen.getByRole('option', { name: 'IN, Mumbai (ap-west)' }) + ).toBeVisible(); + }); + + it('Should select the first region automatically from the linode regions if savePreferences is false', async () => { + queryMocks.useRegionsQuery.mockReturnValue({ + data: [ + regionFactory.build({ + 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', + }), + ], + isError: false, + isLoading: false, + }); + renderWithTheme( + + ); + 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 56af1d7420e..e4c56927a2f 100644 --- a/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.tsx +++ b/packages/manager/src/features/CloudPulse/shared/CloudPulseRegionSelect.tsx @@ -80,10 +80,48 @@ export const CloudPulseRegionSelect = React.memo( : undefined; const [selectedRegion, setSelectedRegion] = React.useState(); - React.useEffect(() => { - if (!savePreferences) { - return; // early exit if savePreferences is false + + const linodeRegionIds = useFetchOptions({ + dimensionLabel: filterKey, + entities: selectedEntities, + regions, + serviceType, + type: 'metrics', + }).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 === LINODE_REGION) { + return supportedLinodeRegions; } + return supportedRegions.filter(({ id }) => + filterUsingDependentFilters(resources, xFilter)?.some( + ({ region }) => region === id + ) + ); + }, [ + filterKey, + supportedLinodeRegions, + supportedRegions, + resources, + xFilter, + ]); + + const dependencyKey = supportedLinodeRegions + .map((region) => region.id) + .sort() + .join(','); + + React.useEffect(() => { if (disabled && !selectedRegion) { return; // no need to do anything } @@ -102,7 +140,21 @@ export const CloudPulseRegionSelect = React.memo( // Notify parent and set internal state handleRegionChange(filterKey, region?.id, region ? [region.label] : []); setSelectedRegion(region?.id); + } else if ( + filterKey === LINODE_REGION && + !savePreferences && + supportedRegionsFromResources?.length && + selectedRegion === undefined + ) { + // Select the first region from the supported regions if savePreferences is false + const defaultRegionId = supportedRegionsFromResources[0].id; + const defaultRegionLabel = supportedRegionsFromResources[0].label; + handleRegionChange(filterKey, defaultRegionId, [defaultRegionLabel]); + setSelectedRegion(defaultRegionId); } else { + if (!disabled && filterKey === LINODE_REGION && selectedRegion) { + return; + } if (selectedRegion !== undefined) { setSelectedRegion(''); } @@ -112,32 +164,9 @@ export const CloudPulseRegionSelect = React.memo( }, [ xFilter, // Reacts to filter changes (to reset region) regions, // Function to call on change + dependencyKey, // Reacts to linode region changes ]); - const linodeRegionIds = useFetchOptions({ - dimensionLabel: filterKey, - entities: selectedEntities, - regions, - serviceType, - type: 'metrics', - }).map((option: Item) => option.value); - - const supportedLinodeRegions = - regions?.filter((region) => linodeRegionIds?.includes(region.id)) ?? []; - - const supportedRegions = React.useMemo(() => { - return filterRegionByServiceType('metrics', regions, serviceType); - }, [regions, serviceType]); - - const supportedRegionsFromResources = - filterKey === LINODE_REGION - ? supportedLinodeRegions - : supportedRegions.filter(({ id }) => - filterUsingDependentFilters(resources, xFilter)?.some( - ({ region }) => region === id - ) - ); - return (