From 0bde4a16525bca4a1852a7d74227d57bec4290c3 Mon Sep 17 00:00:00 2001 From: Florian Charlier Date: Fri, 30 Jun 2023 09:12:55 +0000 Subject: [PATCH] [REF] website_forum: reduce JQuery usage and reduce code duplicity with respect to displaying errors. We'll do more when time allows. Task-3316555 Part-of: odoo/odoo#123709 --- .../static/src/js/website_forum.js | 184 ++++++++---------- 1 file changed, 80 insertions(+), 104 deletions(-) diff --git a/addons/website_forum/static/src/js/website_forum.js b/addons/website_forum/static/src/js/website_forum.js index 73da9c0a575..44cacb871d6 100644 --- a/addons/website_forum/static/src/js/website_forum.js +++ b/addons/website_forum/static/src/js/website_forum.js @@ -8,7 +8,7 @@ import wysiwygLoader from "web_editor.loader"; import publicWidget from "web.public.widget"; import { Markup } from "web.utils"; import session from "web.session"; -import { escape } from "@web/core/utils/strings"; +import { escape, sprintf } from "@web/core/utils/strings"; var qweb = core.qweb; var _t = core._t; @@ -163,13 +163,12 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ forcedOffset: $(scrollingElement).innerHeight() - $(replyEl).innerHeight(), }); }); - - this.$('.o_wforum_question, .o_wforum_answer, .o_wforum_post_comment, .o_wforum_last_activity').toArray() + document.querySelectorAll('.o_wforum_question, .o_wforum_answer, .o_wforum_post_comment, .o_wforum_last_activity') .forEach((post) => { - const relativeDateTime = luxon.DateTime.fromSQL($(post).data('lastActivity'), { zone: 'utc'}).toRelative(); - $(post).find('.o_wforum_relative_datetime').first().text(relativeDateTime); + post.querySelector('.o_wforum_relative_datetime').textContent = luxon.DateTime + .fromSQL(post.dataset.lastActivity, {zone: 'utc'}) + .toRelative(); }); - return this._super.apply(this, arguments); }, @@ -256,31 +255,26 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ if (!karma) { return; } - ev.preventDefault(); - const forumID = parseInt(document.getElementById('wrapwrap').dataset.forum_id); - const notifOptions = { + if (session.is_website_user) { + this._displayAccessDeniedNotification( + Markup`

${sprintf(_t('Oh no! Please sign in to vote'), "/web/login")}

` + ); + return; + } + const forumId = parseInt(document.getElementById('wrapwrap').dataset.forum_id); + const additionalInfoWithForumID = forumId + ? Markup`
+ + ${_t("Read the guidelines to know how to gain karma.")} + ` + : ""; + this.displayNotification({ type: "warning", sticky: false, - }; - if (session.is_website_user) { - notifOptions.title = _t("Access Denied"); - notifOptions.message = Markup` -

Oh no! Please sign in to vote

`; - } else { - notifOptions.title = _t("Karma Error"); - // FIXME this translation is bad, the number should be part of the - // translation, to fix in the appropriate version - notifOptions.message = `${karma} ${_t("karma is required to perform this action. ")}`; - if (forumID) { - const linkLabel = _t("Read the guidelines to know how to gain karma."); - notifOptions.message = Markup` - ${notifOptions.message}
- ${linkLabel} - `; - } - } - this.displayNotification(notifOptions); + title: _t("Karma Error"), + message: Markup`${karma} ${_t("karma is required to perform this action. ")}${additionalInfoWithForumID}` + }); }, /** * @private @@ -328,20 +322,14 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ route: elem.dataset.href || (elem.getAttribute('href') !== '#' && elem.getAttribute('href')) || elem.closest('form').getAttribute('action'), }).then(data => { if (data.error) { - var message; - if (data.error === 'anonymous_user') { - message = _t("Sorry you must be logged to flag a post"); - } else if (data.error === 'post_already_flagged') { - message = _t("This post is already flagged"); - } else if (data.error === 'post_non_flaggable') { - message = _t("This post can not be flagged"); - } - this.displayNotification({ - message: message, - title: _t("Access Denied"), - sticky: false, - type: "warning", - }); + const message = data.error === 'anonymous_user' + ? _t("Sorry you must be logged to flag a post") + : data.error === 'post_already_flagged' + ? _t("This post is already flagged") + : data.error === 'post_non_flaggable' + ? _t("This post can not be flagged") + : data.error; + this._displayAccessDeniedNotification(message); } else if (data.success) { const child = elem.firstElementChild; if (data.success === 'post_flagged_moderator') { @@ -376,19 +364,12 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ route: $btn.data('href'), }).then(data => { if (data.error) { - var message; - if (data.error === 'own_post') { - message = _t('Sorry, you cannot vote for your own posts'); - } else if (data.error === 'anonymous_user') { - message = Markup` -

Oh no! Please sign in to vote

`; - } - this.displayNotification({ - message: message, - title: _t("Access Denied"), - sticky: false, - type: "warning", - }); + const message = data.error === 'own_post' + ? _t('Sorry, you cannot vote for your own posts') + : data.error === 'anonymous_user' + ? Markup`

