From ae81ee3f377f8ce7abaf89d9ef59af0f63abc630 Mon Sep 17 00:00:00 2001 From: Mariah Jacobs <114685994+mjac0bs@users.noreply.github.com> Date: Tue, 4 Jun 2024 08:01:24 -0700 Subject: [PATCH] fix: [M3-7718] - Stale assigned Firewall data displaying on Linode and NodeBalancer details pages (#10534) * Invalidate FWNB devices query when FW updates * Update query key naming for consistency * Added changeset: Stale assigned Firewall data displaying on Linode and NodeBalancer details pages --- .../pr-10534-fixed-1717169773875.md | 5 ++++ .../Devices/RemoveDeviceDialog.tsx | 12 ++++----- .../Rules/FirewallRulesLanding.tsx | 25 +++++++++++++++++-- .../FirewallLanding/CreateFirewallDrawer.tsx | 4 +-- .../FirewallLanding/FirewallDialog.tsx | 24 ++++++++++-------- 5 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 packages/manager/.changeset/pr-10534-fixed-1717169773875.md diff --git a/packages/manager/.changeset/pr-10534-fixed-1717169773875.md b/packages/manager/.changeset/pr-10534-fixed-1717169773875.md new file mode 100644 index 00000000000..acc151e9106 --- /dev/null +++ b/packages/manager/.changeset/pr-10534-fixed-1717169773875.md @@ -0,0 +1,5 @@ +--- +"@linode/manager": Fixed +--- + +Stale assigned Firewall data displaying on Linode and NodeBalancer details pages ([#10534](https://github.com/linode/manager/pull/10534)) diff --git a/packages/manager/src/features/Firewalls/FirewallDetail/Devices/RemoveDeviceDialog.tsx b/packages/manager/src/features/Firewalls/FirewallDetail/Devices/RemoveDeviceDialog.tsx index 39cb445108b..0d9c3cd2d7a 100644 --- a/packages/manager/src/features/Firewalls/FirewallDetail/Devices/RemoveDeviceDialog.tsx +++ b/packages/manager/src/features/Firewalls/FirewallDetail/Devices/RemoveDeviceDialog.tsx @@ -1,15 +1,15 @@ import { FirewallDevice } from '@linode/api-v4'; +import { useQueryClient } from '@tanstack/react-query'; import { useSnackbar } from 'notistack'; import * as React from 'react'; -import { useQueryClient } from '@tanstack/react-query'; import { ActionsPanel } from 'src/components/ActionsPanel/ActionsPanel'; import { ConfirmationDialog } from 'src/components/ConfirmationDialog/ConfirmationDialog'; import { Typography } from 'src/components/Typography'; -import { queryKey as firewallQueryKey } from 'src/queries/firewalls'; import { useRemoveFirewallDeviceMutation } from 'src/queries/firewalls'; +import { queryKey as firewallQueryKey } from 'src/queries/firewalls'; import { queryKey as linodesQueryKey } from 'src/queries/linodes/linodes'; -import { queryKey as nodeBalancerQueryKey } from 'src/queries/nodebalancers'; +import { queryKey as nodebalancersQueryKey } from 'src/queries/nodebalancers'; export interface Props { device: FirewallDevice | undefined; @@ -48,12 +48,12 @@ export const RemoveDeviceDialog = React.memo((props: Props) => { enqueueSnackbar(error[0].reason, { variant: 'error' }); } - const querykey = - deviceType === 'linode' ? linodesQueryKey : nodeBalancerQueryKey; + const queryKey = + deviceType === 'linode' ? linodesQueryKey : nodebalancersQueryKey; // Since the linode was removed as a device, invalidate the linode-specific firewall query queryClient.invalidateQueries([ - querykey, + queryKey, deviceType, device?.entity.id, 'firewalls', diff --git a/packages/manager/src/features/Firewalls/FirewallDetail/Rules/FirewallRulesLanding.tsx b/packages/manager/src/features/Firewalls/FirewallDetail/Rules/FirewallRulesLanding.tsx index 28782cb1f99..5d978b108fc 100644 --- a/packages/manager/src/features/Firewalls/FirewallDetail/Rules/FirewallRulesLanding.tsx +++ b/packages/manager/src/features/Firewalls/FirewallDetail/Rules/FirewallRulesLanding.tsx @@ -1,4 +1,5 @@ import { styled } from '@mui/material/styles'; +import { useQueryClient } from '@tanstack/react-query'; import { useSnackbar } from 'notistack'; import * as React from 'react'; @@ -7,11 +8,15 @@ import { ConfirmationDialog } from 'src/components/ConfirmationDialog/Confirmati import { Notice } from 'src/components/Notice/Notice'; import { Prompt } from 'src/components/Prompt/Prompt'; import { Typography } from 'src/components/Typography'; -import { useUpdateFirewallRulesMutation } from 'src/queries/firewalls'; +import { + useAllFirewallDevicesQuery, + useUpdateFirewallRulesMutation, +} from 'src/queries/firewalls'; +import { queryKey as linodesQueryKey } from 'src/queries/linodes/linodes'; +import { queryKey as nodebalancersQueryKey } from 'src/queries/nodebalancers'; import { getAPIErrorOrDefault } from 'src/utilities/errorUtils'; import { FirewallRuleDrawer } from './FirewallRuleDrawer'; -import { FirewallRuleTable } from './FirewallRuleTable'; import { hasModified as _hasModified, curriedFirewallRuleEditorReducer, @@ -20,6 +25,7 @@ import { prepareRules, stripExtendedFields, } from './firewallRuleEditor'; +import { FirewallRuleTable } from './FirewallRuleTable'; import { parseFirewallRuleError } from './shared'; import type { FirewallRuleDrawerMode } from './FirewallRuleDrawer.types'; @@ -51,6 +57,8 @@ export const FirewallRulesLanding = React.memo((props: Props) => { const { mutateAsync: updateFirewallRules } = useUpdateFirewallRulesMutation( firewallID ); + const { data: devices } = useAllFirewallDevicesQuery(firewallID); + const queryClient = useQueryClient(); const { enqueueSnackbar } = useSnackbar(); @@ -193,6 +201,19 @@ export const FirewallRulesLanding = React.memo((props: Props) => { updateFirewallRules(finalRules) .then((_rules) => { setSubmitting(false); + // Invalidate Firewalls assigned to NodeBalancers and Linodes. + // eslint-disable-next-line no-unused-expressions + devices?.forEach((device) => + queryClient.invalidateQueries([ + device.entity.type === 'linode' + ? linodesQueryKey + : nodebalancersQueryKey, + device.entity.type, + device.entity.id, + 'firewalls', + ]) + ); + // Reset editor state. inboundDispatch({ rules: _rules.inbound ?? [], type: 'RESET' }); outboundDispatch({ rules: _rules.outbound ?? [], type: 'RESET' }); diff --git a/packages/manager/src/features/Firewalls/FirewallLanding/CreateFirewallDrawer.tsx b/packages/manager/src/features/Firewalls/FirewallLanding/CreateFirewallDrawer.tsx index b60668ff09a..24b0e3efdb5 100644 --- a/packages/manager/src/features/Firewalls/FirewallLanding/CreateFirewallDrawer.tsx +++ b/packages/manager/src/features/Firewalls/FirewallLanding/CreateFirewallDrawer.tsx @@ -33,7 +33,7 @@ import { useCreateFirewall, } from 'src/queries/firewalls'; import { queryKey as linodesQueryKey } from 'src/queries/linodes/linodes'; -import { queryKey as nodebalancerQueryKey } from 'src/queries/nodebalancers'; +import { queryKey as nodebalancersQueryKey } from 'src/queries/nodebalancers'; import { useGrants } from 'src/queries/profile'; import { sendLinodeCreateFormStepEvent } from 'src/utilities/analytics/formEventAnalytics'; import { getErrorMap } from 'src/utilities/errorUtils'; @@ -153,7 +153,7 @@ export const CreateFirewallDrawer = React.memo( if (payload.devices?.nodebalancers) { payload.devices.nodebalancers.forEach((nodebalancerId) => { queryClient.invalidateQueries([ - nodebalancerQueryKey, + nodebalancersQueryKey, 'nodebalancer', nodebalancerId, 'firewalls', diff --git a/packages/manager/src/features/Firewalls/FirewallLanding/FirewallDialog.tsx b/packages/manager/src/features/Firewalls/FirewallLanding/FirewallDialog.tsx index a8af6709fbc..0fc5940e071 100644 --- a/packages/manager/src/features/Firewalls/FirewallLanding/FirewallDialog.tsx +++ b/packages/manager/src/features/Firewalls/FirewallLanding/FirewallDialog.tsx @@ -8,7 +8,7 @@ import { useDeleteFirewall, useMutateFirewall } from 'src/queries/firewalls'; import { queryKey as firewallQueryKey } from 'src/queries/firewalls'; import { useAllFirewallDevicesQuery } from 'src/queries/firewalls'; import { queryKey as linodesQueryKey } from 'src/queries/linodes/linodes'; -import { queryKey as nodebalancerQueryKey } from 'src/queries/nodebalancers'; +import { queryKey as nodebalancersQueryKey } from 'src/queries/nodebalancers'; import { capitalize } from 'src/utilities/capitalize'; export type Mode = 'delete' | 'disable' | 'enable'; @@ -66,17 +66,19 @@ export const FirewallDialog = React.memo((props: Props) => { const onSubmit = async () => { await requestMap[mode](); + // Invalidate Firewalls assigned to NodeBalancers and Linodes when Firewall is enabled, disabled, or deleted. + // eslint-disable-next-line no-unused-expressions + devices?.forEach((device) => { + const deviceType = device.entity.type; + queryClient.invalidateQueries([ + deviceType === 'linode' ? linodesQueryKey : nodebalancersQueryKey, + deviceType, + device.entity.id, + 'firewalls', + ]); + }); if (mode === 'delete') { - devices?.forEach((device) => { - const deviceType = device.entity.type; - queryClient.invalidateQueries([ - deviceType === 'linode' ? linodesQueryKey : nodebalancerQueryKey, - deviceType, - device.entity.id, - 'firewalls', - ]); - queryClient.invalidateQueries([firewallQueryKey]); - }); + queryClient.invalidateQueries([firewallQueryKey]); } enqueueSnackbar(`Firewall ${label} successfully ${mode}d`, { variant: 'success',