upcoming: [UIE-10432] - Implement drawer to reserve an IP address#13541
upcoming: [UIE-10432] - Implement drawer to reserve an IP address#13541grevanak-akamai wants to merge 2 commits intolinode:developfrom
Conversation
645da3c to
c27bd14
Compare
c27bd14 to
aae33c8
Compare
There was a problem hiding this comment.
Pull request overview
Implements a reusable “Reserve IP Address” drawer (create/edit/reserve modes) and wires it into the Reserved IPs landing empty state, along with supporting query/mocks and minor UI enhancements.
Changes:
- Added
ReserveIPDrawercomponent (with tests) and integrated it into the Reserved IPs landing empty state. - Added a reserved IP types query (
useReservedIPTypesQuery) and updated API client to use the beta endpoint for reserved IP types. - Extended MSW CRUD mocks to support reserving an IP and fetching reserved IP types; updated
TagsInputto support an optional label.
Reviewed changes
Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/queries/src/networking/networking.ts | Adds a query key + hook for fetching reserved IP pricing types. |
| packages/manager/src/mocks/presets/crud/networking.ts | Registers new networking CRUD handlers for reserved IPs. |
| packages/manager/src/mocks/presets/crud/handlers/networking.ts | Adds MSW handlers for reserving an IP and fetching reserved IP types. |
| packages/manager/src/mocks/presets/baseline/crud.ts | Includes networking CRUD handlers in the baseline CRUD preset. |
| packages/manager/src/features/ReservedIps/constants.ts | Adds drawer description text and docs link constants. |
| packages/manager/src/features/ReservedIps/ReservedIpsLanding/ReservedIpsLandingEmptyState.tsx | Hooks up the “Reserve an IP Address” CTA to open the drawer. |
| packages/manager/src/features/ReservedIps/ReserveIPDrawer.tsx | New drawer component implementing create/edit/reserve behavior, pricing display, and submission. |
| packages/manager/src/features/ReservedIps/ReserveIPDrawer.test.tsx | Adds unit tests covering loading state, create/edit/reserve modes, cancel, and pricing display. |
| packages/manager/src/factories/types.ts | Adds a reservedIPsTypeFactory for mock reserved IP pricing types. |
| packages/manager/src/components/TagsInput/TagsInput.tsx | Adds optional prop and forwards it to the underlying text field. |
| packages/manager/.changeset/pr-13541-upcoming-features-1774844980662.md | Adds an Upcoming Features changeset entry for the drawer. |
| packages/api-v4/src/networking/types.ts | Aligns IPAddress.assigned_entity with the shared Entity type. |
| packages/api-v4/src/networking/networking.ts | Switches getReservedIPsTypes to the beta API root. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Cloud Manager UI test results🎉 888 passing tests on test run #4 ↗︎
|
| try { | ||
| const tags = values.tags.map((tag) => tag.value); | ||
|
|
||
| if (mode === 'create') { |
There was a problem hiding this comment.
Linode/NodeBalancer Details should call PUT /networking/ips/{address} to mark an existing IP as reserved. But currently, reserve mode falls into the else branch and calls updateReservedIP which hits PUT /reserved/ips/{address}.
These are different endpoints:
PUT /networking/ips/{address} — marks an existing Linode/NodeBalancer IP as reserved
PUT /reserved/ips/{address} — updates tags on an already-reserved IP
There was a problem hiding this comment.
Yeah I'm aware of this. This PR focuses on integration of drawer with Reserve IP address feature. I thought rest of the code changes can be implemented as part of their respective tickets.
| }, | ||
| }); | ||
|
|
||
| const isSubmitDisabled = |
There was a problem hiding this comment.
The submit button can be clicked multiple times while a request is in-flight, let's include include isSubmitting in isSubmitDisabled.
|
|
||
| return ( | ||
| <Drawer | ||
| onClose={handleClose} |
There was a problem hiding this comment.
Form is reset in two places, reset() is called both in handleClose and in onTransitionExited.
| <Typography | ||
| sx={(theme) => ({ | ||
| color: theme.palette.text.primary, | ||
| marginTop: `${theme.spacingFunction(8)} !important`, |
There was a problem hiding this comment.
Can we avoid !important here?
| @@ -0,0 +1,266 @@ | |||
| /* Reserve IP Drawer | |||
There was a problem hiding this comment.
Design concerns:
- In Create Linode flow when reserved IP dropdown is empty, the user can call ReserveIP drawer:
In this the drawer should,
- Pre-fill region from the Linode's selected region
- Disable the region field (user can't change it)
- Call POST /reserved/ips
Currently, create mode always enables the region field. We need a way to pass a pre-selected region and disable the field.
- Some use cases may need to trigger side effects after successful submission, we might need an optional onSuccess?: (ip: IPAddress) => void
Description 📝
As part of this PR, implemented common drawer to reserve an IP address that can be reused in different usecases such as reserving a random IP address in a region, editing an IP address or reserving existing IP address. Integrated this drawer in reserved IP addresses landing page.
Changes 🔄
Scope 🚢
Upon production release, changes in this PR will be visible to:
Target release date 🗓️
Apr 2026
Preview 📷
How to test 🧪
Prerequisites
Verification steps
Author Checklists
As an Author, to speed up the review process, I considered 🤔
👀 Doing a self review
❔ Our contribution guidelines
🤏 Splitting feature into small PRs
➕ Adding a changeset
🧪 Providing/improving test coverage
🔐 Removing all sensitive information from the code and PR description
🚩 Using a feature flag to protect the release
👣 Providing comprehensive reproduction steps
📑 Providing or updating our documentation
🕛 Scheduling a pair reviewing session
📱 Providing mobile support
♿ Providing accessibility support
As an Author, before moving this PR from Draft to Open, I confirmed ✅