diff options
| author | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
|---|---|---|
| committer | stephanchrst <stephanchrst@gmail.com> | 2022-05-10 21:51:50 +0700 |
| commit | 3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch) | |
| tree | a44932296ef4a9b71d5f010906253d8c53727726 /addons/website_sale_comparison/static/src | |
| parent | 0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff) | |
initial commit 2
Diffstat (limited to 'addons/website_sale_comparison/static/src')
3 files changed, 394 insertions, 0 deletions
diff --git a/addons/website_sale_comparison/static/src/js/website_sale_comparison.js b/addons/website_sale_comparison/static/src/js/website_sale_comparison.js new file mode 100644 index 00000000..8e8a4436 --- /dev/null +++ b/addons/website_sale_comparison/static/src/js/website_sale_comparison.js @@ -0,0 +1,294 @@ +odoo.define('website_sale_comparison.comparison', function (require) { +'use strict'; + +var concurrency = require('web.concurrency'); +var core = require('web.core'); +var publicWidget = require('web.public.widget'); +var utils = require('web.utils'); +var VariantMixin = require('sale.VariantMixin'); +var website_sale_utils = require('website_sale.utils'); + +var qweb = core.qweb; +var _t = core._t; + +// VariantMixin events are overridden on purpose here +// to avoid registering them more than once since they are already registered +// in website_sale.js +var ProductComparison = publicWidget.Widget.extend(VariantMixin, { + xmlDependencies: ['/website_sale_comparison/static/src/xml/comparison.xml'], + + template: 'product_comparison_template', + events: { + 'click .o_product_panel_header': '_onClickPanelHeader', + }, + + /** + * @constructor + */ + init: function () { + this._super.apply(this, arguments); + + this.product_data = {}; + this.comparelist_product_ids = JSON.parse(utils.get_cookie('comparelist_product_ids') || '[]'); + this.product_compare_limit = 4; + this.guard = new concurrency.Mutex(); + }, + /** + * @override + */ + start: function () { + var self = this; + + self._loadProducts(this.comparelist_product_ids).then(function () { + self._updateContent('hide'); + }); + self._updateComparelistView(); + + $('#comparelist .o_product_panel_header').popover({ + trigger: 'manual', + animation: true, + html: true, + title: function () { + return _t("Compare Products"); + }, + container: '.o_product_feature_panel', + placement: 'top', + template: qweb.render('popover'), + content: function () { + return $('#comparelist .o_product_panel_content').html(); + } + }); + // We trigger a resize to launch the event that checks if this element hides + // a button when the page is loaded. + $(window).trigger('resize'); + + $(document.body).on('click.product_comparaison_widget', '.comparator-popover .o_comparelist_products .o_remove', function (ev) { + ev.preventDefault(); + self._removeFromComparelist(ev); + }); + $(document.body).on('click.product_comparaison_widget', '.o_comparelist_remove', function (ev) { + self._removeFromComparelist(ev); + self.guard.exec(function() { + var new_link = '/shop/compare/?products=' + self.comparelist_product_ids.toString(); + window.location.href = _.isEmpty(self.comparelist_product_ids) ? '/shop' : new_link; + }); + }); + + return this._super.apply(this, arguments); + }, + /** + * @override + */ + destroy: function () { + this._super.apply(this, arguments); + $(document.body).off('.product_comparaison_widget'); + }, + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * @param {jQuery} $elem + */ + handleCompareAddition: function ($elem) { + var self = this; + if (this.comparelist_product_ids.length < this.product_compare_limit) { + var productId = $elem.data('product-product-id'); + if ($elem.hasClass('o_add_compare_dyn')) { + productId = $elem.parent().find('.product_id').val(); + if (!productId) { // case List View Variants + productId = $elem.parent().find('input:checked').first().val(); + } + } + + this.selectOrCreateProduct( + $elem.closest('form'), + productId, + $elem.closest('form').find('.product_template_id').val(), + false + ).then(function (productId) { + productId = parseInt(productId, 10) || parseInt($elem.data('product-product-id'), 10); + if (!productId) { + return; + } + self._addNewProducts(productId).then(function () { + website_sale_utils.animateClone( + $('#comparelist .o_product_panel_header'), + $elem.closest('form'), + -50, + 10 + ); + }); + }); + } else { + this.$('.o_comparelist_limit_warning').show(); + $('#comparelist .o_product_panel_header').popover('show'); + } + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + */ + _loadProducts: function (product_ids) { + var self = this; + return this._rpc({ + route: '/shop/get_product_data', + params: { + product_ids: product_ids, + cookies: JSON.parse(utils.get_cookie('comparelist_product_ids') || '[]'), + }, + }).then(function (data) { + self.comparelist_product_ids = JSON.parse(data.cookies); + delete data.cookies; + _.each(data, function (product) { + self.product_data[product.product.id] = product; + }); + if (product_ids.length > Object.keys(data).length) { + /* If some products have been archived + they are not displayed but the count & cookie + need to be updated. + */ + self._updateCookie(); + } + }); + }, + /** + * @private + */ + _togglePanel: function () { + $('#comparelist .o_product_panel_header').popover('toggle'); + }, + /** + * @private + */ + _addNewProducts: function (product_id) { + return this.guard.exec(this._addNewProductsImpl.bind(this, product_id)); + }, + _addNewProductsImpl: function (product_id) { + var self = this; + $('.o_product_feature_panel').addClass('d-md-block'); + if (!_.contains(self.comparelist_product_ids, product_id)) { + self.comparelist_product_ids.push(product_id); + if (_.has(self.product_data, product_id)){ + self._updateContent(); + } else { + return self._loadProducts([product_id]).then(function () { + self._updateContent(); + self._updateCookie(); + }); + } + } + self._updateCookie(); + }, + /** + * @private + */ + _updateContent: function (force) { + var self = this; + this.$('.o_comparelist_products .o_product_row').remove(); + _.each(this.comparelist_product_ids, function (res) { + var $template = self.product_data[res].render; + self.$('.o_comparelist_products').append($template); + }); + if (force !== 'hide' && (this.comparelist_product_ids.length > 1 || force === 'show')) { + $('#comparelist .o_product_panel_header').popover('show'); + } + else { + $('#comparelist .o_product_panel_header').popover('hide'); + } + }, + /** + * @private + */ + _removeFromComparelist: function (e) { + this.guard.exec(this._removeFromComparelistImpl.bind(this, e)); + }, + _removeFromComparelistImpl: function (e) { + var target = $(e.target.closest('.o_comparelist_remove, .o_remove')); + this.comparelist_product_ids = _.without(this.comparelist_product_ids, target.data('product_product_id')); + target.parents('.o_product_row').remove(); + this._updateCookie(); + $('.o_comparelist_limit_warning').hide(); + this._updateContent('show'); + }, + /** + * @private + */ + _updateCookie: function () { + document.cookie = 'comparelist_product_ids=' + JSON.stringify(this.comparelist_product_ids) + '; path=/'; + this._updateComparelistView(); + }, + /** + * @private + */ + _updateComparelistView: function () { + this.$('.o_product_circle').text(this.comparelist_product_ids.length); + this.$('.o_comparelist_button').removeClass('d-md-block'); + if (_.isEmpty(this.comparelist_product_ids)) { + $('.o_product_feature_panel').removeClass('d-md-block'); + } else { + $('.o_product_feature_panel').addClass('d-md-block'); + this.$('.o_comparelist_products').addClass('d-md-block'); + if (this.comparelist_product_ids.length >=2) { + this.$('.o_comparelist_button').addClass('d-md-block'); + this.$('.o_comparelist_button a').attr('href', '/shop/compare/?products='+this.comparelist_product_ids.toString()); + } + } + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + */ + _onClickPanelHeader: function () { + this._togglePanel(); + }, +}); + +publicWidget.registry.ProductComparison = publicWidget.Widget.extend({ + selector: '.oe_website_sale', + events: { + 'click .o_add_compare, .o_add_compare_dyn': '_onClickAddCompare', + 'click #o_comparelist_table tr': '_onClickComparelistTr', + }, + + /** + * @override + */ + start: function () { + var def = this._super.apply(this, arguments); + this.productComparison = new ProductComparison(this); + return Promise.all([def, this.productComparison.appendTo(this.$el)]); + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + * @param {Event} ev + */ + _onClickAddCompare: function (ev) { + this.productComparison.handleCompareAddition($(ev.currentTarget)); + }, + /** + * @private + * @param {Event} ev + */ + _onClickComparelistTr: function (ev) { + var $target = $(ev.currentTarget); + $($target.data('target')).children().slideToggle(100); + $target.find('.fa-chevron-circle-down, .fa-chevron-circle-right').toggleClass('fa-chevron-circle-down fa-chevron-circle-right'); + }, +}); +return ProductComparison; +}); diff --git a/addons/website_sale_comparison/static/src/scss/website_sale_comparison.scss b/addons/website_sale_comparison/static/src/scss/website_sale_comparison.scss new file mode 100644 index 00000000..204d9d1b --- /dev/null +++ b/addons/website_sale_comparison/static/src/scss/website_sale_comparison.scss @@ -0,0 +1,65 @@ +.o_product_feature_panel { + position: fixed; + bottom: 0; + left: 50%; + transform: translateX(-50%); + z-index:10; + border-top-left-radius: 10px; + border-top-right-radius: 10px; + border-bottom: 0px; + padding: 10px 20px; + text-align: center; + border: 2px solid theme-color('primary'); + border-bottom: 0px; + background-color: white; + opacity: 0.95; + + .o_product_panel { + position: relative; + .o_product_panel_header { + margin: 0 10px 0 10px; + cursor: pointer; + .o_product_icon { + margin-right: 5px; + } + .o_product_text { + text-transform: uppercase; + vertical-align: middle; + font-size: 16px; + } + .o_product_circle { + vertical-align: 6px; + padding: 0 3px; + line-height: 14px; + } + } + .o_product_panel_content { + display: none !important; + } + } +} + +.oe_website_sale { + .product_summary > *{ + display: block; + margin: 15px 0 15px 0; + } + .table-comparator { + .o_product_comparison_collpase { + margin-right: 8px; + } + } + + div.css_not_available .o_add_compare_dyn { + display: none; + } + + .o_comparelist_remove { + @include o-position-absolute($top: 0, $right: 0.5rem); + } + + .o_ws_compare_image { + vertical-align: middle; + } +} + diff --git a/addons/website_sale_comparison/static/src/xml/comparison.xml b/addons/website_sale_comparison/static/src/xml/comparison.xml new file mode 100644 index 00000000..47085955 --- /dev/null +++ b/addons/website_sale_comparison/static/src/xml/comparison.xml @@ -0,0 +1,35 @@ +<templates id="compare_products" xml:space="preserve"> + + <t t-name="product_comparison_template"> + <div class="o_product_feature_panel d-none css_editable_mode_hidden o_bottom_fixed_element"> + <span class="o_product_panel" id="comparelist"> + <span class="o_product_panel_header"> + <span class="o_product_icon"><i class="fa fa-exchange" role="img" aria-label="Product" title="Product"></i></span> + <span class="o_product_text">Compare</span> + <span class="o_product_circle o_animate_blink badge badge-primary">0</span> + </span> + <span class="o_product_panel_content"> + <div class="o_comparelist_products"> + <div class="o_comparelist_limit_warning" style="display:none"> + <div class="o_shortlog alert alert-warning" role="alert"> + <span><i class="fa fa-warning text-danger" role="img" aria-label="Warning" title="Warning"></i> You can compare max 4 products.</span> + </div> + </div> + </div> + <div class="o_comparelist_button" style='display:none'> + <a role="button" class="btn btn-primary btn-block" href="#"><i class="fa fa-exchange mr4"/>Compare</a> + </div> + </span> + </span> + </div> + </t> + + <t t-name="popover"> + <div style="width:600px;" class="popover comparator-popover" role="tooltip"> + <div class="arrow"/> + <h3 class="popover-header"/> + <div class="popover-body"/> + </div> + </t> + +</templates> |
