From e015f07c5cd16f01ae3289c3ab2d238f4df1d4e2 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Wed, 15 May 2024 09:46:59 -0700 Subject: [PATCH 1/2] Add IP Pool to list of floating IPs --- .../project/floating-ips/FloatingIpsPage.tsx | 32 +++++++++++++++++++ app/ui/lib/Tooltip.tsx | 3 +- mock-api/ip-pool.ts | 4 +-- test/e2e/floating-ip-create.e2e.ts | 1 + 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/app/pages/project/floating-ips/FloatingIpsPage.tsx b/app/pages/project/floating-ips/FloatingIpsPage.tsx index 9f7b14a456..b98b4f06d1 100644 --- a/app/pages/project/floating-ips/FloatingIpsPage.tsx +++ b/app/pages/project/floating-ips/FloatingIpsPage.tsx @@ -13,6 +13,7 @@ import { Outlet, useNavigate, type LoaderFunctionArgs } from 'react-router-dom' import { apiQueryClient, useApiMutation, + useApiQuery, useApiQueryClient, usePrefetchedApiQuery, type FloatingIp, @@ -26,10 +27,12 @@ import { getProjectSelector, useProjectSelector } from '~/hooks' import { confirmAction } from '~/stores/confirm-action' import { confirmDelete } from '~/stores/confirm-delete' import { addToast } from '~/stores/toast' +import { EmptyCell } from '~/table/cells/EmptyCell' import { InstanceLinkCell } from '~/table/cells/InstanceLinkCell' import { useColsWithActions, type MenuAction } from '~/table/columns/action-col' import { Columns } from '~/table/columns/common' import { PAGE_SIZE, useQueryTable } from '~/table/QueryTable' +import { Badge } from '~/ui/lib/Badge' import { CreateLink } from '~/ui/lib/CreateButton' import { EmptyMessage } from '~/ui/lib/EmptyMessage' import { Listbox } from '~/ui/lib/Listbox' @@ -37,6 +40,7 @@ import { Message } from '~/ui/lib/Message' import { Modal } from '~/ui/lib/Modal' import { PageHeader, PageTitle } from '~/ui/lib/PageHeader' import { TableActions } from '~/ui/lib/Table' +import { Tooltip } from '~/ui/lib/Tooltip' import { docLinks } from '~/util/links' import { pb } from '~/util/path-builder' @@ -59,15 +63,43 @@ FloatingIpsPage.loader = async ({ params }: LoaderFunctionArgs) => { apiQueryClient.prefetchQuery('instanceList', { query: { project }, }), + apiQueryClient + .fetchQuery('projectIpPoolList', { query: { limit: 1000 } }) + .then((pools) => { + for (const pool of pools.items) { + apiQueryClient.setQueryData( + 'projectIpPoolView', + { path: { pool: pool.id } }, + pool + ) + } + }), ]) return null } +const IpPoolCell = ({ ipPoolId }: { ipPoolId: string }) => { + const pool = useApiQuery('projectIpPoolView', { path: { pool: ipPoolId } }).data + if (!pool) return + const badge = {pool.name} + return pool.description ? ( + + {badge} + + ) : ( + badge + ) +} + const colHelper = createColumnHelper() const staticCols = [ colHelper.accessor('name', {}), colHelper.accessor('description', Columns.description), colHelper.accessor('ip', {}), + colHelper.accessor('ipPoolId', { + cell: (info) => , + header: 'IP pool', + }), colHelper.accessor('instanceId', { cell: (info) => , header: 'Attached to instance', diff --git a/app/ui/lib/Tooltip.tsx b/app/ui/lib/Tooltip.tsx index 101f34b237..ece688b0c7 100644 --- a/app/ui/lib/Tooltip.tsx +++ b/app/ui/lib/Tooltip.tsx @@ -36,7 +36,8 @@ import { usePopoverZIndex } from './SideModal' export interface TooltipProps { delay?: number - children?: React.ReactNode + /** The target the tooltip hovers near; can not be a raw string. */ + children?: ReactElement /** The text to appear on hover/focus */ content: string | React.ReactNode /** diff --git a/mock-api/ip-pool.ts b/mock-api/ip-pool.ts index 0296782ae9..534125ff80 100644 --- a/mock-api/ip-pool.ts +++ b/mock-api/ip-pool.ts @@ -14,7 +14,7 @@ import { defaultSilo } from './silo' export const ipPool1: Json = { id: '69b5c583-74a9-451a-823d-0741c1ec66e2', name: 'ip-pool-1', - description: '', + description: 'public IPs', time_created: new Date().toISOString(), time_modified: new Date().toISOString(), } @@ -22,7 +22,7 @@ export const ipPool1: Json = { const ipPool2: Json = { id: 'af2fbe06-b21d-4364-96b7-a58220bc3242', name: 'ip-pool-2', - description: '', + description: 'VPN IPs', time_created: new Date().toISOString(), time_modified: new Date().toISOString(), } diff --git a/test/e2e/floating-ip-create.e2e.ts b/test/e2e/floating-ip-create.e2e.ts index d8dd2c9ea7..42d674a1d9 100644 --- a/test/e2e/floating-ip-create.e2e.ts +++ b/test/e2e/floating-ip-create.e2e.ts @@ -49,6 +49,7 @@ test('can create a floating IP', async ({ page }) => { await expectRowVisible(page.getByRole('table'), { name: floatingIpName, description: 'A description for this Floating IP', + 'IP pool': 'ip-pool-1', }) }) From 76cbe4d956b987049b228bdc6a04e28969518bb7 Mon Sep 17 00:00:00 2001 From: Charlie Park Date: Wed, 15 May 2024 14:33:45 -0700 Subject: [PATCH 2/2] Update IP column to IP Address --- app/pages/project/floating-ips/FloatingIpsPage.tsx | 4 +++- test/e2e/floating-ip-create.e2e.ts | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/pages/project/floating-ips/FloatingIpsPage.tsx b/app/pages/project/floating-ips/FloatingIpsPage.tsx index b98b4f06d1..685c461ab0 100644 --- a/app/pages/project/floating-ips/FloatingIpsPage.tsx +++ b/app/pages/project/floating-ips/FloatingIpsPage.tsx @@ -95,7 +95,9 @@ const colHelper = createColumnHelper() const staticCols = [ colHelper.accessor('name', {}), colHelper.accessor('description', Columns.description), - colHelper.accessor('ip', {}), + colHelper.accessor('ip', { + header: 'IP address', + }), colHelper.accessor('ipPoolId', { cell: (info) => , header: 'IP pool', diff --git a/test/e2e/floating-ip-create.e2e.ts b/test/e2e/floating-ip-create.e2e.ts index 42d674a1d9..0f847df0ad 100644 --- a/test/e2e/floating-ip-create.e2e.ts +++ b/test/e2e/floating-ip-create.e2e.ts @@ -63,7 +63,7 @@ test('can detach and attach a floating IP', async ({ page }) => { await expectRowVisible(page.getByRole('table'), { name: 'cola-float', - ip: '123.4.56.5', + 'IP address': '123.4.56.5', 'Attached to instance': 'db1', }) await clickRowAction(page, 'cola-float', 'Detach') @@ -92,7 +92,7 @@ test('can detach and attach a floating IP', async ({ page }) => { await expect(page.getByRole('dialog')).toBeHidden() await expectRowVisible(page.getByRole('table'), { name: 'cola-float', - ip: '123.4.56.5', + 'IP address': '123.4.56.5', 'Attached to instance': 'db1', }) })