[IMP] website_forum: bring forum modes
It is now possible to specify the forum mode : Questions and Answers or Discussions. In Q&A mode, a user can only reply once while there is no limit in Discussions mode. task-2008910 closes odoo/odoo#34097 Signed-off-by: Jérémy Kersten (jke) <jke@openerp.com>
This commit is contained in:
committed by
Jeremy Kersten
parent
cfeb8a5185
commit
f9c2716b3e
@@ -11,7 +11,7 @@
|
||||
<main class="modal-body">
|
||||
<form role="form" t-att-id="id">
|
||||
<div class="form-group row mb0">
|
||||
<label for="page-name" class="col-md-3 col-form-label">
|
||||
<label for="page-name" class="col-md-4 col-form-label">
|
||||
<t t-esc="field_name"/>:
|
||||
</label>
|
||||
<div class="col-md-8">
|
||||
|
||||
@@ -48,8 +48,8 @@ class WebsiteForum(WebsiteProfile):
|
||||
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", add_menu=False):
|
||||
forum_id = request.env['forum.forum'].create({'name': forum_name})
|
||||
def forum_create(self, forum_name="New Forum", forum_mode="questions", add_menu=False):
|
||||
forum_id = request.env['forum.forum'].create({'name': forum_name, 'mode': forum_mode})
|
||||
if add_menu:
|
||||
request.env['website.menu'].create({
|
||||
'name': forum_name,
|
||||
|
||||
@@ -30,6 +30,11 @@ class Forum(models.Model):
|
||||
# description and use
|
||||
name = fields.Char('Forum Name', required=True, translate=True)
|
||||
sequence = fields.Integer('Sequence', default=1)
|
||||
mode = fields.Selection([
|
||||
('questions', 'Questions'),
|
||||
('discussions', 'Discussions')],
|
||||
string='Forum Mode', required=True, default='questions',
|
||||
help='Questions mode: only one answer allowed\n Discussions mode: multiple answers allowed')
|
||||
active = fields.Boolean(default=True)
|
||||
faq = fields.Html('Guidelines', default=_get_default_faq, translate=html_translate, sanitize=False)
|
||||
description = fields.Text(
|
||||
@@ -64,7 +69,7 @@ class Forum(models.Model):
|
||||
('vote_count desc', 'Most Voted'),
|
||||
('relevancy desc', 'Relevance'),
|
||||
('child_count desc', 'Answered')],
|
||||
string='Default Order', required=True, default='write_date desc')
|
||||
string='Default', required=True, default='write_date desc')
|
||||
relevancy_post_vote = fields.Float('First Relevance Parameter', default=0.8, help="This formula is used in order to sort by relevance. The variable 'votes' represents number of votes for a post, and 'days' is number of days since the post creation")
|
||||
relevancy_time_decay = fields.Float('Second Relevance Parameter', default=1.8)
|
||||
allow_bump = fields.Boolean('Allow Bump', default=True,
|
||||
|
||||
@@ -3,10 +3,61 @@ odoo.define('website_forum.editor', function (require) {
|
||||
|
||||
var core = require('web.core');
|
||||
var WebsiteNewMenu = require('website.newMenu');
|
||||
var wUtils = require('website.utils');
|
||||
var Dialog = require('web.Dialog');
|
||||
|
||||
var _t = core._t;
|
||||
|
||||
var ForumCreateDialog = Dialog.extend({
|
||||
xmlDependencies: Dialog.prototype.xmlDependencies.concat(
|
||||
['/website_forum/static/src/xml/website_forum_templates.xml']
|
||||
),
|
||||
template: 'website_forum.add_new_forum',
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @param {Object} parent
|
||||
* @param {Object} options
|
||||
*/
|
||||
init: function (parent, options) {
|
||||
options = _.defaults(options || {}, {
|
||||
title: _t("New Forum"),
|
||||
size: 'medium',
|
||||
buttons: [
|
||||
{
|
||||
text: _t("Create"),
|
||||
classes: 'btn-primary',
|
||||
click: this.onCreateClick.bind(this),
|
||||
},
|
||||
{
|
||||
text: _t("Discard"),
|
||||
close: true
|
||||
},
|
||||
]
|
||||
});
|
||||
this._super(parent, options);
|
||||
},
|
||||
onCreateClick: function () {
|
||||
var $dialog = this.$el;
|
||||
var forumName = $dialog.find('input[name=forum_name]').val();;
|
||||
if (!forumName) {
|
||||
return;
|
||||
}
|
||||
var addMenu = ($dialog.find('input[type="checkbox"]').is(':checked'));
|
||||
var forumMode = $dialog.find('input[type="radio"]:checked').val();
|
||||
return this._rpc({
|
||||
route: '/forum/new',
|
||||
params: {
|
||||
forum_name: forumName,
|
||||
forum_mode: forumMode,
|
||||
add_menu: addMenu || "",
|
||||
},
|
||||
}).then(function (url) {
|
||||
window.location.href = url;
|
||||
return new Promise(function () {});
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
WebsiteNewMenu.include({
|
||||
actions: _.extend({}, WebsiteNewMenu.prototype.actions || {}, {
|
||||
new_forum: '_createNewForum',
|
||||
@@ -25,41 +76,12 @@ WebsiteNewMenu.include({
|
||||
*/
|
||||
_createNewForum: function () {
|
||||
var self = this;
|
||||
return wUtils.prompt({
|
||||
id: "editor_new_forum",
|
||||
window_title: _t("New Forum"),
|
||||
input: _t("Forum Name"),
|
||||
init: function () {
|
||||
var $group = this.$dialog.find("div.form-group");
|
||||
$group.removeClass("mb0");
|
||||
|
||||
var $add = $(
|
||||
'<div class="form-group mb0">'+
|
||||
'<label class="offset-md-3 col-md-9 text-left">'+
|
||||
' <input type="checkbox" required="required"/> '+
|
||||
'</label>'+
|
||||
'</div>');
|
||||
$add.find('label').append(_t("Add to menu"));
|
||||
$group.after($add);
|
||||
}
|
||||
}).then(function (result) {
|
||||
var forum_name = result.val;
|
||||
var $dialog = result.dialog;
|
||||
if (!forum_name) {
|
||||
return;
|
||||
}
|
||||
var add_menu = ($dialog.find('input[type="checkbox"]').is(':checked'));
|
||||
return self._rpc({
|
||||
route: '/forum/new',
|
||||
params: {
|
||||
forum_name: forum_name,
|
||||
add_menu: add_menu || "",
|
||||
},
|
||||
}).then(function (url) {
|
||||
window.location.href = url;
|
||||
return new Promise(function () {});
|
||||
});
|
||||
var def = new Promise(function (resolve) {
|
||||
var dialog = new ForumCreateDialog(self, {});
|
||||
dialog.open();
|
||||
dialog.on('closed', self, resolve);
|
||||
});
|
||||
return def;
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="website_forum.add_new_forum">
|
||||
<form id="editor_new_forum">
|
||||
<div class="form-group row">
|
||||
<label for="page-name" class="col-md-4 col-form-label">Forum Name:</label>
|
||||
<div class="col-md-8">
|
||||
<input type="text" name="forum_name" class="form-control" required="required"/>
|
||||
<div class="custom-control custom-checkbox mt-2">
|
||||
<input type="checkbox" class="custom-control-input" id="add_to_menu" required="required"/>
|
||||
<label class="custom-control-label" for="add_to_menu">Add to menu</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group row mt-2">
|
||||
<label class="col-md-4 col-form-label">Forum Mode:</label>
|
||||
<div class="col-md-8">
|
||||
<div class="custom-control custom-radio">
|
||||
<input type="radio" id="questions" name="mode" class="custom-control-input" value="questions" checked="checked"/>
|
||||
<label class="custom-control-label" for="questions">Questions and Answers</label>
|
||||
</div>
|
||||
<div class="custom-control custom-radio">
|
||||
<input type="radio" id="discussions" name="mode" class="custom-control-input" value="discussions"/>
|
||||
<label class="custom-control-label" for="discussions">Discussions</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -391,3 +391,49 @@ class TestForum(TestForumCommon):
|
||||
def test_unlink_post_all(self):
|
||||
self.user_portal.karma = KARMA['unlink_all']
|
||||
self.post.with_user(self.user_portal).unlink()
|
||||
|
||||
def test_forum_mode_questions(self):
|
||||
Forum = self.env['forum.forum']
|
||||
forum_questions = Forum.create({
|
||||
'name': 'Questions Forum',
|
||||
'mode': 'questions',
|
||||
'active': True
|
||||
})
|
||||
Post = self.env['forum.post']
|
||||
questions_post = Post.create({
|
||||
'name': 'My First Post',
|
||||
'forum_id': forum_questions.id,
|
||||
'parent_id': self.post.id,
|
||||
})
|
||||
answer_to_questions_post = Post.create({
|
||||
'name': 'This is an answer',
|
||||
'forum_id': forum_questions.id,
|
||||
'parent_id': questions_post.id,
|
||||
})
|
||||
self.assertEqual(
|
||||
not questions_post.uid_has_answered or questions_post.forum_id.mode == 'discussions', False)
|
||||
self.assertEqual(
|
||||
questions_post.uid_has_answered and questions_post.forum_id.mode == 'questions', True)
|
||||
|
||||
def test_forum_mode_discussions(self):
|
||||
Forum = self.env['forum.forum']
|
||||
forum_discussions = Forum.create({
|
||||
'name': 'Discussions Forum',
|
||||
'mode': 'discussions',
|
||||
'active': True
|
||||
})
|
||||
Post = self.env['forum.post']
|
||||
discussions_post = Post.create({
|
||||
'name': 'My First Post',
|
||||
'forum_id': forum_discussions.id,
|
||||
'parent_id': self.post.id,
|
||||
})
|
||||
answer_to_discussions_post = Post.create({
|
||||
'name': 'This is an answer',
|
||||
'forum_id': forum_discussions.id,
|
||||
'parent_id': discussions_post.id,
|
||||
})
|
||||
self.assertEqual(
|
||||
not discussions_post.uid_has_answered or discussions_post.forum_id.mode == 'discussions', True)
|
||||
self.assertEqual(
|
||||
discussions_post.uid_has_answered and discussions_post.forum_id.mode == 'questions', False)
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
<field name="arch" type="xml">
|
||||
<form string="Forum">
|
||||
<sheet>
|
||||
<field name="active" invisible="1"/>
|
||||
<widget name="web_ribbon" text="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
<field name="image_1920" widget="image" options="{'preview_image': 'image_128'}" class="oe_avatar"/>
|
||||
<div class="oe_title">
|
||||
@@ -37,16 +38,15 @@
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="description"/>
|
||||
<field name="mode" widget="radio" required="True"/>
|
||||
<field name="website_id" options="{'no_create': True}" groups="website.group_multi_website"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Options">
|
||||
<group string="Orders">
|
||||
<group string="Order">
|
||||
<field name="default_order"/>
|
||||
<label for="relevancy_post_vote" string="Relevance Computation" groups="base.group_no_one"/>
|
||||
<div groups="base.group_no_one" class="o_row">
|
||||
<label for="relevancy_post_vote" string="Relevance Computation" groups="base.group_no_one" attrs="{'invisible':[('default_order','!=','relevancy desc')]}"/>
|
||||
<div groups="base.group_no_one" class="o_row" attrs="{'invisible':[('default_order','!=','relevancy desc')]}">
|
||||
(votes - 1) ** <field name="relevancy_post_vote"/> / (days + 2) ** <field name="relevancy_time_decay"/>
|
||||
</div>
|
||||
</group>
|
||||
@@ -97,6 +97,9 @@
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
<group>
|
||||
<field name="description"/>
|
||||
</group>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids" widget="mail_followers" groups="base.group_user"/>
|
||||
|
||||
@@ -830,10 +830,10 @@
|
||||
</t>
|
||||
</div>
|
||||
<div id="post_reply"
|
||||
t-if="not question.uid_has_answered and question.state != 'close' and question.active != False and question.can_answer">
|
||||
t-if="(not question.uid_has_answered or question.forum_id.mode == 'discussions') and question.state != 'close' and question.active != False and question.can_answer">
|
||||
<t t-call="website_forum.post_answer"/>
|
||||
</div>
|
||||
<div t-if="question.uid_has_answered" class="mb16">
|
||||
<div t-if="question.uid_has_answered and question.forum_id.mode == 'questions'" class="mb16">
|
||||
<a role="button" class="btn btn-primary" t-attf-href="/forum/#{slug(forum)}/question/#{slug(question)}/edit_answer">Edit Your Answer</a>
|
||||
<span class="text-muted">(only one answer per question is allowed)</span>
|
||||
</div>
|
||||
@@ -852,10 +852,10 @@
|
||||
<div class="col-1">
|
||||
<t t-call="website_forum.vote">
|
||||
<t t-set="post" t-value="answer"/>
|
||||
<div t-if="question.can_answer" class="mt4">
|
||||
<div t-if="question.can_answer and question.forum_id.mode == 'questions'" class="mt4">
|
||||
<a t-attf-class="accept_answer fa fa-2x fa-check-circle no-decoration #{answer.is_correct and 'oe_answer_true' or 'oe_answer_false'} #{not answer.can_accept and 'karma_required' or ''}"
|
||||
t-attf-data-karma="#{answer.karma_accept}"
|
||||
aria-label="Send answer" title="Send answer"
|
||||
aria-label="Accept this answer as the best" title="Accept this answer as the best"
|
||||
t-attf-data-href="/forum/#{slug(question.forum_id)}/post/#{slug(answer)}/toggle_correct"
|
||||
t-if="not question.has_validated_answer"/>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user