-
Notifications
You must be signed in to change notification settings - Fork 22
Add PriceBenchmarkSuggestions component #2853
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
Add PriceBenchmarkSuggestions component #2853
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## feature/2824-price-benchmarks #2853 +/- ##
==================================================================
+ Coverage 67.2% 67.3% +0.2%
==================================================================
Files 817 334 -483
Lines 24995 5157 -19838
Branches 1252 1251 -1
==================================================================
- Hits 16789 3473 -13316
+ Misses 8065 1545 -6520
+ Partials 141 139 -2
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
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.
@asvinb I took a look through the WIP here and overall the setup seems good to me. I left a few question/comments but think you're on the right track
data, | ||
}; | ||
} catch ( error ) { | ||
handleApiError( |
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'll probably need to add some handling here later for #2852.
* for desktop and mobile views. | ||
* | ||
* @return {JSX.Element} A div containing the PriceBenchmarkTable component. | ||
*/ | ||
const PriceBenchmarkSuggestions = () => { |
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.
Will this component also render the MetricsNotice?
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, it's the PriceBenchmarkTable
component which will render MetricsNotice
.
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.
In that case, I wonder if we can remove one level of nesting here and move all of the fields setup directly into the PriceBenchmarkTable
component?
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 originally had it like that @joemcgill :
c6020d5
But then i thought the PriceBenchmarkTable
should only contain fields that should be part of the basic table. Then any components using PriceBenchmarkTable
should pass their extra fields. I feel that can be more flexible if we have different table types in the future. Let me know what you think. Happy to go with your suggestion as well 😁
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.
Is there a use case you have in mind where another component would need to use PriceBenchmarkTable
? Seems like any custom tables that need different data could do so and wrap their own DataViews component.
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.
So eventually, we’ll have the PriceBenchmarkAdjustments
component. My main concern is that PriceBenchmarkTable
will contain logic related to both suggestions and adjustments, even though we already have (or will have) dedicated components like PriceBenchmarkSuggestions
and PriceBenchmarkAdjustments
that encapsulate that logic. In other words, I’d prefer not to split some of logic across both PriceBenchmarkTable
and PriceBenchmarkSuggestions
. What do you think?
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.
Ah, I see what you have in mind. Let's go with it for now and evaluate as the rest of the feature comes together. 👍🏻
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.
@asvinb I've left a round of feedback on this PR. The most important things that need to be addressed are:
- Ensuring we're using the expected shape from the REST API endpoint for price-benchmarks
- Resolving the bundle watch issues.
For the latter, could we update the webpack config so the dataviews package isn't bundled into the vendors.js
bundle? We will probably need to enqueue it specifically for this page once we do so the bundle isn't loaded on other pages where it is not being used.
Even then, the bundle size might still be too large, so we will likely need to figure out how to allow the max size for that package to be above the current threshold.
* for desktop and mobile views. | ||
* | ||
* @return {JSX.Element} A div containing the PriceBenchmarkTable component. | ||
*/ | ||
const PriceBenchmarkSuggestions = () => { |
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.
In that case, I wonder if we can remove one level of nesting here and move all of the fields setup directly into the PriceBenchmarkTable
component?
tests/e2e/specs/price-benchmark/price-benchmark-suggestions.test.js
Outdated
Show resolved
Hide resolved
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.
Almost there, @asvinb. Unfortunately I found some issues with the change in data shape that need to be fixed before this is merged. Everything else looks non-blocking.
const BASE_FIELDS = [ | ||
{ | ||
id: 'image', | ||
enableHiding: false, | ||
enableSorting: false, | ||
enableGlobalSearch: false, | ||
label: __( 'Image', 'google-listings-and-ads' ), | ||
render: ( { item } ) => { | ||
return ( | ||
<img | ||
src={ item.product.thumbnail } | ||
alt={ item.product.title } | ||
className="gla-price-benchmark-table__image" | ||
/> | ||
); | ||
}, | ||
}, | ||
{ | ||
id: 'title', | ||
enableHiding: false, | ||
enableSorting: false, | ||
enableGlobalSearch: true, | ||
label: __( 'Product', 'google-listings-and-ads' ), | ||
render: ( { item } ) => { | ||
return item.product.title; | ||
}, | ||
}, | ||
{ | ||
id: 'description', | ||
enableHiding: false, | ||
enableSorting: false, | ||
enableGlobalSearch: true, | ||
label: __( 'Description', 'google-listings-and-ads' ), | ||
render: ( { item } ) => { | ||
return <span>{ item.product.id }</span>; | ||
}, | ||
}, | ||
]; |
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 noticed after the data shape updates that there is no validation on the item properties, which caused the app to crash with the following error:
TypeError: Cannot read properties of undefined (reading 'id')
We should probably use optional chaining or validate that the data prop passed to this component includes the expected properties to make this more robust.
Additionally, while testing this after applying the correct data shape, I noticed that the sorting functionality now also causes the app to crash:
TypeError: Cannot read properties of undefined (reading 'localeCompare')
The search functionality also seems to not be working, but am not sure that it was previously.
To reproduce the way I've tested this:
- Open DevTools to the network panel in Chrome
- Look for Fetch/XHR requests to
/wp-json/wc/gla/mc/price-benchmarks
(must have pretty permalinks enabled) - Right click the request and choose "Override Content"
- Paste in the data from the
tests/e2e/utils/__fixtures__/price-benchmark-suggestions.json
file. - Refresh the page with DevTools still open
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.
Same property validation applies to the TABLE_FIELDS in the PriceBenchmarkSuggestions
component.
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.
thanks @joemcgill . I've pushed a fix. Can you kindly check again?
@@ -0,0 +1,50 @@ | |||
.gla-price-benchmark-table { |
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.
@asvinb I'm curious why so much of the dataviews style need to be overridden? Is this just to match the designs? For consistency with other WP UI, it would be nice if we could avoid doing so much customization.
Not a blocker, but something to discuss with @michaeleleder when this is ready to demo.
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.
@joemcgill The main styling changes are:
- Custom alignment for table cells. Some cells are left aligned and some are right aligned.
- The image dimensions are 32x32 with a 2px border radius. By default, it's 60x60 with no border radius.
- Removed the minimum height of 32px for the title to match the designs.
Sure we can discuss with @michaeleleder about that.
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.
@asvinb I know the default DataViews may not have it, but right alignment for number columns is consistently used across multiple different sections that use DataViews in our development. The image dimension is also taken from a previous project (although I’m not sure about its dev status). I understand you don’t have access to those, but maybe @budzanowski could help?
Regarding the last bullet point, I’m not sure what it is referring to.
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.
Thanks @michaeleleder The last bullet point refers to a min height of 32px applied to the title which adds some spacing between the title and product id. Here is the default:
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.
@joemcgill is correct.
It was pointed out to me that we should:
avoid "local overrides" for dataviews: this means do not have CSS overrides and use stock dataviews.
How much this complicate things?
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.
@asvinb @budzanowski Seems like the spacing doesn’t fit the smaller images. It’s tricky because I’ve taken this from another project design (not sure about the dev status), and I think we’ll be using this in another project too, so we might need it in the future. But if now isn’t a good time to spend the effort, we can just use the large image.
These are the two different image sizes we have in our design systems. This one seems to be a combination of the small image and a two-line title:
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.
@michaeleleder In that case, I'am happy to revert the CSS overrides for dataviews and only keep the alignments overrides. Let me know if that works for you.
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.
@asvinb Okay with me, thanks!
* @return {JSX.Element} The rendered price component. | ||
*/ | ||
const Price = ( { amount, highlight = false } ) => { | ||
const { formatAmount } = useAdsCurrency(); |
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.
Eventually, it would be nice to have some jest tests for this component that confirm this is working as intended with different currency types.
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 tests although the test are mostly to test the isNaN functionality and highlight.
"maxSize": "41 kB" | ||
}, | ||
{ | ||
"path": "./js/build/wp-dataviews.js", | ||
"maxSize": "242.57 kB" |
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.
As we discussed in Slack, including the @wordpress/dataviews
package in plugins currently requires using a special bundle that includes all of the needed dependencies so this is cross compatible with different versions of the dependencies externalized to WP core.
Related GB discussion: WordPress/gutenberg#66825
For now, the larger bundle size is fine, but it we should try to improve this in a follow-up issue. For example, can we avoid the additional size in vendors.js
?
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.
Sure @joemcgill . Follow up ticket created: #2863
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 was asked if I could clarify this bit.
What Joe shared is correct: @wordpress/dataviews/wp
(the one used here) comes with bundled dependencies, so it works properly in different environments (different WordPress versions, with/without Gutenberg plugin).
The alternative is using @wordpress/dataviews
. In that case, the dependencies are externalized, which means DataViews will access them via the wp.*
global. This is problematic if the plugin aims to be compatible with different environments: the global components may have a different API depending on the environment, which would cause issues.
Looking at the latest build-wp/index.js
published as part of the @wordpress/dataviews
npm package it seems to be about ~1.6Mb.
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.
Thanks @oandregal ! I think in our case, it's better we use the @wordpress/dataviews/wp
to ensure the app works properly in different environments since we are supporting previous WordPress versions. Can you kindly take a look at the suggested approach here, whether it makes sense to you please? We don't want to bloat the vendors
chunk unnecessarily with dependencies from the @wordpress/dataviews
package. Let me know what you think.
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.
Looks good!
Changes proposed in this Pull Request:
Closes #2828 .
Replace this with a good description of your changes & reasoning.
Screenshots:
Detailed test instructions:
Additional details:
Changelog entry