-
Notifications
You must be signed in to change notification settings - Fork 683
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
[PWA-239] Shipping Method (Cart) #2123
Conversation
- Update select input to support id as element key - Add disabled style to select
- Dependently display shipping methods container
- Handle styling of radio option
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! Nothing major stands out to me other than the ungodly amount of time it can take to perform mutations once you've set a method...
const options = items.map(({ label, value }) => ( | ||
<Option key={value} value={value}> | ||
const options = items.map(({ id = null, label, value }) => ( | ||
<Option key={id || value} value={value}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add id
to items shape. Also why?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is because of a duplicate value in a response maybe its a bug?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed IRL, created https://jira.corp.magento.com/browse/MC-30886
// TODO: these classes may not be defined! | ||
classes={{ | ||
label: classes.radioLabel, | ||
root: classes.radio |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I looked and couldn't find any other reference to the RadioGroup
component outside of your usage in this PR. Perhaps we can just update the styles for it instead of overriding classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These styles were a little opinionated about the label, using grid to flow content based on screen size, which I wouldn't want to make the default style. Decided to leave this as-is.
@@ -40,7 +51,9 @@ export class RadioGroup extends Component { | |||
{options} | |||
</BasicRadioGroup> | |||
</div> | |||
<Message fieldState={fieldState}>{message}</Message> | |||
<Message className={classes.message} fieldState={fieldState}> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Interesting -- was this just not using the class?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inherited some of the UI work from @supernova-at, who made this change, but from what I can tell none of the styles were extensible, which is what was fixed here.
<a href="https://jira.corp.magento.com/browse/PWA-239"> | ||
Shipping Methods to be completed by PWA-239. | ||
</a> | ||
<ShippingMethods /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you set this to isOpen
? I accidentally left the coupon code as the default one (and that got merged).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done in 9c94499. UX would actually prefer this is closed on first render, but given the bug that closes all panels every time an effect is fired, I'm going to suggest leaving open for now.
) { | ||
cart { | ||
id | ||
...PriceSummaryFragment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to refetch the entire cart page fragment (which includes price summary) because we (the shipping mutation) don't know what else may need eventually want to re-render based on the mutation. For example maybe we have a new UI component that needs to show the chosen option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed in 9c94499
<Form className={classes.root}> | ||
<ShippingFields | ||
selectedShippingFields={selectedShippingFields} | ||
setIsFetchingMethods={setIsFetchingMethods} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think you need this state -- you can define the mutations in this component (or talon) and expose the loading state from there. Then you don't need to pass in a callback here and you won't need the effect inside the shipping fields talon, you'd just pass the handleSubmit
callback which would invoke the mutation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll look into this. I was constrained by the mutations access to the form fields, but maybe there is another way to gain access outside of the form with a submit handler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-factored this state sync prop out in 9c94499.
<TextInput | ||
field="zip" | ||
initialValue={zip} | ||
onBlur={handleZipOnBlur} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this field is required for the methods to be fetched we may want to indicate that somehow.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Re-factored to use forms submit handlers, should be more clear what triggers the fetch of methods now.
|
||
const handleShippingSelection = useCallback( | ||
value => { | ||
const [carrierCode, methodCode] = value.split('|'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clever, but can value
not be an object?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Man, you missed a thrilling discussion in Slack about this. tl;dr - no, we should strive for rendered markup to still be valid, and radio values must be of type DomString. Would love your opinion on this as well.
https://magento.slack.com/archives/G8N21AQTV/p1580161395028400
label: region.name, | ||
value: region.code | ||
})); | ||
formattedStatesData.unshift({ label: '', value: '' }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You do this to present an empty state initially, right? Rather than allowing it as an option maybe we should set the initial selection to <option disabled selected value> -- Select a FOO -- </option>
inside the Select
component as a default (or configurable) UI.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, good catch. I intended to add support for disabled
and hidden
props to the Select component options and just completely forgot, will get those added.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added these props in 9c94499
} | ||
|
||
let formattedStatesData = []; | ||
if (fetchStatesCalled && !isStatesLoading && !statesError) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to have a consensus on loading states at some point. Did UX direct you to intentionally show "loading countries" but not "loading states/regions"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No direction, was waiting on demo to confirm those details. There's a bigger problem here too with non-US countries that don't even have state options, and how to handle that. Will get that lined up for tomorrow.
- Adjust some minor things based on UX feedback
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Graceful handling of shipping methods not loading is really the only thing (see #2123 (comment)).
Great job!
- Update test snaps after mainline merge
- Update tests
- Memoize click event for enabling form
...artPage/PriceAdjustments/ShippingMethods/__tests__/__snapshots__/shippingRadios.spec.js.snap
Show resolved
Hide resolved
@@ -82,7 +82,7 @@ const ShippingForm = props => { | |||
{!hasMethods ? ( | |||
<Button | |||
classes={{ root_normalPriority: classes.submit }} | |||
disabled={setShippingLoading ? true : null} | |||
disabled={setShippingLoading} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Took me a second to parse this one because setShippingLoading
reads like a function, not a boolean.
Up to you if you want to change it or not.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, renamed to follow our bool naming convention in cf8fd2e, good call.
Want to memoize the showForm
function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
UX approved.
Nice work!
5596146
@tjwiebell Other than shipping option ordering issue rest all looks good. |
There is an issue with GQL response returning incorrect values for flatrate, but that should be handled separately. If @dpatil-magento made a ticket can you post it here? Thanks! |
Description
When a user (shopper) is in the cart flow for Venia, a shipping method selection/estimate component should display in order to allow a shopper to determine the impact of shipping to their order summary.
Requirements:
Adhere to design specs/flows
Initial design accounts for unauthenticated cart/checkout, authenticated to be a fast follow
out of scope:
detecting location based on customer device
Related Issue
Acceptance
Verification Stakeholders
Specification
Verification Steps
If you want to verify that third-party shipping providers are working, you'll need inventory items that have weight, and your shipping methods configured in the backend. I've done this with a staging environment, you'll have to use Carmina Necklace: https://mcstaging-jnz3dtiuj77ca.dummycachetest.com/
/cart
page and verify that estimate shipping fields are displayed (country, state, zip)Screenshots / Screen Captures (if appropriate)
Checklist