[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:
Sébastien Theys
2018-12-26 11:12:16 +00:00
parent 20478ff12e
commit ff873626ed
4 changed files with 54 additions and 14 deletions
@@ -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>