From 8d09178b4292369ddee36e8ca230ab005c277826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien=20Warnon?= Date: Mon, 23 Mar 2020 09:01:40 +0000 Subject: [PATCH] [FIX] survey: correctly handle "free text sections" in surveys and sessions We now have a way to display "free text sections" during the survey flow. (Since 5b74f54396f6cf8986494e4632d0ea1b9940619b ) However, the behavior during survey sessions was not optimal: - Attendees could click on "submit" and it would raise an error - The section description was not displayed on the host screen - The section description was never the "current question" of the session of it was the first item of the question_and_page_ids This commit fixes all those points to have a nice session flow. While the host is explaining the section description to the attendees, they get a waiting message on their screen. In addition, we fixed the display to avoid showing pages that lack a description, and we reworked the '_get_pages_or_questions' method to have more meaningful and readable cases for every layouts. LINKS PR #48442 Task 2208574 --- addons/survey/controllers/main.py | 3 +- .../controllers/survey_session_manage.py | 2 ++ addons/survey/models/survey_survey.py | 33 +++++++++++-------- addons/survey/static/src/js/survey_form.js | 8 ++++- addons/survey/views/survey_templates.xml | 5 +++ .../survey_templates_user_input_session.xml | 1 + 6 files changed, 37 insertions(+), 15 deletions(-) diff --git a/addons/survey/controllers/main.py b/addons/survey/controllers/main.py index 3b9b29a9036..ee0017672fb 100644 --- a/addons/survey/controllers/main.py +++ b/addons/survey/controllers/main.py @@ -13,7 +13,7 @@ from odoo.addons.base.models.ir_ui_view import keep_query from odoo.exceptions import UserError from odoo.http import request, content_disposition from odoo.osv import expression -from odoo.tools import format_datetime, format_date +from odoo.tools import format_datetime, format_date, is_html_empty from odoo.addons.web.controllers.main import Binary @@ -266,6 +266,7 @@ class Survey(http.Controller): - previous_page_id : come from the breadcrumb or the back button and force the next questions to load to be the previous ones. """ data = { + 'is_html_empty': is_html_empty, 'survey': survey_sudo, 'answer': answer_sudo, 'breadcrumb_pages': [{ diff --git a/addons/survey/controllers/survey_session_manage.py b/addons/survey/controllers/survey_session_manage.py index ad7154b8753..b93a31d94ff 100644 --- a/addons/survey/controllers/survey_session_manage.py +++ b/addons/survey/controllers/survey_session_manage.py @@ -10,6 +10,7 @@ from werkzeug.urls import url_join from odoo import fields, http from odoo.http import request +from odoo.tools import is_html_empty class UserInputSession(http.Controller): @@ -165,6 +166,7 @@ class UserInputSession(http.Controller): } for line in full_statistics.get('table_data', request.env['survey.user_input.line'])[:100]] return { + 'is_html_empty': is_html_empty, 'question_statistics_graph': full_statistics.get('graph_data'), 'input_line_values': input_line_values, 'answers_validity': json.dumps(answers_validity), diff --git a/addons/survey/models/survey_survey.py b/addons/survey/models/survey_survey.py index 52ae373b22f..da8e1670fad 100644 --- a/addons/survey/models/survey_survey.py +++ b/addons/survey/models/survey_survey.py @@ -9,6 +9,7 @@ import werkzeug from odoo import api, exceptions, fields, models, _ from odoo.exceptions import AccessError from odoo.osv import expression +from odoo.tools import is_html_empty class Survey(models.Model): @@ -437,12 +438,21 @@ class Survey(models.Model): @api.model def _get_pages_or_questions(self, user_input): - if self.questions_layout == 'one_page': - return self.env['survey.question'] - elif self.questions_layout == 'page_per_question' and self.questions_selection == 'random': - return user_input.predefined_question_ids - else: - return self.question_and_page_ids if self.questions_layout == 'page_per_question' else self.page_ids + """ Returns the pages or questions (depending on the layout) that will be shown + to the user taking the survey. + In 'page_per_question' layout, we also want to show pages that have a description. """ + + result = self.env['survey.question'] + if self.questions_layout == 'page_per_section': + result = self.page_ids + elif self.questions_layout == 'page_per_question': + if self.questions_selection == 'random': + result = user_input.predefined_question_ids + else: + result = self.question_and_page_ids.filtered( + lambda question: not question.is_page or not is_html_empty(question.description)) + + return result def _get_next_page_or_question(self, user_input, page_or_question_id, go_back=False): """ @@ -580,13 +590,10 @@ class Survey(models.Model): if not self.question_ids or not self.env.user.has_group('survey.group_survey_user'): return - if not self.session_question_id: - next_question = self.question_ids[0] - else: - most_voted_answers = self._get_session_most_voted_answers() - next_question = self._get_next_page_or_question(most_voted_answers, self.session_question_id.id) - - return next_question + most_voted_answers = self._get_session_most_voted_answers() + return self._get_next_page_or_question( + most_voted_answers, + self.session_question_id.id if self.session_question_id else 0) def _get_session_most_voted_answers(self): """ In sessions of survey that has conditional questions, as the survey is passed at the same time by diff --git a/addons/survey/static/src/js/survey_form.js b/addons/survey/static/src/js/survey_form.js index 9e0d82a88eb..c9e9d5942a3 100644 --- a/addons/survey/static/src/js/survey_form.js +++ b/addons/survey/static/src/js/survey_form.js @@ -51,7 +51,7 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ $(document).on('keypress', self._onKeyPress.bind(self)); } if (self.options.sessionInProgress && - (self.options.isStartScreen || self.options.hasAnswered)) { + (self.options.isStartScreen || self.options.hasAnswered || self.options.isPageDescription)) { self.preventEnterSubmit = true; } self._initSessionManagement(); @@ -428,6 +428,12 @@ publicWidget.registry.SurveyFormWidget = publicWidget.Widget.extend({ } self._initChoiceItems(); self._initTextArea(); + + if (this.options.sessionInProgress && this.$('.o_survey_form_content_data').data('isPageDescription')) { + // prevent enter submit if we're on a page description (there is nothing to submit) + this.preventEnterSubmit = true; + } + this.$('.o_survey_form_content').fadeIn(this.fadeInOutDelay); $("html, body").animate({ scrollTop: 0 }, this.fadeInOutDelay); self._focusOnFirstInput(); diff --git a/addons/survey/views/survey_templates.xml b/addons/survey/views/survey_templates.xml index 7984694941b..4cc54cca006 100644 --- a/addons/survey/views/survey_templates.xml +++ b/addons/survey/views/survey_templates.xml @@ -74,6 +74,7 @@ t-att-data-is-start-screen="answer.state == 'new'" t-att-data-readonly="survey_form_readonly" t-att-data-has-answered="bool(has_answered)" + t-att-data-is-page-description="bool(question and question.is_page and not is_html_empty(question.description))" t-att-data-questions-layout="survey.questions_layout" t-att-data-triggered-questions-by-answer="json.dumps(triggered_questions_by_answer)" t-att-data-selected-answers="json.dumps(selected_answers)"> @@ -139,6 +140,7 @@
@@ -192,6 +194,9 @@
Sorry, you have not been fast enough.
We have registered your answer! Please wait for the host to go to the next question.
+ +
Pay attention to the host screen until the next question.
+
diff --git a/addons/survey/views/survey_templates_user_input_session.xml b/addons/survey/views/survey_templates_user_input_session.xml index 1d1a91b368f..19dbddc76f2 100644 --- a/addons/survey/views/survey_templates_user_input_session.xml +++ b/addons/survey/views/survey_templates_user_input_session.xml @@ -112,6 +112,7 @@
+

Waiting for attendees...