From d981d7efc152c129e4212bb1752dc45ce5d74841 Mon Sep 17 00:00:00 2001 From: Adrien Schoffeniels Date: Thu, 19 May 2022 06:18:52 +0000 Subject: [PATCH 1/3] [IMP] survey: improve survey samples accessibility PURPOSE: This commit improves the accessibility of the survey samples when no records are shown. SPECS Remove the modal used to show the samples and show them on the empty screen instead. When no survey exists, the user gets the proposition of trying survey samples. Previously, the user had to click on a button to open a modal showing the different samples. Now, the samples are shown in the empty screen directly. If the user does not have the rights to create surveys, the "Try It" buttons are removed from the NoContentHelper. Task-2794884 Part-of: odoo/odoo#87326 --- .../survey/static/src/js/survey_renderers.js | 73 ++++++++++--------- .../static/src/xml/survey_sample_modal.xml | 37 ---------- addons/survey/views/survey_survey_views.xml | 57 ++++++++++++--- 3 files changed, 86 insertions(+), 81 deletions(-) delete mode 100644 addons/survey/static/src/xml/survey_sample_modal.xml diff --git a/addons/survey/static/src/js/survey_renderers.js b/addons/survey/static/src/js/survey_renderers.js index 7db75e22549..b156df21921 100644 --- a/addons/survey/static/src/js/survey_renderers.js +++ b/addons/survey/static/src/js/survey_renderers.js @@ -1,55 +1,58 @@ /** @odoo-module */ -import Dialog from 'web.Dialog'; import KanbanRenderer from 'web.KanbanRenderer'; import ListRenderer from 'web.ListRenderer'; -import { qweb as QWeb, _t } from 'web.core'; +import { Markup } from 'web.utils'; + +const SurveySampleMixin = { -const SurveySampleModalMixin = { /** - * Opens a dialog allowing the user to load a sample survey - * We currently have 3 different samples to load (and one "tile" to click on - * for each in the modal). + * @override + */ + _render: function () { + // Remove "Try It" buttons of the no content helper if user can not create surveys + if (!this.activeActions.create) { + this.noContentHelp = Markup(this.noContentHelp.replaceAll( + 'Try It', + '' + )); + } + this.isLoadingSample = false; + this._super.apply(this, arguments); + }, + + /** + * Load and show the sample survey related to the clicked element, + * when there is no survey to display. + * We currently have 3 different samples to load: * - Sample Feedback Form * - Sample Certification * - Sample Live Presentation + * + * @private + * @param {Event} ev */ - _onOpenSurveySampleModalClick: function () { - const $content = $(QWeb.render('survey.survey_sample_modal_body')); - $content.find('.o_survey_sample_tile').each((_index, tile) => { - const $tile = $(tile); - $tile.on('click', async () => { - const surveySampleAction = await this._rpc({ - model: 'survey.survey', - method: $tile.data('action'), - }); - this.do_action(surveySampleAction); - }); - }); - const dialog = new Dialog(this, { - title: _t('Load a Survey'), - $content: $content, - renderFooter: false, - }); - dialog.open(); + _loadSample: function (ev) { + // Prevent loading multiple samples if double clicked + if (!this.isLoadingSample && this.activeActions.create) { + this.isLoadingSample = true; + this.do_action(this._rpc({ + model: 'survey.survey', + method: $(ev.target).closest('.o_survey_sample_container').attr('action'), + })); + } }, -} +}; -const SurveyKanbanRenderer = KanbanRenderer.extend(SurveySampleModalMixin, { - xmlDependencies: (KanbanRenderer.prototype.xmlDependencies || []).concat([ - 'survey/static/src/xml/survey_sample_modal.xml', - ]), +const SurveyKanbanRenderer = KanbanRenderer.extend(SurveySampleMixin, { events: _.extend({}, KanbanRenderer.prototype.events, { - 'click .o_survey_open_sample_modal': '_onOpenSurveySampleModalClick', + 'click .o_survey_load_sample': '_loadSample', }), }); -const SurveyListRenderer = ListRenderer.extend(SurveySampleModalMixin, { - xmlDependencies: (ListRenderer.prototype.xmlDependencies || []).concat([ - 'survey/static/src/xml/survey_sample_modal.xml', - ]), +const SurveyListRenderer = ListRenderer.extend(SurveySampleMixin, { events: _.extend({}, ListRenderer.prototype.events, { - 'click .o_survey_open_sample_modal': '_onOpenSurveySampleModalClick', + 'click .o_survey_load_sample': '_loadSample', }), }); diff --git a/addons/survey/static/src/xml/survey_sample_modal.xml b/addons/survey/static/src/xml/survey_sample_modal.xml deleted file mode 100644 index 9416d0b7a2e..00000000000 --- a/addons/survey/static/src/xml/survey_sample_modal.xml +++ /dev/null @@ -1,37 +0,0 @@ - - - -
-
-
- -
- Gather feedbacks from your employees and customers. -
-
-
Feedback Form
-
-
-
- -
- Handle quiz & certifications online. -
-
-
Certification
-
-
-
- -
- Add some fun to your presentations by sharing questions live. -
-
-
Live Presentation
-
-
-
-
diff --git a/addons/survey/views/survey_survey_views.xml b/addons/survey/views/survey_survey_views.xml index b3178cfaadd..530951427ee 100644 --- a/addons/survey/views/survey_survey_views.xml +++ b/addons/survey/views/survey_survey_views.xml @@ -180,7 +180,7 @@ survey.survey.view.tree survey.survey - + @@ -202,7 +202,7 @@ survey.survey.view.kanban survey.survey - + @@ -399,13 +399,52 @@ survey.survey kanban,tree,form,activity -

