From f9c2716b3e76ce9bc36d87d69a37a897391c9cdb Mon Sep 17 00:00:00 2001 From: Andrea Ulliana <aul@odoo.com> Date: Thu, 13 Jun 2019 10:48:12 +0000 Subject: [PATCH] [IMP] website_forum: bring forum modes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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> --- addons/website/static/src/xml/website.xml | 2 +- addons/website_forum/controllers/main.py | 4 +- addons/website_forum/models/forum.py | 7 +- .../static/src/js/website_forum.editor.js | 92 ++++++++++++------- .../src/xml/website_forum_templates.xml | 30 ++++++ addons/website_forum/tests/test_forum.py | 46 ++++++++++ addons/website_forum/views/forum.xml | 13 ++- addons/website_forum/views/website_forum.xml | 8 +- 8 files changed, 154 insertions(+), 48 deletions(-) create mode 100644 addons/website_forum/static/src/xml/website_forum_templates.xml diff --git a/addons/website/static/src/xml/website.xml b/addons/website/static/src/xml/website.xml index 5f85f6d5d096..61528303768f 100644 --- a/addons/website/static/src/xml/website.xml +++ b/addons/website/static/src/xml/website.xml @@ -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"> diff --git a/addons/website_forum/controllers/main.py b/addons/website_forum/controllers/main.py index 272e119f94ca..dd247fbca147 100644 --- a/addons/website_forum/controllers/main.py +++ b/addons/website_forum/controllers/main.py @@ -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, diff --git a/addons/website_forum/models/forum.py b/addons/website_forum/models/forum.py index 8056381da960..2092008b5ca2 100644 --- a/addons/website_forum/models/forum.py +++ b/addons/website_forum/models/forum.py @@ -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, diff --git a/addons/website_forum/static/src/js/website_forum.editor.js b/addons/website_forum/static/src/js/website_forum.editor.js index e2b19ba681f3..2f6d61791c8a 100644 --- a/addons/website_forum/static/src/js/website_forum.editor.js +++ b/addons/website_forum/static/src/js/website_forum.editor.js @@ -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; }, }); }); diff --git a/addons/website_forum/static/src/xml/website_forum_templates.xml b/addons/website_forum/static/src/xml/website_forum_templates.xml new file mode 100644 index 000000000000..0d3ce2407d0b --- /dev/null +++ b/addons/website_forum/static/src/xml/website_forum_templates.xml @@ -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> diff --git a/addons/website_forum/tests/test_forum.py b/addons/website_forum/tests/test_forum.py index ab05ff003928..f52deea315a4 100644 --- a/addons/website_forum/tests/test_forum.py +++ b/addons/website_forum/tests/test_forum.py @@ -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) diff --git a/addons/website_forum/views/forum.xml b/addons/website_forum/views/forum.xml index 1c46079b5187..4e8cfc61e635 100644 --- a/addons/website_forum/views/forum.xml +++ b/addons/website_forum/views/forum.xml @@ -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"/> diff --git a/addons/website_forum/views/website_forum.xml b/addons/website_forum/views/website_forum.xml index e5737e037d1c..15ad892fa10b 100644 --- a/addons/website_forum/views/website_forum.xml +++ b/addons/website_forum/views/website_forum.xml @@ -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> -- GitLab