diff --git a/resources/scripts/api/swr/getServerAllocations.ts b/resources/scripts/api/swr/getServerAllocations.ts index 00af65c8..a5591a39 100644 --- a/resources/scripts/api/swr/getServerAllocations.ts +++ b/resources/scripts/api/swr/getServerAllocations.ts @@ -4,12 +4,12 @@ import http from '@/api/http'; import { rawDataToServerAllocation } from '@/api/transformers'; import { Allocation } from '@/api/server/getServer'; -export default (initialData?: Allocation[]) => { +export default () => { const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); return useSWR([ 'server:allocations', uuid ], async () => { const { data } = await http.get(`/api/client/servers/${uuid}/network/allocations`); return (data.data || []).map(rawDataToServerAllocation); - }, { initialData, revalidateOnFocus: false }); + }, { revalidateOnFocus: false, revalidateOnMount: false }); }; diff --git a/resources/scripts/components/server/network/AllocationRow.tsx b/resources/scripts/components/server/network/AllocationRow.tsx index 99bb121a..5eec2527 100644 --- a/resources/scripts/components/server/network/AllocationRow.tsx +++ b/resources/scripts/components/server/network/AllocationRow.tsx @@ -1,4 +1,4 @@ -import React, { memo, useState } from 'react'; +import React, { memo, useCallback, useState } from 'react'; import isEqual from 'react-fast-compare'; import tw from 'twin.macro'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; @@ -16,20 +16,25 @@ import useFlash from '@/plugins/useFlash'; import { ServerContext } from '@/state/server'; import CopyOnClick from '@/components/elements/CopyOnClick'; import DeleteAllocationButton from '@/components/server/network/DeleteAllocationButton'; +import setPrimaryServerAllocation from '@/api/server/network/setPrimaryServerAllocation'; +import getServerAllocations from '@/api/swr/getServerAllocations'; const Code = styled.code`${tw`font-mono py-1 px-2 bg-neutral-900 rounded text-sm inline-block`}`; const Label = styled.label`${tw`uppercase text-xs mt-1 text-neutral-400 block px-1 select-none transition-colors duration-150`}`; interface Props { allocation: Allocation; - onSetPrimary: (id: number) => void; - onNotesChanged: (id: number, notes: string) => void; } -const AllocationRow = ({ allocation, onSetPrimary, onNotesChanged }: Props) => { +const AllocationRow = ({ allocation }: Props) => { const [ loading, setLoading ] = useState(false); const { clearFlashes, clearAndAddHttpError } = useFlash(); const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); + const { mutate } = getServerAllocations(); + + const onNotesChanged = useCallback((id: number, notes: string) => { + mutate(data => data?.map(a => a.id === id ? { ...a, notes } : a), false); + }, []); const setAllocationNotes = debounce((notes: string) => { setLoading(true); @@ -41,6 +46,17 @@ const AllocationRow = ({ allocation, onSetPrimary, onNotesChanged }: Props) => { .then(() => setLoading(false)); }, 750); + const setPrimaryAllocation = () => { + clearFlashes('server:network'); + mutate(data => data?.map(a => ({ ...a, isDefault: a.id === allocation.id })), false); + + setPrimaryServerAllocation(uuid, allocation.id) + .catch(error => { + clearAndAddHttpError({ key: 'server:network', error }); + mutate(); + }); + }; + return (
@@ -81,7 +97,7 @@ const AllocationRow = ({ allocation, onSetPrimary, onNotesChanged }: Props) => { isSecondary size={'xsmall'} color={'primary'} - onClick={() => onSetPrimary(allocation.id)} + onClick={setPrimaryAllocation} > Make Primary diff --git a/resources/scripts/components/server/network/NetworkContainer.tsx b/resources/scripts/components/server/network/NetworkContainer.tsx index 39855fcf..8583b137 100644 --- a/resources/scripts/components/server/network/NetworkContainer.tsx +++ b/resources/scripts/components/server/network/NetworkContainer.tsx @@ -1,26 +1,31 @@ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useEffect, useState } from 'react'; import Spinner from '@/components/elements/Spinner'; import useFlash from '@/plugins/useFlash'; import ServerContentBlock from '@/components/elements/ServerContentBlock'; import { ServerContext } from '@/state/server'; -import { useDeepMemoize } from '@/plugins/useDeepMemoize'; import AllocationRow from '@/components/server/network/AllocationRow'; -import setPrimaryServerAllocation from '@/api/server/network/setPrimaryServerAllocation'; import Button from '@/components/elements/Button'; import createServerAllocation from '@/api/server/network/createServerAllocation'; import tw from 'twin.macro'; import Can from '@/components/elements/Can'; import SpinnerOverlay from '@/components/elements/SpinnerOverlay'; import getServerAllocations from '@/api/swr/getServerAllocations'; +import isEqual from 'react-fast-compare'; +import { Allocation } from '@/api/server/getServer'; const NetworkContainer = () => { const [ loading, setLoading ] = useState(false); const uuid = ServerContext.useStoreState(state => state.server.data!.uuid); const allocationLimit = ServerContext.useStoreState(state => state.server.data!.featureLimits.allocations); - const allocations = useDeepMemoize(ServerContext.useStoreState(state => state.server.data!.allocations)); + // @ts-ignore + const allocations: Allocation[] = ServerContext.useStoreState(state => state.server.data!.allocations, isEqual); const { clearFlashes, clearAndAddHttpError } = useFlash(); - const { data, error, mutate } = getServerAllocations(allocations); + const { data, error, mutate } = getServerAllocations(); + + useEffect(() => { + mutate(allocations, false); + }, []); useEffect(() => { if (error) { @@ -28,19 +33,6 @@ const NetworkContainer = () => { } }, [ error ]); - const setPrimaryAllocation = (id: number) => { - clearFlashes('server:network'); - - const initial = data; - mutate(data?.map(a => a.id === id ? { ...a, isDefault: true } : { ...a, isDefault: false }), false); - - setPrimaryServerAllocation(uuid, id) - .catch(error => { - clearAndAddHttpError({ key: 'server:network', error }); - mutate(initial, false); - }); - }; - const onCreateAllocation = () => { clearFlashes('server:network'); @@ -51,10 +43,6 @@ const NetworkContainer = () => { .then(() => setLoading(false)); }; - const onNotesAdded = useCallback((id: number, notes: string) => { - mutate(data?.map(a => a.id === id ? { ...a, notes } : a), false); - }, []); - return ( {!data ? @@ -66,8 +54,6 @@ const NetworkContainer = () => { )) }