[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
This commit is contained in:
Florian Charlier
2023-07-18 16:58:44 +02:00
parent 280537b9fe
commit 0bde4a1652
@@ -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`<p>${sprintf(_t('Oh no! Please <a href="%s">sign in</a> to vote'), "/web/login")}</p>`
);
return;
}
const forumId = parseInt(document.getElementById('wrapwrap').dataset.forum_id);
const additionalInfoWithForumID = forumId
? Markup`<br/>
<a class="alert-link" href="/forum/${forumId}/faq">
${_t("Read the guidelines to know how to gain karma.")}
</a>`
: "";
this.displayNotification({
type: "warning",
sticky: false,
};
if (session.is_website_user) {
notifOptions.title = _t("Access Denied");
notifOptions.message = Markup`
<p>Oh no! Please <a href='/web/login'>sign in</a> to vote</p>`;
} 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}<br/>
<a class="alert-link" href="/forum/${encodeURIComponent(forumID)}/faq">${linkLabel}</a>
`;
}
}
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`
<p>Oh no! Please <a href='/web/login'>sign in</a> to vote</p>`;
}
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`<p>${sprintf(_t('Oh no! Please <a href="%s">sign in</a> to vote'), "/web/login")}</p>`
: 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({