${sprintf(_t('Oh no! Please sign in to vote'), "/web/login")}

` + : data.error; + this._displayAccessDeniedNotification(message); } else { var $container = $btn.closest('.vote'); var $items = $container.children(); @@ -475,63 +456,50 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ */ _onAcceptAnswerClick: async function (ev) { ev.preventDefault(); - const $link = $(ev.currentTarget); - const target = $link.data('target'); - - const data = await this._rpc({route: $link.data('href')}); + const link = ev.currentTarget; + const target = link.dataset.target; + const data = await this._rpc({ route: link.dataset.href }); if (data.error) { - let message; - if (data.error === 'anonymous_user') { - message = _t('Sorry, anonymous users cannot choose correct answer.'); - } else if (data.error === 'own_post') { - message = _t('Sorry, you cannot vote for your own posts'); - } - this.displayNotification({ - message: message || data.error, - title: _t('Access Denied'), - sticky: false, - type: 'warning', - }); - } else { - this.$('.o_wforum_answer').toArray().forEach((answer) => { - const $answer = $(answer); - const isCorrect = $answer.is(target) ? data : false; - const $toggler = $answer.find('.o_wforum_validate_toggler'); - const $togglerIcon = $toggler.find('.fa'); - const $correctBadge = $answer.find('.o_wforum_answer_correct_badge'); - const newHelper = isCorrect ? $toggler.data('helper-decline') : $toggler.data('helper-accept'); - $answer.toggleClass( - "o_wforum_answer_correct my-2 mx-n3 mx-lg-n2 mx-xl-n3 py-3 px-3 px-lg-2 px-xl-3", - isCorrect - ); - $answer.find('div .border-start') - .toggleClass('border-success', isCorrect); - $toggler.tooltip('dispose') - .attr('data-bs-original-title', newHelper) - .tooltip({delay: 0}) - .toggleClass('opacity-50', !isCorrect); - $togglerIcon - .toggleClass('fa-check-circle text-success', isCorrect) - .toggleClass('fa-check-circle-o', !isCorrect); - $correctBadge.toggleClass('d-inline', isCorrect).toggleClass('d-none', !isCorrect); - }); + const message = data.error === 'anonymous_user' + ? _t('Sorry, anonymous users cannot choose correct answers.') + : data.error === 'own_post' + ? _t('Sorry, you cannot vote for your own posts') + : data.error; + this._displayAccessDeniedNotification(message); + return; + } + for (const answer of document.querySelectorAll('.o_wforum_answer')) { + const isCorrect = answer.matches(target) ? data : false; + const toggler = answer.querySelector('.o_wforum_validate_toggler'); + toggler.setAttribute('data-bs-original-title', isCorrect ? toggler.dataset.helperDecline : toggler.dataset.helperAccept); + const styleForCorrect = isCorrect ? answer.classList.add : answer.classList.remove; + const styleForIncorrect = isCorrect ? answer.classList.remove : answer.classList.add; + styleForCorrect.call(answer.classList, 'o_wforum_answer_correct', 'my-2', 'mx-n3', 'mx-lg-n2', 'mx-xl-n3', 'py-3', 'px-3', 'px-lg-2', 'px-xl-3'); + styleForIncorrect.call(toggler.classList, 'opacity-50'); + const answerBorder = answer.querySelector('div .border-start'); + styleForCorrect.call(answerBorder.classList, 'border-success'); + const togglerIcon = toggler.querySelector('.fa'); + styleForCorrect.call(togglerIcon.classList, 'fa-check-circle', 'text-success'); + styleForIncorrect.call(togglerIcon.classList, 'fa-check-circle-o'); + const correctBadge = answer.querySelector('.o_wforum_answer_correct_badge'); + styleForCorrect.call(correctBadge.classList, 'd-inline'); + styleForIncorrect.call(correctBadge.classList, 'd-none'); } }, /** * @private * @param {Event} ev */ - _onFavoriteQuestionClick: function (ev) { + _onFavoriteQuestionClick: async function (ev) { ev.preventDefault(); - var $link = $(ev.currentTarget); - var $link_icon = $link.find('.fa'); - this._rpc({ - route: $link.data('href'), - }).then(function (data) { - $link.toggleClass('opacity-50 opacity-100-hover', !data); - $link_icon.toggleClass('o_wforum_gold fa-star', data) - .toggleClass('fa-star-o', !data); - }); + const link = ev.currentTarget; + const data = await this._rpc({ route: link.dataset.href }); + link.classList.toggle('opacity-50', !data); + link.classList.toggle('opacity-100-hover', !data); + const link_icon = link.querySelector('.fa'); + link_icon.classList.toggle('fa-star-o', !data); + link_icon.classList.toggle('o_wforum_gold', data) + link_icon.classList.toggle('fa-star', data) }, /** * @private @@ -612,6 +580,14 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ }); }); }, + _displayAccessDeniedNotification(message) { + this.displayNotification({ + message: message, + title: _t('Access Denied'), + sticky: false, + type: 'warning', + }); + } }); publicWidget.registry.websiteForumSpam = publicWidget.Widget.extend({