From f8a89eb4f066116ad80f1e6d9d596410cb720cfe Mon Sep 17 00:00:00 2001 From: tsiorifamonjena Date: Tue, 26 Nov 2024 15:51:16 +0100 Subject: [PATCH] feat(pci.private-network): improve optimistic call function ref: -1826 Signed-off-by: tsiorifamonjena --- .../translations/listing/Messages_fr_FR.json | 4 +- ...egions.tsx => SlicedRegions.component.tsx} | 0 .../status-info/StatusInfo.component.tsx | 28 ++++++++++++ .../src/data/hooks/networks/useNetworks.ts | 44 +++++++------------ .../src/data/services/services.spec.ts | 8 ++-- .../src/data/services/services.ts | 13 +++--- .../src/hooks/useColumns/useColumns.tsx | 31 +++++-------- .../src/pages/delete/DeleteNetwork.page.tsx | 4 +- .../button-action/ButtonAction.component.tsx | 6 +-- .../src/types/network.type.ts | 5 +++ 10 files changed, 78 insertions(+), 65 deletions(-) rename packages/manager/apps/pci-private-network/src/components/sliced-regions/{SlicedRegions.tsx => SlicedRegions.component.tsx} (100%) create mode 100644 packages/manager/apps/pci-private-network/src/components/status-info/StatusInfo.component.tsx diff --git a/packages/manager/apps/pci-private-network/public/translations/listing/Messages_fr_FR.json b/packages/manager/apps/pci-private-network/public/translations/listing/Messages_fr_FR.json index b445d2224cfa..3de77d1f6d6d 100644 --- a/packages/manager/apps/pci-private-network/public/translations/listing/Messages_fr_FR.json +++ b/packages/manager/apps/pci-private-network/public/translations/listing/Messages_fr_FR.json @@ -24,5 +24,7 @@ "pci_projects_project_network_private_subnet_create": "Créer un sous-réseau", "pci_projects_project_network_private_ip_version": "IP Version", "pci_projects_project_network_private_action": "Actions", - "pci_projects_project_network_private_subnet_show": "Voir les sous-réseaux" + "pci_projects_project_network_private_subnet_show": "Voir les sous-réseaux", + "ACTIVE": "actif", + "DISABLED": "désactivé" } diff --git a/packages/manager/apps/pci-private-network/src/components/sliced-regions/SlicedRegions.tsx b/packages/manager/apps/pci-private-network/src/components/sliced-regions/SlicedRegions.component.tsx similarity index 100% rename from packages/manager/apps/pci-private-network/src/components/sliced-regions/SlicedRegions.tsx rename to packages/manager/apps/pci-private-network/src/components/sliced-regions/SlicedRegions.component.tsx diff --git a/packages/manager/apps/pci-private-network/src/components/status-info/StatusInfo.component.tsx b/packages/manager/apps/pci-private-network/src/components/status-info/StatusInfo.component.tsx new file mode 100644 index 000000000000..ab9199e16feb --- /dev/null +++ b/packages/manager/apps/pci-private-network/src/components/status-info/StatusInfo.component.tsx @@ -0,0 +1,28 @@ +import { FC } from 'react'; +import { ODS_CHIP_SIZE } from '@ovhcloud/ods-components'; +import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; +import { OsdsChip } from '@ovhcloud/ods-components/react'; +import { useTranslation } from 'react-i18next'; +import { ResourceStatus } from '@/types/network.type'; + +const StatusInfo: FC<{ + label: ResourceStatus; +}> = ({ label }) => { + const { t } = useTranslation('listing'); + const color = { + [ResourceStatus.ACTIVE]: ODS_THEME_COLOR_INTENT.success, + [ResourceStatus.DISABLED]: ODS_THEME_COLOR_INTENT.warning, + }; + + return ( + + {t(label)} + + ); +}; + +export default StatusInfo; diff --git a/packages/manager/apps/pci-private-network/src/data/hooks/networks/useNetworks.ts b/packages/manager/apps/pci-private-network/src/data/hooks/networks/useNetworks.ts index c49a81bc9201..8812e607a203 100644 --- a/packages/manager/apps/pci-private-network/src/data/hooks/networks/useNetworks.ts +++ b/packages/manager/apps/pci-private-network/src/data/hooks/networks/useNetworks.ts @@ -17,30 +17,25 @@ import { import queryClient from '@/queryClient'; import { groupedPrivateNetworkByVlanId, paginateResults } from '@/utils/utils'; -const networkQueryKey = (projectId: string, rest: string[] = []): string[] => [ +const networksQueryKey = (projectId: string, rest: string[] = []): string[] => [ 'project', projectId, 'network', ...rest, ]; -const getPrivateNetworkQuery = (projectId: string) => ({ - queryKey: networkQueryKey(projectId), - queryFn: () => getPrivateNetworks(projectId), -}); - -const fetchPrivateNetwork = async (projectId: string) => - queryClient.fetchQuery(getPrivateNetworkQuery(projectId)); - export const usePrivateNetworks = (projectId: string) => - useQuery(getPrivateNetworkQuery(projectId)); + useQuery({ + queryKey: networksQueryKey(projectId), + queryFn: () => getPrivateNetworks(projectId), + }); export const usePrivateNetworksRegion = ( projectId: string, pagination: PaginationState, filters: Filter[] = [], ) => { - const queryKey = networkQueryKey(projectId); + const queryKey = networksQueryKey(projectId); const data = queryClient.getQueryData(queryKey) || []; return useMemo( @@ -88,13 +83,13 @@ const getFormattedSubnets = ( ); export const usePrivateNetworkLZ = (projectId: string) => { - const queryKey = networkQueryKey(projectId); + const queryKey = networksQueryKey(projectId); const data = queryClient.getQueryData(queryKey) || []; const networks = data.filter((network) => !network.vlanId); return useQueries({ queries: networks.map(({ id, region, name }) => ({ - queryKey: networkQueryKey(projectId, ['subnets', region, id]), + queryKey: networksQueryKey(projectId, ['subnets', region, id]), queryFn: () => getSubnets(projectId, region, id), select: (subnets: TSubnet[]) => getFormattedSubnets(id, name, region, subnets), @@ -149,16 +144,14 @@ export const useSubnets = ( enabled: !!(projectId && networkId && region), }); -export const addPrivateNetwork = async ( +export const updatePrivateNetworksList = async ( projectId: string, newNetwork: TNetwork, ) => { - const queryKey = networkQueryKey(projectId); + const queryKey = networksQueryKey(projectId); const networks = queryClient.getQueryData(queryKey); - if (!networks) { - await fetchPrivateNetwork(projectId); - } else { + if (networks) { queryClient.setQueryData(queryKey, (data: TNetwork[]) => [ newNetwork, ...data, @@ -166,20 +159,17 @@ export const addPrivateNetwork = async ( } }; -export const deletePrivateNetworks = async ( +export const deletePrivateNetwork = async ( projectId: string, region: string, networkId: string, ) => { await apiDeleteNetwork(projectId, region, networkId); - const queryKey = networkQueryKey(projectId); - const networks = queryClient.getQueryData(queryKey); + const queryKey = networksQueryKey(projectId); - if (!networks) { - await fetchPrivateNetwork(projectId); - } else { - const newNetworks = networks.filter((network) => network.id !== networkId); - queryClient.setQueryData(queryKey, newNetworks); - } + const networks = await queryClient.ensureQueryData({ queryKey }); + + const newNetworks = networks.filter((network) => network.id !== networkId); + queryClient.setQueryData(queryKey, newNetworks); }; diff --git a/packages/manager/apps/pci-private-network/src/data/services/services.spec.ts b/packages/manager/apps/pci-private-network/src/data/services/services.spec.ts index 28fd767c656f..29905c71c79f 100644 --- a/packages/manager/apps/pci-private-network/src/data/services/services.spec.ts +++ b/packages/manager/apps/pci-private-network/src/data/services/services.spec.ts @@ -8,7 +8,7 @@ import { import { enableSnatOnGateway, assignGateway } from '@/data/api/gateway'; import { fetchCheckPrivateNetworkCreationStatus, - addPrivateNetwork, + updatePrivateNetworksList, } from '@/data/hooks/networks/useNetworks'; import { createPrivateNetwork } from './services'; import { privateNetworkForm as form, projectId } from '@/__mocks__/network'; @@ -73,7 +73,7 @@ describe('Create Private Network', () => { operationId, ); - expect(addPrivateNetwork).toHaveBeenCalledWith(projectId, { + expect(updatePrivateNetworksList).toHaveBeenCalledWith(projectId, { id: resourceId, name, region, @@ -108,7 +108,7 @@ describe('Create Private Network', () => { ); }); - it('should call getNetwork and addPrivateNetwork when region is not LZ and vlanId not defined by user', async () => { + it('should call getNetwork and updatePrivateNetworksList when region is not LZ and vlanId not defined by user', async () => { const { vlanId, ...values } = form; await createPrivateNetwork(values, projectId); @@ -119,7 +119,7 @@ describe('Create Private Network', () => { resourceId, ); - expect(addPrivateNetwork).toHaveBeenCalledWith(projectId, { + expect(updatePrivateNetworksList).toHaveBeenCalledWith(projectId, { id: resourceId, name: values.name, region: values.region, diff --git a/packages/manager/apps/pci-private-network/src/data/services/services.ts b/packages/manager/apps/pci-private-network/src/data/services/services.ts index 63af4be6624b..f6a7396b4d80 100644 --- a/packages/manager/apps/pci-private-network/src/data/services/services.ts +++ b/packages/manager/apps/pci-private-network/src/data/services/services.ts @@ -7,7 +7,7 @@ import { import { assignGateway, enableSnatOnGateway } from '@/data/api/gateway'; import { fetchCheckPrivateNetworkCreationStatus, - addPrivateNetwork, + updatePrivateNetworksList, } from '../hooks/networks/useNetworks'; import queryClient from '@/queryClient'; @@ -46,19 +46,18 @@ export const createPrivateNetwork = async ( await assignGateway(projectId, region, resourceId, existingGatewayId); } - let createdVlanId = data.vlanId || null; - - if (!createdVlanId && !isLocalZone) { + // had to fetch network to get vlanId if user does not define + if (!data.vlanId && !isLocalZone) { const createdNetwork = await getNetwork(projectId, region, resourceId); - createdVlanId = createdNetwork.vlanId; + data.vlanId = createdNetwork.vlanId; } - await addPrivateNetwork(projectId, { + await updatePrivateNetworksList(projectId, { id: resourceId, name: data.name, region, visibility: NetworkVisibility.Private, - vlanId: createdVlanId, + vlanId: data.vlanId, }); }; diff --git a/packages/manager/apps/pci-private-network/src/hooks/useColumns/useColumns.tsx b/packages/manager/apps/pci-private-network/src/hooks/useColumns/useColumns.tsx index 036b864109be..93d679ebf6b1 100644 --- a/packages/manager/apps/pci-private-network/src/hooks/useColumns/useColumns.tsx +++ b/packages/manager/apps/pci-private-network/src/hooks/useColumns/useColumns.tsx @@ -3,7 +3,6 @@ import { useNavigate } from 'react-router-dom'; import { DataGridTextCell } from '@ovh-ux/manager-react-components'; import { OsdsButton, - OsdsChip, OsdsIcon, OsdsText, OsdsTooltip, @@ -12,7 +11,6 @@ import { import { ODS_BUTTON_SIZE, ODS_BUTTON_VARIANT, - ODS_CHIP_SIZE, ODS_ICON_NAME, ODS_ICON_SIZE, ODS_TEXT_COLOR_INTENT, @@ -23,8 +21,13 @@ import { ODS_THEME_COLOR_INTENT, } from '@ovhcloud/ods-common-theming'; import DatagridActions from '@/components/datagrid-actions/DatagridActions.component'; -import { TGroupedNetwork, TGroupedSubnet } from '@/types/network.type'; -import SlicedRegions from '@/components/sliced-regions/SlicedRegions'; +import { + ResourceStatus, + TGroupedNetwork, + TGroupedSubnet, +} from '@/types/network.type'; +import SlicedRegions from '@/components/sliced-regions/SlicedRegions.component'; +import StatusInfo from '@/components/status-info/StatusInfo.component'; export function usePrivateNetworkRegionColumns() { const { t } = useTranslation(['listing', 'common']); @@ -128,12 +131,6 @@ export function usePrivateNetworkRegionColumns() { ]; } -const renderChip = (text: string, color: ODS_THEME_COLOR_INTENT) => ( - - {text} - -); - export function usePrivateNetworkLZColumns() { const { t } = useTranslation(['listing', 'common']); const navigate = useNavigate(); @@ -171,15 +168,11 @@ export function usePrivateNetworkLZColumns() { id: 'dhcp', cell: ({ dhcpEnabled }: TGroupedSubnet) => ( - {dhcpEnabled - ? renderChip( - t('pci_projects_project_network_private_dhcp_active'), - ODS_THEME_COLOR_INTENT.success, - ) - : renderChip( - t('pci_projects_project_network_private_dhcp_disabled'), - ODS_THEME_COLOR_INTENT.warning, - )} + ), label: 'DHCP', diff --git a/packages/manager/apps/pci-private-network/src/pages/delete/DeleteNetwork.page.tsx b/packages/manager/apps/pci-private-network/src/pages/delete/DeleteNetwork.page.tsx index f31c67b9b412..fb15b7f7cff5 100644 --- a/packages/manager/apps/pci-private-network/src/pages/delete/DeleteNetwork.page.tsx +++ b/packages/manager/apps/pci-private-network/src/pages/delete/DeleteNetwork.page.tsx @@ -4,7 +4,7 @@ import { Translation } from 'react-i18next'; import { useLocation, useNavigate, useParams } from 'react-router-dom'; import { ApiError } from '@ovh-ux/manager-core-api'; import DeleteModal from '@/components/delete/DeleteModal.component'; -import { deletePrivateNetworks } from '@/data/hooks/networks/useNetworks'; +import { deletePrivateNetwork } from '@/data/hooks/networks/useNetworks'; export default function DeleteLocalZone() { const navigate = useNavigate(); @@ -25,7 +25,7 @@ export default function DeleteLocalZone() { setIsPending(true); try { - await deletePrivateNetworks(projectId, region, networkId); + await deletePrivateNetwork(projectId, region, networkId); addSuccess( {(t) => diff --git a/packages/manager/apps/pci-private-network/src/pages/new/button-action/ButtonAction.component.tsx b/packages/manager/apps/pci-private-network/src/pages/new/button-action/ButtonAction.component.tsx index 2fc15018e5b4..93d48b030fe1 100644 --- a/packages/manager/apps/pci-private-network/src/pages/new/button-action/ButtonAction.component.tsx +++ b/packages/manager/apps/pci-private-network/src/pages/new/button-action/ButtonAction.component.tsx @@ -17,10 +17,7 @@ import { useNavigate } from 'react-router-dom'; import { useFormContext } from 'react-hook-form'; import { ErrorResponse } from '@/types/network.type'; import { NewPrivateNetworkForm } from '@/types/private-network-form.type'; -import { - createPrivateNetwork, - refreshPrivateNetworkList, -} from '@/data/services/services'; +import { createPrivateNetwork } from '@/data/services/services'; const ButtonAction: React.FC = () => { const { t } = useTranslation(['new', 'common']); @@ -64,7 +61,6 @@ const ButtonAction: React.FC = () => { try { await createPrivateNetwork(values, projectId); - refreshPrivateNetworkList(projectId); onSuccess(values.name); } catch (e) { onError(e); diff --git a/packages/manager/apps/pci-private-network/src/types/network.type.ts b/packages/manager/apps/pci-private-network/src/types/network.type.ts index a353212de8d9..d43e808f8750 100644 --- a/packages/manager/apps/pci-private-network/src/types/network.type.ts +++ b/packages/manager/apps/pci-private-network/src/types/network.type.ts @@ -96,3 +96,8 @@ export type ErrorResponse = { }; message?: string; }; + +export enum ResourceStatus { + ACTIVE = 'ACTIVE', + DISABLED = 'DISABLED', +}