[FIX] website_sale_wishlist: prevent flicker and make tour deterministic
Before this commit, there was a slight chance that the "add to wishlist" button would flicker `disabled` off, which caused the tour to go next step too early. The flicker was because the `_onChangeVariant` could be triggered by the `website_sale` code before the variable `this.wishlistProductIDs` was actually set, so it wrongly computed the state and enabled the button. Now the RPC is done on the `willStart` instead of `start` to solve this issue. The tour has been edited to check the button is actually disabled initially. The view has been edited because the existing condition was too lazy: it checked if any variant of the current template was in the wishlist, instead of checking for the variant actually displayed. That also caused a flicker when the JS correctly computed the state for the variant afterwards. The widget has also been edited to trigger `input.product_id` instead of `input.js_variant_change:checked` to avoid calling `get_combination_info` twice from `website_sale` code. PR: #29675 task-1920036
This commit is contained in:
@@ -83,3 +83,12 @@ class ProductTemplate(models.Model):
|
||||
def _is_in_wishlist(self):
|
||||
self.ensure_one()
|
||||
return self in self.env['product.wishlist'].current().mapped('product_id.product_tmpl_id')
|
||||
|
||||
|
||||
class ProductProduct(models.Model):
|
||||
_inherit = 'product.product'
|
||||
|
||||
@api.multi
|
||||
def _is_in_wishlist(self):
|
||||
self.ensure_one()
|
||||
return self in self.env['product.wishlist'].current().mapped('product_id')
|
||||
|
||||
@@ -61,13 +61,18 @@ tour.register('shop_wishlist', {
|
||||
trigger: '.oe_product_cart a:contains("Customizable Desk")',
|
||||
},
|
||||
{
|
||||
content: "select desk cutomizable",
|
||||
content: "check the first variant is already in wishlist",
|
||||
trigger: '#product_detail .o_add_wishlist_dyn:disabled',
|
||||
run: function () {},
|
||||
},
|
||||
{
|
||||
content: "change variant",
|
||||
extra_trigger: '#product_detail label:contains(Aluminium) input',
|
||||
trigger: 'label:contains(Aluminium) input',
|
||||
},
|
||||
{
|
||||
content: "Change variant, wait button enable and click on add to wishlist",
|
||||
extra_trigger: '#product_detail .o_add_wishlist_dyn:not(".disabled")',
|
||||
content: "wait button enable and click on add to wishlist",
|
||||
extra_trigger: '#product_detail .o_add_wishlist_dyn:not(:disabled)',
|
||||
trigger: '#product_detail .o_add_wishlist_dyn',
|
||||
},
|
||||
{
|
||||
|
||||
@@ -20,30 +20,56 @@ sAnimations.registry.ProductWishlist = sAnimations.Class.extend(ProductConfigura
|
||||
},
|
||||
events: sAnimations.Class.events,
|
||||
|
||||
start: function () {
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
init: function (parent) {
|
||||
this._super.apply(this, arguments);
|
||||
this.wishlistProductIDs = [];
|
||||
},
|
||||
/**
|
||||
* Gets the current wishlist items.
|
||||
* In editable mode, do nothing instead.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
willStart: function () {
|
||||
var self = this;
|
||||
var def = this._super.apply(this, arguments);
|
||||
if (this.editableMode) {
|
||||
return def;
|
||||
}
|
||||
|
||||
this.wishlistProductIDs = [];
|
||||
|
||||
var wishDef = $.get('/shop/wishlist', {
|
||||
count: 1,
|
||||
}).then(function (res) {
|
||||
self.wishlistProductIDs = JSON.parse(res);
|
||||
self._updateWishlistView();
|
||||
// trigger change on only one input
|
||||
if (self.$('input.js_product_change').length) { // manage "List View of variants"
|
||||
self.$('input.js_product_change:checked').first().trigger('change');
|
||||
} else {
|
||||
self.$('input.js_variant_change:checked').first().trigger('change');
|
||||
}
|
||||
});
|
||||
|
||||
return $.when(def, wishDef);
|
||||
},
|
||||
/**
|
||||
* Updates the wishlist view (navbar) & the wishlist button (product page).
|
||||
* In editable mode, do nothing instead.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
var def = this._super.apply(this, arguments);
|
||||
if (this.editableMode) {
|
||||
return def;
|
||||
}
|
||||
|
||||
this._updateWishlistView();
|
||||
// trigger change on only one input
|
||||
if (this.$('input.js_product_change').length) { // manage "List View of variants"
|
||||
this.$('input.js_product_change:checked').first().trigger('change');
|
||||
} else {
|
||||
this.$('input.product_id').first().trigger('change');
|
||||
}
|
||||
|
||||
return def;
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
<template id="product_add_to_wishlist" name='Add to wishlist in product page' inherit_id="website_sale.product" priority="20">
|
||||
<xpath expr="//a[@id='add_to_cart']" position="after">
|
||||
<t t-if="request.website.viewref('website_sale_wishlist.add_to_wishlist').active">
|
||||
<t t-set="in_wish" t-value="product._is_in_wishlist()"/>
|
||||
<t t-set="product_variant" t-value="product_variant or product._create_first_product_variant()"/>
|
||||
<t t-set="in_wish" t-value="product_variant and product_variant._is_in_wishlist()"/>
|
||||
<button t-if="product_variant" type="button" role="button" class="btn btn-secondary btn-lg mt8 o_add_wishlist_dyn" t-att-disabled='in_wish or None' title="Add to Wishlist" t-att-data-product-template-id="product.id" t-att-data-product-product-id="product_variant.id" data-action="o_wishlist"><span class="fa fa-heart" role="img" aria-label="Add to wishlist"></span></button>
|
||||
</t>
|
||||
</xpath>
|
||||
|
||||
Reference in New Issue
Block a user