Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: [M3-7380] - Use volumes/types endpoint for pricing data #10376

Merged
merged 17 commits into from
Apr 15, 2024

Conversation

mjac0bs
Copy link
Contributor

@mjac0bs mjac0bs commented Apr 12, 2024

Description 📝

API is now returning pricing data through the /volumes/types endpoint.

In this PR, prices can be dynamically displayed for base region pricing and DC-specific region pricing, using the prices returned in the new endpoint, for Volumes.

Changes 🔄

  • Created the necessary api-v4 endpoint, query, and interface to use the volumes/types endpoint.
  • Modified getDCSpecificPriceByType to optionally accept a size param, if size is a factor of price and updated util unit test accordingly.
  • Created the necessary factory and endpoint in the MSW to support a mocked response to the API endpoint.
  • Added UX for error handling in the unlikely event that pricing cannot be calculated: disable create button and display tooltip error.
  • Added loading state for display prices.
  • Updated create-volume-smoke.spec.ts to test create volume error flows.

Note: I did not update the resize or clone Cypress tests to test those error flows. These existing specs run slowly since they have to create a linode and I'm not sure it's worth it for an edge-case like this, so held off doing that and will talk to Joe when he returns.

Preview 📷

The only visual changes should be loading state for pricing and the disabled Create Volume, Resize Volume, and Clone Volume buttons if the price is invalid (e.g. undefined).

Flow Screenshot
Create Volume Landing Error State Screenshot 2024-04-12 at 12 17 57 PM
Create Volume from Linode Error State Screenshot 2024-04-12 at 12 18 18 PM
Resize Volume Error State Screenshot 2024-04-12 at 12 18 43 PM
Clone Volume Error State Screenshot 2024-04-12 at 10 41 33 AM

How to test 🧪

Prerequisites

(How to setup test environment)

  • Check out this PR and yarn up.
  • All new types endpoints are all in prod, so use the prod environment.
  • Have an existing linode or create one.

Verification steps

(How to verify changes)

  • Go to http://localhost:3000/volumes/create.
  • Fill out the form.
  • Verify price calculation is correct by testing different options for the Region and comparing with prod.
  • Confirm:
    • There are no regressions in decimal point value or calculations displayed in the UI.
    • $0 is a valid region price if returned from the API, the user sees $0 pricing, and a volume can be created. (Update the mock data to test this.)
    • A user can still create a Volume.
    • If price cannot be calculated (e.g. it is undefined), the Summary displays the unknown price ($--.--) string, the Create button is disabled, and a tooltip displays on hover. (Blocking network requests is one method.)
    • When a region is not yet selected, the Create button is still enabled. (Pricing can't be calculated yet; we don't know if the price is invalid.)
    • Loading state functions as expected.
  • Additionally, confirm the above when creating or resizing a volume from a linode:
    • via Linode Details > Storage > Create Volume
    • via Linode Details > Storage > Clone (the volume you created in the last step)
    • via Linode Details > Storage > Resize (the volume you created)

As an Author I have considered 🤔

Check all that apply

  • 👀 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

@mjac0bs mjac0bs self-assigned this Apr 12, 2024
<Notice
text={
"You don't have permissions to create a new Volume. Please contact an account administrator for details."
}
important
variant="error"
Copy link
Contributor Author

@mjac0bs mjac0bs Apr 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This cleaned up an unrelated inconsistency in our error notice. important does not work without a variant prop, and we shouldn't useimportant here, anyway, to be consistent with how we displayed these errors elsewhere. I added the error variant that was missing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to use the warning variant for permissions banners, cause it's not technically an error

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went back to check what we've done in other "Restricted User Access" PRs and it does look like we're using an error with this. I'm going to keep it an error here for consistency.

Billing access PR: #10201
Nodebalancer PR: #10095

If we want to discuss error vs warning for these restricted access notices, let's bring it up with UX in cafe, @abailly-akamai. (cc @jaalah-akamai)

Screenshot 2024-04-15 at 10 00 07 AM

@@ -32,7 +36,11 @@ export const PricePanel = ({ currentSize, regionId, value }: Props) => {

return (
<Box marginTop={4}>
<DisplayPrice interval="mo" price={Number(price)} />
{isLoading ? (
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added loading state for the display price.

Screen.Recording.2024-04-12.at.1.00.21.PM.mov

@@ -80,7 +85,12 @@ export const SizeField = (props: Props) => {
</FormHelperText>
);

const dynamicPricingHelperText = !resize && !isFromLinode && (
// The price display is only visible next to the size field on the Volumes Create page.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did a little bit of renaming for clarity here and also added loading state to the price display for volumes create page to improve the slow network or error experience.

Screen.Recording.2024-04-12.at.12.58.39.PM.mov

@@ -81,6 +75,16 @@ describe('getDCSpecificPricingByType', () => {
).toBe('14.00');
});

it('calculates dynamic pricing for a volume based on size', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove getDynamicVolumePrice entirely now that we have price data in the /types endpoint; we just have to allow an optional size to be passed into getDCSpecificPriceByType. Test coverage is updated here accordingly.

@mjac0bs mjac0bs marked this pull request as ready for review April 12, 2024 23:59
@mjac0bs mjac0bs requested review from a team as code owners April 12, 2024 23:59
@mjac0bs mjac0bs requested review from cliu-akamai, carrillo-erik and abailly-akamai and removed request for a team April 12, 2024 23:59
@mjac0bs mjac0bs added @linode/api-v4 Changes are made to the @linode/api-v4 package DC-Specific Pricing Ready for Review labels Apr 12, 2024
Copy link

github-actions bot commented Apr 13, 2024

Coverage Report:
Base Coverage: 81.79%
Current Coverage: 81.78%

Copy link
Contributor

@abailly-akamai abailly-akamai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice and clean!

Code is good and consistent ✅
UI Price display, error and loading handling look great ✅

Left a couple comments for consideration

<Notice
text={
"You don't have permissions to create a new Volume. Please contact an account administrator for details."
}
important
variant="error"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want to use the warning variant for permissions banners, cause it's not technically an error

Copy link
Member

@bnussman-akamai bnussman-akamai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome work! 🎉 Didn't spot any issues 👁️

@mjac0bs mjac0bs added Approved Multiple approvals and ready to merge! and removed Ready for Review labels Apr 15, 2024
@mjac0bs mjac0bs merged commit 391b846 into linode:develop Apr 15, 2024
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Approved Multiple approvals and ready to merge! DC-Specific Pricing @linode/api-v4 Changes are made to the @linode/api-v4 package
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants