From b4bab07c784364cc8d15848943fc671d849e9a85 Mon Sep 17 00:00:00 2001 From: David Crespo Date: Thu, 22 Aug 2024 17:01:27 -0500 Subject: [PATCH] shared helpers for converting to and from form data --- app/components/form/fields/useItemsList.ts | 19 +++++++++++++++---- app/forms/subnet-create.tsx | 15 +++++++++++---- app/forms/subnet-edit.tsx | 13 +++++++++---- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/app/components/form/fields/useItemsList.ts b/app/components/form/fields/useItemsList.ts index 5370b0d27..f364899c8 100644 --- a/app/components/form/fields/useItemsList.ts +++ b/app/components/form/fields/useItemsList.ts @@ -12,14 +12,25 @@ 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. + * Special value indicating no router. Must use helper functions to convert + * `undefined` to this when populating form, and this back to `undefined` in + * onSubmit. */ -export const NO_ROUTER = '||no router||' +const NO_ROUTER = '||no router||' + +/** Convert form value to value for PUT body */ +export function customRouterFormToData(value: string): string | undefined { + return value === NO_ROUTER ? undefined : value +} + +/** Convert value from response body to form value */ +export function customRouterDataToForm(value: string | undefined): string { + return value || NO_ROUTER +} export const useCustomRouterItems = () => { const vpcSelector = useVpcSelector() - const { data, isLoading } = useApiQuery('vpcRouterList', { query: { ...vpcSelector } }) + const { data, isLoading } = useApiQuery('vpcRouterList', { query: vpcSelector }) const routerItems = useMemo(() => { const items = (data?.items || []) diff --git a/app/forms/subnet-create.tsx b/app/forms/subnet-create.tsx index c58dc6e74..b492202bc 100644 --- a/app/forms/subnet-create.tsx +++ b/app/forms/subnet-create.tsx @@ -6,6 +6,7 @@ * Copyright Oxide Computer Company */ import { useNavigate } from 'react-router-dom' +import type { SetRequired } from 'type-fest' import { useApiMutation, useApiQueryClient, type VpcSubnetCreate } from '@oxide/api' @@ -13,15 +14,21 @@ 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 { NO_ROUTER, useCustomRouterItems } from '~/components/form/fields/useItemsList' +import { + customRouterDataToForm, + customRouterFormToData, + 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 = { +const defaultValues: SetRequired = { name: '', - customRouter: NO_ROUTER, + // populate the form field with the value corresponding to an undefined custom + // router on a subnet response + customRouter: customRouterDataToForm(undefined), description: '', ipv4Block: '', } @@ -54,7 +61,7 @@ export function CreateSubnetForm() { query: vpcSelector, body: { ...body, - customRouter: body.customRouter === NO_ROUTER ? undefined : body.customRouter, + customRouter: customRouterFormToData(body.customRouter), }, }) } diff --git a/app/forms/subnet-edit.tsx b/app/forms/subnet-edit.tsx index 2f515cca7..5c87e9c8b 100644 --- a/app/forms/subnet-edit.tsx +++ b/app/forms/subnet-edit.tsx @@ -6,6 +6,7 @@ * Copyright Oxide Computer Company */ import { useNavigate, type LoaderFunctionArgs } from 'react-router-dom' +import type { SetRequired } from 'type-fest' import { apiQueryClient, @@ -18,7 +19,11 @@ import { import { DescriptionField } from '~/components/form/fields/DescriptionField' import { ListboxField } from '~/components/form/fields/ListboxField' import { NameField } from '~/components/form/fields/NameField' -import { NO_ROUTER, useCustomRouterItems } from '~/components/form/fields/useItemsList' +import { + customRouterDataToForm, + customRouterFormToData, + useCustomRouterItems, +} from '~/components/form/fields/useItemsList' import { SideModalForm } from '~/components/form/SideModalForm' import { getVpcSubnetSelector, useForm, useVpcSubnetSelector } from '~/hooks' import { FormDivider } from '~/ui/lib/Divider' @@ -52,10 +57,10 @@ export function EditSubnetForm() { }, }) - const defaultValues: VpcSubnetUpdate = { + const defaultValues: SetRequired = { name: subnet.name, description: subnet.description, - customRouter: subnet.customRouterId || NO_ROUTER, + customRouter: customRouterDataToForm(subnet.customRouterId), } const form = useForm({ defaultValues }) @@ -74,7 +79,7 @@ export function EditSubnetForm() { body: { name: body.name, description: body.description, - customRouter: body.customRouter === NO_ROUTER ? undefined : body.customRouter, + customRouter: customRouterFormToData(body.customRouter), }, }) }}