From 23f4b3f6528a4b03a524cb87f0bb42e68ed896d0 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Thu, 31 Jul 2025 11:19:51 -0700 Subject: [PATCH] Add IP pool name to Attach Floating IP dropdown --- app/components/AttachFloatingIpModal.tsx | 23 ++++++++++++++++++- app/pages/project/instances/NetworkingTab.tsx | 14 +++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/app/components/AttachFloatingIpModal.tsx b/app/components/AttachFloatingIpModal.tsx index a2022fe94c..2df5b34fa2 100644 --- a/app/components/AttachFloatingIpModal.tsx +++ b/app/components/AttachFloatingIpModal.tsx @@ -8,7 +8,13 @@ import { useForm } from 'react-hook-form' -import { useApiMutation, useApiQueryClient, type FloatingIp, type Instance } from '~/api' +import { + useApiMutation, + useApiQueryClient, + useApiQueryErrorsAllowed, + 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 +23,27 @@ import { Slash } from '~/ui/lib/Slash' import { ModalForm } from './form/ModalForm' +function IpPoolName({ ipPoolId }: { ipPoolId: string }) { + const { data: result } = useApiQueryErrorsAllowed('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 f90b6e90cb..2e07520d13 100644 --- a/app/pages/project/instances/NetworkingTab.tsx +++ b/app/pages/project/instances/NetworkingTab.tsx @@ -10,8 +10,10 @@ import { useCallback, useMemo, useState } from 'react' import { type LoaderFunctionArgs } from 'react-router' import { + apiq, apiQueryClient, instanceCan, + queryClient, useApiMutation, useApiQuery, useApiQueryClient, @@ -114,8 +116,16 @@ 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) { + const { queryKey } = apiq('projectIpPoolView', { path: { pool: pool.id } }) + queryClient.setQueryData(queryKey, pool) + } + }), ]) return null }