diff --git a/app/components/AttachEphemeralIpModal.tsx b/app/components/AttachEphemeralIpModal.tsx
index d16fbcbf6..73b71f6c2 100644
--- a/app/components/AttachEphemeralIpModal.tsx
+++ b/app/components/AttachEphemeralIpModal.tsx
@@ -50,7 +50,7 @@ export const AttachEphemeralIpModal = ({ onDismiss }: { onDismiss: () => void })
label="IP pool"
placeholder={
siloPools?.items && siloPools.items.length > 0
- ? 'Select pool'
+ ? 'Select a pool'
: 'No pools available'
}
items={
diff --git a/app/components/AttachFloatingIpModal.tsx b/app/components/AttachFloatingIpModal.tsx
index 1430a72ea..eaedd2dbd 100644
--- a/app/components/AttachFloatingIpModal.tsx
+++ b/app/components/AttachFloatingIpModal.tsx
@@ -71,7 +71,7 @@ export const AttachFloatingIpModal = ({
control={form.control}
name="floatingIp"
label="Floating IP"
- placeholder="Select floating IP"
+ placeholder="Select a floating IP"
items={floatingIps.map((ip) => ({
value: ip.id,
label: ,
diff --git a/app/components/form/fields/ListboxField.tsx b/app/components/form/fields/ListboxField.tsx
index 20f3da2b5..6ffefbea6 100644
--- a/app/components/form/fields/ListboxField.tsx
+++ b/app/components/form/fields/ListboxField.tsx
@@ -34,6 +34,7 @@ export type ListboxFieldProps<
items: ListboxItem[]
onChange?: (value: string | null | undefined) => void
isLoading?: boolean
+ noItemsPlaceholder?: string
}
export function ListboxField<
@@ -52,6 +53,7 @@ export function ListboxField<
control,
onChange,
isLoading,
+ noItemsPlaceholder,
}: ListboxFieldProps) {
// TODO: recreate this logic
// validate: (v) => (required && !v ? `${name} is required` : undefined),
@@ -64,6 +66,7 @@ export function ListboxField<
tooltipText={tooltipText}
required={required}
placeholder={placeholder}
+ noItemsPlaceholder={noItemsPlaceholder}
selected={field.value || null}
items={items}
onChange={(value) => {
diff --git a/app/components/form/fields/SubnetListbox.tsx b/app/components/form/fields/SubnetListbox.tsx
index 398dfde7b..77931f63b 100644
--- a/app/components/form/fields/SubnetListbox.tsx
+++ b/app/components/form/fields/SubnetListbox.tsx
@@ -11,12 +11,12 @@ import { useApiQuery } from '@oxide/api'
import { useProjectSelector } from '~/hooks'
-import { ComboboxField, type ComboboxFieldProps } from './ComboboxField'
+import { ListboxField, type ListboxFieldProps } from './ListboxField'
type SubnetListboxProps<
TFieldValues extends FieldValues,
TName extends FieldPath,
-> = Omit, 'items'> & {
+> = Omit, 'items'> & {
vpcNameField: FieldPath
}
@@ -47,11 +47,13 @@ export function SubnetListbox<
).data?.items || []
return (
- ({ value: name, label: name }))}
disabled={!vpcExists}
control={control}
+ placeholder="Select a subnet"
+ noItemsPlaceholder={vpcName ? 'No subnets found' : 'Select a VPC to see subnets'}
/>
)
}
diff --git a/app/forms/floating-ip-create.tsx b/app/forms/floating-ip-create.tsx
index af80f3bb2..6bc8fc8cb 100644
--- a/app/forms/floating-ip-create.tsx
+++ b/app/forms/floating-ip-create.tsx
@@ -111,7 +111,7 @@ export function CreateFloatingIpSideModalForm() {
items={(allPools?.items || []).map((p) => toListboxItem(p))}
label="IP pool"
control={form.control}
- placeholder="Select pool"
+ placeholder="Select a pool"
/>
diff --git a/app/forms/instance-create.tsx b/app/forms/instance-create.tsx
index 9fba26874..4324ce620 100644
--- a/app/forms/instance-create.tsx
+++ b/app/forms/instance-create.tsx
@@ -37,7 +37,6 @@ import {
import { AccordionItem } from '~/components/AccordionItem'
import { DocsPopover } from '~/components/DocsPopover'
import { CheckboxField } from '~/components/form/fields/CheckboxField'
-import { ComboboxField } from '~/components/form/fields/ComboboxField'
import { DescriptionField } from '~/components/form/fields/DescriptionField'
import { DiskSizeField } from '~/components/form/fields/DiskSizeField'
import {
@@ -46,6 +45,7 @@ import {
} from '~/components/form/fields/DisksTableField'
import { FileField } from '~/components/form/fields/FileField'
import { BootDiskImageSelectField as ImageSelectField } from '~/components/form/fields/ImageSelectField'
+import { ListboxField } from '~/components/form/fields/ListboxField'
import { NameField } from '~/components/form/fields/NameField'
import { NetworkInterfaceField } from '~/components/form/fields/NetworkInterfaceField'
import { NumberField } from '~/components/form/fields/NumberField'
@@ -221,9 +221,6 @@ export function CreateInstanceForm() {
const defaultValues: InstanceCreateInput = {
...baseDefaultValues,
bootDiskSourceType: defaultSource,
- siloImageSource: siloImages?.[0]?.id || '',
- projectImageSource: projectImages?.[0]?.id || '',
- diskSource: disks?.[0]?.value || '',
sshPublicKeys: allKeys,
bootDiskSize: nearest10(defaultImage?.size / GiB),
externalIps: [{ type: 'ephemeral', pool: defaultPool }],
@@ -550,7 +547,7 @@ export function CreateInstanceForm() {
/>
) : (
- pool.name === selectedPool)?.name}`}
items={
siloPools.map((pool) => ({
@@ -837,7 +834,7 @@ const AdvancedAccordion = ({
)
}}
required
- placeholder="Select floating IP"
+ placeholder="Select a floating IP"
selected={selectedFloatingIp?.name || ''}
/>
diff --git a/app/forms/network-interface-create.tsx b/app/forms/network-interface-create.tsx
index 756da6c0e..c3e452d32 100644
--- a/app/forms/network-interface-create.tsx
+++ b/app/forms/network-interface-create.tsx
@@ -9,8 +9,8 @@ import { useMemo } from 'react'
import { useApiQuery, type ApiError, type InstanceNetworkInterfaceCreate } from '@oxide/api'
-import { ComboboxField } from '~/components/form/fields/ComboboxField'
import { DescriptionField } from '~/components/form/fields/DescriptionField'
+import { ListboxField } from '~/components/form/fields/ListboxField'
import { NameField } from '~/components/form/fields/NameField'
import { SubnetListbox } from '~/components/form/fields/SubnetListbox'
import { TextField } from '~/components/form/fields/TextField'
@@ -65,12 +65,13 @@ export function CreateNetworkInterfaceForm({
- ({ label: name, value: name }))}
required
control={form.control}
+ placeholder="Select a VPC"
/>
diff --git a/app/pages/system/SiloImagesPage.tsx b/app/pages/system/SiloImagesPage.tsx
index 61cd29212..fa7fa3467 100644
--- a/app/pages/system/SiloImagesPage.tsx
+++ b/app/pages/system/SiloImagesPage.tsx
@@ -169,7 +169,7 @@ const PromoteImageModal = ({ onDismiss }: { onDismiss: () => void }) => {