|
| 1 | +import options from "@web_editor/js/editor/snippets.options"; |
| 2 | + |
| 3 | +options.registry.WebsiteSaleProductsItem = options.registry.WebsiteSaleProductsItem.extend({ |
| 4 | + willStart: async function () { |
| 5 | + const _super = this._super.bind(this); |
| 6 | + this.ppr = this.$target.closest('[data-ppr]').data('ppr'); |
| 7 | + this.defaultSort = this.$target[0].closest('[data-default-sort]').dataset.defaultSort |
| 8 | + this.productTemplateID = parseInt(this.$target.find('[data-oe-model="product.template"]').data('oe-id')); |
| 9 | + this.ribbonPositionClasses = {'left': 'o_ribbon_left o_tag_left', 'right': 'o_ribbon_right o_tag_right'}; |
| 10 | + this.ribbons = await new Promise(resolve => this.trigger_up('get_ribbons', {callback: resolve})); |
| 11 | + this.$ribbon = this.$target.find('.o_ribbon'); |
| 12 | + return _super(...arguments); |
| 13 | + }, |
| 14 | + |
| 15 | + async setRibbonPosition(previewMode, widgetValue, params) { |
| 16 | + const ribbon = this.$ribbon[0]; |
| 17 | + // Get the style (tag or ribbon) from the dataset or params |
| 18 | + const ribbonData = this.ribbons[this.$target[0].dataset.ribbonId] || {}; |
| 19 | + const style = params?.style || ribbonData?.style || "ribbon"; // Safe access // Remove both tag and ribbon position classes |
| 20 | + ribbon.classList.remove('o_ribbon_right', 'o_ribbon_left', 'o_tag_right', 'o_tag_left'); |
| 21 | + |
| 22 | + // Add only the appropriate classes based on the selected style |
| 23 | + ribbon.classList.add(style === "ribbon" ? `o_ribbon_${widgetValue}` : `o_tag_${widgetValue}`); |
| 24 | + |
| 25 | + await this._saveRibbon(); |
| 26 | + }, |
| 27 | + |
| 28 | + async _computeWidgetState(methodName, params) { |
| 29 | + const classList = this.$ribbon[0].classList; |
| 30 | + switch (methodName) { |
| 31 | + case 'setRibbon': |
| 32 | + return this.$target.attr('data-ribbon-id') || ''; |
| 33 | + case 'setRibbonName': |
| 34 | + return this.$ribbon.text(); |
| 35 | + case 'setRibbonPosition': { |
| 36 | + if (classList.contains('o_ribbon_left') || classList.contains('o_tag_left')) { |
| 37 | + return 'left'; |
| 38 | + } |
| 39 | + return 'right'; |
| 40 | + } |
| 41 | + case 'setRibbonStyle': { |
| 42 | + return this.$ribbon.attr('data-style') || |
| 43 | + (this.$ribbon.hasClass('o_tag_left') || this.$ribbon.hasClass('o_tag_right') ? 'tag' : 'ribbon'); |
| 44 | + } |
| 45 | + } |
| 46 | + return this._super(methodName, params); |
| 47 | + }, |
| 48 | + |
| 49 | + async _saveRibbon(isNewRibbon = false) { |
| 50 | + const text = this.$ribbon.text().trim(); |
| 51 | + |
| 52 | + const ribbon = { |
| 53 | + 'name': text, |
| 54 | + 'bg_color': this.$ribbon[0].style.backgroundColor, |
| 55 | + 'text_color': this.$ribbon[0].style.color, |
| 56 | + 'position': (this.$ribbon.attr('class').includes('o_ribbon_left') || this.$ribbon.attr('class').includes('o_tag_left')) ? 'left' : 'right', |
| 57 | + 'style': this.$ribbon.attr('data-style') || 'ribbon', |
| 58 | + }; |
| 59 | + ribbon.id = isNewRibbon ? Date.now() : parseInt(this.$target.closest('.oe_product')[0].dataset.ribbonId); |
| 60 | + this.trigger_up('set_ribbon', {ribbon: ribbon}); |
| 61 | + this.ribbons = await new Promise(resolve => this.trigger_up('get_ribbons', {callback: resolve})); |
| 62 | + this.rerender = true; |
| 63 | + await this._setRibbon(ribbon.id); |
| 64 | + }, |
| 65 | + |
| 66 | + async _setRibbon(ribbonId) { |
| 67 | + this.$target[0].dataset.ribbonId = ribbonId; |
| 68 | + this.trigger_up('set_product_ribbon', { |
| 69 | + templateId: this.productTemplateID, |
| 70 | + ribbonId: ribbonId || false, |
| 71 | + }); |
| 72 | + const ribbon = ( |
| 73 | + this.ribbons[ribbonId] || |
| 74 | + {name: '', bg_color: '', text_color: '', position: 'left', style: 'ribbon'} |
| 75 | + ); |
| 76 | + // This option also manages other products' ribbon, therefore we need a |
| 77 | + // way to access all of them at once. With the content being in an iframe, |
| 78 | + // this is the simplest way. |
| 79 | + const $editableDocument = $(this.$target[0].ownerDocument.body); |
| 80 | + const $ribbons = $editableDocument.find(`[data-ribbon-id="${ribbonId}"] .o_ribbon`); |
| 81 | + $ribbons.empty().append(ribbon.name); |
| 82 | + $ribbons.removeClass('o_ribbon_left o_ribbon_right o_tag_left o_tag_right'); |
| 83 | + |
| 84 | + const ribbonPositionClasses = ribbon.style === 'tag' |
| 85 | + ? (ribbon.position === 'left' ? 'o_tag_left' : 'o_tag_right') |
| 86 | + : (ribbon.position === 'left' ? 'o_ribbon_left' : 'o_ribbon_right'); |
| 87 | + |
| 88 | + $ribbons.addClass(ribbonPositionClasses); |
| 89 | + $ribbons.attr('data-style', ribbon.style); |
| 90 | + $ribbons.css('background-color', ribbon.bg_color || ''); |
| 91 | + $ribbons.css('color', ribbon.text_color || ''); |
| 92 | + |
| 93 | + if (!this.ribbons[ribbonId]) { |
| 94 | + $editableDocument.find(`[data-ribbon-id="${ribbonId}"]`).each((index, product) => delete product.dataset.ribbonId); |
| 95 | + } |
| 96 | + |
| 97 | + // The ribbon does not have a savable parent, so we need to trigger the |
| 98 | + // saving process manually by flagging the ribbon as dirty. |
| 99 | + this.$ribbon.addClass('o_dirty'); |
| 100 | + }, |
| 101 | + |
| 102 | + async setRibbonStyle(previewMode, widgetValue, params) { |
| 103 | + this.$ribbon.attr('data-style', widgetValue); |
| 104 | + |
| 105 | + await this._saveRibbon(); |
| 106 | + }, |
| 107 | +}) |
0 commit comments