diff --git a/app/components/AttachFloatingIpModal.tsx b/app/components/AttachFloatingIpModal.tsx index a2022fe94c..2505ceb4ec 100644 --- a/app/components/AttachFloatingIpModal.tsx +++ b/app/components/AttachFloatingIpModal.tsx @@ -6,9 +6,16 @@ * Copyright Oxide Computer Company */ +import { useQuery } from '@tanstack/react-query' import { useForm } from 'react-hook-form' -import { useApiMutation, useApiQueryClient, type FloatingIp, type Instance } from '~/api' +import { + apiqErrorsAllowed, + useApiMutation, + useApiQueryClient, + type FloatingIp, + type Instance, +} from '~/api' import { ListboxField } from '~/components/form/fields/ListboxField' import { HL } from '~/components/HL' import { addToast } from '~/stores/toast' @@ -17,12 +24,27 @@ import { Slash } from '~/ui/lib/Slash' import { ModalForm } from './form/ModalForm' +function IpPoolName({ ipPoolId }: { ipPoolId: string }) { + const { data: result } = useQuery( + apiqErrorsAllowed('projectIpPoolView', { path: { pool: ipPoolId } }) + ) + // As with IpPoolCell, this should never happen, but to be safe … + if (!result || result.type === 'error') return null + return ( + <> + + {result.data.name} + + ) +} + function FloatingIpLabel({ fip }: { fip: FloatingIp }) { return (
{fip.name}
{fip.ip}
+ {fip.description && ( <> diff --git a/app/pages/project/instances/NetworkingTab.tsx b/app/pages/project/instances/NetworkingTab.tsx index 0af9f4fbc7..5a40289430 100644 --- a/app/pages/project/instances/NetworkingTab.tsx +++ b/app/pages/project/instances/NetworkingTab.tsx @@ -11,8 +11,10 @@ import { type LoaderFunctionArgs } from 'react-router' import { match } from 'ts-pattern' import { + apiqErrorsAllowed, apiQueryClient, instanceCan, + queryClient, useApiMutation, useApiQuery, useApiQueryClient, @@ -118,8 +120,20 @@ export async function clientLoader({ params }: LoaderFunctionArgs) { path: { instance }, query: { project }, }), - // This is used in AttachEphemeralIpModal - apiQueryClient.fetchQuery('projectIpPoolList', { query: { limit: ALL_ISH } }), + // Fetch IP Pools and preload into RQ cache so fetches by ID in + // IpPoolCell and AttachFloatingIpModal can be mostly instant + apiQueryClient + .fetchQuery('projectIpPoolList', { query: { limit: ALL_ISH } }) + .then((pools) => { + for (const pool of pools.items) { + // both IpPoolCell and the fetch in the model use errors-allowed + // versions to avoid blowing up in the unlikely event of an error + const { queryKey } = apiqErrorsAllowed('projectIpPoolView', { + path: { pool: pool.id }, + }) + queryClient.setQueryData(queryKey, { type: 'success', data: pool }) + } + }), ]) return null }