Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add minitable to Floating IP side modal #2630

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
58 changes: 50 additions & 8 deletions app/forms/floating-ip-edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,41 @@
* Copyright Oxide Computer Company
*/
import { useForm } from 'react-hook-form'
import { useNavigate, type LoaderFunctionArgs } from 'react-router-dom'
import { Link, useNavigate, type LoaderFunctionArgs } from 'react-router-dom'

import { apiq, queryClient, useApiMutation, usePrefetchedApiQuery } from '@oxide/api'
import {
apiq,
getListQFn,
queryClient,
useApiMutation,
usePrefetchedQuery,
} from '@oxide/api'

import { DescriptionField } from '~/components/form/fields/DescriptionField'
import { NameField } from '~/components/form/fields/NameField'
import { SideModalForm } from '~/components/form/SideModalForm'
import { HL } from '~/components/HL'
import { getFloatingIpSelector, useFloatingIpSelector } from '~/hooks/use-params'
import { addToast } from '~/stores/toast'
import { EmptyCell } from '~/table/cells/EmptyCell'
import { IpPoolCell } from '~/table/cells/IpPoolCell'
import { CopyableIp } from '~/ui/lib/CopyableIp'
import { PropertiesTable } from '~/ui/lib/PropertiesTable'
import { ALL_ISH } from '~/util/consts'
import type * as PP from '~/util/path-params'
import { pb } from 'app/util/path-builder'

const floatingIpView = ({ project, floatingIp }: PP.FloatingIp) =>
apiq('floatingIpView', { path: { floatingIp }, query: { project } })
const instanceList = (project: string) =>
getListQFn('instanceList', { query: { project, limit: ALL_ISH } })

EditFloatingIpSideModalForm.loader = async ({ params }: LoaderFunctionArgs) => {
const selector = getFloatingIpSelector(params)
await queryClient.prefetchQuery(floatingIpView(selector))
await Promise.all([
queryClient.fetchQuery(floatingIpView(selector)),
queryClient.fetchQuery(instanceList(selector.project).optionsFn()),
])
return null
}

Expand All @@ -35,10 +51,11 @@ export function EditFloatingIpSideModalForm() {

const onDismiss = () => navigate(pb.floatingIps({ project: floatingIpSelector.project }))

const { data: floatingIp } = usePrefetchedApiQuery('floatingIpView', {
path: { floatingIp: floatingIpSelector.floatingIp },
query: { project: floatingIpSelector.project },
})
const { data: floatingIp } = usePrefetchedQuery(floatingIpView(floatingIpSelector))
const { data: instances } = usePrefetchedQuery(
instanceList(floatingIpSelector.project).optionsFn()
)
const instanceName = instances.items.find((i) => i.id === floatingIp.instanceId)?.name

const editFloatingIp = useApiMutation('floatingIpUpdate', {
onSuccess(_floatingIp) {
Expand All @@ -49,7 +66,6 @@ export function EditFloatingIpSideModalForm() {
})

const form = useForm({ defaultValues: floatingIp })

return (
<SideModalForm
form={form}
Expand All @@ -66,6 +82,32 @@ export function EditFloatingIpSideModalForm() {
loading={editFloatingIp.isPending}
submitError={editFloatingIp.error}
>
<PropertiesTable>
<PropertiesTable.IdRow id={floatingIp.id} />
<PropertiesTable.DateRow label="Created" date={floatingIp.timeCreated} />
<PropertiesTable.DateRow label="Updated" date={floatingIp.timeModified} />
<PropertiesTable.Row label="IP Address">
<CopyableIp ip={floatingIp.ip} isLinked={false} />
</PropertiesTable.Row>
<PropertiesTable.Row label="IP Pool">
<IpPoolCell ipPoolId={floatingIp.ipPoolId} />
</PropertiesTable.Row>
<PropertiesTable.Row label="Instance">
{instanceName ? (
<Link
to={pb.instanceNetworking({
project: floatingIpSelector.project,
instance: instanceName,
})}
className="link-with-underline group text-sans-md"
>
{instanceName}
</Link>
) : (
<EmptyCell />
)}
</PropertiesTable.Row>
</PropertiesTable>
<NameField name="name" control={form.control} />
<DescriptionField name="description" control={form.control} />
</SideModalForm>
Expand Down
4 changes: 2 additions & 2 deletions app/pages/project/floating-ips/FloatingIpsPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ const instanceList = (project: string) =>
FloatingIpsPage.loader = async ({ params }: LoaderFunctionArgs) => {
const { project } = getProjectSelector(params)
await Promise.all([
queryClient.prefetchQuery(fipList(project).optionsFn()),
queryClient.prefetchQuery(instanceList(project).optionsFn()),
queryClient.fetchQuery(fipList(project).optionsFn()),
queryClient.fetchQuery(instanceList(project).optionsFn()),
// fetch IP Pools and preload into RQ cache so fetches by ID in
// IpPoolCell can be mostly instant yet gracefully fall back to
// fetching individually if we don't fetch them all here
Expand Down
Loading