[IMP] website_forum: frontend improvements and corrections
This commit adds new features and corrects some others in the frontend of website_forum app. - In the "about" section of a forum, use the s_accordion instead of a custom one for the first 3 elements, the last one is on a new page accessible from a link below the accordion - Cut the description after a specific amount of characters in the page where all forum are listed - In that same view, create options that show the number of post and the last post a forum has. Create an option to render forums in list view - Allow the user to cancel his vote (down or up) - Hide the answer box in the post view. Make it appear when the user click on the "answer" button - Use a JS public widget to validate a Post form (new, save, comment) - Enable the modification of a forum's image from the frontend - Hide Solved/Unsolved categories in "Discussion" forums - Disable the possibility to add snippets to an answer - Corrections of tours that broke after these modifications Part of https://github.com/odoo/odoo/pull/46634 task-2201708
This commit is contained in:
committed by
Jeremy Kersten
parent
b869020401
commit
645056554e
@@ -17,6 +17,7 @@ Ask questions, get answers, no distractions
|
||||
'website_profile',
|
||||
],
|
||||
'data': [
|
||||
'data/forum_default_faq.xml',
|
||||
'data/forum_data.xml',
|
||||
'views/forum.xml',
|
||||
'views/res_users_views.xml',
|
||||
|
||||
@@ -45,7 +45,10 @@ class WebsiteForum(WebsiteProfile):
|
||||
forums = request.env['forum.forum'].search(domain)
|
||||
if len(forums) == 1:
|
||||
return werkzeug.utils.redirect('/forum/%s' % slug(forums[0]), code=302)
|
||||
return request.render("website_forum.forum_all", {'forums': forums})
|
||||
|
||||
return request.render("website_forum.forum_all", {
|
||||
'forums': forums
|
||||
})
|
||||
|
||||
@http.route('/forum/new', type='json', auth="user", methods=['POST'], website=True)
|
||||
def forum_create(self, forum_name="New Forum", forum_mode="questions", forum_privacy="public", forum_privacy_group=False, add_menu=False):
|
||||
@@ -164,6 +167,11 @@ class WebsiteForum(WebsiteProfile):
|
||||
values = self._prepare_user_values(forum=forum, searches=dict(), header={'is_guidelines': True}, **post)
|
||||
return request.render("website_forum.faq", values)
|
||||
|
||||
@http.route(['/forum/<model("forum.forum"):forum>/faq/karma'], type='http', auth="public", website=True, sitemap=False)
|
||||
def forum_faq_karma(self, forum, **post):
|
||||
values = self._prepare_user_values(forum=forum, header={'is_guidelines': True, 'is_karma': True}, **post)
|
||||
return request.render("website_forum.faq_karma", values)
|
||||
|
||||
@http.route('/forum/get_tags', type='http', auth="public", methods=['GET'], website=True, sitemap=False)
|
||||
def tag_read(self, query='', limit=25, **post):
|
||||
data = request.env['forum.tag'].search_read(
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
<div id="accordion">
|
||||
<div class="card mb-2 bg-100">
|
||||
<a href="#collapseOne" class="card-header" id="headingOne" data-toggle="collapse" aria-expanded="false" aria-controls="collapseOne">
|
||||
<b>What kinds of questions can I ask here?</b> <i class="fa fa-caret-down float-right"/>
|
||||
</a>
|
||||
<div id="collapseOne" class="collapse" aria-labelledby="headingOne" data-parent="#accordion">
|
||||
<div class="card-body">
|
||||
<p>This community is for professional and enthusiast users, partners and programmers. You can ask questions about:</p>
|
||||
<ul>
|
||||
<li>how to install Odoo on a specific infrastructure,</li>
|
||||
<li>how to configure or customize Odoo to specific business needs,</li>
|
||||
<li>what's the best way to use Odoo for a specific business need,</li>
|
||||
<li>how to develop modules for your own need,</li>
|
||||
<li>specific questions about Odoo service offers, etc.</li>
|
||||
</ul>
|
||||
<p><b>Before you ask - please make sure to search for a similar question.</b> You can search questions by their title or tags. It’s also OK to answer your own question.</p>
|
||||
<p><b>Please avoid asking questions that are too subjective and argumentative</b> or not relevant to this community.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-2 bg-100">
|
||||
<a href="#collapseTwo" class="card-header" id="headingTwo" data-toggle="collapse" aria-expanded="false" aria-controls="collapseTwo">
|
||||
<b>What should I avoid in my questions?</b> <i class="fa fa-caret-down float-right"/>
|
||||
</a>
|
||||
<div id="collapseTwo" class="collapse" aria-labelledby="headingTwo" data-parent="#accordion">
|
||||
<div class="card-body">
|
||||
<p>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.</p>
|
||||
<p>To prevent your question from being flagged and possibly removed, avoid asking subjective questions where …</p>
|
||||
<ul>
|
||||
<li>every answer is equally valid: “What’s your favorite ______?”</li>
|
||||
<li>your answer is provided along with the question, and you expect more answers: “I use ______ for ______, what do you use?”</li>
|
||||
<li>there is no actual problem to be solved: “I’m curious if other people feel like I do.”</li>
|
||||
<li>we are being asked an open-ended, hypothetical question: “What if ______ happened?”</li>
|
||||
<li>it is a rant disguised as a question: “______ sucks, am I right?”</li>
|
||||
</ul>
|
||||
<p>If you fit in one of these example or if your motivation for asking the question is “I would like to participate in a discussion about ______”, then you should not be asking here but on our mailing lists. However, if your motivation is “I would like others to explain ______ to me”, then you are probably OK.</p>
|
||||
<p>(The above section was adapted from Stackoverflow’s FAQ.)</p>
|
||||
<p>More over:</p>
|
||||
<ul>
|
||||
<li><b>Answers should not add or expand questions</b>. Instead either edit the question or add a question comment.</li>
|
||||
<li><b>Answers should not comment other answers</b>. Instead add a comment on the other answers.</li>
|
||||
<li><b>Answers shouldn't just point to other Questions</b>. Instead add a question comment indication "Possible duplicate of...". However, it's ok to include links to other questions or answers providing relevant additional information.</li>
|
||||
<li><b>Answers shouldn't just provide a link a solution</b>. 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.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card mb-2 bg-100">
|
||||
<a href="#collapseThree" class="card-header" id="headingThree" data-toggle="collapse" aria-expanded="false" aria-controls="collapseThree">
|
||||
<b>What should I avoid in my answers?</b> <i class="fa fa-caret-down float-right"/>
|
||||
</a>
|
||||
<div id="collapseThree" class="collapse" aria-labelledby="headingThree" data-parent="#accordion">
|
||||
<div class="card-body">
|
||||
<p><b>Answers should not add or expand questions</b>. Insteadeither edit the question or add a comment.</p>
|
||||
<p><b>Answers should not comment other answers</b>. Instead add a comment on the other answers.</p>
|
||||
<p><b>Answers shouldn't just point to other questions</b>.Instead add a comment indicating <i>"Possible duplicate of..."</i>. However, it's fine to include links to other questions or answers providing relevant additional information.</p>
|
||||
<p> <b>Answers shouldn't just provide a link a solution</b>. 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.</p>
|
||||
<p><b>Answers should not start debates</b> 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.</p>
|
||||
<p>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.</p>
|
||||
<p>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 10 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.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,92 @@
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="default_faq" model="ir.ui.view">
|
||||
<field name="name">Faq Accordion</field>
|
||||
<field name="type">qweb</field>
|
||||
<field name="key">website_forum.faq_accordion</field>
|
||||
<field name="arch" type="xml">
|
||||
<section class="s_faq_collapse pt32 pb32">
|
||||
<div class="container">
|
||||
<div id="myCollapse" class="accordion" role="tablist">
|
||||
<div class="card bg-white" data-name="Item">
|
||||
<a href="#" role="tab" data-toggle="collapse" aria-expanded="false" class="collapsed card-header" data-target="#collapse1">
|
||||
<b>What kinds of questions can I ask here?</b>
|
||||
</a>
|
||||
<div id="collapse1" class="collapse" role="tabpanel">
|
||||
<div class="card-body">
|
||||
<p>This community is for professional and enthusiast users, partners and programmers. You can ask questions about:</p>
|
||||
<ul>
|
||||
<li>how to install Odoo on a specific infrastructure,</li>
|
||||
<li>how to configure or customize Odoo to specific business needs,</li>
|
||||
<li>what's the best way to use Odoo for a specific business need,</li>
|
||||
<li>how to develop modules for your own need,</li>
|
||||
<li>specific questions about Odoo service offers, etc.</li>
|
||||
</ul>
|
||||
<p><b>Before you ask - please make sure to search for a similar question.</b> You can search questions by their title or tags. It’s also OK to answer your own question.</p>
|
||||
<p><b>Please avoid asking questions that are too subjective and argumentative</b> or not relevant to this community.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card bg-white" data-name="Item">
|
||||
<a href="#" role="tab" data-toggle="collapse" aria-expanded="false" class="collapsed card-header" data-target="#collapse2">
|
||||
<b>What should I avoid in my questions?</b>
|
||||
</a>
|
||||
<div id="collapse2" class="collapse" role="tabpanel">
|
||||
<div class="card-body">
|
||||
<p>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.</p>
|
||||
<p>To prevent your question from being flagged and possibly removed, avoid asking subjective questions where …</p>
|
||||
<ul>
|
||||
<li>every answer is equally valid: “What’s your favorite ______?”</li>
|
||||
<li>your answer is provided along with the question, and you expect more answers: “I use ______ for ______, what do you use?”</li>
|
||||
<li>there is no actual problem to be solved: “I’m curious if other people feel like I do.”</li>
|
||||
<li>we are being asked an open-ended, hypothetical question: “What if ______ happened?”</li>
|
||||
<li>it is a rant disguised as a question: “______ sucks, am I right?”</li>
|
||||
</ul>
|
||||
<p>If you fit in one of these example or if your motivation for asking the question is “I would like to participate in a discussion about ______”, then you should not be asking here but on our mailing lists. However, if your motivation is “I would like others to explain ______ to me”, then you are probably OK.</p>
|
||||
<p>(The above section was adapted from Stackoverflow’s FAQ.)</p>
|
||||
<p>More over:</p>
|
||||
<ul>
|
||||
<li><b>Answers should not add or expand questions</b>. Instead either edit the question or add a question comment.</li>
|
||||
<li><b>Answers should not comment other answers</b>. Instead add a comment on the other answers.</li>
|
||||
<li><b>Answers shouldn't just point to other Questions</b>. Instead add a question comment indication "Possible duplicate of...". However, it's ok to include links to other questions or answers providing relevant additional information.</li>
|
||||
<li><b>Answers shouldn't just provide a link a solution</b>. 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.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card bg-white" data-name="Item">
|
||||
<a href="#" role="tab" data-toggle="collapse" aria-expanded="false" class="collapsed card-header" data-target="#collapse3">
|
||||
<b>What should I avoid in my answers?</b>
|
||||
</a>
|
||||
<div id="collapse3" class="collapse" role="tabpanel">
|
||||
<div class="card-body">
|
||||
<p><b>Answers should not add or expand questions</b>. Insteadeither edit the question or add a comment.</p>
|
||||
<p><b>Answers should not comment other answers</b>. Instead add a comment on the other answers.</p>
|
||||
<p><b>Answers shouldn't just point to other questions</b>.Instead add a comment indicating <i>"Possible duplicate of..."</i>. However, it's fine to include links to other questions or answers providing relevant additional information.</p>
|
||||
<p> <b>Answers shouldn't just provide a link a solution</b>. 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.</p>
|
||||
<p><b>Answers should not start debates</b> 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.</p>
|
||||
<p>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.</p>
|
||||
<p>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 10 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.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card bg-white" data-name="Item">
|
||||
<a href="#" role="tab" data-toggle="collapse" aria-expanded="false" class="collapsed card-header" data-target="#collapse4">
|
||||
<b>Why can other people edit my questions/answers?</b>
|
||||
</a>
|
||||
<div id="collapse4" class="collapse" role="tabpanel">
|
||||
<div class="card-body">
|
||||
<p>The goal of this site is create a relevant knowledge base that would answer questions related to Odoo.</p>
|
||||
<p>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.</p>
|
||||
<p>If this approach is not for you, please respect the community.</p>
|
||||
<a t-attf-href="/forum/#{slug(forum)}/faq/karma">Here a table with the privileges and the karma level</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -22,11 +22,6 @@ class Forum(models.Model):
|
||||
_inherit = ['mail.thread', 'image.mixin', 'website.seo.metadata', 'website.multi.mixin']
|
||||
_order = "sequence"
|
||||
|
||||
@api.model
|
||||
def _get_default_faq(self):
|
||||
with misc.file_open('website_forum/data/forum_default_faq.html', 'r') as f:
|
||||
return f.read()
|
||||
|
||||
# description and use
|
||||
name = fields.Char('Forum Name', required=True, translate=True)
|
||||
sequence = fields.Integer('Sequence', default=1)
|
||||
@@ -44,8 +39,9 @@ class Forum(models.Model):
|
||||
authorized_group_id = fields.Many2one('res.groups', 'Authorized Group')
|
||||
menu_id = fields.Many2one('website.menu', 'Menu', copy=False)
|
||||
active = fields.Boolean(default=True)
|
||||
faq = fields.Html('Guidelines', default=_get_default_faq, translate=html_translate, sanitize=False)
|
||||
faq = fields.Html('Guidelines', translate=html_translate, sanitize=False)
|
||||
description = fields.Text('Description', translate=True)
|
||||
teaser = fields.Text('Teaser', compute='_compute_teaser', store=True)
|
||||
welcome_message = fields.Html(
|
||||
'Welcome Message',
|
||||
translate=True,
|
||||
@@ -85,10 +81,11 @@ class Forum(models.Model):
|
||||
'of the forum content.')
|
||||
# posts statistics
|
||||
post_ids = fields.One2many('forum.post', 'forum_id', string='Posts')
|
||||
total_posts = fields.Integer('Posts', compute='_compute_forum_statistics')
|
||||
total_views = fields.Integer('Views', compute='_compute_forum_statistics')
|
||||
total_answers = fields.Integer('Answers', compute='_compute_forum_statistics')
|
||||
total_favorites = fields.Integer('Favorites', compute='_compute_forum_statistics')
|
||||
last_post_id = fields.Many2one('forum.post', compute='_compute_last_post')
|
||||
total_posts = fields.Integer('# Posts', compute='_compute_forum_statistics')
|
||||
total_views = fields.Integer('# Views', compute='_compute_forum_statistics')
|
||||
total_answers = fields.Integer('# Answers', compute='_compute_forum_statistics')
|
||||
total_favorites = fields.Integer('# Favorites', compute='_compute_forum_statistics')
|
||||
count_posts_waiting_validation = fields.Integer(string="Number of posts waiting for validation", compute='_compute_count_posts_waiting_validation')
|
||||
count_flagged_posts = fields.Integer(string='Number of flagged posts', compute='_compute_count_flagged_posts')
|
||||
# karma generation
|
||||
@@ -129,6 +126,23 @@ class Forum(models.Model):
|
||||
karma_post = fields.Integer(string='Ask questions without validation', default=100)
|
||||
karma_moderate = fields.Integer(string='Moderate posts', default=1000)
|
||||
|
||||
@api.depends('post_ids')
|
||||
def _compute_last_post(self):
|
||||
for forum in self:
|
||||
forum.last_post_id = forum.post_ids.search([('forum_id', '=', forum.id), ('parent_id', '=', False), ('state', '=', 'active')], order='create_date desc', limit=1)
|
||||
|
||||
@api.depends('description')
|
||||
def _compute_teaser(self):
|
||||
for forum in self:
|
||||
if forum.description:
|
||||
desc = forum.description.replace('\n', ' ')
|
||||
if len(forum.description) > 180:
|
||||
forum.teaser = desc[:180] + '...'
|
||||
else:
|
||||
forum.teaser = forum.description
|
||||
else:
|
||||
forum.teaser = ""
|
||||
|
||||
@api.depends('post_ids.state', 'post_ids.views', 'post_ids.child_count', 'post_ids.favourite_count')
|
||||
def _compute_forum_statistics(self):
|
||||
result = dict((cid, dict(total_posts=0, total_views=0, total_answers=0, total_favorites=0)) for cid in self.ids)
|
||||
@@ -157,9 +171,14 @@ class Forum(models.Model):
|
||||
domain = [('forum_id', '=', forum.id), ('state', '=', 'flagged')]
|
||||
forum.count_flagged_posts = self.env['forum.post'].search_count(domain)
|
||||
|
||||
def _set_default_faq(self):
|
||||
self.faq = self.env['ir.ui.view'].render_template('website_forum.faq_accordion', {"forum": self}).decode('utf-8')
|
||||
|
||||
@api.model
|
||||
def create(self, values):
|
||||
return super(Forum, self.with_context(mail_create_nolog=True, mail_create_nosubscribe=True)).create(values)
|
||||
res = super(Forum, self.with_context(mail_create_nolog=True, mail_create_nosubscribe=True)).create(values)
|
||||
res._set_default_faq()
|
||||
return res
|
||||
|
||||
def write(self, vals):
|
||||
if 'privacy' in vals:
|
||||
@@ -411,8 +430,8 @@ class Post(models.Model):
|
||||
post.can_edit = is_admin or user.karma >= post.karma_edit
|
||||
post.can_close = is_admin or user.karma >= post.karma_close
|
||||
post.can_unlink = is_admin or user.karma >= post.karma_unlink
|
||||
post.can_upvote = is_admin or user.karma >= post.forum_id.karma_upvote
|
||||
post.can_downvote = is_admin or user.karma >= post.forum_id.karma_downvote
|
||||
post.can_upvote = is_admin or user.karma >= post.forum_id.karma_upvote or post.user_vote == -1
|
||||
post.can_downvote = is_admin or user.karma >= post.forum_id.karma_downvote or post.user_vote == 1
|
||||
post.can_comment = is_admin or user.karma >= post.karma_comment
|
||||
post.can_comment_convert = is_admin or user.karma >= post.karma_comment_convert
|
||||
post.can_view = is_admin or user.karma >= post.karma_close or (post_sudo.create_uid.karma > 0 and (post_sudo.active or post_sudo.create_uid == user))
|
||||
|
||||
@@ -39,7 +39,13 @@ odoo.define("website_forum.tour_forum", function (require) {
|
||||
extra_trigger: 'div.modal.modal_shown',
|
||||
trigger: ".modal-header button.close",
|
||||
auto: true,
|
||||
}, {
|
||||
},
|
||||
{
|
||||
trigger: "a:contains(\"Answer\").collapsed",
|
||||
content: _t("Click to answer."),
|
||||
position: "bottom",
|
||||
},
|
||||
{
|
||||
trigger: ".note-editable p",
|
||||
content: _t("Put your answer here."),
|
||||
position: "bottom",
|
||||
|
||||
@@ -27,6 +27,7 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
'click .o_wforum_favourite_toggle': '_onFavoriteQuestionClick',
|
||||
'click .comment_delete': '_onDeleteCommentClick',
|
||||
'click .js_close_intro': '_onCloseIntroClick',
|
||||
'submit .js_wforum_submit_form:has(:not(.karma_required).o_wforum_submit_post)': '_onSubmitForm',
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -164,6 +165,12 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
});
|
||||
});
|
||||
|
||||
this.$('#post_reply').on('shown.bs.collapse', function (e) {
|
||||
$('html').animate({
|
||||
scrollTop: $('#post_reply').offset().top - ($(window).innerHeight() - $('#post_reply').innerHeight())
|
||||
}, 500);
|
||||
});
|
||||
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
@@ -171,6 +178,59 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
*
|
||||
* @override
|
||||
* @param {Event} ev
|
||||
*/
|
||||
_onSubmitForm: function (ev) {
|
||||
let validForm = true;
|
||||
|
||||
let $form = $(ev.currentTarget);
|
||||
let $title = $form.find('input[name=post_name]');
|
||||
let $textarea = $form.find('textarea[name=content]');
|
||||
// It's not really in the textarea that the user write at first
|
||||
let textareaContent = $form.find('.o_wysiwyg_wrapper .note-editable.panel-body').text().trim();
|
||||
|
||||
if ($title.length && $title[0].required) {
|
||||
if ($title.val()) {
|
||||
$title.removeClass('is-invalid');
|
||||
} else {
|
||||
$title.addClass('is-invalid');
|
||||
validForm = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Because the textarea is hidden, we add the red or green border to its container
|
||||
if ($textarea[0].required) {
|
||||
let $textareaContainer = $form.find('.o_wysiwyg_wrapper .note-editor.panel.panel-default');
|
||||
if (!textareaContent.length) {
|
||||
$textareaContainer.addClass('border border-danger rounded-top');
|
||||
validForm = false;
|
||||
} else {
|
||||
$textareaContainer.removeClass('border border-danger rounded-top');
|
||||
}
|
||||
}
|
||||
|
||||
if (validForm) {
|
||||
// Stores social share data to display modal on next page.
|
||||
if ($form.has('.oe_social_share_call').length) {
|
||||
sessionStorage.setItem('social_share', JSON.stringify({
|
||||
targetType: $(ev.currentTarget).find('.o_wforum_submit_post').data('social-target-type'),
|
||||
}));
|
||||
}
|
||||
} else {
|
||||
ev.preventDefault();
|
||||
setTimeout(function() {
|
||||
var $buttons = $(ev.currentTarget).find('button[type="submit"], a.a-submit');
|
||||
_.each($buttons, function (btn) {
|
||||
let $btn = $(btn);
|
||||
$btn.find('i').remove();
|
||||
$btn.prop('disabled', false);
|
||||
});
|
||||
}, 0);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @private
|
||||
* @param {Event} ev
|
||||
@@ -317,10 +377,20 @@ publicWidget.registry.websiteForum = publicWidget.Widget.extend({
|
||||
if (userVote === 1) {
|
||||
$voteUp.addClass('text-success');
|
||||
$voteCount.addClass('text-success');
|
||||
$voteDown.removeClass('karma_required');
|
||||
}
|
||||
if (userVote === -1) {
|
||||
$voteDown.addClass('text-danger');
|
||||
$voteCount.addClass('text-danger');
|
||||
$voteUp.removeClass('karma_required');
|
||||
}
|
||||
if (userVote === 0) {
|
||||
if (!$voteDown.data('can-downvote')) {
|
||||
$voteDown.addClass('karma_required');
|
||||
}
|
||||
if (!$voteUp.data('can-upvote')) {
|
||||
$voteUp.addClass('karma_required');
|
||||
}
|
||||
}
|
||||
$voteCount.html(data['vote_count']).addClass('o_forum_vote_animate');
|
||||
}
|
||||
|
||||
@@ -76,9 +76,6 @@ var ForumShare = publicWidget.registry.socialShare.extend({
|
||||
|
||||
publicWidget.registry.websiteForumShare = publicWidget.Widget.extend({
|
||||
selector: '.website_forum',
|
||||
events: {
|
||||
'click :not(.karma_required).oe_social_share_call': '_onShareCallClick',
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
@@ -98,20 +95,5 @@ publicWidget.registry.websiteForumShare = publicWidget.Widget.extend({
|
||||
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Handlers
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Stores social share data to display modal on next page.
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
_onShareCallClick: function (ev) {
|
||||
sessionStorage.setItem('social_share', JSON.stringify({
|
||||
targetType: $(ev.currentTarget).data('social-target-type'),
|
||||
}));
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -35,7 +35,13 @@ odoo.define('website_forum.tour_forum_question', function (require) {
|
||||
content: "Close modal once modal animation is done.",
|
||||
extra_trigger: 'div.modal.modal_shown',
|
||||
trigger: ".modal-header button.close",
|
||||
}, {
|
||||
},
|
||||
{
|
||||
trigger: "a:contains(\"Answer\").collapsed",
|
||||
content: "Click to answer.",
|
||||
position: "bottom",
|
||||
},
|
||||
{
|
||||
content: "Put your answer here.",
|
||||
trigger: '.note-editable p',
|
||||
run: 'text First Answer',
|
||||
|
||||
@@ -83,7 +83,15 @@
|
||||
<li class="breadcrumb-item">
|
||||
<a t-attf-href="/forum/#{ slug(forum) }" t-esc="forum.name"/>
|
||||
</li>
|
||||
<li t-if="header.get('is_guidelines')" class="breadcrumb-item">Guidelines</li>
|
||||
<t t-if="header.get('is_guidelines')">
|
||||
<li class="breadcrumb-item">
|
||||
<a t-if="header.get('is_karma')" t-attf-href="/forum/#{ slug(forum) }/faq">Guidelines</a>
|
||||
<t t-else="">
|
||||
Guidelines
|
||||
</t>
|
||||
</li>
|
||||
<li t-if="header.get('is_karma')" class="breadcrumb-item">Karma</li>
|
||||
</t>
|
||||
<li t-if="queue_type" class="breadcrumb-item">Moderation</li>
|
||||
<li t-if="queue_type == 'validation'" class="breadcrumb-item">To Validate</li>
|
||||
<li t-if="queue_type == 'flagged'" class="breadcrumb-item">Flagged</li>
|
||||
@@ -362,12 +370,18 @@
|
||||
<t t-call="website_forum.header">
|
||||
<div t-field="forum.description" class="mb-4"/>
|
||||
<div t-field="forum.faq"/>
|
||||
<div class="card mb-2">
|
||||
<a href="#collapseFour" class="card-header" id="headingFour" data-toggle="collapse" aria-expanded="false" aria-controls="collapseFour">
|
||||
<b>Why can other people edit my questions/answers?</b> <i class="fa fa-caret-down float-right"/>
|
||||
</a>
|
||||
<div id="collapseFour" class="collapse" aria-labelledby="headingFour" data-parent="#accordion">
|
||||
<div class="card-body">
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- FAQ Karma Layout -->
|
||||
<template id="faq_karma" name="Karma">
|
||||
<t t-call="website_forum.header">
|
||||
<div class="card bg-white" data-name="Item">
|
||||
<div role="tab" class="card-header">
|
||||
<b>Why can other people edit my questions/answers?</b>
|
||||
</div>
|
||||
<div role="tabpanel">
|
||||
<div class="card-body">
|
||||
<p>The goal of this site is create a relevant knowledge base that would answer questions related to Odoo.</p>
|
||||
<p>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.</p>
|
||||
<p>If this approach is not for you, please respect the community.</p>
|
||||
@@ -417,6 +431,13 @@
|
||||
|
||||
<!-- All Forums Layout -->
|
||||
<template id="forum_all" name="Forum Navigation">
|
||||
|
||||
<t t-set="col_class" t-valuef="mb-3 col-sm-6"/>
|
||||
<t t-set="img_class" t-valuef="col-md-4"/>
|
||||
<t t-set="content_class" t-valuef="col-md-8"/>
|
||||
<t t-set="last_post_class" t-valuef="col-md-12 pr-md-3 pt-3"/>
|
||||
<t t-set="nb_post_class" t-valuef="col-md-12 pr-md-3 pt-2"/>
|
||||
|
||||
<t t-call="website.layout">
|
||||
<t t-set="pageName" t-value="'website_forum'"/>
|
||||
<div id="wrap">
|
||||
@@ -444,27 +465,70 @@
|
||||
<!-- First, list all forums (those with descriptions first) -->
|
||||
<t t-foreach="sorted_forums" t-as="forum">
|
||||
<t t-set="has_desc" t-value="forum.description"/>
|
||||
<div t-attf-class="mb-3 col-sm-6 #{not has_desc and 'col-md-3'}">
|
||||
<div t-attf-class="#{has_desc and 'row' or 'd-flex flex-column h-100'} #{no_description_exist and has_desc and 'py-4 bg-200'}">
|
||||
<div t-attf-class="#{has_desc and 'col-md-4 pr-md-0' or 'flex-lg-grow-1'}">
|
||||
<div t-attf-class="#{col_class}">
|
||||
<div class="row py-4 bg-200 mx-1 h-100 o_forum_row">
|
||||
<div t-attf-class="o_forum_image_container pr-md-0 h-100 #{img_class}">
|
||||
<a t-attf-href="/forum/#{slug(forum)}">
|
||||
<div t-attf-class="oe_img_bg rounded shadow-sm py-4 px-5 o_wforum_forum_card_bg flex-shrink-0 h-100 o_not_editable {not has_desc and 'h-100'}"
|
||||
t-attf-style="#{forum.image_256 and ('background-image: url(%s);' % website.image_url(forum, 'image_256'))} background-position: center;"/>
|
||||
<div t-attf-class="h-100 w-100 #{not forum.image_1920 and 'rounded o_wforum_forum_card_bg shadow-sm flex-shrink-0'}">
|
||||
<div t-if="forum.image_1920 or editable" t-attf-class="h-100"
|
||||
t-field="forum.image_1920" t-options="{'widget': 'image', 'preview_image': 'image_256', 'class': 'w-100 h-100 o_object_fit_cover rounded'}" />
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
<div t-attf-class="mt-2 #{has_desc and 'col-md-8 mt-md-0'}">
|
||||
<div t-attf-class="#{content_class} mt-2 mt-md-0 d-flex flex-column h-100">
|
||||
<a t-attf-href="/forum/#{slug(forum)}" class="text-reset" t-att-title="forum.name">
|
||||
<h3 t-attf-class="#{has_desc and 'h4' or 'h5 m-0'}" t-field="forum.name"/>
|
||||
<h3 class="h4" t-field="forum.name"/>
|
||||
</a>
|
||||
<p t-attf-class="m-0 #{has_desc and not no_description_exist and 'text-muted' or not has_desc and 'css_non_editable_mode_hidden'}"
|
||||
<p class="m-0 flex-grow-1"
|
||||
placeholder="Description"
|
||||
t-field="forum.description"/>
|
||||
t-field="forum.teaser"/>
|
||||
<t t-if="is_view_active('website_forum.opt_post_count') or is_view_active('website_forum.opt_last_post')" t-call="website_forum.forum_post_options"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="forum_post_options">
|
||||
<div class="row">
|
||||
<div t-attf-class="#{last_post_class}">
|
||||
<div t-if="is_view_active('website_forum.opt_last_post') and forum.post_ids" class="text-truncate">Last Post: <a t-attf-href="/forum/#{slug(forum)}/question/#{slug(forum.last_post_id)}"><t t-esc="forum.last_post_id.name"/></a></div>
|
||||
</div>
|
||||
<div t-attf-class="#{nb_post_class}">
|
||||
<div t-if="is_view_active('website_forum.opt_post_count')">Posts: <strong><t t-esc="forum.total_posts"/></strong></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- (Options) Forum : List View
|
||||
Display forums as a list -->
|
||||
<template name="List View" id="website_forum.opt_list_view" inherit_id="website_forum.forum_all" active="False" customize_show="True">
|
||||
<xpath expr="//t[@t-set='col_class']" position="attributes">
|
||||
<attribute name="t-valuef">mb-3 col-sm-12</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//t[@t-set='img_class']" position="attributes">
|
||||
<attribute name="t-valuef">col-md-3</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//t[@t-set='content_class']" position="attributes">
|
||||
<attribute name="t-valuef">col-md-9</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//t[@t-set='last_post_class']" position="attributes">
|
||||
<attribute name="t-valuef">col-md-10 pr-md-0 pt-3</attribute>
|
||||
</xpath>
|
||||
<xpath expr="//t[@t-set='nb_post_class']" position="attributes">
|
||||
<attribute name="t-valuef">col-md-2 pr-md-3 pt-3</attribute>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- (Options) Forum : Show Post Count
|
||||
Show the number of post a forum has -->
|
||||
<template name="Show Post Count" id="website_forum.opt_post_count" inherit_id="website_forum.forum_all" active="False" customize_show="True"/>
|
||||
|
||||
<!-- (Options) Forum : Show Last Post
|
||||
Show the title of the latest post in each forum -->
|
||||
<template name="Show Last Post" id="website_forum.opt_last_post" inherit_id="website_forum.forum_all" active="False" customize_show="True"/>
|
||||
|
||||
|
||||
<!-- Default content for the "All Forums Layout" header above -->
|
||||
<!-- (simulate an oe_structure edition) -->
|
||||
<template id="forum_all_oe_structure_forum_all_top" inherit_id="website_forum.forum_all" name="Forum Navigation (oe_structure_forum_all_top)">
|
||||
@@ -620,12 +684,14 @@
|
||||
</a>
|
||||
|
||||
<div class="dropdown-divider"/>
|
||||
<a t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='solved')"
|
||||
class="dropdown-item">Solved
|
||||
</a>
|
||||
<a t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='unsolved')"
|
||||
class="dropdown-item">Unsolved
|
||||
</a>
|
||||
<t t-if="forum.mode == 'questions'">
|
||||
<a t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='solved')"
|
||||
class="dropdown-item">Solved
|
||||
</a>
|
||||
<a t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='unsolved')"
|
||||
class="dropdown-item">Unsolved
|
||||
</a>
|
||||
</t>
|
||||
<a t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', filters='unanswered')"
|
||||
class="dropdown-item">Unanswered
|
||||
</a>
|
||||
@@ -640,13 +706,15 @@
|
||||
t-attf-class="nav-link py-1 rounded-pill #{no_filters and 'active font-weight-bold' or 'pl-0 pr-2'}">
|
||||
All
|
||||
</a>
|
||||
<span class="mx-1 text-400 d-none d-lg-block">|</span>
|
||||
<a t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', 'my', filters='solved')"
|
||||
t-attf-class="nav-link py-1 rounded-pill #{filters == 'solved' and 'active font-weight-bold' or 'px-2'}">Solved
|
||||
</a>
|
||||
<a t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', 'my', filters='unsolved')"
|
||||
t-attf-class="d-none d-lg-block nav-link py-1 rounded-pill #{filters == 'unsolved' and 'active font-weight-bold' or 'px-2'}">Unsolved
|
||||
</a>
|
||||
<t t-if="forum.mode == 'questions'">
|
||||
<span class="mx-1 text-400 d-none d-lg-block">|</span>
|
||||
<a t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', 'my', filters='solved')"
|
||||
t-attf-class="nav-link py-1 rounded-pill #{filters == 'solved' and 'active font-weight-bold' or 'px-2'}">Solved
|
||||
</a>
|
||||
<a t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', 'my', filters='unsolved')"
|
||||
t-attf-class="d-none d-lg-block nav-link py-1 rounded-pill #{filters == 'unsolved' and 'active font-weight-bold' or 'px-2'}">Unsolved
|
||||
</a>
|
||||
</t>
|
||||
<span class="mx-1 text-400 d-none d-lg-block">|</span>
|
||||
<a t-att-href="url_for('') + '?' + keep_query( 'search', 'sorting', 'my', filters='unanswered')"
|
||||
t-attf-class="nav-link py-1 rounded-pill #{filters == 'unanswered' and 'active font-weight-bold' or 'px-2'}">Unanswered
|
||||
@@ -765,7 +833,7 @@
|
||||
<a t-attf-href="/forum/#{ slug(forum) }" title="All Topics"><i class="fa fa-chevron-left mr-2"/>Back to All Topics</a>
|
||||
</div>
|
||||
|
||||
<form t-else="" t-attf-action="/forum/#{slug(forum)}/new" method="post" role="form" class="tag_text js_website_submit_form o_wforum_readable">
|
||||
<form t-else="" t-attf-action="/forum/#{slug(forum)}/new" method="post" role="form" class="tag_text js_website_submit_form js_wforum_submit_form o_wforum_readable">
|
||||
<div class="form-group">
|
||||
<label for="content">Title</label>
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
@@ -801,9 +869,9 @@
|
||||
<input type="hidden" name="post_tags" placeholder="Tags" class="form-control js_select2"/>
|
||||
</div>
|
||||
<div class="mb-5">
|
||||
<button type="submit" t-attf-class="btn btn-primary #{forum.allow_share and 'oe_social_share_call'} #{(user.karma < forum.karma_ask) and 'karma_required'}"
|
||||
t-att-data-karma="forum.karma_ask"
|
||||
data-hashtags="#question" data-social-target-type="question">Post Your Question</button>
|
||||
<button type="submit" t-attf-class="btn btn-primary o_wforum_submit_post #{forum.allow_share and 'oe_social_share_call'} #{(user.karma < forum.karma_ask) and 'karma_required'}"
|
||||
t-att-data-karma="forum.karma_ask"
|
||||
data-hashtags="#question" data-social-target-type="question">Post Your Question</button>
|
||||
<a class="btn btn-secondary" title="Back to Question" t-attf-href="/forum/#{ slug(forum) }"> Discard</a>
|
||||
</div>
|
||||
</form>
|
||||
@@ -818,7 +886,7 @@
|
||||
<h5 class="mb-1 text-muted" t-esc="post.parent_id.name"/>
|
||||
<div t-field="post.parent_id.content" class="o_wforum_post_content text-muted oe_no_empty"/>
|
||||
</article>
|
||||
<form t-attf-action="/forum/#{slug(forum)}/post/#{slug(post)}/save" method="post" role="form" class="tag_text js_website_submit_form o_wforum_readable">
|
||||
<form t-attf-action="/forum/#{slug(forum)}/post/#{slug(post)}/save" method="post" role="form" class="tag_text js_website_submit_form js_wforum_submit_form o_wforum_readable">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<div t-if="not is_answer" class="form-group">
|
||||
<label for="post_name">Title</label>
|
||||
@@ -860,7 +928,7 @@
|
||||
t-att-title="edit_tags_karma_fail and edit_tags_karma_error_message"/>
|
||||
</div>
|
||||
<div class="mb-4">
|
||||
<button type="submit" class="btn btn-primary">Save changes</button>
|
||||
<button type="submit" class="btn btn-primary o_wforum_submit_post">Save Changes</button>
|
||||
<a class="btn btn-secondary" title="Back to Question" t-attf-href="/forum/#{ slug(forum) }/question/#{ slug(post)}">
|
||||
Discard
|
||||
</a>
|
||||
@@ -912,13 +980,13 @@
|
||||
<!-- Edition: post a reply -->
|
||||
<template id="post_reply">
|
||||
<div class="css_editable_mode_hidden">
|
||||
<form class="collapse js_website_submit_form"
|
||||
<form class="collapse js_website_submit_form js_wforum_submit_form"
|
||||
t-attf-action="/forum/#{slug(forum)}/#{slug(object)}/reply" method="post" role="form">
|
||||
<h3 class="mt8">Your Reply</h3>
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input type="hidden" name="karma" t-attf-value="#{user.karma}" id="karma"/>
|
||||
<textarea name="content" class="form-control o_wysiwyg_loader" required="required" t-att-data-karma="forum.karma_editor"/>
|
||||
<button type="submit" class="btn btn-primary mb16">Post Answer</button>
|
||||
<textarea name="content" class="form-control o_wysiwyg_loader" required="required" minlength="50" t-att-data-karma="forum.karma_editor"/>
|
||||
<button type="submit" class="btn btn-primary mb16 o_wforum_submit_post">Post Answer</button>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
@@ -932,19 +1000,24 @@
|
||||
<t t-if="request.params.get('nocontent')">
|
||||
<p class="alert alert-danger" role="alert">You cannot post an empty answer</p>
|
||||
</t>
|
||||
<form t-attf-action="/forum/#{ slug(forum) }/#{slug(question)}/reply" method="post" class="js_website_submit_form" role="form">
|
||||
<form t-attf-action="/forum/#{ slug(forum) }/#{slug(question)}/reply" method="post" class="js_website_submit_form js_wforum_submit_form" role="form">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input type="hidden" name="karma" t-attf-value="#{user.karma}" id="karma"/>
|
||||
<textarea name="content" t-attf-id="content-#{str(question.id)}" class="form-control o_wysiwyg_loader" required="required" t-att-data-karma="forum.karma_editor"/>
|
||||
<textarea name="content" t-attf-id="content-#{str(question.id)}" class="form-control o_wysiwyg_loader" required="required" minlength="50" t-att-data-karma="forum.karma_editor"/>
|
||||
<p class="small mt-2 mb-1">
|
||||
<b>Please try to give a substantial answer.</b> If you wanted to comment on the question or answer, just
|
||||
<b>use the commenting tool.</b> Please remember that you can always <b>revise your answers</b>
|
||||
- no need to answer the same question twice. Also, please <b>don't forget to vote</b>
|
||||
- it really helps to select the best questions and answers!
|
||||
</p>
|
||||
<button type="submit" t-attf-class="btn btn-primary #{forum.allow_share and 'oe_social_share_call'} my-3 #{not question.can_answer and 'karma_required'}"
|
||||
<button type="submit" t-attf-class="btn btn-primary o_wforum_submit_post #{forum.allow_share and 'oe_social_share_call'} my-3 #{not question.can_answer and 'karma_required'}"
|
||||
t-att-data-karma="question.forum_id.karma_answer"
|
||||
data-social-target-type="answer" data-hashtags="#answer">Post Answer</button>
|
||||
<a href="#"
|
||||
class="btn btn-secondary"
|
||||
data-toggle="collapse"
|
||||
data-target=".answer_collapse"
|
||||
aria-expanded="false">Discard</a>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
@@ -958,6 +1031,7 @@
|
||||
t-attf-class="btn btn-link vote_up fa fa-caret-up pl-0 #{vertical and 'px-md-0 pt-md-0' or 'pr-2'} #{own_vote == 1 and 'text-success' or 'text-muted'} #{not can_upvote and 'karma_required'}"
|
||||
t-att-disabled="own_vote == 1 and 'disabled'"
|
||||
t-att-data-karma="forum.karma_upvote"
|
||||
t-att-data-can-upvote="can_upvote"
|
||||
aria-label="Positive vote" title="Positive vote"/>
|
||||
<b t-attf-class="vote_count #{own_vote == 1 and 'text-success' or (own_vote == -1 and 'text-danger' or 'text-muted')}"
|
||||
t-esc="post.vote_count"/>
|
||||
@@ -965,6 +1039,7 @@
|
||||
t-attf-class="btn btn-link vote_down fa fa-caret-down #{vertical and 'px-md-0' or 'px-2'} #{own_vote == -1 and 'text-danger' or 'text-muted'} #{not can_downvote and 'karma_required'}"
|
||||
t-att-disabled="own_vote == -1 and 'disabled'"
|
||||
t-att-data-karma="forum.karma_downvote"
|
||||
t-att-data-can-downvote="can_downvote"
|
||||
aria-label="Negative vote" title="Negative vote"/>
|
||||
<t t-raw="0"/>
|
||||
</div>
|
||||
@@ -1074,15 +1149,17 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div t-field="question.content" class="o_wforum_post_content o_wforum_readable oe_no_empty"/>
|
||||
<div t-field="question.content" class="o_wforum_post_content o_wforum_readable oe_no_empty o_not_editable"/>
|
||||
|
||||
<t t-set="_question_comment_collapse_uid" t-value="'comment_%s_%s' % (question._name.replace('.', '_'), question.id)"/>
|
||||
<div t-if="question.state == 'active' and question.active != False"
|
||||
class="btn-toolbar mb-3" role="toolbar">
|
||||
<div t-if="not question.uid_has_answered and question.can_answer" class="btn-group btn-group-sm mr-2">
|
||||
<a t-attf-class="btn btn-primary #{not question.can_answer and 'karma_required text-muted'}"
|
||||
<a t-attf-class="btn btn-primary collapsed #{not question.can_answer and 'karma_required text-muted'}"
|
||||
t-att-data-karma="question.forum_id.karma_answer"
|
||||
href="#post_reply">
|
||||
data-toggle="collapse"
|
||||
data-target=".answer_collapse"
|
||||
href="#">
|
||||
<i class="fa fa-reply mr-1"/>Answer
|
||||
</a>
|
||||
</div>
|
||||
@@ -1119,8 +1196,19 @@
|
||||
</div>
|
||||
</t>
|
||||
</section>
|
||||
|
||||
<div t-if="not question.uid_has_answered and question.can_answer and question.child_ids" class="btn-group btn-group-sm mr-2">
|
||||
<a t-attf-class="btn btn-primary answer_collapse show collapsed collapse #{not question.can_answer and 'karma_required text-muted'}"
|
||||
t-att-data-karma="question.forum_id.karma_answer"
|
||||
data-toggle="collapse"
|
||||
data-target=".answer_collapse"
|
||||
href="#">
|
||||
<i class="fa fa-reply mr-1"/>Answer
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<t t-if="question.state != 'close' and question.active != False and question.can_answer and not request.env.user.forum_waiting_posts_count">
|
||||
<div id="post_reply" t-if="(not question.uid_has_answered or question.forum_id.mode == 'discussions')">
|
||||
<div id="post_reply" class="collapse answer_collapse" t-if="(not question.uid_has_answered or question.forum_id.mode == 'discussions')">
|
||||
<t t-call="website_forum.post_answer"/>
|
||||
</div>
|
||||
<div t-elif="uid and request.env.user.forum_waiting_posts_count" class="alert alert-gamma text-center">
|
||||
@@ -1237,7 +1325,7 @@
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div t-field="answer.content" class="mb-2 o_wforum_readable oe_no_empty"/>
|
||||
<div t-field="answer.content" class="mb-2 o_wforum_readable oe_no_empty o_not_editable"/>
|
||||
|
||||
<t t-set="_answer_comment_collapse_uid" t-value="'comment_%s_%s' % (answer._name.replace('.', '_'), answer.id)"/>
|
||||
<div class="btn-toolbar mb-3">
|
||||
@@ -1371,7 +1459,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="css_editable_mode_hidden o_wforum_readable">
|
||||
<form t-att-id="_collapse_uid" class="collapse p-1 oe_comment_grey js_website_submit_form"
|
||||
<form t-att-id="_collapse_uid" class="collapse p-1 oe_comment_grey js_website_submit_form js_wforum_submit_form"
|
||||
t-attf-action="/forum/#{slug(forum)}/post/#{slug(object)}/comment" method="POST">
|
||||
<div class="shadow bg-white rounded px-3 pt-3 pb-4 mb-4">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
@@ -1381,7 +1469,7 @@
|
||||
<div class="w-100">
|
||||
<textarea name="comment" class="form-control mb-2" placeholder="Comment this post..."/>
|
||||
<div>
|
||||
<button type="submit" class="btn btn-primary">Post comment</button>
|
||||
<button type="submit" class="btn btn-primary o_wforum_submit_post">Post Comment</button>
|
||||
<a t-attf-href="##{_collapse_uid}" data-toggle="collapse" class="btn border">Discard</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -40,9 +40,9 @@
|
||||
<div class="row align-items-start">
|
||||
<div class="col-12 col-sm-4">
|
||||
<a t-attf-href="/forum/#{slug(forum)}">
|
||||
<div class="oe_img_bg rounded shadow-sm py-4 px-5 o_wforum_forum_card_bg flex-shrink-0"
|
||||
t-attf-style="#{forum.image_256 and ('background-image: url(%s);' % website.image_url(forum, 'image_256'))} background-position: center;">
|
||||
<div class="p-5"/>
|
||||
<div t-attf-class="h-100 w-100 o_editable #{not forum.image_1920 and 'rounded o_wforum_forum_card_bg shadow-sm flex-shrink-0'}">
|
||||
<div t-if="forum.image_1920 or editable" t-attf-class="h-100"
|
||||
t-field="forum.image_1920" t-options="{'widget': 'image', 'preview_image': 'image_256', 'class': 'w-100 h-100 o_object_fit_cover rounded'}" />
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
@@ -52,7 +52,7 @@
|
||||
</a>
|
||||
<p t-attf-class="m-0 lead #{not forum.description and 'css_non_editable_mode_hidden'}"
|
||||
placeholder="Description"
|
||||
t-field="forum.description"/>
|
||||
t-field="forum.teaser"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user