[IMP] portal_rating: remove the flicker of the "portal rating" widget

Purpose
=======
Remove the flicker of the "portal rating" widget when we load the page.

Specifications
==============
Currently, the portal rating widget is composed of 2 parts
- A Python template
- A JS template

There's also 2 widget, one widget who is linked to the Python template
and which instantiate another widget (which will render the JS template).

That's why we have a flicker, the button of the widget is rendered in
Javascript.

The purpose of this commit is to simplify that, to have only 1 widget
and to have as munch as possible in the Python template.

Technical
=========
We still need 2 different template (Python / JS) because in the
non-fullscreen view, after editing our review, we do not want to refresh
the page, but we want the average rating to be updated.

Task 2322583
This commit is contained in:
std-odoo
2021-07-16 11:32:57 +00:00
parent 97f0f648f1
commit 137843de5f
3 changed files with 84 additions and 69 deletions
@@ -1,11 +1,12 @@
odoo.define('portal.rating.composer', function (require) {
'use strict';
var publicWidget = require('web.public.widget');
var session = require('web.session');
var portalComposer = require('portal.composer');
const publicWidget = require('web.public.widget');
const session = require('web.session');
const portalComposer = require('portal.composer');
const {_t, qweb} = require('web.core');
var PortalComposer = portalComposer.PortalComposer;
const PortalComposer = portalComposer.PortalComposer;
/**
* RatingPopupComposer
@@ -13,8 +14,11 @@ var PortalComposer = portalComposer.PortalComposer;
* Display the rating average with a static star widget, and open
* a popup with the portal composer when clicking on it.
**/
var RatingPopupComposer = publicWidget.Widget.extend({
template: 'portal_rating.PopupComposer',
const RatingPopupComposer = publicWidget.Widget.extend({
selector: '.o_rating_popup_composer',
custom_events: {
reload_rating_popup_composer: '_onReloadRatingPopupComposer',
},
xmlDependencies: [
'/portal/static/src/xml/portal_chatter.xml',
'/portal_rating/static/src/xml/portal_chatter.xml',
@@ -22,8 +26,10 @@ var RatingPopupComposer = publicWidget.Widget.extend({
'/portal_rating/static/src/xml/portal_rating_composer.xml',
],
init: function (parent, options) {
this._super.apply(this, arguments);
willStart: function (parent) {
const def = this._super.apply(this, arguments);
const options = this.$el.data();
this.rating_avg = Math.round(options['rating_avg'] * 100) / 100 || 0.0;
this.rating_count = options['rating_count'] || 0.0;
@@ -32,64 +38,65 @@ var RatingPopupComposer = publicWidget.Widget.extend({
'res_model': false,
'res_id': false,
'pid': 0,
'display_composer': options['disable_composer'] ? false : !session.is_website_user,
'display_rating': true,
'csrf_token': odoo.csrf_token,
'user_id': session.user_id,
});
},
/**
* @override
*/
start: function () {
var defs = [];
defs.push(this._super.apply(this, arguments));
// instanciate and insert composer widget
this._composer = new PortalComposer(this, this.options);
defs.push(this._composer.replace(this.$('.o_portal_chatter_composer')));
return Promise.all(defs);
},
});
publicWidget.registry.RatingPopupComposer = publicWidget.Widget.extend({
selector: '.o_rating_popup_composer',
custom_events: {
reload_rating_popup_composer: '_onReloadRatingPopupComposer',
return def;
},
/**
* @override
*/
start: function () {
this.ratingPopupData = this.$el.data();
this.ratingPopupData.display_composer = !this.ratingPopupData.disable_composer && !session.is_website_user;
this.ratingPopup = new RatingPopupComposer(this, this.ratingPopupData);
return Promise.all([
this._super.apply(this, arguments),
this.ratingPopup.appendTo(this.$el)
this._reloadRatingPopupComposer(),
]);
},
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* Destroy existing ratingPopup and insert new ratingPopup widget
*
* @private
* @param {Object} data
*/
_reloadRatingPopupComposer: function (data) {
if (this.ratingPopup) {
this.ratingPopup.destroy();
_reloadRatingPopupComposer: function () {
if (this.options.hide_rating_avg) {
this.$('.o_rating_popup_composer_stars').empty();
} else {
const ratingAverage = qweb.render(
'portal_rating.rating_stars_static', {
inline_mode: true,
widget: this,
val: this.rating_avg,
});
this.$('.o_rating_popup_composer_stars').empty().html(ratingAverage);
}
if (this.ratingPopupData.display_composer) {
this.ratingPopup = new RatingPopupComposer(this, Object.assign(this.ratingPopupData, data));
this.ratingPopup.appendTo(this.$el);
// Append the modal
const modal = qweb.render(
'portal_rating.PopupComposer', {
inline_mode: true,
widget: this,
val: this.rating_avg,
});
this.$('.o_rating_popup_composer_modal').html(modal);
if (this._composer) {
this._composer.destroy();
}
// Instantiate the "Portal Composer" widget and insert it into the modal
this._composer = new PortalComposer(this, this.options);
return this._composer.appendTo(this.$('.o_rating_popup_composer_modal .o_portal_chatter_composer')).then(() => {
// Change the text of the button
this.$('.o_rating_popup_composer_text').text(
this.options.default_message_id ?
_t('Modify your review') : _t('Add a review')
);
});
},
//--------------------------------------------------------------------------
@@ -98,13 +105,29 @@ publicWidget.registry.RatingPopupComposer = publicWidget.Widget.extend({
/**
* @private
* @param {OdooEvent} ev
* @param {OdooEvent} event
*/
_onReloadRatingPopupComposer: function (ev) {
this._reloadRatingPopupComposer(ev.data);
_onReloadRatingPopupComposer: function (event) {
const data = event.data;
// Refresh the internal state of the widget
this.rating_avg = data.rating_avg;
this.rating_count = data.rating_count;
this.rating_value = data.rating_value;
// Clean the dictionary
delete data.rating_avg;
delete data.rating_count;
delete data.rating_value;
this.options = _.extend(this.options, data);
this._reloadRatingPopupComposer();
}
});
publicWidget.registry.RatingPopupComposer = RatingPopupComposer;
return RatingPopupComposer;
});
@@ -5,30 +5,6 @@
It can also be used to modify a message
-->
<t t-name="portal_rating.PopupComposer">
<div class="d-flex flex-wrap align-items-center">
<div class="text-nowrap">
<t t-call="portal_rating.rating_stars_static" t-if="!widget.options['hide_rating_avg']">
<t t-set="val" t-value="widget.rating_avg || 0"/>
<t t-set="inline_mode" t-value="true"/>
</t>
</div>
<button t-if="widget.options['display_composer']" type="button"
t-att-class="'btn ' + widget.options['link_btn_classes'] or 'btn-primary'"
data-toggle="modal" data-target="#ratingpopupcomposer">
<i t-if="widget.options['icon']" t-att-class="widget.options['icon']"/>
<span t-att-class="widget.options['_text_classes']">
<t t-if="widget.options['display_composer']">
<t t-if="widget.options['default_message_id']">
Modify your review
</t>
<t t-else="">
Write a review
</t>
</t>
</span>
</button>
</div>
<div t-if="widget.options['display_composer']" class="modal fade" id="ratingpopupcomposer" tabindex="-1" role="dialog" aria-labelledby="ratingpopupcomposerlabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
@@ -35,6 +35,8 @@
the message will be posted with the identity of the partner_id of the object
-->
<template id="rating_stars_static_popup_composer" name="Rating: rating composer in popup">
<t t-set="display_composer" t-value="not disable_composer and not request.session.is_website_user"/>
<div class="d-print-none o_rating_popup_composer o_not_editable p-0"
t-att-data-rating_avg="rating_avg or 0.0"
t-att-data-rating_count="rating_count or 0.0"
@@ -50,10 +52,24 @@
t-att-data-default_attachment_ids="default_attachment_ids"
t-att-data-force_submit_url="force_submit_url"
t-att-data-disable_composer="disable_composer"
t-att-data-display_composer="display_composer"
t-att-data-link_btn_classes="_link_btn_classes"
t-att-data-icon="icon"
t-att-data-text_classes="_text_classes"
t-att-data-hide_rating_avg="hide_rating_avg">
<div class="d-flex flex-wrap align-items-center">
<div class="o_rating_popup_composer_stars text-nowrap"/>
<button t-if="display_composer" type="button"
t-att-class="'btn ' + _link_btn_classes or 'btn-primary'"
data-toggle="modal" data-target="#ratingpopupcomposer">
<i t-if="icon" t-att-class="icon"/>
<span t-attf-class="#{_text_classes} o_rating_popup_composer_text">
<t t-if="default_message_id">Modify your review</t>
<t t-else="">Write a review</t>
</span>
</button>
<div class="o_rating_popup_composer_modal"/>
</div>
</div>
</template>
</odoo>