From 21531bd9b9ac24bec57665432d9c18c807c31b44 Mon Sep 17 00:00:00 2001 From: Elisabeth Dickinson Date: Fri, 31 Mar 2023 13:58:39 +0000 Subject: [PATCH] [IMP] website_forum, *: redesign forum's frontend * = website_slides_forum, website_mail, website_profile In `website_(slides)_forum`: All forums page: Course forums are displayed on the same level as regular forums (with a tag "Course" to differentiate them). We don't see this page if there is only one forum. This new design resembles that of Discourse with a table for the list of questions and a sidebar on the left. Other pages such as the Tags, FAQ, and Moderation pages have also been revamped. Some of the functionality comes in the following commits. Notes: The table rows have been made fully clickable, but by doing so other clickable or hoverable elements lose their function. In order to counteract this, a `position-relative` and `z-index-1` classes are added to them. The image_url definition wasn't working properly: When a user didn't have and avatar, a placeholder with their initial is generated. But it did not take the size option defined in the widget. This has been corrected by changing it to `request.website.image_url(...)` In the posts' page, the answer box now comes up from the bottom of the screen. In the FAQ pages, the accordion has been replaced by BS accordion component using `accordion-item` instead of cards. The web editor however is still using the old system. In `website_mail`: A new template for the follow button has been created in order to redesign it for the forum without disrupting this element in other modules (ie: website_mail, blog). Task-3083657 Part of Task-3316555 Part-of: odoo/odoo#123709 Co-authored-by: Florian Charlier --- addons/website_forum/__manifest__.py | 2 + .../controllers/website_forum.py | 19 + .../website_forum/data/forum_forum_data.xml | 1 + .../data/forum_forum_template_faq.xml | 66 +- addons/website_forum/models/forum_forum.py | 48 +- addons/website_forum/static/src/img/empty.svg | 1 + addons/website_forum/static/src/img/help.jpg | Bin 0 -> 49172 bytes addons/website_forum/static/src/img/tasks.svg | 1 + .../static/src/js/tours/website_forum.js | 2 +- .../static/src/js/website_forum.js | 161 +++- .../static/src/scss/website_forum.scss | 329 ++++--- .../static/src/xml/public_templates.xml | 2 +- .../tests/tours/website_forum_question.js | 25 +- .../views/base_contact_templates.xml | 6 +- .../views/forum_forum_templates.xml | 450 ++++----- .../views/forum_forum_templates_forum_all.xml | 87 +- .../views/forum_forum_templates_layout.xml | 565 ++++++----- .../forum_forum_templates_moderation.xml | 187 ++-- .../views/forum_forum_templates_post.xml | 902 +++++++++--------- .../views/forum_forum_templates_tools.xml | 93 +- .../views/forum_templates_mail.xml | 51 + .../views/website_profile_templates.xml | 76 +- .../static/src/css/website_mail.scss | 15 +- .../static/src/js/website_profile.js | 4 +- .../website_profile/views/website_profile.xml | 2 +- .../models/forum_forum.py | 6 + .../views/forum_forum_templates.xml | 122 +-- 27 files changed, 1705 insertions(+), 1518 deletions(-) create mode 100644 addons/website_forum/static/src/img/empty.svg create mode 100644 addons/website_forum/static/src/img/help.jpg create mode 100644 addons/website_forum/static/src/img/tasks.svg create mode 100644 addons/website_forum/views/forum_templates_mail.xml diff --git a/addons/website_forum/__manifest__.py b/addons/website_forum/__manifest__.py index 80019e925d1..25c5828edd0 100644 --- a/addons/website_forum/__manifest__.py +++ b/addons/website_forum/__manifest__.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. + { 'name': 'Forum', 'category': 'Website/Website', @@ -41,6 +42,7 @@ Ask questions, get answers, no distractions 'views/forum_forum_templates_moderation.xml', 'views/forum_forum_templates_post.xml', 'views/forum_forum_templates_tools.xml', + 'views/forum_templates_mail.xml', 'views/website_profile_templates.xml', 'views/snippets/snippets.xml', diff --git a/addons/website_forum/controllers/website_forum.py b/addons/website_forum/controllers/website_forum.py index 8a5ffe4086d..20c01b85043 100644 --- a/addons/website_forum/controllers/website_forum.py +++ b/addons/website_forum/controllers/website_forum.py @@ -501,6 +501,23 @@ class WebsiteForum(WebsiteProfile): return request.render("website_forum.moderation_queue", values) + @http.route('/forum//closed_posts', type='http', auth="user", website=True) + def closed_posts(self, forum, **kwargs): + if request.env.user.karma < forum.karma_moderate: + raise werkzeug.exceptions.NotFound() + + closed_posts_ids = request.env['forum.post'].search( + [('forum_id', '=', forum.id), ('state', '=', 'close')], + order='write_date DESC, id DESC', + ) + values = self._prepare_user_values(forum=forum) + values.update({ + 'posts_ids': closed_posts_ids, + 'queue_type': 'close', + }) + + return request.render("website_forum.moderation_queue", values) + @http.route('/forum//post//validate', type='http', auth="user", website=True) def post_accept(self, forum, post, **kwargs): url = "/forum/%s/validation_queue" % (slug(forum)) @@ -508,6 +525,8 @@ class WebsiteForum(WebsiteProfile): url = "/forum/%s/flagged_queue" % (slug(forum)) elif post.state == 'offensive': url = "/forum/%s/offensive_posts" % (slug(forum)) + elif post.state == 'close': + url = "/forum/%s/closed_posts" % (slug(forum)) post.validate() return request.redirect(url) diff --git a/addons/website_forum/data/forum_forum_data.xml b/addons/website_forum/data/forum_forum_data.xml index 00866b0f7d7..9bdc46a9a11 100644 --- a/addons/website_forum/data/forum_forum_data.xml +++ b/addons/website_forum/data/forum_forum_data.xml @@ -3,6 +3,7 @@ Help + This community is for professionals and enthusiasts of our products and services. Share and discuss the best content and new marketing ideas, build your professional profile and become a better marketer together. diff --git a/addons/website_forum/data/forum_forum_template_faq.xml b/addons/website_forum/data/forum_forum_template_faq.xml index d6b936d4f56..77a3fbdca8b 100644 --- a/addons/website_forum/data/forum_forum_template_faq.xml +++ b/addons/website_forum/data/forum_forum_template_faq.xml @@ -5,15 +5,19 @@ qweb website_forum.faq_accordion -
+ + Guidelines +
-
-
- -
-
+
+
+

