From de4d7e14f8186fd19cd6cb8924957a0a508b0dfb Mon Sep 17 00:00:00 2001 From: Benjamin Vray Date: Wed, 18 Dec 2019 13:10:09 +0000 Subject: [PATCH] [IMP] website: review snippet rating Adding more control on the rating snippet. Choose the color, select other icons in media dialog, no limit to add active or inactive icons, display the rating inline or below the title. task-2146209 closes odoo/odoo#41169 Signed-off-by: Quentin Smetz (qsm) --- .../static/src/snippets/s_rating/000.scss | 2 +- .../static/src/snippets/s_rating/001.scss | 15 ++ .../static/src/snippets/s_rating/options.js | 151 ++++++++++++++++++ addons/website/views/assets.xml | 1 + addons/website/views/snippets/s_rating.xml | 77 ++++++--- addons/website/views/snippets/snippets.xml | 2 +- 6 files changed, 220 insertions(+), 28 deletions(-) create mode 100644 addons/website/static/src/snippets/s_rating/001.scss create mode 100644 addons/website/static/src/snippets/s_rating/options.js diff --git a/addons/website/static/src/snippets/s_rating/000.scss b/addons/website/static/src/snippets/s_rating/000.scss index c16b99e9c59..968ee7d3f15 100644 --- a/addons/website/static/src/snippets/s_rating/000.scss +++ b/addons/website/static/src/snippets/s_rating/000.scss @@ -1,5 +1,5 @@ -.s_rating { +.s_rating:not([data-vcss]) { $star: "\f005"; $star-o: "\f006"; $circle: "\f111"; diff --git a/addons/website/static/src/snippets/s_rating/001.scss b/addons/website/static/src/snippets/s_rating/001.scss new file mode 100644 index 00000000000..a1fc87c0996 --- /dev/null +++ b/addons/website/static/src/snippets/s_rating/001.scss @@ -0,0 +1,15 @@ + +.s_rating[data-vcss="001"] { + &.s_rating_inline { + display: flex; + align-items: center; + + .s_rating_title { + margin: 0; + margin-right: 0.5em; + } + .s_rating_icons { + margin-left: auto; + } + } +} diff --git a/addons/website/static/src/snippets/s_rating/options.js b/addons/website/static/src/snippets/s_rating/options.js new file mode 100644 index 00000000000..2a640ea3ec0 --- /dev/null +++ b/addons/website/static/src/snippets/s_rating/options.js @@ -0,0 +1,151 @@ +odoo.define('website.s_rating_options', function (require) { +'use strict'; + +const weWidgets = require('wysiwyg.widgets'); +const options = require('web_editor.snippets.options'); + +options.registry.Rating = options.Class.extend({ + /** + * @override + */ + start: function () { + this.iconType = this.$target[0].dataset.icon; + this.faClassActiveCustomIcons = this.$target[0].dataset.activeCustomIcon || ''; + this.faClassInactiveCustomIcons = this.$target[0].dataset.inactiveCustomIcon || ''; + return this._super.apply(this, arguments); + }, + + //-------------------------------------------------------------------------- + // Options + //-------------------------------------------------------------------------- + + /** + * Displays the selected icon type. + * + * @see this.selectClass for parameters + */ + setIcons: function (previewMode, widgetValue, params) { + this.iconType = widgetValue; + this._renderIcons(); + this.$target[0].dataset.icon = widgetValue; + delete this.$target[0].dataset.activeCustomIcon; + delete this.$target[0].dataset.inactiveCustomIcon; + }, + /** + * Allows to select a font awesome icon with media dialog. + * + * @see this.selectClass for parameters + */ + customIcon: async function (previewMode, widgetValue, params) { + return new Promise(resolve => { + const dialog = new weWidgets.MediaDialog( + this, + {noImages: true, noDocuments: true, noVideos: true, mediaWidth: 1920}, + $('') + ); + this._saving = false; + dialog.on('save', this, function (attachments) { + this._saving = true; + const customClass = 'fa fa-fw ' + attachments.className; + const $activeIcons = this.$target.find('.s_rating_active_icons > i'); + const $inactiveIcons = this.$target.find('.s_rating_inactive_icons > i'); + const $icons = params.customActiveIcon === 'true' ? $activeIcons : $inactiveIcons; + $icons.removeClass().addClass(customClass); + this.faClassActiveCustomIcons = $activeIcons.length > 0 ? $activeIcons.attr('class') : customClass; + this.faClassInactiveCustomIcons = $inactiveIcons.length > 0 ? $inactiveIcons.attr('class') : customClass; + this.$target[0].dataset.activeCustomIcon = this.faClassActiveCustomIcons; + this.$target[0].dataset.inactiveCustomIcon = this.faClassInactiveCustomIcons; + this.$target[0].dataset.icon = 'custom'; + this.iconType = 'custom'; + resolve(); + }); + dialog.on('closed', this, function () { + if (!this._saving) { + resolve(); + } + }); + dialog.open(); + }); + }, + /** + * Sets the number of active icons. + * + * @see this.selectClass for parameters + */ + activeIconsNumber: function (previewMode, widgetValue, params) { + this.nbActiveIcons = parseInt(widgetValue); + this._createIcons(); + }, + /** + * Sets the total number of icons. + * + * @see this.selectClass for parameters + */ + totalIconsNumber: function (previewMode, widgetValue, params) { + this.nbTotalIcons = Math.max(parseInt(widgetValue), 1); + this._createIcons(); + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @override + */ + _computeWidgetState: function (methodName, params) { + switch (methodName) { + case 'setIcons': { + return this.$target[0].dataset.icon; + } + case 'activeIconsNumber': { + this.nbActiveIcons = this.$target.find('.s_rating_active_icons > i').length; + return this.nbActiveIcons; + } + case 'totalIconsNumber': { + this.nbTotalIcons = this.$target.find('.s_rating_icons i').length; + return this.nbTotalIcons; + } + } + return this._super(...arguments); + }, + /** + * Creates the icons. + * + * @private + */ + _createIcons: function () { + const $activeIcons = this.$target.find('.s_rating_active_icons'); + const $inactiveIcons = this.$target.find('.s_rating_inactive_icons'); + this.$target.find('.s_rating_icons i').remove(); + for (let i = 0; i < this.nbTotalIcons; i++) { + if (i < this.nbActiveIcons) { + $activeIcons.append(' '); + } else { + $inactiveIcons.append(' '); + } + } + this._renderIcons(); + }, + /** + * Renders icons with selected fonts. + * + * @private + */ + _renderIcons: function () { + const icons = { + 'fa-star': 'fa-star-o', + 'fa-thumbs-up': 'fa-thumbs-o-up', + 'fa-circle': 'fa-circle-o', + 'fa-square': 'fa-square-o', + 'fa-heart': 'fa-heart-o' + }; + const faClassActiveIcons = (this.iconType === "custom") ? this.faClassActiveCustomIcons : 'fa fa-fw ' + this.iconType; + const faClassInactiveIcons = (this.iconType === "custom") ? this.faClassInactiveCustomIcons : 'fa fa-fw ' + icons[this.iconType]; + const $activeIcons = this.$target.find('.s_rating_active_icons > i'); + const $inactiveIcons = this.$target.find('.s_rating_inactive_icons > i'); + $activeIcons.removeClass().addClass(faClassActiveIcons); + $inactiveIcons.removeClass().addClass(faClassInactiveIcons); + }, +}); +}); diff --git a/addons/website/views/assets.xml b/addons/website/views/assets.xml index 2ca524475ab..80e65be488b 100644 --- a/addons/website/views/assets.xml +++ b/addons/website/views/assets.xml @@ -114,6 +114,7 @@