-
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
Merged
asvinb
merged 40 commits into
feature/2824-price-benchmarks
from
add/2828-price-suggestions-table
Apr 23, 2025
Merged
Changes from all commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
9179974
Add Badge component.
asvinb 7e25ec5
Add EffectivenessIndicator component.
asvinb 52b57c2
Add @wordpress/dataviews package.
asvinb ab6b5b2
Add basic styles and placeholder content.
asvinb 727701e
Merge branch 'add/2826-price-benchmark-tab' into add/2828-price-sugge…
asvinb 0136f0e
Merge branch 'feature/2824-price-benchmarks' into add/2828-price-sugg…
asvinb f2bfb16
Add badge colors.
asvinb 8a18e67
Use new badge colors.
asvinb b74baf9
Tweak styles for table.
asvinb 26a9ed0
Use CurrentFactory.formatAmount function.
asvinb 7f36e34
Add Label component.
asvinb 550c1eb
Add Price component.
asvinb c6020d5
Add PriceBenchmarkTable component.
asvinb 0ac927d
Update suggestions table to use PriceBenchmarkTable component.
asvinb 6963cad
Add placeholder ChangePrice component.
asvinb 566aa89
Update datastore.
asvinb 311e621
Merge branch 'feature/2824-price-benchmarks' into add/2828-price-sugg…
asvinb 95bb6db
Add usePriceBenchmarkSuggestions hook.
asvinb 201592f
Add correct way of getting effectiveness badge.
asvinb 79edc72
Remove test data.
asvinb ff64912
Add @wordpress/viewport package.
asvinb be438a1
Add unspecified type for effectiveness.
asvinb 1b29a27
Add E2E tests.
asvinb ce85471
Add unspecified effectiveness test.
asvinb d7073ea
Fix font sizes
asvinb a91842f
Add tests for mobile view.
asvinb 21b1fac
Fix typo.
asvinb eb4f02a
Add check for non numbers for Price component.
asvinb 333723a
Use same data format as the API.
asvinb 6dd92ce
Exclude @wordpress/dataviews package from vendors chunk.
asvinb 52b3bf8
Tweak webpack config.
asvinb e30112f
Temporarily increase bundle size.
asvinb 83db740
Increase vendors bundle max size.
asvinb d865e18
Add useCallback to callback function.
asvinb a185509
Add unit tests for Price component.
asvinb e9d0b35
Change description to be string.
asvinb daf93bc
Fix searching and logic to show fields.
asvinb 86a80fd
Cast description to string.
asvinb 8904ea9
Enable sorting by product title.
asvinb c47df83
Remove dataview CSS overrides.
asvinb File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
["@woocommerce/block-templates","@woocommerce/components","@woocommerce/currency","@woocommerce/customer-effort-score","@woocommerce/data","@woocommerce/date","@woocommerce/navigation","@woocommerce/number","@woocommerce/product-editor","@woocommerce/settings","@woocommerce/tracks","@wordpress/api-fetch","@wordpress/components","@wordpress/compose","@wordpress/data","@wordpress/data-controls","@wordpress/date","@wordpress/dom","@wordpress/element","@wordpress/hooks","@wordpress/html-entities","@wordpress/i18n","@wordpress/primitives","@wordpress/url","jquery","lodash","react","react-dom"] | ||
["@woocommerce/block-templates","@woocommerce/components","@woocommerce/currency","@woocommerce/customer-effort-score","@woocommerce/data","@woocommerce/date","@woocommerce/navigation","@woocommerce/number","@woocommerce/product-editor","@woocommerce/settings","@woocommerce/tracks","@wordpress/api-fetch","@wordpress/components","@wordpress/compose","@wordpress/data","@wordpress/data-controls","@wordpress/date","@wordpress/dom","@wordpress/element","@wordpress/hooks","@wordpress/html-entities","@wordpress/i18n","@wordpress/primitives","@wordpress/url","@wordpress/viewport","jquery","lodash","react","react-dom"] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import classnames from 'classnames'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import './index.scss'; | ||
|
||
/** | ||
* Badge component. | ||
* | ||
* A reusable badge component that displays content with optional styling based on intent. | ||
* This is a temporary port of the Badge component from the Gutenberg repository: | ||
* https://github.com/WordPress/gutenberg/tree/trunk/packages/components/src/badge | ||
* until that package is made public. | ||
* | ||
* @param {Object} props - The component props. | ||
* @param {string} [props.className] - Additional CSS classes to apply to the badge. | ||
* @param {string} [props.intent='default'] - The intent of the badge, which determines its styling. | ||
* Possible values include 'default', 'success', 'info', 'warning ,'error', etc. | ||
* @param {JSX.Element} props.children - The content to display inside the badge. | ||
* @param {Object} [props.props] - Additional props to spread onto the badge element. | ||
* @return {JSX.Element} The rendered badge component. | ||
*/ | ||
function Badge( { className, intent = 'default', children, ...props } ) { | ||
return ( | ||
<span | ||
className={ classnames( 'gla-badge', className, { | ||
[ `is-${ intent }` ]: intent, | ||
} ) } | ||
{ ...props } | ||
> | ||
<span className="gla-badge__content">{ children }</span> | ||
</span> | ||
); | ||
} | ||
|
||
export default Badge; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
.gla-badge { | ||
padding: 0 $grid-unit-10; | ||
min-height: $grid-unit-30; | ||
max-width: 100%; | ||
border-radius: $gla-border-radius; | ||
font-size: $gla-font-smaller; | ||
font-weight: 400; | ||
line-height: $gla-line-height-smaller; | ||
display: inline-flex; | ||
align-items: center; | ||
gap: 2px; | ||
|
||
&:where(.is-default) { | ||
background-color: $gray-100; | ||
color: $gray-800; | ||
} | ||
|
||
&:where(.is-warning) { | ||
background-color: $gla-color-yellow-0; | ||
color: $gla-color-yellow-70; | ||
} | ||
|
||
&:where(.is-error) { | ||
background-color: $gla-color-red-0; | ||
color: $gla-color-red-70; | ||
} | ||
|
||
&:where(.is-success) { | ||
background-color: $gla-color-green-0; | ||
color: $gla-color-green-70; | ||
} | ||
} | ||
|
||
.gla-badge__content { | ||
overflow: hidden; | ||
white-space: nowrap; | ||
text-overflow: ellipsis; | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1208,7 +1208,7 @@ | |
export function* fetchPriceBenchmarkSummary() { | ||
try { | ||
const data = yield apiFetch( { | ||
path: `${ API_NAMESPACE }/mc/price-benchmark/summary`, | ||
path: `${ API_NAMESPACE }/mc/price-benchmarks/summary`, | ||
} ); | ||
|
||
return { | ||
|
@@ -1225,3 +1225,27 @@ | |
); | ||
} | ||
} | ||
|
||
/** | ||
* Action to fetch the Price Benchmark suggestions. | ||
*/ | ||
export function* fetchPriceBenchmarkSuggestions() { | ||
try { | ||
const data = yield apiFetch( { | ||
path: `${ API_NAMESPACE }/mc/price-benchmarks`, | ||
} ); | ||
|
||
return { | ||
type: TYPES.RECEIVE_PRICE_BENCHMARK_SUGGESTIONS, | ||
data, | ||
}; | ||
} catch ( error ) { | ||
handleApiError( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'll probably need to add some handling here later for #2852. |
||
error, | ||
__( | ||
'There was an error getting the price benchmark suggestions.', | ||
'google-listings-and-ads' | ||
) | ||
); | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { useSelect } from '@wordpress/data'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { STORE_KEY } from '~/data/constants'; | ||
|
||
const selectorName = 'getPriceBenchmarkSuggestions'; | ||
|
||
const usePriceBenchmarkSuggestions = () => { | ||
return useSelect( ( select ) => { | ||
const selector = select( STORE_KEY ); | ||
|
||
return { | ||
suggestions: selector[ selectorName ](), | ||
hasFinishedResolution: selector.hasFinishedResolution( | ||
selectorName, | ||
[] | ||
), | ||
}; | ||
}, [] ); | ||
}; | ||
|
||
export default usePriceBenchmarkSuggestions; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import AppButton from '~/components/app-button'; | ||
|
||
/** | ||
* ChangePrice component. | ||
* | ||
* Placeholder component. | ||
* | ||
* @param {Object} props - Component properties. | ||
* @param {number} props.productID - The ID of the product for which the price is being changed. | ||
* @param {string} [props.label='Change price'] - The label text for the button. Defaults to 'Change price'. | ||
* @return {JSX.Element} The rendered AppButton component. | ||
*/ | ||
const ChangePrice = ( { | ||
productID, | ||
label = __( 'Change price', 'google-listings-and-ads' ), | ||
} ) => { | ||
return <AppButton id={ productID }>{ label }</AppButton>; | ||
}; | ||
|
||
export default ChangePrice; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,56 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
export const TABLE_TYPE_SUGGESTIONS = 'suggestions'; | ||
export const TABLE_TYPE_ADJUSTMENTS = 'adjustments'; | ||
|
||
export const LABEL_PRICE_CHANGE_EFFECTIVENESS = | ||
'LABEL_PRICE_CHANGE_EFFECTIVENESS'; | ||
export const LABEL_PRICE_ON_GOOGLE = 'LABEL_PRICE_ON_GOOGLE'; | ||
export const LABEL_PRICE_GAP = 'LABEL_PRICE_GAP'; | ||
export const LABEL_SUGGESTED_PRICE = 'LABEL_SUGGESTED_PRICE'; | ||
export const LABEL_REGULAR_PRICE = 'LABEL_REGULAR_PRICE'; | ||
export const LABEL_ACTION = 'LABEL_ACTION'; | ||
export const EFFECTIVENESS_UNSPECIFIED = 0; | ||
export const EFFECTIVENESS_LOW = 1; | ||
export const EFFECTIVENESS_MEDIUM = 2; | ||
export const EFFECTIVENESS_HIGH = 3; | ||
|
||
export const LABELS = { | ||
[ LABEL_PRICE_CHANGE_EFFECTIVENESS ]: { | ||
title: __( 'Change Effectiveness', 'google-listings-and-ads' ), | ||
tooltip: __( | ||
'Effectiveness tells you which products would benefit most from price changes. This rating takes into consideration the performance boost predicted by adjusting the sale price and the difference between your current price and the suggested price. Price suggestions with “High” effectiveness are predicted to drive the largest increase in performance. Keep in mind that predictions do not guarantee improvements in future performance.', | ||
'google-listings-and-ads' | ||
), | ||
}, | ||
[ LABEL_PRICE_ON_GOOGLE ]: { | ||
title: __( 'Avg. Price on Google', 'google-listings-and-ads' ), | ||
tooltip: __( | ||
'The effective price for a product across all retailers selling the same product weighted by customer clicks. Products are matched based on the GTIN you provide in the product details.', | ||
'google-listings-and-ads' | ||
), | ||
}, | ||
[ LABEL_PRICE_GAP ]: { | ||
title: __( 'Price Gap %', 'google-listings-and-ads' ), | ||
tooltip: __( | ||
'The percentage difference between your price and the price on Google for this product.', | ||
'google-listings-and-ads' | ||
), | ||
}, | ||
[ LABEL_SUGGESTED_PRICE ]: { | ||
title: __( 'Suggested Price', 'google-listings-and-ads' ), | ||
tooltip: __( | ||
'Suggested sale price predicted by Google for products that benefit most from pricing adjustments. It is based on advanced simulations at different price points over the past 7 days factoring in price elasticity, current performance and the performance impact on price changes for businesses similar to you. Use suggested sale prices as valuable directional guidance to help shape your pricing strategy. Learn more about how to change the sale price of your products. Keep in mind that predictions do not guarantee future performance outcomes.', | ||
'google-listings-and-ads' | ||
), | ||
}, | ||
[ LABEL_REGULAR_PRICE ]: { | ||
title: __( 'Regular Price', 'google-listings-and-ads' ), | ||
}, | ||
[ LABEL_ACTION ]: { | ||
title: __( 'Action', 'google-listings-and-ads' ), | ||
}, | ||
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/** | ||
* External dependencies | ||
*/ | ||
import { __ } from '@wordpress/i18n'; | ||
|
||
/** | ||
* Internal dependencies | ||
*/ | ||
import { | ||
EFFECTIVENESS_UNSPECIFIED, | ||
EFFECTIVENESS_LOW, | ||
joemcgill marked this conversation as resolved.
Show resolved
Hide resolved
|
||
EFFECTIVENESS_MEDIUM, | ||
EFFECTIVENESS_HIGH, | ||
} from './constants'; | ||
import Badge from '~/components/badge'; | ||
|
||
const EFFECTIVENESS_MAP = { | ||
[ EFFECTIVENESS_UNSPECIFIED ]: { | ||
intent: 'default', | ||
label: __( 'Unspecified', 'google-listings-and-ads' ), | ||
}, | ||
[ EFFECTIVENESS_LOW ]: { | ||
intent: 'error', | ||
label: __( 'Low', 'google-listings-and-ads' ), | ||
}, | ||
[ EFFECTIVENESS_MEDIUM ]: { | ||
intent: 'warning', | ||
label: __( 'Medium', 'google-listings-and-ads' ), | ||
}, | ||
[ EFFECTIVENESS_HIGH ]: { | ||
intent: 'success', | ||
label: __( 'High', 'google-listings-and-ads' ), | ||
}, | ||
}; | ||
|
||
/** | ||
* Component to display an effectiveness indicator badge based on the provided effectiveness level. | ||
* | ||
* @param {Object} props - The component props. | ||
* @param {string} props.effectiveness - The effectiveness level to determine the badge's intent and label. | ||
* @return {JSX.Element|null} A Badge component with the corresponding intent and label, or null if the effectiveness level is invalid. | ||
*/ | ||
const EffectivenessIndicator = ( { effectiveness } ) => { | ||
if ( ! EFFECTIVENESS_MAP[ effectiveness ] ) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<Badge intent={ EFFECTIVENESS_MAP[ effectiveness ].intent }> | ||
{ EFFECTIVENESS_MAP[ effectiveness ].label } | ||
</Badge> | ||
); | ||
}; | ||
|
||
export default EffectivenessIndicator; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,10 @@ | ||
@import "@wordpress/dataviews/build-style/style.css"; | ||
|
||
.gla-price-benchmark__card .app-tab-nav:first-child { | ||
padding: 0 $grid-unit-40; | ||
} | ||
|
||
.gla-price-benchmark__comparison-chart { | ||
margin: $grid-unit-40 0; | ||
} | ||
|
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.