[FIX] website_sale: fix behaviors for loading recently viewed products
If there is no product in the recently viewed product snippet, it will simply not be shown. It appears only if there are products (with some flickering we may decide to improve in future versions). Also fix the behavior when the last product of the snippet is moved to the cart. task-2076271 closes odoo/odoo#38438 X-original-commit: 02037bc20c6d3f5f2bad70a1a30b424ec432eb6b Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com> Co-authored-by: qsm-odoo <qsm@odoo.com>
This commit is contained in:
committed by
qsm-odoo
co-authored by
qsm-odoo
parent
91a5021763
commit
46b818db1e
@@ -392,50 +392,4 @@ options.registry.ProductsSearchBar = options.Class.extend({
|
||||
}).open();
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* Handles the edition of products search bar snippet.
|
||||
*/
|
||||
options.registry.ProductsRecentlyViewed = options.Class.extend({
|
||||
xmlDependencies: ['/website_sale/static/src/xml/website_sale_recently_viewed.xml'],
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
start: function () {
|
||||
var carouselOptions = {
|
||||
productsGroups: [[{
|
||||
id: 0,
|
||||
website_url: '#',
|
||||
display_name: 'Product 1',
|
||||
price: '$ <span class="oe_currency_value">750.00</span>',
|
||||
}, {
|
||||
id: 0,
|
||||
website_url: '#',
|
||||
display_name: 'Product 2',
|
||||
price: '$ <span class="oe_currency_value">750.00</span>',
|
||||
}, {
|
||||
id: 0,
|
||||
website_url: '#',
|
||||
display_name: 'Product 3',
|
||||
price: '$ <span class="oe_currency_value">750.00</span>',
|
||||
}, {
|
||||
id: 0,
|
||||
website_url: '#',
|
||||
display_name: 'Product 4',
|
||||
price: '$ <span class="oe_currency_value">750.00</span>',
|
||||
}]],
|
||||
uniqueId: 1,
|
||||
productFrame: 4
|
||||
};
|
||||
this.$target.find('.slider').html($(qweb.render('website_sale.productsRecentlyViewed', carouselOptions))).fadeIn();
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
cleanForSave: function () {
|
||||
this.$target.find('.slider').html('').css('display', 'none');
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,6 +12,7 @@ var qweb = core.qweb;
|
||||
publicWidget.registry.productsRecentlyViewedSnippet = publicWidget.Widget.extend({
|
||||
selector: '.s_wsale_products_recently_viewed',
|
||||
xmlDependencies: ['/website_sale/static/src/xml/website_sale_recently_viewed.xml'],
|
||||
disabledInEditableMode: false,
|
||||
events: {
|
||||
'click .js_add_cart': '_onAddToCart',
|
||||
'click .js_remove': '_onRemove',
|
||||
@@ -36,6 +37,14 @@ publicWidget.registry.productsRecentlyViewedSnippet = publicWidget.Widget.extend
|
||||
});
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
destroy: function () {
|
||||
this._super(...arguments);
|
||||
this.$el.addClass('d-none');
|
||||
this.$el.find('.slider').html('');
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Private
|
||||
@@ -47,42 +56,70 @@ publicWidget.registry.productsRecentlyViewedSnippet = publicWidget.Widget.extend
|
||||
_fetch: function () {
|
||||
return this._rpc({
|
||||
route: '/shop/products/recently_viewed',
|
||||
}).then(res => {
|
||||
var products = res['products'];
|
||||
|
||||
// In edit mode, if the current visitor has no recently viewed
|
||||
// products, use demo data.
|
||||
if (this.editableMode && (!products || !products.length)) {
|
||||
return {
|
||||
'products': [{
|
||||
id: 0,
|
||||
website_url: '#',
|
||||
display_name: 'Product 1',
|
||||
price: '$ <span class="oe_currency_value">750.00</span>',
|
||||
}, {
|
||||
id: 0,
|
||||
website_url: '#',
|
||||
display_name: 'Product 2',
|
||||
price: '$ <span class="oe_currency_value">750.00</span>',
|
||||
}, {
|
||||
id: 0,
|
||||
website_url: '#',
|
||||
display_name: 'Product 3',
|
||||
price: '$ <span class="oe_currency_value">750.00</span>',
|
||||
}, {
|
||||
id: 0,
|
||||
website_url: '#',
|
||||
display_name: 'Product 4',
|
||||
price: '$ <span class="oe_currency_value">750.00</span>',
|
||||
}],
|
||||
};
|
||||
}
|
||||
|
||||
return res;
|
||||
});
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
_render: function (res) {
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
var products = res['products'];
|
||||
if (products && products.length) {
|
||||
var mobileProducts = [], webProducts = [], productsTemp = [];
|
||||
_.each(products, function (product) {
|
||||
if (productsTemp.length === 4) {
|
||||
webProducts.push(productsTemp);
|
||||
productsTemp = [];
|
||||
}
|
||||
productsTemp.push(product);
|
||||
mobileProducts.push([product]);
|
||||
});
|
||||
if (productsTemp.length) {
|
||||
var mobileProducts = [], webProducts = [], productsTemp = [];
|
||||
_.each(products, function (product) {
|
||||
if (productsTemp.length === 4) {
|
||||
webProducts.push(productsTemp);
|
||||
productsTemp = [];
|
||||
}
|
||||
|
||||
this.mobileCarousel = $(qweb.render('website_sale.productsRecentlyViewed', {
|
||||
uniqueId: this.uniqueId,
|
||||
productFrame: 1,
|
||||
productsGroups: mobileProducts,
|
||||
}));
|
||||
this.webCarousel = $(qweb.render('website_sale.productsRecentlyViewed', {
|
||||
uniqueId: this.uniqueId,
|
||||
productFrame: 4,
|
||||
productsGroups: webProducts,
|
||||
}));
|
||||
this._addCarousel();
|
||||
productsTemp.push(product);
|
||||
mobileProducts.push([product]);
|
||||
});
|
||||
if (productsTemp.length) {
|
||||
webProducts.push(productsTemp);
|
||||
}
|
||||
|
||||
this.mobileCarousel = $(qweb.render('website_sale.productsRecentlyViewed', {
|
||||
uniqueId: this.uniqueId,
|
||||
productFrame: 1,
|
||||
productsGroups: mobileProducts,
|
||||
}));
|
||||
this.webCarousel = $(qweb.render('website_sale.productsRecentlyViewed', {
|
||||
uniqueId: this.uniqueId,
|
||||
productFrame: 4,
|
||||
productsGroups: webProducts,
|
||||
}));
|
||||
this._addCarousel();
|
||||
this.$el.toggleClass('d-none', !(products && products.length));
|
||||
},
|
||||
/**
|
||||
* Add the right carousel depending on screen size.
|
||||
@@ -90,7 +127,7 @@ publicWidget.registry.productsRecentlyViewedSnippet = publicWidget.Widget.extend
|
||||
*/
|
||||
_addCarousel: function () {
|
||||
var carousel = config.device.size_class <= config.device.SIZES.SM ? this.mobileCarousel : this.webCarousel;
|
||||
this.$('.slider').html(carousel).fadeIn(1000);
|
||||
this.$('.slider').html(carousel).css('display', ''); // Removing display is kept for compatibility (it was hidden before)
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
@@ -114,9 +151,11 @@ publicWidget.registry.productsRecentlyViewedSnippet = publicWidget.Widget.extend
|
||||
}).then(function (data) {
|
||||
wSaleUtils.updateCartNavBar(data);
|
||||
var $navButton = wSaleUtils.getNavBarButton('.o_wsale_my_cart');
|
||||
wSaleUtils.animateClone($navButton, $(ev.currentTarget).parents('.o_carousel_product_card'), 25, 40);
|
||||
|
||||
self._dp.add(self._fetch()).then(self._render.bind(self));
|
||||
var fetch = self._fetch();
|
||||
var animation = wSaleUtils.animateClone($navButton, $(ev.currentTarget).parents('.o_carousel_product_card'), 25, 40);
|
||||
Promise.all([fetch, animation]).then(function (values) {
|
||||
self._render(values[0]);
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -20,43 +20,52 @@ function getNavBarButton(selector) {
|
||||
}
|
||||
|
||||
function animateClone($cart, $elem, offsetTop, offsetLeft) {
|
||||
$cart.find('.o_animate_blink').addClass('o_red_highlight o_shadow_animation').delay(500).queue(function(){
|
||||
$cart.find('.o_animate_blink').addClass('o_red_highlight o_shadow_animation').delay(500).queue(function () {
|
||||
$(this).removeClass("o_shadow_animation").dequeue();
|
||||
}).delay(2000).queue(function(){
|
||||
}).delay(2000).queue(function () {
|
||||
$(this).removeClass("o_red_highlight").dequeue();
|
||||
});
|
||||
var $imgtodrag = $elem.find('img').eq(0);
|
||||
if ($imgtodrag.length) {
|
||||
var $imgclone = $imgtodrag.clone()
|
||||
.offset({
|
||||
top: $imgtodrag.offset().top,
|
||||
left: $imgtodrag.offset().left
|
||||
})
|
||||
.addClass('o_website_sale_animate')
|
||||
.appendTo(document.body)
|
||||
.animate({
|
||||
top: $cart.offset().top + offsetTop,
|
||||
left: $cart.offset().left + offsetLeft,
|
||||
width: 75,
|
||||
height: 75,
|
||||
}, 1000, 'easeInOutExpo');
|
||||
return new Promise(function (resolve, reject) {
|
||||
var $imgtodrag = $elem.find('img').eq(0);
|
||||
if ($imgtodrag.length) {
|
||||
var $imgclone = $imgtodrag.clone()
|
||||
.offset({
|
||||
top: $imgtodrag.offset().top,
|
||||
left: $imgtodrag.offset().left
|
||||
})
|
||||
.addClass('o_website_sale_animate')
|
||||
.appendTo(document.body)
|
||||
.animate({
|
||||
top: $cart.offset().top + offsetTop,
|
||||
left: $cart.offset().left + offsetLeft,
|
||||
width: 75,
|
||||
height: 75,
|
||||
}, 1000, 'easeInOutExpo');
|
||||
|
||||
$imgclone.animate({
|
||||
width: 0,
|
||||
height: 0,
|
||||
}, function () {
|
||||
$(this).detach();
|
||||
});
|
||||
}
|
||||
$imgclone.animate({
|
||||
width: 0,
|
||||
height: 0,
|
||||
}, function () {
|
||||
resolve();
|
||||
$(this).detach();
|
||||
});
|
||||
} else {
|
||||
resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates both navbar cart
|
||||
* @param {Object} data
|
||||
*/
|
||||
function updateCartNavBar(data) {
|
||||
var $q = $(".my_cart_quantity");
|
||||
$q.parents('li:first').removeClass('d-none');
|
||||
$q.html(data.cart_quantity).hide().fadeIn(600);
|
||||
var $qtyNavBar = $(".my_cart_quantity");
|
||||
_.each($qtyNavBar, function (qty) {
|
||||
var $qty = $(qty);
|
||||
$qty.parents('li:first').removeClass('d-none');
|
||||
$qty.html(data.cart_quantity).hide().fadeIn(600);
|
||||
});
|
||||
$(".js_cart_lines").first().before(data['website_sale.cart_lines']).end().remove();
|
||||
$(".js_cart_summary").first().before(data['website_sale.short_cart_summary']).end().remove();
|
||||
}
|
||||
|
||||
@@ -25,3 +25,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.oe_drop_zone + .s_wsale_products_recently_viewed {
|
||||
display: block !important;
|
||||
}
|
||||
|
||||
@@ -25,19 +25,16 @@
|
||||
</template>
|
||||
|
||||
<template id="s_products_recently_viewed" name="Products Recently Viewed">
|
||||
<section class="s_wsale_products_recently_viewed pt24 pb24" style="min-height: 400px;">
|
||||
<div class="alert alert-info alert-dismissible rounded-0 fade show d-print-none css_non_editable_mode_hidden">
|
||||
<div class="container">
|
||||
<div class="text-center">
|
||||
This is a preview of the recently viewed products by the user.<br/>
|
||||
Once the user has seen at least one product this snippet will be visible.
|
||||
</div>
|
||||
<section class="s_wsale_products_recently_viewed d-none pt24 pb24" style="min-height: 400px;">
|
||||
<div class="container">
|
||||
<div class="alert alert-info alert-dismissible rounded-0 fade show d-print-none css_non_editable_mode_hidden o_not_editable">
|
||||
This is a preview of the recently viewed products by the user.<br/>
|
||||
Once the user has seen at least one product this snippet will be visible.
|
||||
<button type="button" class="close" data-dismiss="alert" aria-label="Close"> × </button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
|
||||
<h3 class="text-center mb32">Recently viewed Products</h3>
|
||||
<div class="slider o_not_editable" style="display: none;"/>
|
||||
<div class="slider o_not_editable"/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
@@ -121,10 +118,6 @@
|
||||
<i class="fa fa-search"/> Products Search Bar
|
||||
</we-button>
|
||||
</div>
|
||||
|
||||
<div data-js="ProductsRecentlyViewed"
|
||||
data-selector=".s_wsale_products_recently_viewed">
|
||||
</div>
|
||||
</xpath>
|
||||
<xpath expr="//div[@id='so_content_addition']" position="attributes">
|
||||
<attribute name="data-selector" add=".s_wsale_products_searchbar_input" separator=","/>
|
||||
|
||||
Reference in New Issue
Block a user