Skip to content

Commit

Permalink
Add minitable to top of floating-ip-edit
Browse files Browse the repository at this point in the history
  • Loading branch information
charliepark committed Dec 18, 2024
1 parent d583ae7 commit 5c2ff28
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 9 deletions.
55 changes: 50 additions & 5 deletions app/forms/floating-ip-edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,42 @@
* 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,
usePrefetchedApiQuery,
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 @@ -39,6 +56,12 @@ export function EditFloatingIpSideModalForm() {
path: { floatingIp: floatingIpSelector.floatingIp },
query: { project: floatingIpSelector.project },
})
const { name, description, ip, ipPoolId, instanceId } = floatingIp

const { data: instances } = usePrefetchedQuery(
instanceList(floatingIpSelector.project).optionsFn()
)
const instanceName = instances.items.find((i) => i.id === instanceId)?.name

const editFloatingIp = useApiMutation('floatingIpUpdate', {
onSuccess(_floatingIp) {
Expand All @@ -48,8 +71,7 @@ export function EditFloatingIpSideModalForm() {
},
})

const form = useForm({ defaultValues: floatingIp })

const form = useForm({ defaultValues: { name, description } })
return (
<SideModalForm
form={form}
Expand All @@ -66,6 +88,29 @@ export function EditFloatingIpSideModalForm() {
loading={editFloatingIp.isPending}
submitError={editFloatingIp.error}
>
<PropertiesTable>
<PropertiesTable.Row label="IP Address">
<CopyableIp ip={ip} isLinked={false} />
</PropertiesTable.Row>
<PropertiesTable.Row label="IP Pool">
<IpPoolCell ipPoolId={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
4 changes: 2 additions & 2 deletions app/table/cells/InstanceLinkCell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { useApiQuery } from '@oxide/api'
import { useProjectSelector } from '~/hooks/use-params'
import { pb } from '~/util/path-builder'

import { SkeletonCell } from './EmptyCell'
import { EmptyCell, SkeletonCell } from './EmptyCell'
import { LinkCell } from './LinkCell'

export const InstanceLinkCell = ({ instanceId }: { instanceId?: string }) => {
Expand All @@ -23,7 +23,7 @@ export const InstanceLinkCell = ({ instanceId }: { instanceId?: string }) => {
)

// has to be after the hooks because hooks can't be executed conditionally
if (!instanceId) return null
if (!instanceId) return <EmptyCell />
if (!instance) return <SkeletonCell />

return (
Expand Down

0 comments on commit 5c2ff28

Please sign in to comment.