Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6cbbf37
Update instance-create to handle both v4 and v6 ephemeral IP options
charliepark Feb 6, 2026
acd97a4
Update copy; smarter handling of compatible defaults
charliepark Feb 7, 2026
badd541
refactor/bugfix
charliepark Feb 7, 2026
b1cbf12
remove useEffects
charliepark Feb 7, 2026
b10cf36
A bit more logic around custom NICs
charliepark Feb 7, 2026
5600704
fix text
charliepark Feb 7, 2026
198d870
Merge branch 'main' into dual_ephemeral_ips
charliepark Feb 9, 2026
ee8c38a
Use Remeda helpers
charliepark Feb 10, 2026
bcb7779
revert compact function, as it seems to be unavailable
charliepark Feb 10, 2026
4623869
Refactoring post-aipr review
charliepark Feb 10, 2026
0002e80
small adjustments
charliepark Feb 10, 2026
7641d9f
fix test
charliepark Feb 10, 2026
fc14295
Merge branch 'main' into dual_ephemeral_ips
charliepark Feb 10, 2026
b2b9f65
Merge branch 'main' into dual_ephemeral_ips
charliepark Feb 11, 2026
db89494
post-review updates
charliepark Feb 14, 2026
273102f
merge trunk
david-crespo Feb 13, 2026
503fac6
test proving the required={false} issue, fix the issue
david-crespo Feb 13, 2026
8f979dc
hide pool picker label on instance create
david-crespo Feb 13, 2026
f6397b4
fix comment
charliepark Feb 20, 2026
bdb6736
Merge branch 'main' into dual_ephemeral_ips
charliepark Feb 25, 2026
775f4a6
tighten up attached floating IPs calc to avoid non-null assertion
david-crespo Feb 27, 2026
4527860
clean up more useEffects and useMemos
david-crespo Feb 27, 2026
77b7979
move ephemeral IP pools logic inside the checkboxes
david-crespo Feb 27, 2026
af1781c
add a couple last bits of testing
david-crespo Feb 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@

- Reach for primitives in `app/ui` before inventing page-specific widgets; that directory holds router-agnostic building blocks.
- When you just need Tailwind classes on a DOM element, use the `classed` helper instead of creating one-off wrappers (`app/util/classed.ts`).
- Define helper components at the module level, not inside other components' render functions—the `react/no-unstable-nested-components` eslint rule enforces this to prevent performance issues and broken component identity. Extract nested components to the top level and pass any needed values as props.
- Reuse utility components for consistent formatting—`TimeAgo`, `EmptyMessage`, `CardBlock`, `DocsPopover`, `PropertiesTable`, etc.
- Import icons from `@oxide/design-system/icons/react` with size suffixes: `16` for inline/table, `24` for headers/buttons, `12` for tiny indicators.
- Keep help URLs in `links`/`docLinks` (`app/util/links.ts`).
Expand Down
11 changes: 10 additions & 1 deletion app/components/form/fields/IpPoolSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ type IpPoolSelectorProps<
/** Compatible IP versions based on network interface type */
compatibleVersions?: IpVersion[]
required?: boolean
hideOptionalTag?: boolean
label?: string
/** Hide visible label, using it as aria-label instead */
hideLabel?: boolean
}

export function IpPoolSelector<
Expand All @@ -67,6 +71,9 @@ export function IpPoolSelector<
disabled = false,
compatibleVersions = ALL_IP_VERSIONS,
required = true,
hideOptionalTag = false,
label = 'Pool',
hideLabel = false,
}: IpPoolSelectorProps<TFieldValues, TName>) {
// Note: pools are already filtered by poolType before being passed to this component
const sortedPools = useMemo(() => {
Expand All @@ -84,12 +91,14 @@ export function IpPoolSelector<
<ListboxField
name={poolFieldName}
items={sortedPools.map(toIpPoolItem)}
label="Pool"
label={label}
hideLabel={hideLabel}
noItemsPlaceholder="No pools available"
control={control}
placeholder="Select a pool"
required={required}
disabled={disabled}
hideOptionalTag={hideOptionalTag}
/>
</div>
)
Expand Down
4 changes: 4 additions & 0 deletions app/components/form/fields/ListboxField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export type ListboxFieldProps<
placeholder?: string
className?: string
label?: string
/** Hide visible label, using it as aria-label instead */
hideLabel?: boolean
required?: boolean
description?: string | React.ReactNode
control: Control<TFieldValues>
Expand Down Expand Up @@ -54,6 +56,7 @@ export function ListboxField<
isLoading,
noItemsPlaceholder,
hideOptionalTag,
hideLabel,
}: ListboxFieldProps<TFieldValues, TName>) {
// TODO: recreate this logic
// validate: (v) => (required && !v ? `${name} is required` : undefined),
Expand All @@ -63,6 +66,7 @@ export function ListboxField<
<Listbox
description={description}
label={label}
hideLabel={hideLabel}
required={required}
placeholder={placeholder}
noItemsPlaceholder={noItemsPlaceholder}
Expand Down
Loading
Loading