+ +

+
+

This community is for professional and enthusiast users, partners and programmers. You can ask questions about:

  • how to install Odoo on a specific infrastructure,
  • @@ -27,12 +31,14 @@
-
- -
-
+
+

+ +

+
+

You should only ask practical, answerable questions based on actual problems that you face. Chatty, open-ended questions diminish the usefulness of this site and push other questions off the front page.

To prevent your question from being flagged and possibly removed, avoid asking subjective questions where …

    @@ -54,28 +60,32 @@
-
- -
-
+
+

+ +

+
+

Answers should not add or expand questions. Instead, either edit the question or add a comment.

Answers should not comment other answers. Instead add a comment on the other answers.

Answers shouldn't just point to other questions.Instead add a comment indicating "Possible duplicate of...". However, it's fine to include links to other questions or answers providing relevant additional information.

-

Answers shouldn't just provide a link a solution. Instead provide the solution description text in your answer, even if it's just a copy/paste. Links are welcome, but should be complementary to answer, referring sources or additional reading.

+

Answers shouldn't just provide a link a solution. Instead provide the solution description text in your answer, even if it's just a copy/paste. Links are welcome, but should be complementary to answer, referring sources or additional reading.

Answers should not start debates This community Q&A is not a discussion group. Please avoid holding debates in your answers as they tend to dilute the essence of questions and answers. For brief discussions please use commenting facility.

When a question or answer is upvoted, the user who posted them will gain some points, which are called "karma points". These points serve as a rough measure of the community trust to him/her. Various moderation tasks are gradually assigned to the users based on those points.

For example, if you ask an interesting question or give a helpful answer, your input will be upvoted. On the other hand if the answer is misleading - it will be downvoted. Each vote in favor will generate 10 points, each vote against will subtract 2 points. There is a limit of 200 points that can be accumulated for a question or answer per day. The table given at the end explains reputation point requirements for each type of moderation task.

-
- -
-
+
+

+ +

+
+

The goal of this site is create a relevant knowledge base that would answer questions related to Odoo.

Therefore questions and answers can be edited like wiki pages by experienced users of this site in order to improve the overall quality of the knowledge base content. Such privileges are granted based on user karma level: you will be able to do the same once your karma gets high enough.

