Skip to content

Commit

Permalink
use special None value in router picker
Browse files Browse the repository at this point in the history
  • Loading branch information
david-crespo committed Aug 22, 2024
1 parent 82169e9 commit b4e9277
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 29 deletions.
7 changes: 0 additions & 7 deletions app/components/form/fields/ListboxField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,6 @@ export function ListboxField<
onChange,
isLoading,
noItemsPlaceholder,
isClearable,
onClear,
}: ListboxFieldProps<TFieldValues, TName>) {
// TODO: recreate this logic
// validate: (v) => (required && !v ? `${name} is required` : undefined),
Expand Down Expand Up @@ -86,11 +84,6 @@ export function ListboxField<
buttonRef={field.ref}
/>
<ErrorMessage error={fieldState.error} label={label} />
{isClearable && (
<button type="button" onClick={onClear}>
clear
</button>
)}
</div>
)
}
23 changes: 15 additions & 8 deletions app/components/form/fields/useItemsList.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,23 @@ import { useMemo } from 'react'
import { useApiQuery } from '~/api'
import { useVpcSelector } from '~/hooks'

/**
* Special value indicating no router. Must convert `undefined` to this when
* populating form, and must convert this to `undefined` in onSubmit.
*/
export const NO_ROUTER = '||no router||'

export const useCustomRouterItems = () => {
const vpcSelector = useVpcSelector()
const routers = useApiQuery('vpcRouterList', { query: { ...vpcSelector } })
const { data, isLoading } = useApiQuery('vpcRouterList', { query: { ...vpcSelector } })

const routerItems = useMemo(() => {
return (
routers?.data?.items
.filter((item) => item.kind === 'custom')
.map((router) => ({ value: router.id, label: router.name })) || []
)
}, [routers])
const items = (data?.items || [])
.filter((item) => item.kind === 'custom')
.map((router) => ({ value: router.id, label: router.name }))

return [{ value: NO_ROUTER, label: 'None' }, ...items]
}, [data])

return { isLoading: routers.isLoading, items: routerItems }
return { isLoading, items: routerItems }
}
15 changes: 12 additions & 3 deletions app/forms/subnet-create.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ import { DescriptionField } from '~/components/form/fields/DescriptionField'
import { ListboxField } from '~/components/form/fields/ListboxField'
import { NameField } from '~/components/form/fields/NameField'
import { TextField } from '~/components/form/fields/TextField'
import { useCustomRouterItems } from '~/components/form/fields/useItemsList'
import { NO_ROUTER, useCustomRouterItems } from '~/components/form/fields/useItemsList'
import { SideModalForm } from '~/components/form/SideModalForm'
import { useForm, useVpcSelector } from '~/hooks'
import { FormDivider } from '~/ui/lib/Divider'
import { pb } from '~/util/path-builder'

const defaultValues: VpcSubnetCreate = {
name: '',
customRouter: undefined,
customRouter: NO_ROUTER,
description: '',
ipv4Block: '',
}
Expand Down Expand Up @@ -49,7 +49,15 @@ export function CreateSubnetForm() {
formType="create"
resourceName="subnet"
onDismiss={onDismiss}
onSubmit={(body) => createSubnet.mutate({ query: vpcSelector, body })}
onSubmit={(body) =>
createSubnet.mutate({
query: vpcSelector,
body: {
...body,
customRouter: body.customRouter === NO_ROUTER ? undefined : body.customRouter,
},
})
}
loading={createSubnet.isPending}
submitError={createSubnet.error}
>
Expand All @@ -63,6 +71,7 @@ export function CreateSubnetForm() {
isLoading={isLoading}
items={items}
control={form.control}
required
/>
<FormDivider />
<TextField name="ipv4Block" label="IPv4 block" required control={form.control} />
Expand Down
15 changes: 4 additions & 11 deletions app/forms/subnet-edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
import { DescriptionField } from '~/components/form/fields/DescriptionField'
import { ListboxField } from '~/components/form/fields/ListboxField'
import { NameField } from '~/components/form/fields/NameField'
import { useCustomRouterItems } from '~/components/form/fields/useItemsList'
import { NO_ROUTER, useCustomRouterItems } from '~/components/form/fields/useItemsList'
import { SideModalForm } from '~/components/form/SideModalForm'
import { getVpcSubnetSelector, useForm, useVpcSubnetSelector } from '~/hooks'
import { FormDivider } from '~/ui/lib/Divider'
Expand Down Expand Up @@ -55,17 +55,11 @@ export function EditSubnetForm() {
const defaultValues: VpcSubnetUpdate = {
name: subnet.name,
description: subnet.description,
customRouter: subnet.customRouterId,
customRouter: subnet.customRouterId || NO_ROUTER,
}

const form = useForm({ defaultValues })
const { isLoading, items } = useCustomRouterItems()
const customRouterValue = form.watch('customRouter')
const clearCustomRouter = () => {
// Because this is `undefined`, the dropdown isn't behaving correctly; it should revert to the placeholder
// It works when the value is '', but that's not a valid value for this field and it trips zod's validator
form.setValue('customRouter', undefined)
}

return (
<SideModalForm
Expand All @@ -80,7 +74,7 @@ export function EditSubnetForm() {
body: {
name: body.name,
description: body.description,
customRouter: body.customRouter,
customRouter: body.customRouter === NO_ROUTER ? undefined : body.customRouter,
},
})
}}
Expand All @@ -97,8 +91,7 @@ export function EditSubnetForm() {
isLoading={isLoading}
items={items}
control={form.control}
isClearable={!!customRouterValue}
onClear={clearCustomRouter}
required
/>
</SideModalForm>
)
Expand Down

0 comments on commit b4e9277

Please sign in to comment.