- Create a Survey -

- Surveys can serve many purposes: collect customer feedback, gather market insights, structure employee evaluations, test and certify resellers, support a live presentation, ... -

- Let's create one and share it! Not sure where to start? Load a survey -

+
+
+
+ +
+ Gather feedbacks from your employees and customers. +
+
+ + Try It +
+
+
+ +
+ Handle quiz & certifications online. +
+
+ + Try It +
+
+
+ +
+ Add some fun to your presentations by sharing questions live. +
+
+ + Try It +
+
+

+ Create a Survey +

+

+ Surveys can serve many purposes: collect customer feedback, gather market insights, structure employee evaluations, test and certify resellers, support a live presentation, ... +

+ Not sure where to start? Try a sample Survey! +

From 24e8e3adc39bae4f2549e9b6ded42acb51c5a47c Mon Sep 17 00:00:00 2001 From: Adrien Schoffeniels Date: Thu, 19 May 2022 06:21:11 +0000 Subject: [PATCH 2/3] [IMP] survey: revamp onboarding data & test surveys integration PURPOSE: This commit revamps the onboarding data and slightly modifies the integration of test surveys and related filters. SPECS - Revamp sample surveys data: Considering this is the data we want to push forward, it needs to be as relevant as possible while being "light" for the db. - Consider completed test surveys as completed surveys: Most people expect to see the test the just did counted in the completed surveys counter in the survey view. The filter excluding the tests surveys has therefore also been removed from the participation view. - Rename the filters related to the test surveys: "Tests Only" and "Exclude Tests" are more straight to the point than "Test Entries" and "Exclude Test Entries". - Rename "answer(s)(ed)" at some locations: "answer" and its various forms are used too often, which sometimes makes it hard to understand who is who. Therefore, we replaced some of them with synonyms. - Set "one page per question" as the default layout. Added the "one_page" layout in some tests for which the layout was not set. Task-2794884 Part-of: odoo/odoo#87326 --- addons/survey/models/survey_survey.py | 17 +- .../survey/models/survey_survey_template.py | 202 ++++++++---------- .../tests/test_survey_ui_certification.py | 1 + addons/survey/views/survey_survey_views.xml | 2 +- .../views/survey_templates_management.xml | 4 +- .../views/survey_templates_statistics.xml | 2 +- addons/survey/views/survey_user_views.xml | 4 +- .../tests/test_ui_wslides.py | 1 + 8 files changed, 108 insertions(+), 125 deletions(-) diff --git a/addons/survey/models/survey_survey.py b/addons/survey/models/survey_survey.py index f9030b730d0..e97f9900f4a 100644 --- a/addons/survey/models/survey_survey.py +++ b/addons/survey/models/survey_survey.py @@ -76,10 +76,10 @@ class Survey(models.Model): question_ids = fields.One2many('survey.question', string='Questions', compute="_compute_page_and_question_ids") question_count = fields.Integer('# Questions', compute="_compute_page_and_question_ids") questions_layout = fields.Selection([ - ('one_page', 'One page with all the questions'), + ('page_per_question', 'One page per question'), ('page_per_section', 'One page per section'), - ('page_per_question', 'One page per question')], - string="Pagination", required=True, default='one_page') + ('one_page', 'One page with all the questions')], + string="Pagination", required=True, default='page_per_question') questions_selection = fields.Selection([ ('all', 'All questions'), ('random', 'Randomized per Section')], @@ -200,7 +200,7 @@ class Survey(models.Model): } stat = dict((cid, dict(default_vals, answer_score_avg_total=0.0)) for cid in self.ids) UserInput = self.env['survey.user_input'] - base_domain = ['&', ('survey_id', 'in', self.ids), ('test_entry', '!=', True)] + base_domain = [('survey_id', 'in', self.ids)] read_group_res = UserInput._read_group(base_domain, ['survey_id', 'state'], ['survey_id', 'state', 'scoring_percentage', 'scoring_success'], lazy=False) for item in read_group_res: @@ -961,8 +961,7 @@ class Survey(models.Model): action = self.env['ir.actions.act_window']._for_xml_id('survey.action_survey_user_input') ctx = dict(self.env.context) ctx.update({'search_default_survey_id': self.ids[0], - 'search_default_completed': 1, - 'search_default_not_test': 1}) + 'search_default_completed': 1}) action['context'] = ctx return action @@ -970,16 +969,14 @@ class Survey(models.Model): action = self.env['ir.actions.act_window']._for_xml_id('survey.action_survey_user_input') ctx = dict(self.env.context) ctx.update({'search_default_survey_id': self.ids[0], - 'search_default_scoring_success': 1, - 'search_default_not_test': 1}) + 'search_default_scoring_success': 1}) action['context'] = ctx return action def action_survey_user_input(self): action = self.env['ir.actions.act_window']._for_xml_id('survey.action_survey_user_input') ctx = dict(self.env.context) - ctx.update({'search_default_survey_id': self.ids[0], - 'search_default_not_test': 1}) + ctx.update({'search_default_survey_id': self.ids[0]}) action['context'] = ctx return action diff --git a/addons/survey/models/survey_survey_template.py b/addons/survey/models/survey_survey_template.py index 82fde7ede6b..289257e108c 100644 --- a/addons/survey/models/survey_survey_template.py +++ b/addons/survey/models/survey_survey_template.py @@ -18,78 +18,67 @@ class SurveyTemplate(models.Model): @api.model def action_load_sample_feedback_form(self): + company = self.env.user.company_id.name return self.env['survey.survey'].create({ 'title': _('Feedback Form'), - 'description': _('What do you think of our new eShop? Let us hear your voice!'), - 'description_done': _('Thank you very much for your feedback. We at MyCompany value your opinion!'), + 'description': '
'.join([ + _('Please complete this very short survey to let us know how satisfied your are with our products.'), + _('Your responses will help us improve our product range to serve you even better.') + ]), + 'description_done': _('Thank you very much for your feedback. We at %s value your opinion very highly!', company), 'progression_mode': 'number', - 'questions_layout': 'one_page', + 'questions_layout': 'page_per_question', 'question_and_page_ids': [ (0, 0, { # survey.question - 'title': _('About you'), - 'is_page': True, - 'question_type': False - }), - (0, 0, { # survey.question - 'title': _('How frequently do you buy products online?'), + 'title': _('How frequently do you use our products?'), 'question_type': 'simple_choice', + 'constr_mandatory': True, 'suggested_answer_ids': [ (0, 0, { # survey.question.answer - 'value': _('Once a day') + 'value': _('Often (1-3 times per week)') }), (0, 0, { # survey.question.answer - 'value': _('Once a week') + 'value': _('Rarely (1-3 times per month)') }), (0, 0, { # survey.question.answer - 'value': _('Once a month') - }), - (0, 0, { # survey.question.answer - 'value': _('Once a year') - }), - (0, 0, { # survey.question.answer - 'value': _('Never') + 'value': _('Never (less than once a month)') }) ] }), (0, 0, { # survey.question - 'title': _('How many times did you order products on our website?'), - 'question_type': 'numerical_box' + 'title': _('How many orders did you pass during the last 6 months?'), + 'question_type': 'numerical_box', }), (0, 0, { # survey.question - 'title': _('About our ecommerce'), - 'is_page': True, - 'question_type': False - }), - (0, 0, { # survey.question - 'title': _('What do you think about our new eCommerce?'), + 'title': _('How likely are you to recommend the following products to a friend?'), 'question_type': 'matrix', 'matrix_subtype': 'simple', 'suggested_answer_ids': [ (0, 0, { # survey.question.answer - 'value': _('Strongly disagree') + 'value': _('Very Unlikely') }), (0, 0, { # survey.question.answer - 'value': _('Disagree') + 'value': _('Unlikely') }), (0, 0, { # survey.question.answer 'value': _('Neutral') }), (0, 0, { # survey.question.answer - 'value': _('Agree') + 'value': _('Likely') }), (0, 0, { # survey.question.answer - 'value': _('Strongly agree') + 'value': _('Very Likely') }) ], 'matrix_row_ids': [ (0, 0, { # survey.question.answer - 'value': _('The new layout and design is fresh and up-to-date') + 'value': _('Red Pen') }), (0, 0, { # survey.question.answer - 'value': _('It is easy to find the product that I want') + 'value': _('Blue Pen') }), (0, 0, { # survey.question.answer - 'value': _('The tool to compare the products is useful to make a choice') + 'value': _('Yellow Pen') }) ] }) @@ -109,8 +98,11 @@ class SurveyTemplate(models.Model): 'progression_mode': 'number', 'scoring_type': 'scoring_without_answers', 'users_can_go_back': True, - 'description': '
'.join([ - _('Welcome to the History certification. You will receive 2 random questions.'), + 'description': ''.join([ + _('Welcome to this Odoo certification. You will receive 2 random questions out of a pool of 3.'), + '(', + _('Cheating on your neighbors will not help!'), + ' 😁).
', _('Good luck!') ]), 'description_done': _('Thank you. We will contact you soon.'), @@ -118,68 +110,65 @@ class SurveyTemplate(models.Model): 'questions_selection': 'random', 'question_and_page_ids': [ (0, 0, { # survey.question - 'title': _('History'), + 'title': _('Odoo Certification'), 'is_page': True, 'question_type': False, 'random_questions_count': 2 }), (0, 0, { # survey.question - 'title': _('When did Genghis Khan die?'), + 'title': _('What does "ODOO" stand for?'), 'question_type': 'simple_choice', 'suggested_answer_ids': [ (0, 0, { # survey.question.answer - 'value': _('1227'), + 'value': _('It\'s a Belgian word for "Management"') + }), + (0, 0, { # survey.question.answer + 'value': _('Object-Directed Open Organization') + }), + (0, 0, { # survey.question.answer + 'value': _('Organizational Development for Operation Officers') + }), + (0, 0, { # survey.question.answer + 'value': _('It does not mean anything specific'), + 'is_correct': True, + 'answer_score': 10 + }), + ] + }), + (0, 0, { # survey.question + 'title': _('On Survey questions, one can define "placeholders". But what are they for?'), + 'question_type': 'simple_choice', + 'suggested_answer_ids': [ + (0, 0, { # survey.question.answer + 'value': _('They are a default answer, used if the participant skips the question') + }), + (0, 0, { # survey.question.answer + 'value': _('It is a small bit of text, displayed to help participants answer'), 'is_correct': True, 'answer_score': 10 }), (0, 0, { # survey.question.answer - 'value': _('1324') - }), - (0, 0, { # survey.question.answer - 'value': _('1055') + 'value': _('They are technical parameters that guarantees the responsiveness of the page') }) ] }), (0, 0, { # survey.question - 'title': _('Who is the architect of the Great Pyramid of Giza ?'), + 'title': _('What does one need to get to pass an Odoo Survey?'), 'question_type': 'simple_choice', 'suggested_answer_ids': [ (0, 0, { # survey.question.answer - 'value': _('Imhotep') - }), - (0, 0, { # survey.question.answer - 'value': _('Amenhotep') - }), - (0, 0, { # survey.question.answer - 'value': _('Hemiunu'), + 'value': _('It is an option that can be different for each Survey'), 'is_correct': True, 'answer_score': 10 }), (0, 0, { # survey.question.answer - 'value': _('Papyrus') + 'value': _('One needs to get 50% of the total score') + }), + (0, 0, { # survey.question.answer + 'value': _('One needs to answer at least half the questions correctly') }) ] }), - (0, 0, { # survey.question - 'title': _('How many years did the 100 years war last?'), - 'question_type': 'simple_choice', - 'suggested_answer_ids': [ - (0, 0, { # survey.question.answer - 'value': _('99 years') - }), - (0, 0, { # survey.question.answer - 'value': _('100 years') - }), - (0, 0, { # survey.question.answer - 'value': _('116 years'), - 'is_correct': True, - 'answer_score': 10 - }), - (0, 0, { # survey.question.answer - 'value': _('127 years') - }) - ] - }) ] } mail_template = self.env.ref('survey.mail_template_certification', raise_if_not_found=False) @@ -194,7 +183,7 @@ class SurveyTemplate(models.Model): return self.env['survey.survey'].create({ 'title': _('Live Presentation'), 'description': '
'.join([ - _('How well do you know trees? Let\'s find out!'), + _('How good of a presenter are you? Let\'s find out!'), _('But first, keep listening to the host.') ]), 'description_done': _('Thank you for your participation, hope you had a blast!'), @@ -204,66 +193,61 @@ class SurveyTemplate(models.Model): 'session_speed_rating': True, 'question_and_page_ids': [ (0, 0, { # survey.question - 'title': _('About you'), - 'is_page': True, - 'question_type': False - }), - (0, 0, { # survey.question - 'title': _('Pick a nickname'), - 'question_type': 'char_box', - 'save_as_nickname': True - }), - (0, 0, { # survey.question - 'title': _('Quiz'), - 'is_page': True, - 'question_type': False - }), - (0, 0, { # survey.question - 'title': _('In which country did the bonsai technique develop?'), + 'title': _('What is the best way to catch the attention of an audience?'), 'question_type': 'simple_choice', 'suggested_answer_ids': [ (0, 0, { # survey.question.answer - 'value': _('Japan'), + 'value': _('Speak softly so that they need to focus to hear you') + }), + (0, 0, { # survey.question.answer + 'value': _('Use a fun visual support, like a live presentation'), 'is_correct': True, 'answer_score': 20 }), (0, 0, { # survey.question.answer - 'value': _('China') - }), - (0, 0, { # survey.question.answer - 'value': _('Vietnam') - }), - (0, 0, { # survey.question.answer - 'value': _('South Korea') + 'value': _('Show them slides with a ton of text they need to read fast') }) ] }), (0, 0, { # survey.question - 'title': _('In the list below, select all the coniferous.'), + 'title': _('What is a frequent mistake public speakers do?'), + 'question_type': 'simple_choice', + 'suggested_answer_ids': [ + (0, 0, { # survey.question.answer + 'value': _('Practice in front of a mirror') + }), + (0, 0, { # survey.question.answer + 'value': _('Speak too fast'), + 'is_correct': True, + 'answer_score': 20 + }), + (0, 0, { # survey.question.answer + 'value': _('Use humor and make jokes') + }) + ] + }), + (0, 0, { # survey.question + 'title': _('Why should you consider making your presentation more fun with a small quiz?'), 'question_type': 'multiple_choice', 'suggested_answer_ids': [ (0, 0, { # survey.question.answer - 'value': _('Douglas Fir'), + 'value': _('It helps attendees focus on what you are saying'), 'is_correct': True, - 'answer_score': 5 + 'answer_score': 20 }), (0, 0, { # survey.question.answer - 'value': _('Norway Spruce'), + 'value': _('It is more engaging for your audience'), 'is_correct': True, - 'answer_score': 5 + 'answer_score': 20 }), (0, 0, { # survey.question.answer - 'value': _('European Yew'), + 'value': _('It helps attendees remember the content of your presentation'), 'is_correct': True, - 'answer_score': 5 - }), - (0, 0, { # survey.question.answer - 'value': _('Mountain Pine'), - 'is_correct': True, - 'answer_score': 5 + 'answer_score': 20 }) ] - }) + }), + ] }).action_show_sample() diff --git a/addons/survey/tests/test_survey_ui_certification.py b/addons/survey/tests/test_survey_ui_certification.py index 07649075c2c..be1d59ef787 100644 --- a/addons/survey/tests/test_survey_ui_certification.py +++ b/addons/survey/tests/test_survey_ui_certification.py @@ -15,6 +15,7 @@ class TestUiCertification(HttpCaseWithUserDemo): 'title': 'MyCompany Vendor Certification', 'access_token': '4ead4bc8-b8f2-4760-a682-1fde8daaaaac', 'access_mode': 'public', + 'questions_layout': 'one_page', 'users_can_go_back': True, 'users_login_required': True, 'scoring_type': 'scoring_with_answers', diff --git a/addons/survey/views/survey_survey_views.xml b/addons/survey/views/survey_survey_views.xml index 530951427ee..0461eda42b4 100644 --- a/addons/survey/views/survey_survey_views.xml +++ b/addons/survey/views/survey_survey_views.xml @@ -44,7 +44,7 @@ type="object" class="oe_stat_button" icon="fa-check-square-o"> - + diff --git a/addons/survey/views/survey_templates_management.xml b/addons/survey/views/survey_templates_management.xml index 7888eeb3a85..18754a4ac08 100644 --- a/addons/survey/views/survey_templates_management.xml +++ b/addons/survey/views/survey_templates_management.xml @@ -80,7 +80,7 @@