If this approach is not for you, please respect the community.

@@ -89,4 +99,4 @@ - \ No newline at end of file + diff --git a/addons/website_forum/models/forum_forum.py b/addons/website_forum/models/forum_forum.py index 0f1fe1a1a51..f1306d2d8ba 100644 --- a/addons/website_forum/models/forum_forum.py +++ b/addons/website_forum/models/forum_forum.py @@ -3,6 +3,8 @@ import textwrap +from markupsafe import Markup + from odoo import _, api, fields, models from odoo.tools.translate import html_translate from odoo.addons.http_routing.models.ir_http import slug @@ -21,25 +23,26 @@ class Forum(models.Model): _order = "sequence" def _get_default_welcome_message(self): - return """ -
-
-
-
-

Welcome!

-

%(message_intro)s
%(message_post)s

-
- -
-
-
""" % { - 'message_intro': _("This community is for professionals and enthusiasts of our products and services."), - 'message_post': _("Share and discuss the best content and new marketing ideas, build your professional profile and become a better marketer together."), - 'hide_text': _('Hide Intro'), - 'register_text': _('Register')} + return Markup(""" +

%(message_intro)s

+
+

%(message_post)s

+

+ %(register_text)s + +

+
+ """) % { + 'message_intro': _("Welcome!"), + 'message_post': _( + "Share and discuss the best content and new marketing ideas, build your professional profile and become" + " a better marketer together." + ), + 'hide_text': _('Dismiss'), + 'register_text': _('Sign up'), + } # description and use name = fields.Char('Forum Name', required=True, translate=True) @@ -131,6 +134,7 @@ class Forum(models.Model): karma_post = fields.Integer(string='Ask questions without validation', default=100) karma_moderate = fields.Integer(string='Moderate posts', default=1000) has_pending_post = fields.Boolean(string='Has pending post', compute='_compute_has_pending_post') + can_moderate = fields.Boolean(string="Is a moderator", compute="_compute_can_moderate") @api.depends_context('uid') def _compute_has_pending_post(self): @@ -146,6 +150,12 @@ class Forum(models.Model): pending_forums.has_pending_post = True (self - pending_forums).has_pending_post = False + @api.depends_context('uid') + @api.depends('karma_moderate') + def _compute_can_moderate(self): + for forum in self: + forum.can_moderate = self.env.user.karma >= forum.karma_moderate + @api.depends('description') def _compute_teaser(self): for forum in self: diff --git a/addons/website_forum/static/src/img/empty.svg b/addons/website_forum/static/src/img/empty.svg new file mode 100644 index 00000000000..6e371b2ff02 --- /dev/null +++ b/addons/website_forum/static/src/img/empty.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/website_forum/static/src/img/help.jpg b/addons/website_forum/static/src/img/help.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8827620cb2e344c8a6694a7b78bd859cbc33fc63 GIT binary patch literal 49172 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 literal 0 HcmV?d00001 diff --git a/addons/website_forum/static/src/img/tasks.svg b/addons/website_forum/static/src/img/tasks.svg new file mode 100644 index 00000000000..4f5d810c102 --- /dev/null +++ b/addons/website_forum/static/src/img/tasks.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/website_forum/static/src/js/tours/website_forum.js b/addons/website_forum/static/src/js/tours/website_forum.js index 3c1a396de3d..d09371d0690 100644 --- a/addons/website_forum/static/src/js/tours/website_forum.js +++ b/addons/website_forum/static/src/js/tours/website_forum.js @@ -9,7 +9,7 @@ wTourUtils.registerBackendAndFrontendTour("question", { url: '/forum/1', }, [{ - trigger: ".o_forum_ask_btn", + trigger: ".o_wforum_ask_btn", position: "left", content: _t("Create a new post in this forum by clicking on the button."), }, { diff --git a/addons/website_forum/static/src/js/website_forum.js b/addons/website_forum/static/src/js/website_forum.js index 6153f1c6d8b..e78f3f0f86c 100644 --- a/addons/website_forum/static/src/js/website_forum.js +++ b/addons/website_forum/static/src/js/website_forum.js @@ -26,11 +26,12 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ 'click .o_wforum_flag_validator': '_onFlagValidatorClick', 'click .o_wforum_flag_mark_as_offensive': '_onFlagMarkAsOffensiveClick', 'click .vote_up:not(.karma_required), .vote_down:not(.karma_required)': '_onVotePostClick', - 'click .o_js_validation_queue a[href*="/validate"]': '_onValidationQueueClick', + 'click .o_wforum_validation_queue a[href*="/validate"]': '_onValidationQueueClick', 'click .o_wforum_validate_toggler:not(.karma_required)': '_onAcceptAnswerClick', 'click .o_wforum_favourite_toggle': '_onFavoriteQuestionClick', 'click .comment_delete': '_onDeleteCommentClick', 'click .js_close_intro': '_onCloseIntroClick', + 'click .answer_collapse': '_onExpandAnswerClick', 'submit .js_wforum_submit_form:has(:not(.karma_required).o_wforum_submit_post)': '_onSubmitForm', }, @@ -225,6 +226,21 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ }, 0); } }, + /** + * @private + * @param {Event} ev + */ + _onExpandAnswerClick: function (ev) { + const expandableWindow = ev.currentTarget; + if (ev.target.matches('.o_wforum_expand_toggle')) { + expandableWindow.classList.toggle('o_expand') + expandableWindow.classList.toggle('min-vh-100'); + expandableWindow.classList.toggle('w-lg-50'); + } else if (ev.target.matches('.o_wforum_discard_btn')){ + expandableWindow.classList.remove('o_expand', 'min-vh-100'); + expandableWindow.classList.add('w-lg-50'); + } + }, /** * @private * @param {Event} ev @@ -243,7 +259,8 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ }; if (session.is_website_user) { notifOptions.title = _t("Access Denied"); - notifOptions.message = _t("Sorry you must be logged in to perform this action"); + 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 @@ -327,6 +344,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ elem.prepend(child); if (countFlaggedPosts) { countFlaggedPosts.classList.remove('bg-light'); + countFlaggedPosts.classList.remove('d-none'); countFlaggedPosts.classList.add('bg-danger'); countFlaggedPosts.innerText = parseInt(countFlaggedPosts.innerText, 10) + 1; } @@ -356,7 +374,8 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ if (data.error === 'own_post') { message = _t('Sorry, you cannot vote for your own posts'); } else if (data.error === 'anonymous_user') { - message = _t('Sorry you must be logged to vote'); + message = Markup` +

