Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion app/pages/project/floating-ips/FloatingIpsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { Outlet, useNavigate, type LoaderFunctionArgs } from 'react-router-dom'
import {
apiQueryClient,
useApiMutation,
useApiQuery,
useApiQueryClient,
usePrefetchedApiQuery,
type FloatingIp,
Expand All @@ -26,17 +27,20 @@ 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'
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'

Expand All @@ -59,15 +63,45 @@ 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 <EmptyCell />
const badge = <Badge color="neutral">{pool.name}</Badge>
return pool.description ? (
<Tooltip content={pool.description} placement="right">
<span>{badge}</span>
</Tooltip>
) : (
badge
)
}

const colHelper = createColumnHelper<FloatingIp>()
const staticCols = [
colHelper.accessor('name', {}),
colHelper.accessor('description', Columns.description),
colHelper.accessor('ip', {}),
colHelper.accessor('ip', {
header: 'IP address',
}),
colHelper.accessor('ipPoolId', {
cell: (info) => <IpPoolCell ipPoolId={info.getValue()} />,
header: 'IP pool',
}),
colHelper.accessor('instanceId', {
cell: (info) => <InstanceLinkCell instanceId={info.getValue()} />,
header: 'Attached to instance',
Expand Down
3 changes: 2 additions & 1 deletion app/ui/lib/Tooltip.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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
/**
Expand Down
4 changes: 2 additions & 2 deletions mock-api/ip-pool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ import { defaultSilo } from './silo'
export const ipPool1: Json<IpPool> = {
id: '69b5c583-74a9-451a-823d-0741c1ec66e2',
name: 'ip-pool-1',
description: '',
description: 'public IPs',
time_created: new Date().toISOString(),
time_modified: new Date().toISOString(),
}

const ipPool2: Json<IpPool> = {
id: 'af2fbe06-b21d-4364-96b7-a58220bc3242',
name: 'ip-pool-2',
description: '',
description: 'VPN IPs',
time_created: new Date().toISOString(),
time_modified: new Date().toISOString(),
}
Expand Down
5 changes: 3 additions & 2 deletions test/e2e/floating-ip-create.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
})
})

Expand All @@ -62,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')
Expand Down Expand Up @@ -91,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',
})
})