Oh no! Please sign in to vote

`; } this.displayNotification({ message: message, @@ -401,62 +420,96 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ }); }, /** + * Call the route to moderate/validate the post, then hide the validated post + * and decrement the count in the appropriate queue badge of the sidebar on success. + * * @private * @param {Event} ev */ - _onValidationQueueClick: function (ev) { + _onValidationQueueClick: async function (ev) { ev.preventDefault(); - var $link = $(ev.currentTarget); - $link.parents('.post_to_validate').hide(); - $.get($link.attr('href')).then(() => { - var left = $('.o_js_validation_queue:visible').length; - var type = $('h2.o_page_header a.active').data('type'); - $('#count_post').text(left); - $('#moderation_tools a[href*="/' + type + '_"]').find('strong').text(left); - if (!left) { - this.$('.o_caught_up_alert').removeClass('d-none'); - } - }, function () { - $link.parents('.o_js_validation_queue > div').addClass('bg-danger text-white').css('background-color', '#FAA'); - $link.parents('.post_to_validate').show(); - }); + const approvalLink = ev.currentTarget; + const postBeingValidated = this._findParent(approvalLink, '.post_to_validate'); + if (!postBeingValidated) { + return; + } + postBeingValidated.classList.add('d-none'); + let ok; + try { + ok = (await fetch(approvalLink.href)).ok; + } catch { + // Calling the endpoint like this returns an HTML page. As we can't + // extract the error message from that, we disregard it and simply + // restore the post's visibility. This __should__ be improved. + } + if (!ok) { + postBeingValidated.classList.remove('d-none'); + return; + } + const nbLeftInQueue = Array.from(document.querySelectorAll('.post_to_validate')) + .filter(e => window.getComputedStyle(e).display !== 'none') + .length; + const queueType = document.querySelector('#queue_type').dataset.queueType; + const queueCountBadge = document.querySelector(`#count_posts_queue_${queueType}`); + queueCountBadge.innerText = nbLeftInQueue; + if (!nbLeftInQueue) { + document.querySelector('.o_caught_up_alert').classList.remove('d-none'); + queueCountBadge.classList.add('d-none'); + } + }, + _findParent: function (el, selector) { + while (el.parentElement && !el.matches(selector)) { + el = el.parentElement; + } + return el.matches(selector) ? el : null; }, /** * @private * @param {Event} ev */ - _onAcceptAnswerClick: function (ev) { + _onAcceptAnswerClick: async function (ev) { ev.preventDefault(); - var $link = $(ev.currentTarget); - var target = $link.data('target'); + const $link = $(ev.currentTarget); + const target = $link.data('target'); - this._rpc({ - route: $link.data('href'), - }).then(data => { - if (data.error) { - if (data.error === 'anonymous_user') { - var message = _t("Sorry, anonymous users cannot choose correct answer."); - } - this.displayNotification({ - message: message, - title: _t("Access Denied"), - sticky: false, - type: "warning", - }); - } else { - this.$('.forum_answer').toArray().forEach((answer) => { - var $answer = $(answer); - var isCorrect = $answer.is(target) ? data : false; - var $toggler = $answer.find('.o_wforum_validate_toggler'); - var newHelper = isCorrect ? $toggler.data('helper-decline') : $toggler.data('helper-accept'); - - $answer.toggleClass('o_wforum_answer_correct', isCorrect); - $toggler.tooltip('dispose') - .attr('data-bs-original-title', newHelper) - .tooltip({delay: 0}); - }); + const data = await this._rpc({route: $link.data('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); + }); + } }, /** * @private @@ -465,11 +518,13 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ _onFavoriteQuestionClick: 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('o_wforum_gold fa-star', data) - .toggleClass('fa-star-o text-muted', !data); + $link.toggleClass('opacity-50 opacity-100-hover', !data); + $link_icon.toggleClass('o_wforum_gold fa-star', data) + .toggleClass('fa-star-o', !data); }); }, /** @@ -516,16 +571,16 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ method: currentTarget.dataset.action, args: [parseInt(currentTarget.dataset.postId)], }); - currentTarget.parentElement.querySelectorAll('.flag_validator').forEach((element) => element.classList.toggle('d-none')); + this._findParent(currentTarget, '.o_wforum_flag_alert')?.classList.toggle('d-none'); const flaggedButton = currentTarget.parentElement.firstElementChild, child = flaggedButton.firstElementChild, - countFlaggedPosts = this.el.querySelector('#count_flagged_posts'), + countFlaggedPosts = this.el.querySelector('#count_posts_queue_flagged'), count = parseInt(countFlaggedPosts.innerText, 10) - 1; flaggedButton.innerText = _t(' Flag'); flaggedButton.prepend(child); if (count === 0) { - countFlaggedPosts.classList.add("bg-light"); + countFlaggedPosts.classList.add('bg-light'); } countFlaggedPosts.innerText = count; }, @@ -545,7 +600,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({ renderFooter: false, }).open(); dialog.opened().then(() => { - dialog.$(".btn-light:contains('Discard')").click((ev) => { + dialog.$(".btn-link:contains('Discard')").click((ev) => { ev.preventDefault(); dialog.close(); }); diff --git a/addons/website_forum/static/src/scss/website_forum.scss b/addons/website_forum/static/src/scss/website_forum.scss index 5b9639e17b8..124de84a628 100644 --- a/addons/website_forum/static/src/scss/website_forum.scss +++ b/addons/website_forum/static/src/scss/website_forum.scss @@ -1,42 +1,103 @@ $gold: #eca801; -$silver: #cccccc; -$bronze: #eea91e; +$silver: #acacac; +$bronze: #ba651f; +$-forum-sidebar-width: map-get($container-max-widths, sm) / 2; +.website_forum, .o_wprofile_body { + --o-avatar-height: 1.875rem; + + .o_wforum_avatar { + width: var(--o-avatar-height); + height: var(--o-avatar-height); + } + + .o_wforum_author_box { + &.o_show_info { + line-height: 1.2; + } + + &.o_compact { + --o-avatar-height: 1.4rem; + line-height: 1; + } + } +} .website_forum { - .o_forum_ask_btn { - @include media-breakpoint-up(md) { - box-shadow: $box-shadow; - width: 200px; + --o-post-header-height: var(--o-avatar-height); + + .o_wforum_wrapper { + @include media-breakpoint-up(xl) { + grid-template-columns: $-forum-sidebar-width minmax(0, auto); + } + + @include media-breakpoint-up(xxl) { + max-width: 100%; } } - .o_wforum_nav .nav-link { - @include o-hover-text-color($body-color, $link-color); - line-height: 1; + .o_wforum_content_wrapper { + @include media-breakpoint-up(xxl) { + margin-left: -$-forum-sidebar-width; - .fa { - opacity: 0.5; - } - - &:hover, &.active { - .fa { - opacity: 1; + > div { + max-width: map-get($grid-breakpoints, xl) - $-forum-sidebar-width - 100px; + @include make-container(); } } + } - &.active { - background-color: rgba(map-get($theme-colors, 'info'), 0.1); - color: darken(map-get($theme-colors, 'info'), 15%)!important; + aside.o_wforum_sidebar { + min-width: $-forum-sidebar-width; + + .btn.w-100:hover { + background-color: darken(map-get($o-color-palette, 'o-color-3'), 4%); + } + } + + .o_wforum_table { + --o-avatar-height: 2.25rem; + + img.o_wforum_avatar { + border: 2px solid var(--o-color-4); } - img.o_forum_avatar { - width: 30px; - height: 30px; + .o_wforum_reply_count, .o_wforum_view_count, .o_wforum_last_activity { + width: 100px; } + + &> :not(caption) > * > * { + @include media-breakpoint-down(lg) { + padding-left: 0; + padding-right: $table-cell-padding-x-sm; + } + + } + + tbody { + @include media-breakpoint-down(lg) { + border-top: 0; + } + + tr:hover { + @if ($body-bg and color-contrast($body-bg) != $color-contrast-dark) { + background-color: lighten($body-bg, 10%); + } @else { + background-color: darken($body-bg, 2%); + } + } + } + } + + .o_wforum_index_entry_title a:visited span { + color: lighten($body-color, 50%); + } + + .btn[aria-expanded="true"] { + opacity: 1 !important; } // Single Post - .o_wforum_post, .note-editable.panel-body { + .o_wforum_post, .note-editable { word-wrap: break-word; pre { @@ -49,22 +110,61 @@ $bronze: #eea91e; blockquote { position: relative; - padding-left: 1em; border-left: .25em solid map-get($grays, '500'); + padding-left: 1em; color: map-get($grays, '600'); } + } - #post_reply { - img.o_forum_avatar { - width: 24px; - height: 24px; + #post_reply { + z-index: $zindex-modal; + min-height: 0; + max-height: 0; + border-radius: $border-radius $border-radius 0 0; + transition: max-#{$transition-collapse}, min-#{$transition-collapse}, #{$transition-collapse}, #{$transition-collapse-width}; + + &.show { + max-height: 100%; + + &.o_expand { + .o_wforum_expand_toggle { + content:'\f066'; + } + + .odoo-editor-editable { + transition: $transition-collapse; + flex-grow: 1; + } + + form.js_website_submit_form { + height: calc(100vh - 100px); + } + } + + .o_wysiwyg_textarea_wrapper { + display: flex; + flex-flow: column; + flex-grow: 1; + + .odoo-editor { + height: 200px !important; + display: flex; + flex-grow: 1; + flex-flow: column; + + .note-editable { + flex-grow: 1; + } + } } } } - .o_wforum_readable { - max-width: 700px; + .o_wforum_post_header, .o_wforum_answer_header { + min-height: var(--o-post-header-height); + } + .o_wforum_readable { p { margin-bottom: 0.5rem; } @@ -99,61 +199,25 @@ $bronze: #eea91e; } } - .o_wforum_author_box { - &.o_show_info { - line-height: 1.2; - img { - width: 2em; - height: 2em; - } - } - - &.o_compact { - line-height: 1; - - img { - width: 1.4em; - height: 1.4em; - } - } - - } - - .forum_answer { - .o_wforum_answer_correct_badge { - display: none; - } - - .o_wforum_author_box_check { - width: 1em; - height: 1em; - display: none; - top: 0; - right: -3px; - box-shadow: 0 0 0 2px white; - line-height: .8; - } - - .o_wforum_validate_toggler { - @include o-hover-text-color(map-get($grays, '400'), lighten(map-get($theme-colors, 'success'), 20%)); - } + .o_wforum_answer { + transition: $transition-base; &.o_wforum_answer_correct { - .o_wforum_answer_correct_badge, .o_wforum_author_box .o_wforum_author_box_check { - display: inline; + // This hack is to have either a light or dark success color + // depending on the background color's contrast + $-cc1-bg: o-color(map-get($o-color-palette, o-cc1-bg)); + $-isBright: color-contrast($-cc1-bg) == $color-contrast-dark; + + @if ($-isBright) { + background-color: mix($color-contrast-light, $success, 90%); + } @else { + $-success-light: lighten(saturate($success, 70), 30); + border: 1px solid $-success-light; + background-color: mix($color-contrast-dark, $-success-light, 80%); } - .o_wforum_validate_toggler { - @include o-hover-text-color(map-get($theme-colors, 'success'), map-get($theme-colors, 'warning')); - - &:hover .fa.fa-check:before { - content: '\f00d'; - } - } - - .o_wforum_answer_header .o_wforum_author_pic { - border: 2px solid $success; - padding: 3px; + .o_wforum_author_pic img { + box-shadow: 0 0 0 2px $success; } } } @@ -177,7 +241,6 @@ $bronze: #eea91e; .website_forum, .o_wforum_profile_tab { .vote { .vote_count { - line-height: 1; animation-play-state: paused; &.o_forum_vote_animate { @@ -185,62 +248,13 @@ $bronze: #eea91e; } } - .vote_down, .vote_up { - line-height: 0.5; - font-size: 1.1em; - @include o-hover-text-color(rgba($text-muted, 0.5), map-get($theme-colors, 'success')); + .vote_up { + @include o-hover-text-color(inherit, $success); } .vote_down { - @include o-hover-text-color(rgba($text-muted, 0.5), map-get($theme-colors, 'danger')); + @include o-hover-text-color(inherit, $danger); } - - &.o_wforum_vote_vertical { - @include media-breakpoint-up(sm) { - font-size: 1.2em; - } - } - } -} - -.o_js_forum_tag_follow { - position: relative; - - .badge { - font-size: 100%; - } - - .o_forum_tag_follow_box { - @include o-position-absolute(100%, auto, auto, 0); - display: none; - z-index: 1; - - .card { - padding: ($grid-gutter-width*0.5) - 1px; - } - } -} - -.o_profile_main { - overflow: hidden; -} - -img.o_forum_avatar { - width: 40px; - height: 40px; - object-fit: cover; -} - -img.o_forum_avatar_big { - width: 75px; - height: 75px; - object-fit: cover; -} - -.o_wprofile_email_validation_container { - img.o_forum_avatar { - width: 16px; - height: 16px; } } @@ -250,6 +264,7 @@ img.o_forum_avatar_big { display: flex; align-items: center; } + span[data-oe-model="res.country"] { margin-left: 10px; } @@ -258,31 +273,37 @@ img.o_forum_avatar_big { .o_wforum_bio_popover_info .css_editable_mode_hidden > div:last-child > .o_forum_tooltip_line { margin-top: -0.5rem; // compensate parent 'mt-2' class } - - .o_wforum_bio_popover_bio p { - margin-top: 8px; - margin-bottom: 0; - } -} - -.o_wforum_elearning_navtabs_container { - @include media-breakpoint-up(md) { - background-color: map-get($theme-colors, 'secondary'); - } -} - -.website_forum { - margin-bottom: $spacer; } .popover.o_wforum_bio_popover_container { + box-shadow: 0 2px 5px $gray-400; + + .popover-header { + background-color: tint-color($primary, 80%); + border-bottom: 0; + color: $primary; + } + max-width: 552px; -} -.o_wforum_forum_card_bg { - background-image: linear-gradient(99deg, map-get($theme-colors, 'secondary') 10%, darken(map-get($theme-colors, 'secondary'), 10%) 90%); + .o-text-gold { + color: $gold; + } - #o_wforum_forums_index_list & { - min-height: 100px; + .o-text-silver { + color: $silver; + } + + .o-text-bronze { + color: $bronze; + } +} + +#o_wforum_forums_index_list .card { + border-radius: .75rem; + + &:hover { + transform: translateY(-5px); + box-shadow: $box-shadow !important; } } diff --git a/addons/website_forum/static/src/xml/public_templates.xml b/addons/website_forum/static/src/xml/public_templates.xml index 95458e9a303..31843da2ffa 100644 --- a/addons/website_forum/static/src/xml/public_templates.xml +++ b/addons/website_forum/static/src/xml/public_templates.xml @@ -3,7 +3,7 @@