mirror of
https://github.com/bringout/oca-ocb-core.git
synced 2026-04-24 11:12:05 +02:00
Initial commit: Core packages
This commit is contained in:
commit
12c29a983b
9512 changed files with 8379910 additions and 0 deletions
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo><data>
|
||||
<record id="gamification_badge_form_view_simplified" model="ir.ui.view">
|
||||
<field name="name">gamification.badge.form.view.simplified</field>
|
||||
<field name="model">gamification.badge</field>
|
||||
<field name="priority">100</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Badge">
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box"/>
|
||||
<field name="image_1920" widget="image" class="oe_avatar" options="{'preview_image': 'image_128'}"/>
|
||||
<div class="oe_title">
|
||||
<label for="name"/>
|
||||
<h1>
|
||||
<field name="name" placeholder="e.g. Problem Solver"/>
|
||||
</h1>
|
||||
</div>
|
||||
<field name="description" placeholder="e.g. No one can solve challenges like you do"/>
|
||||
<group string="Rewards for challenges">
|
||||
<field name="level"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
</data></odoo>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo><data>
|
||||
|
||||
<record id="res_partner_action_certifications" model="ir.actions.act_window">
|
||||
<field name="name">Certifications Succeeded</field>
|
||||
<field name="res_model">survey.user_input</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'search_default_scoring_success': 1}</field>
|
||||
</record>
|
||||
|
||||
<record id="res_partner_view_form" model="ir.ui.view">
|
||||
<field name="name">res.partner.view.form.inherit.survey</field>
|
||||
<field name="model">res.partner</field>
|
||||
<field name="inherit_id" ref="base.view_partner_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<button class="oe_stat_button" type="object"
|
||||
icon="fa-trophy" name="action_view_certifications"
|
||||
groups="survey.group_survey_user"
|
||||
attrs="{'invisible': ['|', ('certifications_count', '=', 0), ('is_company', '=', True)]}">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_value"><field name="certifications_count" /></span>
|
||||
<span class="o_stat_text" attrs="{'invisible': [('certifications_count', '<', 2)]}">Certifications</span>
|
||||
<span class="o_stat_text" attrs="{'invisible': [('certifications_count', '>', 1)]}">Certification</span>
|
||||
</div>
|
||||
</button>
|
||||
<button class="oe_stat_button" type="object"
|
||||
icon="fa-trophy" name="action_view_certifications"
|
||||
groups="survey.group_survey_user"
|
||||
attrs="{'invisible': ['|', ('certifications_company_count', '=', 0), ('is_company', '=', False)]}">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_value"><field name="certifications_company_count" /></span>
|
||||
<span class="o_stat_text" attrs="{'invisible': [('certifications_company_count', '<', 2)]}">Certifications</span>
|
||||
<span class="o_stat_text" attrs="{'invisible': [('certifications_company_count', '>', 1)]}">Certification</span>
|
||||
</div>
|
||||
</button>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data></odoo>
|
||||
17
odoo-bringout-oca-ocb-survey/survey/views/survey_menus.xml
Normal file
17
odoo-bringout-oca-ocb-survey/survey/views/survey_menus.xml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- Main menu -->
|
||||
<menuitem name="Surveys"
|
||||
id="menu_surveys"
|
||||
sequence="130"
|
||||
groups="group_survey_user"
|
||||
web_icon="survey,static/description/icon.svg"/>
|
||||
|
||||
<!-- Parent menus -->
|
||||
<menuitem name="Questions & Answers"
|
||||
id="survey_menu_questions"
|
||||
parent="menu_surveys"
|
||||
sequence="90"/>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,368 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- QUESTIONS -->
|
||||
<record model="ir.ui.view" id="survey_question_form">
|
||||
<field name="name">Form view for survey question</field>
|
||||
<field name="model">survey.question</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Survey Question" create="false" class="o_survey_question_view_form">
|
||||
<field name="is_page" invisible="1"/>
|
||||
<field name="page_id" invisible="1" required="False"/>
|
||||
<field name="survey_id" invisible="1"/>
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="scoring_type" invisible="1"/>
|
||||
<sheet>
|
||||
<div class="float-end d-flex flex-column text-center" attrs="{'invisible': [('is_page', '=', False)]}">
|
||||
<label for="background_image"/>
|
||||
<field name="background_image" widget="image" class="oe_avatar"/>
|
||||
</div>
|
||||
<div class="oe_title" style="width: 100%;">
|
||||
<label for="title" string="Section" attrs="{'invisible': [('is_page', '=', False)]}"/>
|
||||
<label for="title" string="Question" attrs="{'invisible': [('is_page', '=', True)]}"/>
|
||||
<field name="title" placeholder="e.g. "What is the..."" colspan="4"/>
|
||||
<field name="questions_selection" invisible="1"/>
|
||||
</div>
|
||||
<group class="o_label_nowrap" attrs="{'invisible': ['|', ('is_page', '=', False), ('questions_selection', '=', 'all')]}">
|
||||
<field name="random_questions_count"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('is_page', '=', True)]}">
|
||||
<group>
|
||||
<field name="question_type" widget="radio" attrs="{'required': [('is_page', '=', False)]}" />
|
||||
</group>
|
||||
<group>
|
||||
<div class="mx-lg-auto w-lg-50 d-none d-sm-block o_preview_questions" colspan="2">
|
||||
<!-- Multiple choice: only one answer -->
|
||||
<div attrs="{'invisible': [('question_type', '!=', 'simple_choice')]}" role="img" aria-label="Multiple choice with one answer"
|
||||
title="Multiple choice with one answer">
|
||||
<span>Which is yellow?</span><br/>
|
||||
<div class="o_preview_questions_choice mb-2"><i class="fa fa-circle-o fa-lg me-2"/>answer</div>
|
||||
<div class="o_preview_questions_choice mb-2"><i class="fa fa-dot-circle-o fa-lg me-2"/>answer</div>
|
||||
<div class="o_preview_questions_choice"><i class="fa fa-circle-o fa-lg me-2"/>answer</div>
|
||||
</div>
|
||||
<!-- Multiple choice: multiple answers allowed -->
|
||||
<div attrs="{'invisible': [('question_type', '!=', 'multiple_choice')]}" role="img" aria-label="Multiple choice with multiple answers"
|
||||
title="Multiple choice with multiple answers">
|
||||
<span>Which are yellow?</span><br/>
|
||||
<div class="o_preview_questions_choice mb-2"><i class="fa fa-square-o fa-lg me-2"/>answer</div>
|
||||
<div class="o_preview_questions_choice mb-2"><i class="fa fa-check-square-o fa-lg me-2"/>answer</div>
|
||||
<div class="o_preview_questions_choice"><i class="fa fa-square-o fa-lg me-2"/>answer</div>
|
||||
</div>
|
||||
<!-- Multiple Lines Text Zone -->
|
||||
<div attrs="{'invisible': [('question_type', '!=', 'text_box')]}">
|
||||
<span>Name all the animals</span><br/>
|
||||
<i class="fa fa-align-justify fa-4x" role="img" aria-label="Multiple lines" title="Multiple Lines"/>
|
||||
</div>
|
||||
<!-- Single Line Text Zone -->
|
||||
<div attrs="{'invisible': [('question_type', '!=', 'char_box')]}">
|
||||
<span>Name one animal</span><br/>
|
||||
<i class="fa fa-minus fa-4x" role="img" aria-label="Single Line" title="Single Line"/>
|
||||
</div>
|
||||
<!-- Numerical Value -->
|
||||
<div attrs="{'invisible': [('question_type', '!=', 'numerical_box')]}">
|
||||
<span>How many ...?</span><br/>
|
||||
<i class="fa fa-2x" role="img" aria-label="Numeric" title="Numeric">123 </i>
|
||||
<i class="fa fa-2x fa-sort" role="img" aria-label="Numeric"/>
|
||||
</div>
|
||||
<!-- Date -->
|
||||
<div attrs="{'invisible': [('question_type', '!=', 'date')]}">
|
||||
<span>When is Christmas?</span><br/>
|
||||
<p class="o_datetime border-0" >YYYY-MM-DD
|
||||
<i class="fa fa-calendar" role="img" aria-label="Calendar" title="Calendar"/>
|
||||
</p>
|
||||
</div>
|
||||
<!-- Date and Time -->
|
||||
<div attrs="{'invisible': [('question_type', '!=', 'datetime')]}">
|
||||
<span>When does ... start?</span><br/>
|
||||
<p class="o_datetime border-0">YYYY-MM-DD hh:mm:ss
|
||||
<i class="fa fa-calendar" role="img" aria-label="Calendar" title="Calendar"/>
|
||||
</p>
|
||||
</div>
|
||||
<!-- Matrix -->
|
||||
<div attrs="{'invisible': [('question_type', '!=', 'matrix')]}">
|
||||
<div class="row o_matrix_head">
|
||||
<div class="col-3"></div>
|
||||
<div class="col-3">ans</div>
|
||||
<div class="col-3">ans</div>
|
||||
<div class="col-3">ans</div>
|
||||
</div>
|
||||
<div class="row o_matrix_row">
|
||||
<div class="col-3">Row1</div>
|
||||
<div class="col-3"><i class="fa fa-circle-o fa-lg" role="img" aria-label="Not checked" title="Not checked"/></div>
|
||||
<div class="col-3"><i class="fa fa-dot-circle-o fa-lg" role="img" aria-label="Checked" title="Checked"/></div>
|
||||
<div class="col-3"><i class="fa fa-circle-o fa-lg" role="img" aria-label="Not checked" title="Not checked"/></div>
|
||||
</div>
|
||||
<div class="row o_matrix_row">
|
||||
<div class="col-3">Row2</div>
|
||||
<div class="col-3"><i class="fa fa-circle-o fa-lg" role="img" aria-label="Not checked" title="Not checked"/></div>
|
||||
<div class="col-3"><i class="fa fa-circle-o fa-lg" role="img" aria-label="Not checked" title="Not checked"/></div>
|
||||
<div class="col-3"><i class="fa fa-dot-circle-o fa-lg" role="img" aria-label="Checked" title="Checked"/></div>
|
||||
</div>
|
||||
<div class="row o_matrix_row">
|
||||
<div class="col-3">Row3</div>
|
||||
<div class="col-3"><i class="fa fa-dot-circle-o fa-lg" role="img" aria-label="Checked" title="Checked"/></div>
|
||||
<div class="col-3"><i class="fa fa-circle-o fa-lg" role="img" aria-label="Not checked" title="Not checked"/></div>
|
||||
<div class="col-3"><i class="fa fa-circle-o fa-lg" role="img" aria-label="Not checked" title="Not checked"/></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Answers" name="answers" attrs="{'invisible': ['|', '|',
|
||||
('is_page', '=', True), ('question_type', '=', 'text_box'),
|
||||
'&', ('scoring_type', '=', 'no_scoring'), ('question_type', 'in', ['numerical_box', 'date', 'datetime']),
|
||||
]}">
|
||||
<group>
|
||||
<group attrs="{'invisible': [('question_type', 'not in', ['char_box', 'numerical_box', 'date', 'datetime'])]}">
|
||||
<field name="answer_numerical_box" string="Correct Answer"
|
||||
attrs="{'invisible': [('question_type', '!=', 'numerical_box')], 'required': [('is_scored_question', '=', True), ('question_type', '=', 'numerical_box')]}" class="oe_inline"/>
|
||||
<field name="answer_date" string="Correct Answer"
|
||||
attrs="{'invisible': [('question_type', '!=', 'date')], 'required': [('is_scored_question', '=', True), ('question_type', '=', 'date')]}" class="oe_inline"/>
|
||||
<field name="answer_datetime" string="Correct Answer"
|
||||
attrs="{'invisible': [('question_type', '!=', 'datetime')], 'required': [('is_scored_question', '=', True), ('question_type', '=', 'datetime')]}" class="oe_inline"/>
|
||||
|
||||
<field name="validation_email" attrs="{'invisible': [('question_type', '!=', 'char_box')]}"/>
|
||||
<field name="save_as_email" attrs="{'invisible': ['|', ('validation_email', '=', False), ('question_type', '!=', 'char_box')]}"/>
|
||||
<field name="save_as_nickname" attrs="{'invisible': [('question_type', '!=', 'char_box')]}"/>
|
||||
</group>
|
||||
|
||||
<group attrs="{'invisible': ['|', ('scoring_type', '=', 'no_scoring'), ('question_type', 'not in', ['numerical_box', 'date', 'datetime'])]}">
|
||||
<label for="is_scored_question"/>
|
||||
<div name="survey_scored_question">
|
||||
<field name="is_scored_question" nolabel="1"/>
|
||||
<field name="answer_score" class="w-50 mx-2" attrs="{'invisible': [('is_scored_question', '=', False)]}" nolabel="1"/>
|
||||
<span attrs="{'invisible': [('is_scored_question', '!=', True)]}">Points</span>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('question_type', 'not in', ['simple_choice', 'multiple_choice', 'matrix'])]}">
|
||||
<field name="suggested_answer_ids" context="{'default_question_id': active_id}" nolabel="1" colspan="2">
|
||||
<tree editable="bottom">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="value" string="Choices"/>
|
||||
<field name="is_correct"
|
||||
attrs="{'column_invisible': ['|', ('parent.scoring_type', '=', 'no_scoring'), ('parent.question_type', '=', 'matrix')]}"/>
|
||||
<field name="answer_score"
|
||||
attrs="{'column_invisible': ['|', ('parent.scoring_type', '=', 'no_scoring'), ('parent.question_type', '=', 'matrix')]}"/>
|
||||
<field name="value_image_filename" invisible="1"/>
|
||||
<field name="value_image" width="200px" filename="value_image_filename" options="{'accepted_file_extensions': 'image/*'}"
|
||||
attrs="{'column_invisible': [('parent.question_type', '=', 'matrix')]}"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
|
||||
<group attrs="{'invisible': [('question_type', '!=', 'matrix')]}">
|
||||
<field name="matrix_row_ids" context="{'default_matrix_question_id': active_id}"
|
||||
attrs="{'invisible': [('question_type', '!=', 'matrix')]}" nolabel="1" colspan="2">
|
||||
<tree editable="bottom">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="value" string="Rows"/>
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Description" name="survey_description">
|
||||
<field name="description" widget="html"
|
||||
placeholder="e.g. Guidelines, instructions, picture, ... to help attendees answer"/>
|
||||
</page>
|
||||
<page string="Options" name="options" attrs="{'invisible': [('is_page', '=', True)]}">
|
||||
<group>
|
||||
<group string="Answers">
|
||||
<!-- Global validation setting -->
|
||||
<field name="validation_required"
|
||||
attrs="{'invisible': [('question_type', 'not in', ['char_box', 'numerical_box', 'date', 'datetime'])]}"/>
|
||||
<!-- Char -->
|
||||
<field name="validation_length_min" attrs="{'invisible': ['|', ('question_type', '!=', 'char_box'), ('validation_required', '=', False)]}"/>
|
||||
<field name="validation_length_max" attrs="{'invisible': ['|', ('question_type', '!=', 'char_box'), ('validation_required', '=', False)]}"/>
|
||||
<!-- Numerical -->
|
||||
<field name="validation_min_float_value"
|
||||
attrs="{'invisible': ['|', ('question_type', '!=', 'numerical_box'), ('validation_required', '=', False)]}"/>
|
||||
<field name="validation_max_float_value"
|
||||
attrs="{'invisible': ['|', ('question_type', '!=', 'numerical_box'), ('validation_required', '=', False)]}"/>
|
||||
<!-- Date and datetime -->
|
||||
<field name="validation_min_date" attrs="{'invisible': ['|', ('question_type', '!=', 'date'), ('validation_required', '=', False)]}"/>
|
||||
<field name="validation_max_date" attrs="{'invisible': ['|', ('question_type', '!=', 'date'), ('validation_required', '=', False)]}"/>
|
||||
<field name="validation_min_datetime" widget="datetime"
|
||||
attrs="{'invisible': ['|', ('question_type', '!=', 'datetime'), ('validation_required', '=', False)]}"/>
|
||||
<field name="validation_max_datetime" widget="datetime"
|
||||
attrs="{'invisible': ['|', ('question_type', '!=', 'datetime'), ('validation_required', '=', False)]}"/>
|
||||
|
||||
<field name="validation_error_msg" attrs="{
|
||||
'invisible': [('validation_required', '=', False)]}"
|
||||
placeholder="The answer you entered is not valid."/>
|
||||
|
||||
<field name="matrix_subtype" attrs="{'invisible':[('question_type','not in',['matrix'])],'required':[('question_type','=','matrix')]}"/>
|
||||
<field name="question_placeholder"
|
||||
attrs="{'invisible': [('question_type', 'not in', ['text_box', 'char_box', 'date', 'datetime', 'numerical_box'])]}"
|
||||
placeholder="Help Participants know what to write"/>
|
||||
<field name='comments_allowed' attrs="{'invisible':[('question_type','not in',['simple_choice','multiple_choice', 'matrix'])]}"/>
|
||||
<field name='comments_message'
|
||||
attrs="{'invisible': ['|', ('question_type', 'not in', ['simple_choice','multiple_choice', 'matrix']), ('comments_allowed', '=', False)]}"
|
||||
placeholder="If other, please specify:"/>
|
||||
<field name='comment_count_as_answer'
|
||||
attrs="{'invisible': ['|', ('question_type', 'not in', ['simple_choice','multiple_choice', 'matrix']), ('comments_allowed', '=', False)]}"/>
|
||||
</group>
|
||||
<group string="Layout">
|
||||
<field name="is_conditional" attrs="{'invisible': [('questions_selection', '=', 'random')]}"/>
|
||||
<field name="triggering_question_id" options="{'no_open': True, 'no_create': True}"
|
||||
attrs="{'invisible': [('is_conditional','=', False)], 'required': [('is_conditional','=', True)]}"/>
|
||||
<field name="triggering_answer_id" options="{'no_open': True, 'no_create': True}"
|
||||
attrs="{'invisible': ['|', ('is_conditional','=', False), ('triggering_question_id','=', False)],
|
||||
'required': [('is_conditional','=', True)]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<group string="Constraints">
|
||||
<field name="constr_mandatory" string="Mandatory Answer"/>
|
||||
<field name="constr_error_msg"
|
||||
attrs="{'invisible': [('constr_mandatory', '=', False)]}"
|
||||
placeholder="This question requires an answer."/>
|
||||
</group>
|
||||
<group string="Live Sessions">
|
||||
<label for="is_time_limited" string="Question Time Limit"/>
|
||||
<div>
|
||||
<field name="is_time_limited" nolabel="1"/>
|
||||
<field name="time_limit" nolabel="1" class="oe_inline"
|
||||
attrs="{'invisible': [('is_time_limited', '=', False)]}" />
|
||||
<span attrs="{'invisible': [('is_time_limited', '=', False)]}"> seconds</span>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="survey_question_tree">
|
||||
<field name="name">Tree view for survey question</field>
|
||||
<field name="model">survey.question</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Survey Question" create="false">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="title"/>
|
||||
<field name="survey_id"/>
|
||||
<field name="question_type"/>
|
||||
<field name="triggering_question_id" invisible="1"/>
|
||||
<button disabled="disabled" icon="fa-code-fork" attrs="{'invisible': [('triggering_question_id', '=', False)]}"
|
||||
title="This question depends on another question's answer." class="icon_rotates"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="survey_question_search">
|
||||
<field name="name">Search view for survey question</field>
|
||||
<field name="model">survey.question</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Question">
|
||||
<field name="title"/>
|
||||
<field name="survey_id" string="Survey"/>
|
||||
<field name="question_type" string="Type"/>
|
||||
<group expand="1" string="Group By">
|
||||
<filter name="group_by_type" string="Type" domain="[]" context="{'group_by':'question_type'}"/>
|
||||
<filter name="group_by_survey" string="Survey" domain="[]" context="{'group_by':'survey_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_survey_question_form">
|
||||
<field name="name">Questions</field>
|
||||
<field name="res_model">survey.question</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="survey_question_search"/>
|
||||
<field name="context">{'search_default_group_by_page': True}</field>
|
||||
<field name="domain">[('is_page', '=', False)]</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_empty_folder">
|
||||
No Questions yet!
|
||||
</p><p>
|
||||
Come back once you have added questions to your Surveys.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- LABELS -->
|
||||
<record id="survey_question_answer_view_tree" model="ir.ui.view">
|
||||
<field name="name">survey.question.answer.view.tree</field>
|
||||
<field name="model">survey.question.answer</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Survey Label" create="false">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="question_id"/>
|
||||
<field name="matrix_question_id"/>
|
||||
<field name="value"/>
|
||||
<field name="answer_score" groups="base.group_no_one"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="survey_question_answer_view_form" model="ir.ui.view">
|
||||
<field name="name">survey.question.answer.view.form</field>
|
||||
<field name="model">survey.question.answer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Question Answer Form">
|
||||
<sheet>
|
||||
<field name="question_type" invisible="1"/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="scoring_type" invisible="1"/>
|
||||
<field name="question_id"/>
|
||||
<field name="is_correct" attrs="{'invisible': [('scoring_type', '=', 'no_scoring')]}"/>
|
||||
<field name="answer_score" attrs="{'invisible': ['|', ('scoring_type', '=', 'no_scoring'), ('question_type', '=', 'matrix')]}"/>
|
||||
<field name="value_image"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="value"/>
|
||||
<field name="matrix_question_id" attrs="{'invisible': [('question_type', '!=', 'matrix')]}"/>
|
||||
<field name="sequence"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="survey_question_answer_view_search" model="ir.ui.view">
|
||||
<field name="name">survey.question.answer.view.search</field>
|
||||
<field name="model">survey.question.answer</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Label">
|
||||
<field name="question_id"/>
|
||||
<group expand="1" string="Group By">
|
||||
<filter name="group_by_question" string="Question" domain="[]" context="{'group_by':'question_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="survey_question_answer_action" model="ir.actions.act_window">
|
||||
<field name="name">Suggested Values</field>
|
||||
<field name="res_model">survey.question.answer</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="survey_question_answer_view_search"/>
|
||||
<field name="context">{'search_default_group_by_question': True}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_empty_folder">
|
||||
No survey labels found
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Questions"
|
||||
id="menu_survey_question_form1"
|
||||
action="action_survey_question_form"
|
||||
parent="survey_menu_questions"
|
||||
sequence="2"/>
|
||||
<menuitem name="Suggested Values"
|
||||
id="menu_survey_label_form1"
|
||||
action="survey_question_answer_action"
|
||||
parent="survey_menu_questions"
|
||||
sequence="3"/>
|
||||
<menuitem name="Detailed Answers"
|
||||
id="menu_survey_response_line_form"
|
||||
action="survey_user_input_line_action"
|
||||
parent="survey_menu_questions"
|
||||
sequence="4"/>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<template id="certification_report_view_modern">
|
||||
<!-- Style classes to be applyed to '#o_survey_certification': [no class](purple), gold, blue -->
|
||||
<div id="o_survey_certification" t-att-data-oe-model="user_input._name" t-att-data-oe-id="user_input.id" t-att-class="'article certification-wrapper modern %s' % layout_color">
|
||||
<div class="certification">
|
||||
<div class="certification-seal" t-if="user_input.scoring_success"/>
|
||||
<div class="certification-top">
|
||||
<h1><b>Certificate</b>
|
||||
<br/><span t-if="user_input.scoring_success">of achievement</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="certification-content">
|
||||
<div t-if="user_input.scoring_success">
|
||||
<p>This certificate is presented to
|
||||
<br/>
|
||||
<t t-set="certif_style" t-value="''"/>
|
||||
<t t-set="certified_name" t-value="user_input.partner_id.name or user_input.email or ''"/>
|
||||
<t t-if="certified_name.isupper()">
|
||||
<t t-set="certif_style" t-value="certif_style + 'font-family: certification-serif;'"/>
|
||||
</t>
|
||||
<t t-if="len(certified_name) > 20">
|
||||
<t t-set="certif_style" t-value="certif_style + 'font-size: 40px; line-height: 4;'"/>
|
||||
</t>
|
||||
<span t-att-style="certif_style" class="user-name" t-esc="certified_name"/>
|
||||
|
||||
<br/>by <span class="certification-company" t-field="user_input.env.company.display_name"/> for successfully completing
|
||||
<br/><b><span class="certification-name" t-field="user_input.survey_id.display_name"/></b>
|
||||
</p>
|
||||
</div>
|
||||
<div t-else="" class="certification-failed">
|
||||
<p>Certification Failed</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="certification-bottom">
|
||||
<div class="certification-date-wrapper">
|
||||
<div class="certification-date" t-field="user_input.create_date" t-options='{"widget": "date"}'/>
|
||||
<span>Date</span>
|
||||
</div>
|
||||
<div class="certification-company">
|
||||
<span class="certification-company-logo" t-field="user_input.env.company.logo" t-options="{'widget': 'image'}" role="img"/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="certification-number" t-if="user_input.scoring_success">
|
||||
Certification n°<t t-esc="str(user_input.id).rjust(10, '0')"/>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="user_input.test_entry" class="test-entry"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="certification_report_view_classic">
|
||||
<!-- Style classes to be applyed to '#o_survey_certification': [no class](purple), gold, blue -->
|
||||
<div id="o_survey_certification" t-att-data-oe-model="user_input._name" t-att-data-oe-id="user_input.id" t-att-class="'article certification-wrapper classic %s' % layout_color">
|
||||
<div t-if="user_input.test_entry" class="test-entry"/>
|
||||
<div class="certification">
|
||||
<div class="certification-top">
|
||||
<h1><b>Certificate</b>
|
||||
<br/><span t-if="user_input.scoring_success">of achievement</span>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<div class="certification-content">
|
||||
<div t-if="user_input.scoring_success">
|
||||
<p>This certificate is presented to
|
||||
<t t-set="certif_style" t-value="''"/>
|
||||
<t t-set="certified_name" t-value="user_input.partner_id.name or user_input.email or ''"/>
|
||||
<t t-if="certified_name.isupper()">
|
||||
<t t-set="certif_style" t-value="certif_style + 'font-family: certification-serif;'"/>
|
||||
</t>
|
||||
<t t-if="len(certified_name) > 35">
|
||||
<t t-set="certif_style" t-value="certif_style + 'font-size: 20px; line-height: 4; font-family: certification-serif; '"/>
|
||||
</t>
|
||||
<t t-elif="len(certified_name) > 20">
|
||||
<t t-set="certif_style" t-value="certif_style + 'font-size: 30px; line-height: 4;'"/>
|
||||
</t>
|
||||
<br/>
|
||||
<span t-att-style="certif_style" class="user-name" t-esc="certified_name"/>
|
||||
|
||||
<br/>by <span class="certification-company" t-field="user_input.env.company.display_name"/>
|
||||
for successfully completing
|
||||
<br/><b><span class="certification-name" t-field="user_input.survey_id.display_name"/></b>
|
||||
</p>
|
||||
</div>
|
||||
<div t-else="" class="certification-failed">
|
||||
<p>Certification Failed</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="certification-bottom">
|
||||
<div class="certification-date-wrapper">
|
||||
<b><div class="certification-date" t-field="user_input.create_date" t-options='{"widget": "date"}'/></b>
|
||||
<span>Date</span>
|
||||
</div>
|
||||
<div class="certification-seal"/>
|
||||
<div class="certification-company">
|
||||
<span class="certification-company-logo" t-field="user_input.env.company.logo" t-options="{'widget': 'image'}" role="img"/>
|
||||
</div>
|
||||
<div class="certification-number" t-if="user_input.scoring_success">
|
||||
Certification n°<t t-esc="str(user_input.id).rjust(10, '0')"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="certification_report_view">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="user_input">
|
||||
<t t-set="layout_values" t-value="user_input.survey_id.certification_report_layout.split('_') if user_input.survey_id.certification_report_layout else ['modern', 'purple']"/>
|
||||
<t t-set="layout_template" t-value="'survey.certification_report_view_%s' % (layout_values[0])"/>
|
||||
<t t-set="layout_color" t-value="layout_values[1]"/>
|
||||
<t t-call="{{layout_template}}"/>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</data>
|
||||
</odoo>
|
||||
33
odoo-bringout-oca-ocb-survey/survey/views/survey_reports.xml
Normal file
33
odoo-bringout-oca-ocb-survey/survey/views/survey_reports.xml
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- Paper Format -->
|
||||
<record id="paperformat_survey_certification" model="report.paperformat">
|
||||
<field name="name">Survey Certification</field>
|
||||
<field name="default" eval="True"/>
|
||||
<field name="format">A4</field>
|
||||
<field name="orientation">Landscape</field>
|
||||
<field name="margin_top">0</field>
|
||||
<field name="margin_bottom">0</field>
|
||||
<field name="margin_left">0</field>
|
||||
<field name="margin_right">0</field>
|
||||
<field name="header_line" eval="False"/>
|
||||
<field name="header_spacing">0</field>
|
||||
<field name="disable_shrinking" eval="True"/>
|
||||
<field name="dpi">96</field>
|
||||
</record>
|
||||
<!-- QWeb Reports -->
|
||||
<record id="certification_report" model="ir.actions.report">
|
||||
<field name="name">Certifications</field>
|
||||
<field name="model">survey.user_input</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">survey.certification_report_view</field>
|
||||
<field name="report_file">survey.certification_report_view</field>
|
||||
<field name="print_report_name">'Certification - %s' % (object.survey_id.display_name)</field>
|
||||
<field name="attachment">'certification.pdf'</field>
|
||||
<field name="binding_model_id" ref="model_survey_user_input"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="paperformat_survey_certification"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,468 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="survey_survey_view_form" model="ir.ui.view">
|
||||
<field name="name">survey.survey.view.form</field>
|
||||
<field name="model">survey.survey</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Survey" class="o_survey_form">
|
||||
<field name="id" invisible="1"/>
|
||||
<field name="session_state" invisible="1"/>
|
||||
<field name="question_ids" invisible="1"/>
|
||||
<header>
|
||||
<button name="action_send_survey" string="Share" type="object" class="oe_highlight" attrs="{'invisible': [('active', '=', False)]}"/>
|
||||
<button name="action_result_survey" string="See results" type="object" class="oe_highlight"
|
||||
attrs="{'invisible': [('answer_done_count', '<=', 0)]}"/>
|
||||
<button name="action_start_session" string="Create Live Session" type="object" class="d-none d-sm-block"
|
||||
attrs="{'invisible': ['|', ('session_state', '!=', False), '|', ('active', '=', False), ('certification', '=', True)]}" />
|
||||
<button name="action_open_session_manager" string="Open Session Manager" type="object" class="d-none d-sm-block"
|
||||
attrs="{'invisible': [('session_state', '=', False)]}" />
|
||||
<button name="action_end_session" string="Close Live Session" type="object" class="d-none d-sm-block"
|
||||
attrs="{'invisible': [('session_state', 'not in', ['ready', 'in_progress'])]}" />
|
||||
<button name="action_test_survey" string="Test" type="object" attrs="{'invisible': ['|', ('active', '=', False), ('question_ids', '=', [])]}"/>
|
||||
<button name="action_unarchive" string="Reopen" class="btn-primary" type="object" attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
<button name="action_print_survey" string="Print" type="object" attrs="{'invisible': [('active', '=', False)]}"/>
|
||||
<button name="action_archive" string="Close" type="object" attrs="{'invisible': [('active', '=', False)]}"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_survey_user_input"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
attrs="{'invisible': [('access_mode', '=', 'public')]}"
|
||||
icon="fa-envelope-o">
|
||||
<field string="Registered" name="answer_count" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="action_survey_user_input_certified"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
attrs="{'invisible': [('certification', '=', False)]}"
|
||||
icon="fa-trophy">
|
||||
<field string="Certified" name="success_count" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="action_survey_user_input_completed"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
icon="fa-check-square-o">
|
||||
<field string="Participations" name="answer_done_count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
<field name="background_image" widget="image" class="oe_avatar"/>
|
||||
<div class="oe_title" style="width: 100%;">
|
||||
<label for="title" class="oe_edit_only" string="Survey Title" attrs="{'invisible': [('certification', '=', True)]}"/>
|
||||
<label for="title" class="oe_edit_only" string="Certification Title" attrs="{'invisible': [('certification', '=', False)]}"/>
|
||||
<h1>
|
||||
<field name="title" placeholder="e.g. Satisfaction Survey"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="user_id" domain="[('share', '=', False)]" widget="many2one_avatar_user"/>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="has_conditional_questions" invisible="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Questions" name="questions">
|
||||
<field name="question_and_page_ids" nolabel="1" widget="question_page_one2many" mode="tree,kanban" context="{'default_survey_id': active_id, 'default_questions_selection': questions_selection}">
|
||||
<tree decoration-bf="is_page">
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="title" widget="survey_description_page"/>
|
||||
<field name="background_image" invisible="1"/>
|
||||
<field name="question_type" />
|
||||
<field name="is_page" invisible="1"/>
|
||||
<field name="questions_selection" invisible="1"/>
|
||||
<field name="survey_id" invisible="1"/>
|
||||
<field name="triggering_question_id" invisible="1"/>
|
||||
<field name="random_questions_count"
|
||||
attrs="{'column_invisible': [('parent.questions_selection', '=', 'all')], 'invisible': [('is_page', '=', False)]}"/>
|
||||
<button disabled="disabled" icon="fa-code-fork" attrs="{'invisible': [('triggering_question_id', '=', False)]}"
|
||||
title="This question depends on another question's answer." class="icon_rotates"/>
|
||||
<control>
|
||||
<create name="add_question_control" string="Add a question"/>
|
||||
<create name="add_section_control" string="Add a section" context="{'default_is_page': True, 'default_questions_selection': 'all'}"/>
|
||||
</control>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Options" name="options">
|
||||
<group name="options">
|
||||
<group string="Questions" name="questions">
|
||||
<field name="questions_layout" widget="radio"
|
||||
attrs="{'readonly': [('session_state', 'in', ['ready', 'in_progress'])]}"/>
|
||||
<field name="progression_mode" widget="radio" attrs="{'invisible': [('questions_layout', '=', 'one_page')]}"/>
|
||||
<field name="questions_selection" widget="radio" />
|
||||
<field name="users_can_go_back" string="Back Button" attrs="{'invisible': [('questions_layout', '=', 'one_page')]}"/>
|
||||
</group>
|
||||
<group string="Participants" name="participants">
|
||||
<field name="access_mode"/>
|
||||
<field name="users_login_required"/>
|
||||
<label for="is_attempts_limited" string="Limit Attempts"
|
||||
attrs="{'invisible': ['&', ('access_mode', '=', 'public'), ('users_login_required', '=', False)]}"/>
|
||||
<div class="o_checkbox_optional_field"
|
||||
attrs="{'invisible': ['&', ('access_mode', '=', 'public'), ('users_login_required', '=', False)]}">
|
||||
<field name="is_attempts_limited" nolabel="1"/>
|
||||
<div attrs="{'invisible': [('is_attempts_limited', '=', False)]}">
|
||||
to <field name="attempts_limit" nolabel="1" class="oe_inline"/> attempts
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
<group string="Time & Scoring" name="scoring">
|
||||
<label for="is_time_limited" string="Survey Time Limit"/>
|
||||
<div class="o_checkbox_optional_field">
|
||||
<field name="is_time_limited" nolabel="1"/>
|
||||
<div attrs="{'invisible': [('is_time_limited', '=', False)]}">
|
||||
<field name="time_limit" widget="float_time" nolabel="1" class="oe_inline"/> minutes
|
||||
</div>
|
||||
</div>
|
||||
<field name="scoring_type" widget="radio" />
|
||||
<field name="scoring_success_min" attrs="{'invisible': [('scoring_type', '=', 'no_scoring')]}" />
|
||||
<label for="certification" attrs="{'invisible': [('scoring_type', '=', 'no_scoring')]}"/>
|
||||
<div class="o_checkbox_optional_field">
|
||||
<field name="certification" attrs="{'invisible': [('scoring_type', '=', 'no_scoring')]}"/>
|
||||
<div attrs="{'invisible': [('certification', '=', False)]}" class="w-100">
|
||||
<field name="certification_report_layout" placeholder="Pick a Style..." class="w-50"/>
|
||||
<button name="action_survey_preview_certification_template"
|
||||
string="Preview" type="object"
|
||||
icon="fa-external-link" target="_blank" class="btn-link pt-0"/>
|
||||
</div>
|
||||
</div>
|
||||
<field name="certification_mail_template_id"
|
||||
placeholder="Pick a Template..."
|
||||
attrs="{'invisible': [('certification', '=', False)]}"/>
|
||||
<label for="certification_give_badge"
|
||||
attrs="{'invisible': ['|', ('certification', '=', False), ('users_login_required', '=', False)]}"/>
|
||||
<div class="float-start o_checkbox_optional_field"
|
||||
attrs="{'invisible': ['|', ('certification', '=', False), ('users_login_required', '=', False)]}">
|
||||
<field name="certification_give_badge"/>
|
||||
<div attrs="{'invisible': [('certification_give_badge', '=', False)]}">
|
||||
<field name="certification_badge_id"
|
||||
placeholder="Pick a Badge..."
|
||||
attrs="{'invisible': ['|', ('certification_give_badge', '=', False), ('certification_badge_id', '!=', False)], 'required': [('certification_give_badge', '=', True)]}"
|
||||
domain="[('survey_id', '=', active_id), ('survey_id', '!=', False)]"
|
||||
context="{'default_name': title,
|
||||
'default_description': 'Congratulations, you have succeeded this certification',
|
||||
'default_rule_auth': 'nobody',
|
||||
'default_level': None,
|
||||
'form_view_ref': 'survey.gamification_badge_form_view_simplified'}"/>
|
||||
<field name="certification_badge_id_dummy" attrs="{'invisible': ['|', ('certification_give_badge', '=', False), ('certification_badge_id', '=', False)]}"
|
||||
placeholder="Pick a Badge..."
|
||||
options="{'no_create': True}"
|
||||
context="{'form_view_ref': 'survey.gamification_badge_form_view_simplified'}"/>
|
||||
</div>
|
||||
</div>
|
||||
</group>
|
||||
<group string="Live Session">
|
||||
<field name="session_code" />
|
||||
<field name="session_link" widget="CopyClipboardChar" />
|
||||
<field name="session_speed_rating" />
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Description" name="description">
|
||||
<field name="description" placeholder="e.g. "The following Survey will help us..."" nolabel="1"></field>
|
||||
</page>
|
||||
<page string="End Message" name="description_done">
|
||||
<field name="description_done" placeholder="e.g. "Thank you very much for your feedback!"" nolabel="1"></field>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids"/>
|
||||
<field name="activity_ids"/>
|
||||
<field name="message_ids"/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="survey_survey_view_tree" model="ir.ui.view">
|
||||
<field name="name">survey.survey.view.tree</field>
|
||||
<field name="model">survey.survey</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Survey" js_class="survey_view_tree">
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="certification" invisible="1"/>
|
||||
<field name="title"/>
|
||||
<button name="certification" type="button" disabled="disabled"
|
||||
icon="fa-trophy" title="Certification" aria-label="Certification"
|
||||
attrs="{'invisible': [('certification', '=', False)]}"/>
|
||||
<field name="user_id" widget="many2one_avatar_user"/>
|
||||
<field name="answer_duration_avg" widget="float_time"/>
|
||||
<field name="answer_count"/>
|
||||
<field name="answer_done_count" optional="hide"/>
|
||||
<field name="success_count" optional="hide"/>
|
||||
<field name="success_ratio"/>
|
||||
<field name="answer_score_avg"/>
|
||||
<!-- Tweak as icons aren't directly supported in xml -->
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="survey_survey_view_kanban" model="ir.ui.view">
|
||||
<field name="name">survey.survey.view.kanban</field>
|
||||
<field name="model">survey.survey</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban class="o_survey_survey_view_kanban" js_class="survey_view_kanban">
|
||||
<field name="active"/>
|
||||
<field name="certification"/>
|
||||
<field name="color"/>
|
||||
<field name="create_date"/>
|
||||
<field name="scoring_type"/>
|
||||
<field name="session_state"/>
|
||||
<field name="success_ratio"/>
|
||||
<templates>
|
||||
<div t-name="kanban-box"
|
||||
t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)}
|
||||
oe_kanban_card oe_kanban_global_click
|
||||
o_survey_kanban_card #{record.certification.raw_value ? 'o_survey_kanban_card_certification' : ''}">
|
||||
<!-- displayed in ungrouped mode -->
|
||||
<div class="o_survey_kanban_card_ungrouped row mx-0">
|
||||
<div class="col-lg-2 col-sm-8 py-0 my-2 my-lg-0 col-12">
|
||||
<div class="d-flex flex-grow-1 flex-column my-0 my-lg-2">
|
||||
<span class="fw-bold"><field name="title"/></span>
|
||||
<span t-if="!selection_mode">
|
||||
<field name="user_id" widget="many2one_avatar_user"
|
||||
options="{'display_avatar_name': True}"/>
|
||||
-
|
||||
<t t-esc="luxon.DateTime.fromISO(record.create_date.raw_value).toFormat('MMM yyyy')"/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div t-attf-class="col-lg-1 col-sm-4 d-none d-sm-block py-0 my-2 col-#{selection_mode ? '12' : '6'}">
|
||||
<span class="fw-bold"><field name="question_count"/></span><br t-if="!selection_mode"/>
|
||||
<span class="text-muted">Questions</span>
|
||||
</div>
|
||||
<div t-if="selection_mode" class="col-12 d-flex justify-content-end">
|
||||
<field name="user_id" widget="many2one_avatar_user"/>
|
||||
</div>
|
||||
<div t-if="!selection_mode" class="col-lg-1 col-sm-4 col-6 py-0 my-2">
|
||||
<span class="fw-bold">
|
||||
<field name="answer_duration_avg" widget="float_time"/>
|
||||
</span><br />
|
||||
<span class="text-muted">Average Duration</span>
|
||||
</div>
|
||||
<div t-if="!selection_mode" class="col-lg-1 col-sm-4 col-6 py-0 my-2">
|
||||
<a type="object"
|
||||
name="action_survey_user_input"
|
||||
class="fw-bold">
|
||||
<field name="answer_count"/><br />
|
||||
<span class="text-muted">Registered</span>
|
||||
</a>
|
||||
</div>
|
||||
<div t-if="!selection_mode" class="col-lg-1 col-sm-4 col-6 d-none d-sm-block py-0 my-2">
|
||||
<a type="object"
|
||||
name="action_survey_user_input_completed"
|
||||
class="fw-bold">
|
||||
<field name="answer_done_count"/><br />
|
||||
<span class="text-muted">Completed</span>
|
||||
</a>
|
||||
</div>
|
||||
<div t-if="!selection_mode" class="col-lg-1 col-sm-4 col-6 py-0 my-2"
|
||||
name="o_survey_kanban_card_section_success">
|
||||
<a t-if="record.scoring_type.raw_value != 'no_scoring'"
|
||||
type="object"
|
||||
name="action_survey_user_input_certified"
|
||||
class="fw-bold">
|
||||
<field name="success_ratio" widget="progressbar" class="d-block"/>
|
||||
<span class="text-muted" t-if="!record.certification.raw_value">Passed</span>
|
||||
<span class="text-muted" t-else="">Certified</span>
|
||||
</a>
|
||||
</div>
|
||||
<div t-if="!selection_mode" class="col-lg-3 col-sm-12 d-none d-sm-block py-0 my-2 pb-lg-3 ms-auto text-lg-end">
|
||||
<button name="action_send_survey"
|
||||
string="Share" type="object"
|
||||
class="btn btn-secondary border"
|
||||
attrs="{'invisible': [('active', '=', False)]}">
|
||||
Share
|
||||
</button>
|
||||
<button name="action_test_survey"
|
||||
string="Test" type="object"
|
||||
class="btn btn-secondary border"
|
||||
attrs="{'invisible': [('active', '=', False)]}">
|
||||
Test
|
||||
</button>
|
||||
<button name="action_result_survey"
|
||||
string="See results" type="object"
|
||||
class="btn btn-secondary border"
|
||||
attrs="{'invisible': [('active', '=', False)]}">
|
||||
See results
|
||||
</button>
|
||||
<button name="action_start_session"
|
||||
string="Start Live Session" type="object"
|
||||
class="btn btn-secondary border"
|
||||
attrs="{'invisible': ['|', '|', ('session_state', '!=', False), ('certification', '=', True), ('active', '=', False)]}">
|
||||
Start Live Session
|
||||
</button>
|
||||
<button name="action_end_session"
|
||||
string="End Live Session" type="object"
|
||||
class="btn btn-secondary border"
|
||||
attrs="{'invisible': ['|', ('session_state', 'not in', ['ready', 'in_progress']), ('active', '=', False)]}">
|
||||
End Live Session
|
||||
</button>
|
||||
</div>
|
||||
<widget name="web_ribbon" title="Archived"
|
||||
bg_color="bg-danger"
|
||||
attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
</div>
|
||||
<!-- displayed in grouped mode -->
|
||||
<div class="o_survey_kanban_card_grouped">
|
||||
<widget name="web_ribbon" title="Archived"
|
||||
bg_color="bg-danger"
|
||||
attrs="{'invisible': [('active', '=', True)]}"/>
|
||||
<div class="o_dropdown_kanban dropdown" t-if="widget.editable">
|
||||
<a href="#" role="button"
|
||||
class="dropdown-toggle o-no-caret btn"
|
||||
data-bs-toggle="dropdown" data-bs-display="static"
|
||||
aria-label="Dropdown menu" title="Dropdown menu">
|
||||
<span class="fa fa-ellipsis-v"/>
|
||||
</a>
|
||||
<div class="dropdown-menu" role="menu">
|
||||
<a role="menuitem" type="edit" class="dropdown-item">Edit Survey</a>
|
||||
<a t-if="record.active.raw_value" role="menuitem" type="object" class="dropdown-item" name="action_send_survey">Share</a>
|
||||
<a t-if="widget.deletable" role="menuitem" type="delete" class="dropdown-item">Delete</a>
|
||||
<div role="separator" class="dropdown-divider"/>
|
||||
<div role="separator" class="dropdown-item-text">Color</div>
|
||||
<ul class="oe_kanban_colorpicker" data-field="color"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_kanban_record_top">
|
||||
<h4 class="o_kanban_record_title p-0 mb4"><field name="title" /></h4>
|
||||
</div>
|
||||
<div class="row g-0">
|
||||
<div class="col-10 p-0 pb-1">
|
||||
<div class="container o_kanban_card_content" t-if="record.answer_count.raw_value != 0">
|
||||
<div class="row mt-4 ms-5">
|
||||
<div class="col-4 p-0">
|
||||
<a name="action_survey_user_input" type="object" class="d-flex flex-column align-items-center">
|
||||
<span class="fw-bold"><field name="answer_count"/></span>
|
||||
<span class="text-muted">Registered</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-4 p-0 border-start">
|
||||
<a name="action_survey_user_input_completed" type="object" class="d-flex flex-column align-items-center">
|
||||
<span class="fw-bold"><field name="answer_done_count"/></span>
|
||||
<span class="text-muted">Completed</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="col-4 p-0 border-start" t-if="record.scoring_type.raw_value != 'no_scoring'" >
|
||||
<a name="action_survey_user_input_certified" type="object" class="d-flex flex-column align-items-center">
|
||||
<span class="fw-bold"> <t t-esc="Math.round(record.success_ratio.raw_value)"></t> %</span>
|
||||
<span class="text-muted" >Success</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Generic -->
|
||||
<div t-if="!selection_mode" class="o_survey_kanban_card_bottom">
|
||||
<field name="activity_ids" widget="kanban_activity"/>
|
||||
</div>
|
||||
</div>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
<record id="survey_survey_view_search" model="ir.ui.view">
|
||||
<field name="name">survey.survey.search</field>
|
||||
<field name="model">survey.survey</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Survey">
|
||||
<field string="Survey" name="title"/>
|
||||
<field string="Question & Pages" name="question_and_page_ids"/>
|
||||
<filter string="Is a Certification" name="certification" domain="[('certification', '=', True)]"/>
|
||||
<filter string="Is not a Certification" name="not_certification" domain="[('certification', '=', False)]"/>
|
||||
<separator/>
|
||||
<filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
|
||||
<separator/>
|
||||
<filter invisible="1" string="Late Activities" name="activities_overdue"
|
||||
domain="[('my_activity_date_deadline', '<', context_today().strftime('%Y-%m-%d'))]"
|
||||
help="Show all records which has next action date is before today"/>
|
||||
<filter invisible="1" string="Today Activities" name="activities_today"
|
||||
domain="[('my_activity_date_deadline', '=', context_today().strftime('%Y-%m-%d'))]"/>
|
||||
<filter invisible="1" string="Upcoming Activities" name="activities_upcoming_all"
|
||||
domain="[('my_activity_date_deadline', '>', context_today().strftime('%Y-%m-%d'))]"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Responsible" name="group_by_responsible"
|
||||
context="{'group_by': 'user_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_survey_form">
|
||||
<field name="name">Surveys</field>
|
||||
<field name="res_model">survey.survey</field>
|
||||
<field name="view_mode">kanban,tree,form,activity</field>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
No Survey Found
|
||||
</p><p>
|
||||
Ready to test? Pick a sample...
|
||||
</p>
|
||||
<div class="row mb-4">
|
||||
<div class="col-sm-4 o_survey_sample_container" action="action_load_sample_feedback_form">
|
||||
<div class="o_survey_sample_tile position-relative w-100 d-flex align-items-center justify-content-center m-auto">
|
||||
<img src="/survey/static/src/img/survey_sample_feedback_form.png" class="img-fluid"/>
|
||||
<div class="o_survey_sample_tile_cover o_survey_load_sample w-100 h-100 position-absolute rounded-circle text-center text-white p-3">
|
||||
Gather feedbacks from your employees and customers
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-3">
|
||||
<a class="o_survey_load_sample h3 text-center text-primary">Feedback Form</a>
|
||||
</div>
|
||||
<a class="btn btn-outline-primary o_survey_load_sample"><span>Try It</span></a>
|
||||
</div>
|
||||
<div class="col-sm-4 o_survey_sample_container" action="action_load_sample_certification">
|
||||
<div class="o_survey_sample_tile position-relative w-100 d-flex align-items-center justify-content-center m-auto">
|
||||
<img src="/survey/static/src/img/survey_sample_certification.png" class="img-fluid"/>
|
||||
<div class="o_survey_sample_tile_cover o_survey_load_sample w-100 h-100 position-absolute rounded-circle text-center text-white p-3">
|
||||
Handle quiz & certifications
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-3">
|
||||
<a class="o_survey_load_sample h3 text-center text-primary">Certification</a>
|
||||
</div>
|
||||
<a class="btn btn-outline-primary o_survey_load_sample"><span>Try It</span></a>
|
||||
</div>
|
||||
<div class="col-sm-4 o_survey_sample_container" action="action_load_sample_live_presentation">
|
||||
<div class="o_survey_sample_tile position-relative w-100 d-flex align-items-center justify-content-center m-auto">
|
||||
<img src="/survey/static/src/img/survey_sample_live_presentation.png" class="img-fluid"/>
|
||||
<div class="o_survey_sample_tile_cover o_survey_load_sample w-100 h-100 position-absolute rounded-circle text-center text-white p-3">
|
||||
Add some fun to your presentations by sharing questions live
|
||||
</div>
|
||||
</div>
|
||||
<div class="my-3">
|
||||
<a class="o_survey_load_sample h3 text-center text-primary">Live Presentation</a>
|
||||
</div>
|
||||
<a class="btn btn-outline-primary o_survey_load_sample"><span>Try It</span></a>
|
||||
</div>
|
||||
</div>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="survey_survey_view_graph" model="ir.ui.view">
|
||||
<field name="name">survey.survey.view.graph</field>
|
||||
<field name="model">survey.survey</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph>
|
||||
<field type="measure" name="color" invisible="1"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="survey_survey_view_pivot" model="ir.ui.view">
|
||||
<field name="name">survey.survey.view.pivot</field>
|
||||
<field name="model">survey.survey</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot>
|
||||
<field type="measure" name="color" invisible="1"/>
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Surveys" id="menu_survey_form" action="action_survey_form" parent="menu_surveys" sequence="1"/>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
641
odoo-bringout-oca-ocb-survey/survey/views/survey_templates.xml
Normal file
641
odoo-bringout-oca-ocb-survey/survey/views/survey_templates.xml
Normal file
|
|
@ -0,0 +1,641 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- Main survey layout -->
|
||||
<template id="survey.layout" name="Survey Layout" inherit_id="web.frontend_layout" primary="True">
|
||||
<xpath expr="//div[@id='wrapwrap']" position="before">
|
||||
<!--TODO DBE Fix me : If one day, there is a survey_livechat bridge module, put this in that module-->
|
||||
<t t-set="no_livechat" t-value="True"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[@id='wrapwrap']" position="attributes">
|
||||
<attribute name="t-att-style"
|
||||
add="(('background-image: url(' + question.background_image_url + ');')
|
||||
if question and question.background_image_url
|
||||
else ('background-image: url(' + page.background_image_url + ');')
|
||||
if page and page.background_image_url
|
||||
else ('background-image: url(' + survey.background_image_url + ');')
|
||||
if survey and survey.background_image_url
|
||||
else '')"/>
|
||||
<attribute name="t-att-class"
|
||||
add="(('o_survey_background o_survey_background_shadow')
|
||||
if (question and question.background_image_url)
|
||||
or (page and page.background_image_url)
|
||||
or (survey and survey.background_image_url)
|
||||
else 'o_survey_background')"
|
||||
separator=" "/>
|
||||
</xpath>
|
||||
<xpath expr="//head/t[@t-call-assets][last()]" position="after">
|
||||
<t t-call-assets="survey.survey_assets" lazy_load="True"/>
|
||||
</xpath>
|
||||
<xpath expr="//header" position="before">
|
||||
<t t-set="no_header" t-value="True"/>
|
||||
<t t-set="no_footer" t-value="True"/>
|
||||
</xpath>
|
||||
<xpath expr="//header" position="after">
|
||||
<div id="wrap" class="oe_structure oe_empty"/>
|
||||
</xpath>
|
||||
<xpath expr="//footer" position="after">
|
||||
<div class="py-3 m-0 p-0 text-end">
|
||||
<div class="o_survey_progress_wrapper d-inline-block pe-1 text-start">
|
||||
<t t-call="survey.survey_progression"
|
||||
t-if="survey and survey.questions_layout != 'one_page' and answer and answer.state == 'in_progress' and (not question or not question.is_page) and not survey_form_readonly">
|
||||
<t t-if="survey.questions_layout == 'page_per_section'">
|
||||
<t t-set="page_ids" t-value="survey.page_ids.ids"/>
|
||||
<t t-set="page_number" t-value="page_ids.index(page.id) + (1 if survey.progression_mode == 'number' else 0)"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-if="not answer.is_session_answer and survey.questions_selection == 'random'">
|
||||
<t t-set="page_ids" t-value="answer.predefined_question_ids.ids"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-set="page_ids" t-value="survey.question_ids.ids"/>
|
||||
</t>
|
||||
<t t-set="page_number" t-value="page_ids.index(question.id)"/>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
<div class="o_survey_brand_message float-end rounded me-3 border">
|
||||
<div class="px-2 py-2 d-inline-block" t-call="web.brand_promotion_message">
|
||||
<t t-set="_message"></t>
|
||||
<t t-set="_utm_medium" t-valuef="survey"/>
|
||||
</div>
|
||||
<div class="o_survey_navigation_wrapper d-inline-block" t-call="survey.survey_navigation">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- Main survey template -->
|
||||
<template id="survey_page_fill" name="Survey: main page (take survey)">
|
||||
<t t-call="survey.layout">
|
||||
<t t-if="answer.test_entry" t-call="survey.survey_button_form_view" />
|
||||
<div class="wrap o_survey_wrap d-flex">
|
||||
<div class="container o_survey_form d-flex flex-column mb-5">
|
||||
<t t-call="survey.survey_fill_header" />
|
||||
<t t-call="survey.survey_fill_form" />
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="survey_fill_header" name="Survey: main page header">
|
||||
<div class="o_survey_nav pt16 mb-2">
|
||||
<div class="container m-0 p-0">
|
||||
<div class="row">
|
||||
<div class="col-lg-10">
|
||||
<h1 t-if="answer.state == 'new' or survey.questions_layout != 'page_per_question'"
|
||||
t-esc="survey.title" class="o_survey_main_title pt-4"></h1>
|
||||
</div>
|
||||
<div class="o_survey_timer col-lg-2 pt-4">
|
||||
<h1 class="o_survey_timer_container timer text-end">
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div t-att-class="'o_survey_breadcrumb_container mt8' + (' d-none ' if answer.state != 'in_progress' else '')"
|
||||
t-if="not survey.has_conditional_questions and survey.questions_layout == 'page_per_section' and answer.state != 'done'"
|
||||
t-att-data-can-go-back="survey.users_can_go_back"
|
||||
t-att-data-pages="json.dumps(breadcrumb_pages)" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="survey_fill_form" name="Survey: main page content">
|
||||
<t t-set="survey_form_readonly" t-value="answer.state == 'done'"/>
|
||||
<t t-set="background_image_url"
|
||||
t-value="question.background_image_url
|
||||
if question else page.background_image_url
|
||||
if page else survey.background_image_url
|
||||
if survey.background_image_url else False"/>
|
||||
<form role="form" method="post" t-att-name="survey.id"
|
||||
class="d-flex flex-grow-1 align-items-center"
|
||||
t-att-data-answer-token="answer.access_token"
|
||||
t-att-data-survey-token="survey.access_token"
|
||||
t-att-data-users-can-go-back="survey.users_can_go_back and not answer.is_session_answer"
|
||||
t-att-data-session-in-progress="answer.is_session_answer"
|
||||
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)"
|
||||
t-att-data-refresh-background="any(page.background_image for page in survey.page_ids)">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
||||
<input type="hidden" name="token" t-att-value="answer.access_token" />
|
||||
<div class="o_survey_error alert alert-danger d-none" role="alert">
|
||||
<p>There was an error during the validation of the survey.</p>
|
||||
</div>
|
||||
|
||||
<div class="o_survey_form_content w-100">
|
||||
<t t-if="answer.state == 'new'" t-call="survey.survey_fill_form_start"/>
|
||||
<t t-elif="answer.state == 'in_progress'" t-call="survey.survey_fill_form_in_progress" />
|
||||
<t t-else="" t-call="survey.survey_fill_form_done"/>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<!-- Modal used to display error message, i.c.o. ajax error -->
|
||||
<div role="dialog" class="modal fade" id="MasterTabErrorModal" >
|
||||
<div class="modal-dialog">
|
||||
<div class="modal-content">
|
||||
<header class="modal-header">
|
||||
<h4 class="modal-title">A problem has occurred</h4>
|
||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||
</header>
|
||||
<main class="modal-body"><p>To take this survey, please close all other tabs on <strong class="text-danger"></strong>.</p></main>
|
||||
<footer class="modal-footer"><button type="button" class="btn btn-primary" data-bs-dismiss="modal">Continue here</button></footer>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="survey_fill_form_start" name="Survey: start form content">
|
||||
<div class="wrap o_survey_start">
|
||||
<div class='mb32'>
|
||||
<div t-field='survey.description' class="oe_no_empty pb-5 text-break"/>
|
||||
<t t-if="answer.is_session_answer">
|
||||
<div class="fw-bold">
|
||||
The session will begin automatically when the host starts.
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div t-if="survey.is_time_limited">
|
||||
<p>
|
||||
<span t-if="not survey.certification">Time limit for this survey: </span>
|
||||
<span t-else="">Time limit for this certification: </span>
|
||||
<span class="fw-bold text-danger" t-field="survey.time_limit" t-options="{'widget': 'duration', 'unit': 'minute'}"></span>
|
||||
</p>
|
||||
</div>
|
||||
<button type="submit" value="start" class="btn btn-primary btn-lg disabled">
|
||||
<t t-if="survey.certification">
|
||||
Start Certification
|
||||
</t>
|
||||
<t t-else="">
|
||||
Start Survey
|
||||
</t>
|
||||
</button>
|
||||
<span class="o_survey_enter fw-bold text-muted ms-2 d-none d-md-inline">or press Enter</span>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="survey_fill_form_in_progress" name="Survey: form with questions">
|
||||
<div class="o_survey_form_content_data d-none"
|
||||
t-att-data-question-time-limit-reached="answer.question_time_limit_reached"
|
||||
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-server-time="server_time"
|
||||
t-att-data-timer="timer_start"
|
||||
t-att-data-time-limit-minutes="time_limit_minutes"/>
|
||||
<t t-if="survey.questions_layout == 'one_page'">
|
||||
<t t-foreach='survey.question_and_page_ids' t-as='question'>
|
||||
<h2 t-if="question.is_page" t-field='question.title' class="o_survey_title pb16 text-break" />
|
||||
<div t-if="question.is_page" t-field='question.description' class="text-break"/>
|
||||
<t t-if="not question.is_page and question in answer.predefined_question_ids" t-call="survey.question_container"/>
|
||||
</t>
|
||||
|
||||
<div class="text-center mt16 mb256">
|
||||
<button type="submit" value="finish" class="btn btn-primary disabled">Submit</button>
|
||||
<span class="fw-bold text-muted ms-2 d-none d-md-inline">
|
||||
<span id="enter-tooltip">or press Enter</span>
|
||||
</span>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<t t-if="survey.questions_layout == 'page_per_section'">
|
||||
<h2 t-field='page.title' class="o_survey_title pb16 text-break" />
|
||||
<div t-field='page.description' class="oe_no_empty text-break"/>
|
||||
|
||||
<input type="hidden" name="page_id" t-att-value="page.id" />
|
||||
<t t-foreach='page.question_ids' t-as='question'>
|
||||
<t t-if="question in answer.predefined_question_ids" t-call="survey.question_container"/>
|
||||
</t>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 text-center mt16">
|
||||
<button type="submit" t-att-value="'next' if not survey_last else 'finish'" class="btn btn-primary disabled">
|
||||
<t t-if="not survey_last">Continue</t>
|
||||
<t t-else="">Submit</t>
|
||||
</button>
|
||||
<span class="fw-bold text-muted ms-2 d-none d-md-inline" id="enter-tooltip"> or press Enter</span>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<!-- If we have a choice question and less than 6 options, we want minimized display.
|
||||
Minimized display means we display the choices vertically (instead of optimized based on screen space).
|
||||
An exception is made for options with images, where we always want to optimize screen space.
|
||||
Numeric, date and datetime questions are also displayed "minimized", with a smaller screen width.-->
|
||||
<t t-set="minimized_display" t-value="survey.questions_layout == 'page_per_question' and len(question.suggested_answer_ids) <= 5 and not any(suggestion.value_image for suggestion in question.suggested_answer_ids)" />
|
||||
<div t-if="survey.questions_layout == 'page_per_question'"
|
||||
t-attf-class="o_survey_page_per_question o_survey_#{question.question_type} #{'o_survey_minimized_display' if minimized_display else ''}">
|
||||
<input type="hidden" name="question_id" t-att-value="question.id" />
|
||||
<!-- User has already answered for this session -->
|
||||
<t t-if="answer.is_session_answer and (has_answered or answer.question_time_limit_reached)">
|
||||
<fieldset disabled="disabled">
|
||||
<t t-set="survey_form_readonly" t-value="True" />
|
||||
<div class="mt-5">
|
||||
<t t-call="survey.question_container" />
|
||||
</div>
|
||||
</fieldset>
|
||||
<div t-if="answer.question_time_limit_reached and not has_answered" class="fw-bold">Sorry, you have not been fast enough.</div>
|
||||
<div t-else="" class="fw-bold">We have registered your answer! Please wait for the host to go to the next question.</div>
|
||||
</t>
|
||||
<t t-elif="answer.is_session_answer and question.is_page and not is_html_empty(question.description)">
|
||||
<div class="fw-bold mt-5">Pay attention to the host screen until the next question.</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div class="mt-5">
|
||||
<t t-call="survey.question_container"/>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-12 text-center mt16">
|
||||
<button type="submit" t-att-value="'next' if not survey_last else 'finish'" class="btn btn-primary disabled">
|
||||
<t t-if="answer.is_session_answer or survey_last">Submit</t>
|
||||
<t t-else="">Continue</t>
|
||||
</button>
|
||||
<span class="fw-bold text-muted ms-2 d-none d-md-inline">
|
||||
<span id="enter-tooltip">or press Enter</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Finished (taken and finished) survey page -->
|
||||
<template id="survey_fill_form_done" name="Survey: finished">
|
||||
<div class="wrap">
|
||||
<div class="o_survey_finished mt32 mb32">
|
||||
<h1>Thank you!</h1>
|
||||
<div t-field="survey.description_done" class="oe_no_empty" />
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<t t-if="survey.scoring_type != 'no_scoring' and survey.scoring_success_min">
|
||||
<div>You scored <t t-esc="answer.scoring_percentage" />%</div>
|
||||
<t t-if="answer.scoring_success">
|
||||
<div>Congratulations, you have passed the test!</div>
|
||||
|
||||
<div t-if="survey.certification" class="mt16 mb16">
|
||||
<a role="button"
|
||||
class="btn btn-primary btn-lg"
|
||||
t-att-href="'/survey/%s/get_certification' % survey.id">
|
||||
<i class="fa fa-fw fa-trophy" role="img" aria-label="Download certification" title="Download certification"/>
|
||||
Download certification
|
||||
</a>
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<div>Unfortunately, you have failed the test.</div>
|
||||
</t>
|
||||
</t>
|
||||
<t t-call="survey.survey_button_retake"/>
|
||||
<div t-if="survey.scoring_type != 'scoring_without_answers'" class="o_survey_review">
|
||||
If you wish, you can <a t-att-href="'/survey/print/%s?answer_token=%s&review=True' % (survey.access_token, answer.access_token)">review your answers</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-6 text-center" t-if="survey.certification_give_badge and answer.scoring_success">
|
||||
<img t-att-src="'/web/image/gamification.badge/%s/image_128' % survey.certification_badge_id.id"/>
|
||||
<div>You received the badge <span class="fw-bold" t-esc="survey.certification_badge_id.name"/>!</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_survey_result p-4 col-12 row" t-if="graph_data">
|
||||
<div t-if="survey.page_ids" class="survey_graph col-lg-6 d-none d-md-block"
|
||||
data-graph-type="by_section"
|
||||
t-att-data-graph-data="graph_data">
|
||||
<canvas id="by_section_chart"></canvas>
|
||||
</div>
|
||||
<div t-attf-class="survey_graph col-lg-6 #{'offset-lg-3' if not survey.page_ids else ''}"
|
||||
data-graph-type="doughnut"
|
||||
t-att-data-graph-data="graph_data">
|
||||
<canvas id="doughnut_chart"></canvas>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Question widgets -->
|
||||
<template id="question_container" name="Survey: question container">
|
||||
<t t-set="display_question"
|
||||
t-value="survey.questions_layout == 'page_per_question'
|
||||
or survey.questions_selection == 'random'
|
||||
or (survey.questions_layout == 'one_page' and not question.is_conditional)
|
||||
or (survey.questions_layout == 'page_per_section' and (not question.is_conditional or triggering_answer_by_question[question.id] in selected_answers))"/>
|
||||
|
||||
<t t-set="answer_lines" t-value="answer.user_input_line_ids.filtered(lambda line: line.question_id == question)"/>
|
||||
<!--Use Key selection if number of choices is < 26 to keep Z for other choice if any-->
|
||||
<t t-set="letters" t-value="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
|
||||
<t t-set="useKeySelection" t-value="len(question.suggested_answer_ids) < len(letters) and survey.questions_layout == 'page_per_question'"/>
|
||||
<!-- Extra 'right' margin is added on layouts that are not "page_per_question" to align with choices questions, since all choices have a me-2 class (pixel perfect yay...) -->
|
||||
<t t-set="extra_right_margin" t-value="survey.questions_layout != 'page_per_question' and question.question_type not in ['simple_choice', 'multiple_choice']"/>
|
||||
<t t-set="default_constr_error_msg">This question requires an answer.</t>
|
||||
<t t-set="default_validation_error_msg">The answer you entered is not valid.</t>
|
||||
<t t-set="default_comments_message">If other, please specify:</t>
|
||||
<div t-att-class="'js_question-wrapper pb-4 %s %s' % ('d-none' if not display_question else '', 'me-2' if extra_right_margin else '')"
|
||||
t-att-id="question.id" t-att-data-required="question.constr_mandatory"
|
||||
t-att-data-constr-error-msg="question.constr_error_msg or default_constr_error_msg"
|
||||
t-att-data-validation-error-msg="question.validation_error_msg or default_validation_error_msg">
|
||||
<div class="mb-4">
|
||||
<h3 t-if="not hide_question_title">
|
||||
<span t-field='question.title' class="text-break" />
|
||||
<span t-if="question.constr_mandatory" class="text-danger">*</span>
|
||||
</h3>
|
||||
<div t-if="not is_html_empty(question.description)" t-field='question.description' class="text-muted oe_no_empty mt-1 text-break"/>
|
||||
</div>
|
||||
<t t-if="question.question_type == 'text_box'"><t t-call="survey.question_text_box"/></t>
|
||||
<t t-if="question.question_type == 'char_box'"><t t-call="survey.question_char_box"/></t>
|
||||
<t t-if="question.question_type == 'numerical_box'"><t t-call="survey.question_numerical_box"/></t>
|
||||
<t t-if="question.question_type == 'date'"><t t-call="survey.question_date"/></t>
|
||||
<t t-if="question.question_type == 'datetime'"><t t-call="survey.question_datetime"/></t>
|
||||
<t t-if="question.question_type == 'simple_choice'"><t t-call="survey.question_simple_choice"/></t>
|
||||
<t t-if="question.question_type == 'multiple_choice'"><t t-call="survey.question_multiple_choice"/></t>
|
||||
<t t-if="question.question_type == 'matrix'"><t t-call="survey.question_matrix"/></t>
|
||||
<div class="o_survey_question_error overflow-hidden border-0 py-0 px-3 alert alert-danger" role="alert"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="question_text_box" name="Question: free text box">
|
||||
<div class="o_survey_comment_container p-0">
|
||||
<textarea class="form-control o_survey_question_text_box bg-transparent rounded-0 p-0" rows="3"
|
||||
t-att-name="question.id" t-att-placeholder="question.question_placeholder"
|
||||
t-att-data-question-type="question.question_type"><t t-if="answer_lines" t-esc="answer_lines[0].value_text_box or None"/></textarea>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="question_char_box" name="Question: text box">
|
||||
<div class="o_survey_comment_container p-0">
|
||||
<input t-att-type="'email' if question.validation_email else 'text'"
|
||||
class="form-control o_survey_question_text_box bg-transparent rounded-0 p-0"
|
||||
t-att-name="question.id" t-att-placeholder="question.question_placeholder"
|
||||
t-att-value="answer_lines[0].value_char_box if answer_lines else None"
|
||||
t-att-data-question-type="question.question_type"
|
||||
t-att-data-validation-length-min="question.validation_length_min if question.validation_required else False"
|
||||
t-att-data-validation-length-max="question.validation_length_max if question.validation_required else False"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="question_numerical_box" name="Question: numerical box">
|
||||
<input type="number" step="any" class="form-control o_survey_question_numerical_box bg-transparent rounded-0 p-0"
|
||||
t-att-name="question.id" t-att-placeholder="question.question_placeholder"
|
||||
t-att-value="answer_lines[0].value_numerical_box if answer_lines else None"
|
||||
t-att-data-question-type="question.question_type"
|
||||
t-att-data-validation-float-min="question.validation_min_float_value if question.validation_required else False"
|
||||
t-att-data-validation-float-max="question.validation_max_float_value if question.validation_required else False"/>
|
||||
</template>
|
||||
|
||||
<template id="question_date" name="Question: date box">
|
||||
<div class="input-group o_survey_form_date" t-attf-id="datetimepicker_#{question.id}" data-target-input="nearest"
|
||||
t-att-data-mindate="question.validation_min_date"
|
||||
t-att-data-maxdate="question.validation_max_date">
|
||||
<input type="text" class="form-control datetimepicker-input o_survey_question_date bg-transparent rounded-0 p-0"
|
||||
t-attf-data-target="#datetimepicker_#{question.id}"
|
||||
t-att-name="question.id" t-att-placeholder="question.question_placeholder"
|
||||
t-att-value="format_date(answer_lines[0].value_date) if answer_lines else None"
|
||||
t-att-data-question-type="question.question_type"/>
|
||||
<div t-if="not survey_form_readonly" class="position-absolute input-group-text text-primary border-0 bg-transparent p-0" t-attf-data-target="#datetimepicker_#{question.id}" data-toggle="datetimepicker"><i class="fa fa-calendar"></i></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="question_datetime" name="Question: datetime box">
|
||||
<div class="input-group o_survey_form_date" t-attf-id="datetimepicker_#{question.id}" data-target-input="nearest"
|
||||
t-att-data-mindate="question.validation_min_datetime"
|
||||
t-att-data-maxdate="question.validation_max_datetime">
|
||||
<input type="text" class="form-control datetimepicker-input o_survey_question_datetime bg-transparent rounded-0 p-0"
|
||||
t-attf-data-target="#datetimepicker_#{question.id}"
|
||||
t-att-name="question.id" t-att-placeholder="question.question_placeholder"
|
||||
t-att-value="format_datetime(answer_lines[0].value_datetime) if answer_lines else None"
|
||||
t-att-data-question-type="question.question_type"/>
|
||||
<div t-if="not survey_form_readonly" class="position-absolute input-group-text text-primary border-0 bg-transparent p-0" t-attf-data-target="#datetimepicker_#{question.id}" data-toggle="datetimepicker"><i class="fa fa-calendar"></i></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="question_suggested_value_image" name="Image from the question suggested answer">
|
||||
<t t-if="label.value_image">
|
||||
<!-- Directly use field or route if the user doesn't have access rights -->
|
||||
<div t-if="not env.user.has_group('survey.group_survey_user')"
|
||||
class="o_survey_choice_img d-flex my-3 justify-content-center">
|
||||
<img t-att-src="'/survey/get_question_image/%s/%s/%s/%s' % (survey.access_token, answer.access_token, question.id, label.id)"/>
|
||||
</div>
|
||||
<div t-else="" t-field="label.value_image"
|
||||
class="o_survey_choice_img d-flex my-3 justify-content-center"
|
||||
t-options="{'widget': 'image', 'alt-field': 'name', 'itemprop': 'image'}"/>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="question_simple_choice" name="Question: simple choice">
|
||||
<t t-set="answer_line" t-value="answer_lines.filtered(lambda line: line.suggested_answer_id)"/>
|
||||
<t t-set="comment_line" t-value="answer_lines.filtered(lambda line: line.value_char_box)"/>
|
||||
<div class="row o_survey_form_choice"
|
||||
t-att-data-name="question.id"
|
||||
data-question-type="simple_choice_radio">
|
||||
<t t-set="item_idx" t-value="0"/>
|
||||
<div t-attf-class="col-lg-12 d-flex flex-wrap">
|
||||
<t t-set="has_correct_answer" t-value="scoring_display_correction and any(label.is_correct for label in question.suggested_answer_ids)"/>
|
||||
<t t-foreach='question.suggested_answer_ids' t-as='label'>
|
||||
<t t-set="item_idx" t-value="label_index"/>
|
||||
<t t-set="answer_selected" t-value="answer_line and answer_line.suggested_answer_id.id == label.id"/>
|
||||
<t t-set="is_correct" t-value="label.is_correct"/>
|
||||
|
||||
<!--Used for print mode with corrections -->
|
||||
<t t-set="answer_class" t-if="not has_correct_answer" t-value="''" />
|
||||
<t t-set="answer_class" t-elif="is_correct" t-value="'bg-success'" />
|
||||
<t t-set="answer_class" t-elif="not is_correct" t-value="'bg-danger'" />
|
||||
|
||||
<label t-att-for="str(question.id) + '_' + str(label.id)"
|
||||
t-att-class="'o_survey_choice_btn me-2 mb-2 py-1 px-3 rounded %s %s' % (answer_class, 'o_survey_selected' if answer_selected else '')">
|
||||
<t t-call="survey.survey_selection_key">
|
||||
<t t-set="selection_key_class" t-value="'position-relative o_survey_radio_btn float-start d-flex'"/>
|
||||
</t>
|
||||
<span class="ms-2 text-break" t-field='label.value'/>
|
||||
<input t-att-id="str(question.id) + '_' + str(label.id)" type="radio" t-att-value='label.id'
|
||||
t-attf-class="o_survey_form_choice_item invisible position-absolute #{'o_survey_form_choice_item_selected' if answer_selected else ''}"
|
||||
t-att-name='question.id'
|
||||
t-att-checked="'checked' if answer_selected else None"
|
||||
t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"/>
|
||||
<t t-if="has_correct_answer and answer_selected">
|
||||
<!-- While displaying results: change icons to have a check mark for a right answer and a cross for a wrong one -->
|
||||
<i t-if="is_correct" class="float-end mt-1 position-relative d-inline fa fa-check-circle"/>
|
||||
<i t-else="" class="float-end mt-1 position-relative d-inline fa fa-times-circle"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<i class="fa fa-check-circle float-end mt-1 position-relative"></i>
|
||||
<i class="fa fa-circle-thin float-end mt-1 position-relative"></i>
|
||||
</t>
|
||||
<t t-call="survey.question_suggested_value_image"/>
|
||||
</label>
|
||||
</t>
|
||||
</div>
|
||||
<div t-if='question.comments_allowed and question.comment_count_as_answer' class="js_comments col-lg-12" >
|
||||
<div class="d-flex flex-wrap">
|
||||
<label t-att-class="'o_survey_choice_btn form-label me-2 py-1 px-3 rounded %s' % ('o_survey_selected' if comment_line else '')">
|
||||
<t t-set="item_idx" t-value="item_idx + 1"/>
|
||||
<t t-call="survey.survey_selection_key">
|
||||
<t t-set="selection_key_class" t-value="'position-relative o_survey_radio_btn float-start d-flex'"/>
|
||||
</t>
|
||||
<input type="radio" class="o_survey_form_choice_item o_survey_js_form_other_comment invisible position-absolute" value="-1"
|
||||
t-att-name='question.id'
|
||||
t-att-checked="comment_line and 'checked' or None"
|
||||
t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"/>
|
||||
<span class="ms-2" t-out="question.comments_message or default_comments_message" />
|
||||
<i class="fa fa-check-circle float-end mt-1 position-relative"></i>
|
||||
<i class="fa fa-circle-thin float-end mt-1 position-relative"></i>
|
||||
</label>
|
||||
</div>
|
||||
<div t-attf-class="o_survey_comment_container mt-3 py-0 px-1 #{'d-none' if not comment_line else ''}">
|
||||
<textarea type="text" class="form-control o_survey_question_text_box bg-transparent rounded-0 p-0"
|
||||
t-att-disabled="None if comment_line else 'disabled'"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if='question.comments_allowed and not question.comment_count_as_answer' class="col-lg-12 o_survey_comment_container mx-1 mt-3 ps-3 pe-4">
|
||||
<textarea type="text" class="form-control o_survey_comment o_survey_question_text_box bg-transparent rounded-0 p-0"
|
||||
t-att-placeholder="question.comments_message or default_comments_message if not survey_form_readonly else ''"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="question_multiple_choice" name="Question: multiple choice">
|
||||
<t t-set="comment_line" t-value="answer_lines.filtered(lambda line: line.value_char_box)"/>
|
||||
<div class="row o_survey_form_choice o_survey_question_multiple_choice"
|
||||
t-att-data-name="question.id"
|
||||
t-att-data-question-type="question.question_type">
|
||||
<t t-set="item_idx" t-value="0"/>
|
||||
<div class="d-flex flex-wrap col-lg-12">
|
||||
<t t-set="has_correct_answer" t-value="scoring_display_correction and any(label.is_correct for label in question.suggested_answer_ids)"/>
|
||||
<t t-foreach='question.suggested_answer_ids' t-as='label'>
|
||||
<t t-set="item_idx" t-value="label_index"/>
|
||||
<t t-set="answer_line" t-value="answer_lines.filtered(lambda line: line.suggested_answer_id == label)"/>
|
||||
<t t-set="answer_selected" t-value="answer_line and answer_line.suggested_answer_id.id == label.id"/>
|
||||
<t t-set="is_correct" t-value="label.is_correct"/>
|
||||
|
||||
<!--Used for print mode with corrections -->
|
||||
<t t-set="answer_class" t-if="not has_correct_answer" t-value="''" />
|
||||
<t t-set="answer_class" t-elif="is_correct" t-value="'bg-success'" />
|
||||
<t t-set="answer_class" t-elif="not is_correct" t-value="'bg-danger'" />
|
||||
|
||||
<label t-att-class="'o_survey_choice_btn form-label me-2 py-1 px-3 rounded %s %s' % (answer_class, 'o_survey_selected' if answer_line else '')">
|
||||
<t t-call="survey.survey_selection_key">
|
||||
<t t-set="selection_key_class" t-value="'position-relative float-start d-flex'"/>
|
||||
</t>
|
||||
<input type="checkbox" t-att-value='label.id' class="o_survey_form_choice_item invisible position-absolute"
|
||||
t-att-name="question.id"
|
||||
t-att-checked="'checked' if answer_line else None"
|
||||
t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"/>
|
||||
<span class="ms-2 text-break" t-field='label.value'/>
|
||||
<t t-if="has_correct_answer and answer_selected">
|
||||
<!-- While displaying results: change icons to have a check mark for a right answer and a cross for a wrong one -->
|
||||
<i t-if="is_correct" class="float-end mt-1 position-relative d-inline fa fa-check-circle"/>
|
||||
<i t-else="" class="float-end mt-1 position-relative d-inline fa fa-times-circle"/>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<i class="fa fa-check-circle float-end mt-1 position-relative"></i>
|
||||
<i class="fa fa-circle-thin float-end mt-1 position-relative"></i>
|
||||
</t>
|
||||
<t t-call="survey.question_suggested_value_image"/>
|
||||
</label>
|
||||
</t>
|
||||
</div>
|
||||
<div t-if='question.comments_allowed and question.comment_count_as_answer' class="js_ck_comments col-lg-12" >
|
||||
<div class="d-flex flex-wrap">
|
||||
<label t-att-class="'o_survey_choice_btn form-label me-2 py-1 px-3 rounded %s' % ('o_survey_selected' if comment_line else '')">
|
||||
<t t-set="item_idx" t-value="item_idx + 1"/>
|
||||
<t t-call="survey.survey_selection_key">
|
||||
<t t-set="selection_key_class" t-value="'position-relative float-start d-flex'"/>
|
||||
</t>
|
||||
<input type="checkbox" class="o_survey_form_choice_item o_survey_js_form_other_comment invisible position-absolute" value="-1"
|
||||
t-att-name="question.id"
|
||||
t-att-checked="comment_line and 'checked' or None"
|
||||
t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"/>
|
||||
<span class="ms-2" t-out="question.comments_message or default_comments_message" />
|
||||
<i class="fa fa-check-circle float-end mt-1 position-relative"></i>
|
||||
<i class="fa fa-circle-thin float-end mt-1 position-relative"></i>
|
||||
</label>
|
||||
</div>
|
||||
<div t-attf-class="o_survey_comment_container mt-3 py-0 px-1 #{'d-none' if not comment_line else ''}">
|
||||
<textarea type="text" class="form-control o_survey_question_text_box bg-transparent rounded-0 p-0"
|
||||
t-att-disabled="None if comment_line else 'disabled'"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if='question.comments_allowed and not question.comment_count_as_answer' class="col-lg-12 o_survey_comment_container mx-1 mt-3 py-0 ps-3 pe-4">
|
||||
<textarea type="text" class="form-control o_survey_comment o_survey_question_text_box bg-transparent rounded-0 p-0"
|
||||
t-att-placeholder="question.comments_message or default_comments_message if not survey_form_readonly else ''"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="question_matrix" name="Question: matrix">
|
||||
<t t-set="comment_line" t-value="answer_lines.filtered(lambda line: line.value_char_box)"/>
|
||||
<table class="table table-borderless o_survey_question_matrix text-white text-center mb-0"
|
||||
t-att-data-name="question.id"
|
||||
t-att-data-question-type="question.question_type"
|
||||
t-att-data-sub-questions="question.matrix_row_ids.ids">
|
||||
<thead>
|
||||
<tr>
|
||||
<th> </th>
|
||||
<th class="fw-normal" t-foreach="question.suggested_answer_ids" t-as="col_label"><span t-field="col_label.value" /></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-set="item_idx" t-value="0"/>
|
||||
<!-- For matrix, we have an extra check because we have rows * columns total options -->
|
||||
<t t-set="useKeySelection" t-value="useKeySelection and (len(question.suggested_answer_ids) * len(question.matrix_row_ids)) < len(letters)" />
|
||||
<tr class="bg-white text-white" t-foreach="question.matrix_row_ids" t-as="row_label" t-att-id="row_label.id">
|
||||
<th class="fw-normal text-start"><span t-field="row_label.value" /></th>
|
||||
<t t-foreach="question.suggested_answer_ids" t-as="col_label">
|
||||
<t t-set="answer" t-value="answer_lines.filtered(lambda line: line.suggested_answer_id == col_label and line.matrix_row_id == row_label)"/>
|
||||
<td t-att-class="'o_survey_matrix_btn text-primary position-relative %s'
|
||||
% ('o_survey_selected' if answer else '')">
|
||||
<input t-att-type="'checkbox' if question.matrix_subtype == 'multiple' else 'radio'"
|
||||
t-att-name="'%s_%s' % (question.id, row_label.id)" t-att-value='col_label.id'
|
||||
t-att-checked="'checked' if answer else None"
|
||||
t-att-data-row-id="row_label.id"
|
||||
t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"
|
||||
class="o_survey_form_choice_item d-none"/>
|
||||
<i t-att-class="'o_survey_matrix_empty_checkbox fa fa-%s position-relative'
|
||||
% ('square-o' if question.matrix_subtype == 'multiple' else 'circle-thin')"></i>
|
||||
<i t-att-class="'fa fa-%s position-relative'
|
||||
% ('check-square' if question.matrix_subtype == 'multiple' else 'check-circle')"></i>
|
||||
<t t-call="survey.survey_selection_key">
|
||||
<t t-set="selection_key_class"
|
||||
t-value="'position-absolute float-end fw-bold %s' % ('o_survey_radio_btn' if question.matrix_subtype != 'multiple' else '')"/>
|
||||
</t>
|
||||
<t t-set="item_idx" t-value="item_idx + 1"/>
|
||||
</td>
|
||||
</t>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div t-if='question.comments_allowed'>
|
||||
<textarea type="text" class="form-control o_survey_question_text_box o_survey_comment bg-transparent rounded-0 p-0 mt-3"
|
||||
t-att-placeholder="question.comments_message or default_comments_message if not survey_form_readonly else ''"
|
||||
t-att-name="'%s_%s' % (question.id, 'comment')"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="survey_selection_key">
|
||||
<div t-if="useKeySelection" t-att-class="'o_survey_choice_key bg-white rounded %s' % selection_key_class">
|
||||
<span class="o_survey_key text-center position-absolute bg-white rounded-start py-0 ps-2"><span class="text-primary text-center text-center w-100 position-relative">Key</span></span>
|
||||
<span class="text-primary text-center w-100 position-relative" t-esc="letters[item_idx]"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="survey_progression" name="Survey: Progression">
|
||||
<t t-if="len(page_ids) > 1 and not survey.has_conditional_questions">
|
||||
<t t-set="percentage" t-value="round(100*(page_number/len(page_ids)))"/>
|
||||
<t t-if="survey.progression_mode == 'percent'">
|
||||
<span class="o_survey_progress_percent" t-esc="percentage"/> % completed
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span class="o_survey_progress_number" t-esc="page_number"/> of <span t-esc="len(page_ids)"/>
|
||||
<span t-if="survey.questions_layout == 'page_per_question'">answered</span>
|
||||
<span t-else="">pages</span>
|
||||
</t>
|
||||
<div class="o_survey_progress progress flex-grow-1">
|
||||
<div class="progress-bar bg-primary" t-att-style="'width: ' + str(percentage) + '%'"/>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,161 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo><data>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<!-- Errors / Corner case management -->
|
||||
<!-- ============================================================ -->
|
||||
|
||||
<!-- Forbidden error messages-->
|
||||
<template id="survey_403_page" name="Survey: custom 403 page">
|
||||
<t t-call="survey.layout">
|
||||
<div id="wrap">
|
||||
<div class="container">
|
||||
<h1 class="mt32">403: Forbidden</h1>
|
||||
<p>The page you were looking for could not be authorized.</p>
|
||||
<p>Maybe you were looking for
|
||||
<a t-attf-href="/web#view_type=form&model=survey.survey&id=#{survey.id}&action=survey.action_survey_form">this page</a> ?
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Error: void survey -->
|
||||
<template id="survey_void_content" name="Survey: void content">
|
||||
<t t-call="survey.layout">
|
||||
<t t-if="answer.test_entry" t-call="survey.survey_button_form_view" />
|
||||
<div class="wrap">
|
||||
<div class="container">
|
||||
<div class="jumbotron mt32">
|
||||
<h1><span t-field="survey.title"/> survey is empty</h1>
|
||||
<p t-if="env.user.has_group('survey.group_survey_user')">
|
||||
Please make sure you have at least one question in your survey. You also need at least one section if you chose the "Page per section" layout.<br />
|
||||
<a t-att-href="'/web#view_type=form&model=survey.survey&id=%s&action=survey.action_survey_form' % survey.id"
|
||||
class="btn btn-secondary"
|
||||
groups="survey.group_survey_manager">Edit in backend</a>
|
||||
</p>
|
||||
<p t-else="">
|
||||
No question yet, come back later.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Error: auth required -->
|
||||
<template id="survey_auth_required" name="Survey: login required">
|
||||
<t t-call="survey.layout">
|
||||
<div class="wrap">
|
||||
<div class="container">
|
||||
<div class="jumbotron mt32">
|
||||
<h1>Login required</h1>
|
||||
<p>This survey is open only to registered people. Please
|
||||
<a t-att-href="redirect_url">log in</a>.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- Expired (closed) survey page -->
|
||||
<template id="survey_closed_expired" name="Survey: expired">
|
||||
<t t-call="survey.layout">
|
||||
<div class="wrap">
|
||||
<div class="container">
|
||||
<div class="jumbotron mt32">
|
||||
<h1><span t-field="survey.title"/> survey expired</h1>
|
||||
<p>This survey is now closed. Thank you for your interest !</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<!-- Tools / Utilities -->
|
||||
<!-- ============================================================ -->
|
||||
|
||||
<template id="survey_button_form_view" name="Survey: back to form view">
|
||||
<div groups="survey.group_survey_manager" t-ignore="true" class="alert alert-info p-2 border-0 rounded-0 d-print-none css_editable_mode_hidden mb-0">
|
||||
<div t-ignore="true" class="text-center">
|
||||
<a t-attf-href="/web#view_type=form&model=survey.survey&id=#{survey.id}&action=survey.action_survey_form"><span t-if="answer and answer.test_entry">This is a Test Survey. </span><i class="fa fa-fw fa-arrow-right"/>Edit Survey</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="survey_button_retake" name="Survey: retake button">
|
||||
<div>
|
||||
<t t-if="not answer.scoring_success and not answer.is_session_answer">
|
||||
<t t-if="survey.is_attempts_limited">
|
||||
<t t-set="attempts_left" t-value="survey._get_number_of_attempts_lefts(answer.partner_id, answer.email, answer.invite_token)" />
|
||||
<t t-if="attempts_left > 0">
|
||||
<p><span>Number of attempts left</span>: <span t-esc="attempts_left"></span></p>
|
||||
<p><a role="button" class="btn btn-primary btn-lg" t-att-href="'/survey/retry/%s/%s' % (survey.access_token, answer.access_token)">
|
||||
Retry</a></p>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<p><a role="button" class="btn btn-primary btn-lg" t-att-href="'/survey/retry/%s/%s' % (survey.access_token, answer.access_token)">
|
||||
Take Again</a></p>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Survey Home page - Session Code
|
||||
Used in 'session mode' to give an easy access to the survey through the '/s' route. -->
|
||||
<template id="survey_session_code" name="Survey: Access Code page">
|
||||
<t t-call="survey.layout">
|
||||
<div class="wrap o_survey_wrap pb16 d-flex">
|
||||
<div class="container o_survey_quick_access d-flex flex-column">
|
||||
<div class="d-flex flex-grow-1 align-items-center">
|
||||
<div class="w-100 px-4 px-md-0">
|
||||
<div class="text-center mb32">
|
||||
<h3>Enter Session Code</h3>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-12 col-md-4 offset-md-4 text-center">
|
||||
<input id="session_code"
|
||||
type="text" placeholder="e.g. 4812"
|
||||
autocomplete="off"
|
||||
t-attf-value="{{session_code if session_code else ''}}"
|
||||
class="form-control o_survey_question_text_box fw-bold bg-transparent text-primary text-center rounded-0 p-2 w-100"/>
|
||||
</div>
|
||||
<div class="col-12 col-md-4 offset-md-4 text-center o_survey_error text-danger h4 pt-2 px-0" role="alert">
|
||||
<span t-attf-class="o_survey_session_error_invalid_code {{'d-none' if error != 'survey_wrong' else ''}}">Oops! No survey matches this code.</span>
|
||||
<span t-attf-class="o_survey_session_error_not_launched {{'d-none' if error != 'survey_session_not_launched' else ''}}">The session did not start yet.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-center mt32 p-2">
|
||||
<button groups="survey.group_survey_user" type="button" t-attf-class="o_survey_launch_session btn btn-primary {{'d-none' if error != 'survey_session_not_launched' else ''}}" t-att-data-survey-id="survey_id">Launch Session</button>
|
||||
<button type="submit" t-attf-class="btn btn-primary {{'d-none' if error == 'survey_session_not_launched' and request.env.user.has_group('survey.group_survey_user') else ''}}">Join Session</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="survey_navigation" name="Survey: Navigation">
|
||||
<div class="d-inline-block">
|
||||
<button
|
||||
t-if="survey and survey.users_can_go_back"
|
||||
t-att-disabled="not can_go_back"
|
||||
type="submit" class="btn border-start p-0 shadow-none o_survey_navigation_submit" name="button_submit" value="previous" t-att-data-previous-page-id="previous_page_id">
|
||||
<i class="fa fa-chevron-left p-2" />
|
||||
</button>
|
||||
<t t-set="can_go_forward"
|
||||
t-value="survey and survey.questions_layout in ['page_per_question', 'page_per_section'] and answer and answer.state != 'done' and not answer.is_session_answer"/>
|
||||
<button
|
||||
t-att-disabled="not can_go_forward"
|
||||
type="submit" class="btn border-start p-0 shadow-none o_survey_navigation_submit" t-att-value="'next' if not survey_last else 'finish'">
|
||||
<i class="fa fa-chevron-right p-2" />
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- Survey: printable page view (all pages) -->
|
||||
<template id="survey_page_print" name="Survey: print page">
|
||||
<t t-call="survey.layout">
|
||||
<t t-set="survey_form_readonly" t-value="true"/>
|
||||
<t t-if="answer.test_entry" t-call="survey.survey_button_form_view" />
|
||||
<div class="wrap">
|
||||
<div class="o_survey_print container">
|
||||
<div class='py-5 mt32'>
|
||||
<h1><span t-field='survey.title' class="text-break"/></h1>
|
||||
<t t-if="survey.description"><div t-field='survey.description' class="oe_no_empty text-break"/></t>
|
||||
<t t-if="review" t-call="survey.survey_button_retake"/>
|
||||
</div>
|
||||
<div role="form">
|
||||
<fieldset disabled="disabled">
|
||||
<t t-set="question" t-value="False" />
|
||||
<t t-foreach='survey.question_and_page_ids' t-as='question'>
|
||||
<t t-if="question.is_page and
|
||||
(any(q in questions_to_display for q in question.question_ids)
|
||||
or not is_html_empty(question.description))">
|
||||
<hr t-if="question != survey.page_ids[0]" />
|
||||
<div class="o_page_header mb-5">
|
||||
<h1 t-field='question.title' class="text-break" />
|
||||
<div t-if="question.description" t-field='question.description' class="oe_no_empty"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-if="not question.is_page and not answer or (question in answer.predefined_question_ids & questions_to_display)" >
|
||||
<t t-set="answer_lines" t-value="answer.user_input_line_ids.filtered(lambda line: line.question_id == question)"/>
|
||||
<div class="js_question-wrapper" t-att-id="question.id">
|
||||
<h2>
|
||||
<span t-field='question.title' class="text-break"/>
|
||||
<span t-if="question.constr_mandatory" class="text-danger">*</span>
|
||||
<span t-if="scoring_display_correction" class="badge rounded-pill" t-att-data-score-question="question.id"></span>
|
||||
</h2>
|
||||
<div class="text-muted oe_no_empty mt-1 text-break" t-if="not is_html_empty(question.description)" t-field='question.description'/>
|
||||
<t t-if="question.question_type in ['numerical_box', 'date', 'datetime', 'text_box', 'char_box']">
|
||||
<t t-if="answer_lines">
|
||||
<t t-set="answer_line" t-value="answer_lines[0]"/>
|
||||
<t t-if="answer_line.skipped">
|
||||
<!-- question was skipped, display an orange block with the text "Skipped" in place of the answer -->
|
||||
<div class="row g-0">
|
||||
<div class="col-12 col-md-6 col-lg-4 rounded ps-4 o_survey_question_skipped">
|
||||
<input type="text"
|
||||
t-attf-class="form-control fst-italic o_survey_question_{{question.question_type}} bg-transparent rounded-0 p-0" value="Skipped"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-elif="answer_line.survey_id.scoring_type != 'no_scoring' and question.question_type in ['numerical_box', 'date', 'datetime'] and question['answer_%s' % question.question_type]">
|
||||
<div class="row g-0">
|
||||
<div t-attf-class="col-12 col-md-6 col-lg-4 rounded ps-4 #{'bg-success' if answer_line.answer_is_correct else 'bg-danger'}">
|
||||
<t t-if="question.question_type == 'numerical_box'" t-call="survey.question_numerical_box"/>
|
||||
<t t-if="question.question_type == 'date'" t-call="survey.question_date"/>
|
||||
<t t-if="question.question_type == 'datetime'" t-call="survey.question_datetime"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-if="question.question_type == 'text_box'" t-call="survey.question_text_box"/>
|
||||
<t t-if="question.question_type == 'char_box'" t-call="survey.question_char_box"/>
|
||||
<t t-if="question.question_type == 'numerical_box'" t-call="survey.question_numerical_box"/>
|
||||
<t t-if="question.question_type == 'date'" t-call="survey.question_date"/>
|
||||
<t t-if="question.question_type == 'datetime'" t-call="survey.question_datetime"/>
|
||||
</t>
|
||||
<t t-if="answer_lines.survey_id.scoring_type != 'no_scoring'
|
||||
and question.question_type in ['numerical_box', 'date', 'datetime']
|
||||
and question['answer_%s' % question.question_type]
|
||||
and not answer_line.answer_is_correct">
|
||||
<div class="row g-0">
|
||||
<t t-set="correct_answer" t-value="question['answer_%s' % question.question_type ]"/>
|
||||
<div class="col-12 text-success mt-1">
|
||||
The correct answer was:
|
||||
<strong t-esc="correct_answer" t-if="question.question_type == 'numerical_box'"/>
|
||||
<strong t-esc="format_date(correct_answer)" t-if="question.question_type == 'date'"/>
|
||||
<strong t-esc="format_datetime(correct_answer)" t-if="question.question_type == 'datetime'"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<t t-if="question.question_type == 'text_box'" t-call="survey.question_text_box"/>
|
||||
<t t-if="question.question_type == 'char_box'" t-call="survey.question_char_box"/>
|
||||
<t t-if="question.question_type == 'numerical_box'" t-call="survey.question_numerical_box"/>
|
||||
<t t-if="question.question_type == 'date'" t-call="survey.question_date"/>
|
||||
<t t-if="question.question_type == 'datetime'" t-call="survey.question_datetime"/>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="question.question_type == 'simple_choice'" t-call="survey.question_simple_choice"/>
|
||||
<t t-if="question.question_type == 'multiple_choice'" t-call="survey.question_multiple_choice"/>
|
||||
<t t-if="question.question_type == 'matrix'" t-call="survey.question_matrix"/>
|
||||
<t t-if="question.question_type in ['simple_choice', 'multiple_choice','matrix']">
|
||||
<t t-if="answer_lines">
|
||||
<t t-if="answer_lines[0].skipped">
|
||||
<div class="row g-0">
|
||||
<div class="col-12 o_survey_choice_question_skipped mt-1">
|
||||
This question was skipped
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
<div class="o_survey_question_error overflow-hidden border-0 py-0 px-3 alert alert-danger" role="alert"></div>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<!--Set question to false to avoid background miss match as last question is still in context and is used in survey.layout t-call.-->
|
||||
<t t-set="question" t-value="False"/>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<!-- simple template with no assets, to show title on the certification preview -->
|
||||
<template id="certification_preview">
|
||||
<html>
|
||||
<head>
|
||||
<title t-esc="'%s Preview' % page_title"/>
|
||||
<link rel="shortcut icon" href="/web/static/img/favicon.ico" type="image/x-icon"/>
|
||||
</head>
|
||||
<body style="margin:0;">
|
||||
<iframe type="application/pdf" t-att-src="preview_url" frameBorder="0" width="100%" height="100%"/>
|
||||
</body>
|
||||
</html>
|
||||
</template>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,513 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<template id="survey_page_statistics" name="Survey: result statistics page">
|
||||
<t t-call="survey.layout">
|
||||
<t t-call="survey.survey_button_form_view" />
|
||||
<t t-set="page_record_limit" t-value="10"/><!-- Change this record_limit to change number of record per page-->
|
||||
<div class="container o_survey_result">
|
||||
<t t-call="survey.survey_page_statistics_header" />
|
||||
<t t-call="survey.survey_page_statistics_inner" />
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="survey_page_statistics_header" name="Survey: result statistics header">
|
||||
<div class="o_survey_statistics_header pt-5 mt32">
|
||||
<h1>
|
||||
<span t-field="survey.title"/>
|
||||
<span style="font-size:1.5em;"
|
||||
t-attf-class="fa fa-bar-chart-o #{'fa-bar-chart-o' if survey.scoring_type == 'no_scoring' else 'fa-trophy' if survey.certification else 'fa-question-circle-o'} float-end " role="img" aria-label="Chart" title="Chart"/>
|
||||
</h1>
|
||||
<div t-field="survey.description" class="oe_no_empty"/>
|
||||
<h2 t-if="not question_and_page_data">
|
||||
Sorry, no one answered this survey yet.
|
||||
</h2>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="survey_page_statistics_inner" name="Survey: result statistics content">
|
||||
<div t-if="survey.session_show_leaderboard" class="o_survey_session_leaderboard mb-5 mt-1">
|
||||
<h2 class="mt16 text-uppercase text-muted">Leaderboard</h2>
|
||||
<t t-call="survey.user_input_session_leaderboard"/>
|
||||
</div>
|
||||
<div t-if="question_and_page_data" class="o_survey_results_topbar rounded d-print-none mb-5">
|
||||
<t t-call="survey.survey_results_filters"/>
|
||||
</div>
|
||||
<div t-if="survey.scoring_type in ['scoring_with_answers', 'scoring_without_answers']">
|
||||
<h2 class="mt16 text-uppercase text-muted">Results Overview</h2>
|
||||
<div>Success rate: <span class="fw-bold"><t t-call="survey.survey_remove_unnecessary_decimals">
|
||||
<t t-set="value_to_format" t-value="survey_data['global_success_rate']"/></t>%</span></div>
|
||||
<div class="survey_graph" data-graph-type="pie" t-att-data-graph-data="survey_data['global_success_graph']">
|
||||
<!-- canvas element for drawing pie chart -->
|
||||
<canvas/>
|
||||
</div>
|
||||
<hr/>
|
||||
</div>
|
||||
|
||||
<div t-foreach="question_and_page_data" t-as='question_data'>
|
||||
<t t-set="question" t-value="question_data['question']"/>
|
||||
<t t-if="question_data['is_page']">
|
||||
<h2 class="mt16 text-uppercase text-muted" t-field="question.title"/>
|
||||
<div t-field="question.description" class="oe_no_empty" />
|
||||
<hr class="mt-2 mb-2"/>
|
||||
</t>
|
||||
<div t-else="" class="ms-4 mt-5">
|
||||
<t t-call="survey.survey_page_statistics_question" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="survey_page_statistics_question" name="Question: result statistics">
|
||||
<t t-set="comment_lines" t-value="question_data['comment_line_ids']"/>
|
||||
<t t-set="graph_data" t-value="question_data['graph_data']"/>
|
||||
<t t-set="table_data" t-value="question_data['table_data']"/>
|
||||
|
||||
<div class="o_survey_results_question pb-5 border-bottom">
|
||||
<div class="row mb-3">
|
||||
<div class="col-sm-6">
|
||||
<h5 t-field="question.title" class="me-3"/>
|
||||
</div>
|
||||
<!-- Question info -->
|
||||
<div class="col-sm-6 text-sm-end">
|
||||
<span class="badge text-bg-info ms-0 ms-sm-1 me-1 me-sm-0" t-field='question.question_type'/>
|
||||
<t t-if="question.question_type == 'matrix'">
|
||||
<span class="badge text-bg-info ms-0 ms-sm-1 me-1 me-sm-0" t-field='question.matrix_subtype'/>
|
||||
</t>
|
||||
<!-- Scoring info -->
|
||||
<t t-if="question.question_type in ['numerical_box', 'date', 'datetime']">
|
||||
<span class="badge text-bg-success ms-0 ms-sm-1 me-1 me-sm-0"><span t-esc="question_data['right_inputs_count']" class="me-1"/>Correct</span>
|
||||
<t t-if="question.question_type in ['simple_choice', 'multiple_choice']">
|
||||
<span class="badge text-bg-warning ms-0 ms-sm-1 me-1 me-sm-0" t-if="question.question_type == 'multiple_choice'">
|
||||
<span t-esc="question_data['partial_inputs_count']" class="me-1"/>Partial
|
||||
</span>
|
||||
</t>
|
||||
</t>
|
||||
<!-- Inputs info -->
|
||||
<span class="badge text-bg-info ms-0 ms-sm-1 me-1 me-sm-0">
|
||||
<span t-esc="len(question_data['answer_input_done_ids'])" class="me-1"/>Responded
|
||||
</span>
|
||||
<span class="badge text-bg-info ms-0 ms-sm-1 me-1 me-sm-0">
|
||||
<span t-esc="len(question_data['answer_input_skipped_ids'])" class="me-1"/>Skipped
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Question Description -->
|
||||
<div class="ms-3 text-muted" t-field="question.description"/>
|
||||
|
||||
<!-- Answers -->
|
||||
<t t-set="question_answered" t-value="question_data['answer_input_done_ids']"/>
|
||||
<div t-if="not question_answered" class="alert alert-secondary m-3" role="alert">
|
||||
No one answered this question.
|
||||
</div>
|
||||
|
||||
<t t-if="question_answered and question.question_type in ['text_box', 'char_box']"
|
||||
t-call="survey.question_result_text"/>
|
||||
<t t-elif="question_answered and question.question_type in ['numerical_box', 'date', 'datetime']"
|
||||
t-call="survey.question_result_number_or_date_or_datetime"/>
|
||||
<t t-elif="question.question_type in ['simple_choice', 'multiple_choice']"
|
||||
t-call="survey.question_result_choice"/>
|
||||
<t t-elif="question.question_type in ['matrix']"
|
||||
t-call="survey.question_result_matrix"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="survey_results_filters" name="Survey: Filter results">
|
||||
<t t-set="search_passed_or_failed" t-value="search_failed or search_passed"/>
|
||||
<div class="card-header">
|
||||
<span class="fa fa-filter me-1"/>Filters
|
||||
<span t-if="search_filters or search_finished or search_passed_or_failed"
|
||||
class="o_survey_results_topbar_clear_filters text-primary ms-4">
|
||||
<i class="fa fa-trash me-1"/>Remove all filters
|
||||
</span>
|
||||
</div>
|
||||
<div class="question_and_page_data o_survey_result p-0">
|
||||
<nav class="navbar navbar-light rounded">
|
||||
<div t-if="question_and_page_data" class="justify-content-between w-100">
|
||||
<ul class="nav o_survey_results_topbar_dropdown_filters">
|
||||
<t t-set="dropdown_item_classes" t-translation="off">dropdown-item d-flex align-items-center justify-content-between</t>
|
||||
<li class="nav-item dropdown me-2 my-1">
|
||||
<a href="#" role="button" data-bs-toggle="dropdown"
|
||||
t-attf-class="btn btn-outline-primary dropdown-toggle #{'active' if search_finished else ''}">
|
||||
<span t-if="search_finished">Completed surveys</span>
|
||||
<span t-else="">All surveys</span>
|
||||
</a>
|
||||
<div class="dropdown-menu">
|
||||
<a t-attf-class="#{dropdown_item_classes} filter-finished-or-not #{'active' if not search_finished else ''}">
|
||||
<span>All surveys</span>
|
||||
<span t-if="not search_finished" t-esc="survey_data['count_all']" class="badge rounded-pill text-bg-primary ms-3"/>
|
||||
</a>
|
||||
<a t-attf-class="#{dropdown_item_classes} filter-finished #{'active' if search_finished else ''}">
|
||||
<span>Completed surveys</span>
|
||||
<span t-if="not search_finished" t-esc="survey_data['count_finished']" class="badge rounded-pill text-bg-primary ms-3"/>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
<li t-if="survey.scoring_type != 'no_scoring'" class="nav-item dropdown me-2 my-1">
|
||||
<a href="#" role="button" data-bs-toggle="dropdown"
|
||||
t-attf-class="btn btn-outline-primary dropdown-toggle #{'active' if search_passed_or_failed else ''}">
|
||||
<span t-if="search_failed">Failed only</span>
|
||||
<span t-elif="search_passed">Passed only</span>
|
||||
<span t-else="">Passed and Failed</span>
|
||||
</a>
|
||||
<div class="dropdown-menu">
|
||||
<a t-attf-class="#{dropdown_item_classes} filter-passed-and-failed #{'active' if not search_passed_or_failed else ''}">
|
||||
<span>Passed and Failed</span>
|
||||
<span t-if="not search_passed_or_failed" t-esc="survey_data['count_all']" class="badge rounded-pill text-bg-primary ms-3"/>
|
||||
</a>
|
||||
<a t-attf-class="#{dropdown_item_classes} filter-passed #{'active' if search_passed else ''}">
|
||||
<span>Passed only</span>
|
||||
<span t-if="not search_passed_or_failed" t-esc="survey_data['count_passed']" class="badge rounded-pill text-bg-primary ms-3"/>
|
||||
</a>
|
||||
<a t-attf-class="#{dropdown_item_classes} filter-failed #{'active' if search_failed else ''}">
|
||||
<span>Failed only</span>
|
||||
<span t-if="not search_passed_or_failed" t-esc="survey_data['count_failed']" class="badge rounded-pill text-bg-primary ms-3"/>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="nav o_survey_results_topbar_answer_filters mt-2">
|
||||
<t t-if="search_filters">
|
||||
<li t-foreach="search_filters" t-as="filter_data" class="nav-item me-2 my-1">
|
||||
<span t-attf-class="btn btn-light filter-remove-answer cursor-default">
|
||||
<span t-esc="filter_data['question']"/> | <span t-esc="filter_data['answers']"></span>
|
||||
<i class="fa fa-times filter-remove-answer text-primary"
|
||||
t-att-data-row-id="filter_data['row_id']" t-att-data-answer-id="filter_data['answer_id']"></i>
|
||||
</span>
|
||||
</li>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<p class="my-auto text-muted fst-italic">
|
||||
<span>Click on the filter icon (<span class="fa fa-filter text-primary"/>)
|
||||
next to an answer to filter surveys on similar answers only.</span>
|
||||
</p>
|
||||
</t>
|
||||
</ul>
|
||||
</div>
|
||||
</nav>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="question_result_text" name="Question: text result (text_box, char_box)">
|
||||
<table class="table table-hover table-sm" t-att-id="'survey_table_question_%d' % question.id">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>User Responses</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-foreach="table_data" t-as="input_line">
|
||||
<tr t-if="not input_line.skipped" t-att-class="'d-none' if input_line_index >= page_record_limit else ''">
|
||||
<td>
|
||||
<t t-if="no_print_url"><t t-esc="input_line_index + 1"></t></t>
|
||||
<t t-else="">
|
||||
<a t-att-href="input_line.user_input_id.get_print_url()">
|
||||
<t t-esc="input_line_index + 1"></t>
|
||||
</a>
|
||||
</t>
|
||||
</td>
|
||||
<td>
|
||||
<t t-if="question.question_type == 'text_box'">
|
||||
<span t-if="no_print_url" t-field="input_line.value_text_box" />
|
||||
<a t-else="" t-att-href="input_line.user_input_id.get_print_url()" t-field="input_line.value_text_box"></a>
|
||||
</t>
|
||||
<t t-if="question.question_type == 'char_box'">
|
||||
<span t-if="no_print_url" t-field="input_line.value_char_box" />
|
||||
<a t-else="" t-att-href="input_line.user_input_id.get_print_url()" t-field="input_line.value_char_box"></a>
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
<t t-call="survey.question_table_pagination"/>
|
||||
</template>
|
||||
|
||||
<template id="question_result_number_or_date_or_datetime" name="Question: number or date (and time) result (numerical_box or date or datetime)">
|
||||
<t t-if="question.question_type == 'numerical_box'">
|
||||
<span class="float-end mt8">
|
||||
<div class="btn-group o_survey_results_question_pill" role="group" aria-label="Maximum">
|
||||
<span class="badge text-bg-secondary only_left_radius px-2 pt-1">Maximum </span>
|
||||
<span class="badge text-bg-success only_right_radius px-2 pt-1" t-esc="question_data['numerical_max']"></span>
|
||||
</div>
|
||||
<div class="btn-group o_survey_results_question_pill" role="group" aria-label="Minimum">
|
||||
<span class="badge text-bg-secondary only_left_radius px-2 pt-1">Minimum </span>
|
||||
<span class="badge text-bg-danger only_right_radius px-2 pt-1" t-esc="question_data['numerical_min']"></span>
|
||||
</div>
|
||||
<div class="btn-group o_survey_results_question_pill" role="group" aria-label="Average">
|
||||
<span class="badge text-bg-secondary only_left_radius px-2 pt-1">Average </span>
|
||||
<span class="badge text-bg-warning only_right_radius px-2 pt-1" t-esc="question_data['numerical_average']"></span>
|
||||
</div>
|
||||
</span>
|
||||
</t>
|
||||
|
||||
<ul class="nav nav-tabs d-print-none" role="tablist">
|
||||
<li class="nav-item">
|
||||
<a t-att-href="'#survey_stats_question_%d' % question.id"
|
||||
t-att-aria-controls="'survey_stats_question_%d' % question.id"
|
||||
class="nav-link active" data-bs-toggle="tab" role="tab">
|
||||
<i class="fa fa-list-ol me-1"/>Most Common
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a t-att-href="'#survey_data_question_%d' % question.id"
|
||||
t-att-aria-controls="'survey_data_question_%d' % question.id"
|
||||
class="nav-link" data-bs-toggle="tab" role="tab">
|
||||
<i class="fa fa-list-alt me-1"/>All Data
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div role="tabpanel" class="tab-pane active with-3d-shadow with-transitions" t-att-id="'survey_stats_question_%d' % question.id">
|
||||
<table class="table table-hover table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>User Responses</th>
|
||||
<th>Occurrence</th>
|
||||
<th t-if="question.is_scored_question">Score</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="question_data['common_lines']" t-as="common_line">
|
||||
<td>
|
||||
<t t-if="question.question_type == 'numerical_box'">
|
||||
<t t-set="right_answer" t-value="common_line[0] == question.answer_numerical_box"/>
|
||||
<span t-call="survey.survey_remove_unnecessary_decimals"><t t-set="value_to_format" t-value="common_line[0]"/></span>
|
||||
<i t-if="right_answer" class="fa fa-check"/>
|
||||
</t>
|
||||
<t t-elif="question.question_type == 'date'">
|
||||
<t t-set="right_answer" t-value="common_line[0] == question.answer_date"/>
|
||||
<span t-esc="common_line[0]" t-options='{"widget": "date"}'/>
|
||||
<i t-if="right_answer" class="fa fa-check"/>
|
||||
</t>
|
||||
<t t-elif="question.question_type == 'datetime'">
|
||||
<t t-set="right_answer" t-value="common_line[0] == question.answer_datetime"/>
|
||||
<span t-esc="common_line[0]" t-options='{"widget": "datetime"}'/>
|
||||
<i t-if="right_answer" class="fa fa-check"/>
|
||||
</t>
|
||||
</td>
|
||||
<td><span t-esc="common_line[1]"></span></td>
|
||||
<td t-if="question.is_scored_question">
|
||||
<span t-if="right_answer" t-call="survey.survey_remove_unnecessary_decimals">
|
||||
<t t-set="value_to_format" t-value="question.answer_score"/>
|
||||
</span>
|
||||
<span t-else="">0</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" t-att-id="'survey_data_question_%d' % question.id">
|
||||
<table class="table table-hover table-sm" t-att-id="'survey_table_question_%d' % question.id">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>User Responses</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-foreach="table_data" t-as="input_line">
|
||||
<tr t-if="not input_line.skipped" t-att-class="'d-none' if input_line_index >= page_record_limit else ''">
|
||||
<td>
|
||||
<t t-if="no_print_url"><t t-esc="input_line_index + 1"></t></t>
|
||||
<t t-else="">
|
||||
<a t-att-href="input_line.user_input_id.get_print_url()">
|
||||
<t t-esc="input_line_index + 1"></t>
|
||||
</a>
|
||||
</t>
|
||||
</td>
|
||||
<td>
|
||||
<a t-if="question.question_type == 'numerical_box'" t-att-href="input_line.user_input_id.get_print_url()" t-field="input_line.value_numerical_box"/>
|
||||
<a t-if="question.question_type == 'date'" t-att-href="input_line.user_input_id.get_print_url()" t-field="input_line.value_date"/>
|
||||
<t t-if="question.question_type == 'datetime'">
|
||||
<span t-if="no_print_url" t-field="input_line.value_datetime"/>
|
||||
<a t-else="" t-att-href="input_line.user_input_id.get_print_url()" t-field="input_line.value_datetime"></a>
|
||||
</t>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
</table>
|
||||
<t t-call="survey.question_table_pagination"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="question_result_choice" name="Question: choice result (simple_choice, multiple_choice)">
|
||||
<ul class="nav nav-tabs d-print-none" role="tablist">
|
||||
<li t-if="question_answered" class="nav-item">
|
||||
<a t-att-href="'#survey_graph_question_%d' % question.id"
|
||||
t-att-aria-controls="'survey_graph_question_%d' % question.id"
|
||||
class="nav-link active" data-bs-toggle="tab" role="tab">
|
||||
<i class="fa fa-bar-chart-o"></i>
|
||||
<span t-if="question.question_type == 'simple_choice'">Pie Graph</span>
|
||||
<span t-else="">Graph</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a t-att-href="'#survey_data_question_%d' % question.id"
|
||||
t-att-aria-controls="'survey_data_question_%d' % question.id"
|
||||
t-attf-class="nav-link #{'active' if not question_answered else ''}"
|
||||
data-bs-toggle="tab" role="tab">
|
||||
<i class="fa fa-list-alt me-1"/>Data
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div t-if="question_answered" role="tabpanel" class="tab-pane active survey_graph"
|
||||
t-att-id="'survey_graph_question_%d' % question.id"
|
||||
t-att-data-question-id="question.id"
|
||||
t-att-data-graph-type="'pie' if question.question_type == 'simple_choice' else 'bar'"
|
||||
t-att-data-graph-data="graph_data"
|
||||
t-att-data-right-answers="list(question_data['right_answers'].mapped('value'))">
|
||||
<!-- canvas element for drawing bar chart -->
|
||||
<canvas/>
|
||||
</div>
|
||||
<div role="tabpanel" t-att-id="'survey_data_question_%d' % question.id"
|
||||
t-attf-class="tab-pane #{'active' if not question_answered else ''}">
|
||||
<table class="table table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Answer</th>
|
||||
<th>User Choice</th>
|
||||
<th t-if="question.is_scored_question">Score</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="table_data" t-as="choice_data">
|
||||
<td>
|
||||
<p>
|
||||
<span t-if="question.question_type == 'numerical_box'" t-call="survey.survey_remove_unnecessary_decimals">
|
||||
<t t-set="value_to_format" t-value="choice_data['value']"/>
|
||||
</span>
|
||||
<span t-else="" t-esc="choice_data['value']"/>
|
||||
<i t-if="question.is_scored_question and choice_data['suggested_answer'].is_correct" class="fa fa-check"/>
|
||||
</p>
|
||||
</td>
|
||||
<td class="o_survey_answer">
|
||||
<span t-esc="round(choice_data['count'] * 100.0/ (len(question_data['answer_line_done_ids']) or 1), 2)"></span> %
|
||||
<span t-out="choice_data['count_text']" class="badge text-bg-primary"/>
|
||||
<i t-if="choice_data['suggested_answer'].id and choice_data['count']"
|
||||
class="fa fa-filter text-primary filter-add-answer"
|
||||
t-att-data-question-id="question.id"
|
||||
t-att-data-answer-id="choice_data['suggested_answer'].id"
|
||||
role="img" aria-label="Filter surveys" title="Only show survey results having selected this answer"/>
|
||||
</td>
|
||||
<td t-if="question.is_scored_question" t-call="survey.survey_remove_unnecessary_decimals">
|
||||
<t t-set="value_to_format" t-value="choice_data['suggested_answer'].answer_score"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div t-if="comment_lines" t-call="survey.question_result_comments" />
|
||||
</template>
|
||||
|
||||
<template id="question_result_matrix" name="Question: matrix result (matrix)">
|
||||
<t t-set="graph_data" t-value="question_data['graph_data']"/>
|
||||
<t t-set="table_data" t-value="question_data['table_data']"/>
|
||||
<ul class="nav nav-tabs d-print-none" role="tablist">
|
||||
<li t-if="question_answered" class="nav-item active" >
|
||||
<a t-att-href="'#survey_graph_question_%d' % question.id"
|
||||
t-att-aria-controls="'survey_graph_question_%d' % question.id"
|
||||
class="nav-link active" data-bs-toggle="tab" role="tab">
|
||||
<i class="fa fa-bar-chart me-1"/>Graph
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a t-att-href="'#survey_data_question_%d' % question.id"
|
||||
t-att-aria-controls="'survey_data_question_%d' % question.id"
|
||||
t-attf-class="nav-link #{'active' if not question_answered else ''}" data-bs-toggle="tab" role="tab">
|
||||
<i class="fa fa-list-alt me-1"/>Data
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div t-if="question_answered" role="tabpanel" class="tab-pane active with-3d-shadow with-transitions survey_graph"
|
||||
t-att-id="'survey_graph_question_%d' % question.id"
|
||||
t-att-data-question-id= "question.id"
|
||||
data-graph-type= "multi_bar"
|
||||
t-att-data-graph-data="graph_data">
|
||||
<!-- canvas element for drawing Multibar chart -->
|
||||
<canvas/>
|
||||
</div>
|
||||
<div role="tabpanel" t-attf-class="tab-pane #{'active' if not question_answered else ''}" t-att-id="'survey_data_question_%d' % question.id">
|
||||
<table class="table table-hover table-sm text-end">
|
||||
<thead t-if="table_data">
|
||||
<tr>
|
||||
<th></th>
|
||||
<th class="text-end" t-foreach="table_data[0]['columns']" t-as="column_data">
|
||||
<span t-esc="column_data['suggested_answer'].value"></span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="table_data" t-as="choice_data">
|
||||
<td>
|
||||
<span t-esc="choice_data['row'].value"></span>
|
||||
</td>
|
||||
<td class="o_survey_answer" t-foreach="choice_data['columns']" t-as="column_data">
|
||||
<span t-esc="round(column_data['count'] * 100.0/ (len(question_data['answer_input_done_ids']) or 1), 2)"></span> %
|
||||
<span class="badge text-bg-primary" t-esc="column_data['count']"></span>
|
||||
<i t-if="column_data['count']" class="fa fa-filter text-primary filter-add-answer"
|
||||
t-att-data-question-id="question.id"
|
||||
t-att-data-row-id="choice_data['row'].id"
|
||||
t-att-data-answer-id="column_data['suggested_answer'].id" role="img" aria-label="Filter surveys"
|
||||
title="Only show survey results having selected this answer"></i>
|
||||
<i t-else="" class="o_survey_answer_matrix_whitespace"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div t-if="comment_lines" t-call="survey.question_result_comments" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="question_result_comments" name="Question: comments">
|
||||
<table class="table table-hover table-sm" t-att-id="'survey_table_question_%d' % question.id">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>Comment</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="comment_lines" t-as="input_line">
|
||||
<td>
|
||||
<t t-if="no_print_url"><t t-esc="input_line_index + 1"></t></t>
|
||||
<t t-else="">
|
||||
<a t-att-href="input_line.user_input_id.get_print_url()">
|
||||
<t t-esc="input_line_index + 1"></t>
|
||||
</a>
|
||||
</t>
|
||||
</td>
|
||||
<td>
|
||||
<span t-field="input_line.value_char_box"></span><br/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</template>
|
||||
|
||||
<template id="question_table_pagination" name="Survey: statistics table pagination">
|
||||
<ul t-att-id="'pagination_%d' % question.id" class="pagination" t-att-data-question_id="question.id" t-att-data-record_limit="page_record_limit">
|
||||
<t t-if="len(table_data) > page_record_limit">
|
||||
<t t-set="total" t-value="ceil(len(table_data) / page_record_limit) + 1"/>
|
||||
<li t-foreach="range(1, total)" t-as="num"
|
||||
t-att-class="'page-item o_survey_js_results_pagination %s' % ('active' if num == 1 else '')">
|
||||
<a href="#" class="page-link" t-esc="num"></a>
|
||||
</li>
|
||||
</t>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<template id="survey_remove_unnecessary_decimals" name="Survey: remove .0">
|
||||
<t t-esc="value_to_format if value_to_format % 1 else int(value_to_format)"/>
|
||||
</template>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<template id="user_input_session" name="Survey User Input Session" inherit_id="web.frontend_layout" primary="True">
|
||||
<xpath expr="//div[@id='wrapwrap']" position="before">
|
||||
<!--TODO DBE Fix me : If one day, there is a survey_livechat bridge module, put this in that module-->
|
||||
<t t-set="no_livechat" t-value="True"/>
|
||||
</xpath>
|
||||
<xpath expr="//div[@id='wrapwrap']" position="attributes">
|
||||
<attribute name="t-att-style"
|
||||
add="(('background-image: url(' + survey.session_question_id.background_image_url + ');')
|
||||
if survey.session_question_id and survey.session_question_id.background_image_url
|
||||
else ('background-image: url(' + survey.background_image_url + ');')
|
||||
if survey.background_image_url
|
||||
else '')"/>
|
||||
<attribute name="t-att-class" add="'o_survey_background'"/>
|
||||
</xpath>
|
||||
<xpath expr="//head/t[@t-call-assets][last()]" position="after">
|
||||
<t t-call-assets="survey.survey_assets" lazy_load="True"/>
|
||||
<t t-call-assets="survey.survey_user_input_session_assets" lazy_load="True"/>
|
||||
</xpath>
|
||||
<xpath expr="//header" position="before">
|
||||
<t t-set="no_header" t-value="True"/>
|
||||
<t t-set="no_footer" t-value="True"/>
|
||||
</xpath>
|
||||
<xpath expr="//header" position="after">
|
||||
<div id="wrap" class="oe_structure oe_empty"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="user_input_session_open" name="Survey: Open Session">
|
||||
<t t-call="survey.user_input_session">
|
||||
<div class="wrap py-3 min-vh-100 align-items-center justify-content-center d-flex o_survey_session_open o_survey_session_manage"
|
||||
t-att-data-survey-access-token="survey.access_token"
|
||||
t-att-data-survey-id="survey.id"
|
||||
t-att-data-is-start-screen="True">
|
||||
<div class="w-75 p-4">
|
||||
<div class="text-center">
|
||||
<h1 class="mb-4" t-field="survey.title" />
|
||||
<h2 class="mb-5 fw-normal">
|
||||
<span class="text-break">To join: <span class="text-info o_survey_session_copy" t-esc="survey.session_link"/></span>
|
||||
<input class="o_survey_session_copy_url d-none" type="text" t-att-value="survey.session_link" />
|
||||
</h2>
|
||||
<h2 class="fw-normal"><span>Waiting for attendees...</span>
|
||||
<span class="ms-1 fw-bold o_survey_session_attendees_count" t-esc="survey.session_answer_count" />
|
||||
</h2>
|
||||
</div>
|
||||
<a role="button"
|
||||
class="fw-bold fa fa-chevron-right o_survey_session_navigation o_survey_session_navigation_next p-3" />
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="user_input_session_manage" name="Survey: Manage Session">
|
||||
<t t-call="survey.user_input_session">
|
||||
<t t-call="survey.user_input_session_manage_content" />
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="user_input_session_manage_content" name="Survey User Input Session Manage">
|
||||
<t t-set="question" t-value="survey.session_question_id" />
|
||||
<t t-set="is_scored_question" t-value="any(answer.answer_score for answer in question.suggested_answer_ids)" />
|
||||
<t t-set="show_bar_chart" t-value="question.question_type in ['simple_choice', 'multiple_choice']" />
|
||||
<t t-set="show_text_answers" t-value="question.question_type in ['char_box', 'date', 'datetime'] and not question.save_as_email and not question.save_as_nickname" />
|
||||
<div class="wrap min-vh-100 align-items-center justify-content-center d-flex flex-column o_survey_session_manage invisible"
|
||||
t-att-style="'display: none;' if is_rpc_call else ''"
|
||||
t-att-data-is-rpc-call="is_rpc_call"
|
||||
t-att-data-survey-id="survey.id"
|
||||
t-att-data-attendees-count="survey.session_answer_count"
|
||||
t-att-data-survey-access-token="survey.access_token"
|
||||
t-att-data-timer="survey.session_question_start_time.isoformat()"
|
||||
t-att-data-time-limit-minutes="question.time_limit / 60"
|
||||
t-att-data-is-scored-question="is_scored_question"
|
||||
t-att-data-session-show-leaderboard="survey.session_show_leaderboard"
|
||||
t-att-data-question-statistics="question_statistics_graph"
|
||||
t-att-data-question-type="question.question_type"
|
||||
t-att-data-has-correct-answers="any(answer.is_correct for answer in question.suggested_answer_ids)"
|
||||
t-att-data-answers-validity="answers_validity"
|
||||
t-att-data-is-first-question="is_first_question"
|
||||
t-att-data-is-last-question="is_last_question"
|
||||
t-att-data-current-screen="'question' if is_scored_question else 'userInputs'"
|
||||
t-att-data-show-bar-chart="show_bar_chart"
|
||||
t-att-data-show-text-answers="show_text_answers"
|
||||
t-att-data-refresh-background="any(page.background_image for page in survey.page_ids)"
|
||||
t-att-data-is-session-closed="is_session_closed">
|
||||
<div t-if="not is_session_closed" class="o_survey_question_header flex-wrap px-3 w-100 d-flex justify-content-between align-items-center position-absolute">
|
||||
<h3>
|
||||
<span>To join: <span class="text-info o_survey_session_copy" t-esc="survey.session_link"/></span>
|
||||
<input class="o_survey_session_copy_url d-none" type="text" t-att-value="survey.session_link" />
|
||||
</h3>
|
||||
<h1 t-if="question.is_time_limited" class="o_survey_timer_container">
|
||||
<span class="o_survey_timer d-inline-block"/>
|
||||
</h1>
|
||||
<div class="text-end d-flex flex-column justify-content-center">
|
||||
<div t-if="show_bar_chart or show_text_answers">
|
||||
<div class="progress" title="Attendees are answering the question...">
|
||||
<div class="progress-bar o_survey_session_progress_small fw-bold"
|
||||
style="overflow: visible" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
|
||||
<span class="px-2">0 / <t t-esc="survey.session_answer_count" /></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container px-4 pb-3 pt96 d-flex flex-column o_survey_session_manage_container">
|
||||
<div class="o_survey_session_description_done d-none">
|
||||
<h1>Thank you!</h1>
|
||||
<div t-field="survey.description_done"/>
|
||||
</div>
|
||||
<a role="button"
|
||||
class="fw-bold fa fa-chevron-right o_survey_session_navigation o_survey_session_navigation_next p-3" />
|
||||
<a role="button"
|
||||
class="fw-bold fa fa-chevron-left o_survey_session_navigation o_survey_session_navigation_previous p-3" />
|
||||
<div class="o_survey_session_results flex-column flex-grow-1 mx-5">
|
||||
<div class="row">
|
||||
<div class="col-lg-12"><h1 t-esc="question.title"></h1></div>
|
||||
</div>
|
||||
<div t-attf-class="d-flex flex-column flex-grow-1 #{'justify-content-center' if not show_text_answers else ''} #{'align-items-center' if show_bar_chart else ''}">
|
||||
<!-- Has to stay in 'style' attribute for Chartjs -->
|
||||
<div t-if="show_bar_chart" class="p-2 o_survey_session_chart"
|
||||
style="position: relative; width: 75vw; height: 70vh;">
|
||||
<!-- canvas element for drawing bar chart -->
|
||||
<canvas />
|
||||
</div>
|
||||
<div t-elif="show_text_answers" class="p-2 pt-4 o_survey_session_text_answers_container">
|
||||
</div>
|
||||
<div t-elif="question.is_page and not is_html_empty(question.description)" class="mb-6 o_survey_manage_fontsize_14" t-field="question.description" />
|
||||
<div t-else="" class="mb-6">
|
||||
<h2 class="fw-normal mb-3">
|
||||
<span>Waiting for attendees...</span>
|
||||
<span>
|
||||
<span class="o_survey_session_answer_count">0</span>
|
||||
/
|
||||
<span t-esc="survey.session_answer_count" />
|
||||
</span>
|
||||
</h2>
|
||||
<div class="progress">
|
||||
<div class="progress-bar fw-bold" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
|
||||
</div>
|
||||
<fieldset disabled="disabled" class="mt-5" t-if="question.question_type == 'matrix'" t-call="survey.question_container">
|
||||
<t t-set="hide_question_title" t-value="true" />
|
||||
<t t-set="answer" t-value="env['survey.user_input']" />
|
||||
<t t-set="survey_form_readonly" t-value="True"/>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_survey_session_leaderboard w-100 flex-column flex-grow-1" style="display: none;">
|
||||
<!--Set question to false to avoid background miss match when no question are displayed.-->
|
||||
<t t-set="question" t-value="False"/>
|
||||
<div class="d-flex">
|
||||
<h1 class="o_survey_session_leaderboard_title flex-grow-1">
|
||||
<span t-if="is_last_question">Final Leaderboard</span>
|
||||
<span t-else="">Leaderboard</span>
|
||||
</h1>
|
||||
<div t-att-class="'o_survey_leaderboard_buttons fw-bold %s' % 'd-none' if not is_last_question else ''">
|
||||
<a href="#" role="button" class="o_survey_session_close btn btn-primary me-4"><i class="fa fa-close"/> Close</a>
|
||||
<a href="#" role="button" class="o_survey_session_close btn btn-primary" t-att-data-show-results="True"><i class="fa fa-bar-chart"/> Results</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="justify-content-center d-flex flex-column flex-grow-1 mt-5 mb-5 pb-5 o_survey_session_leaderboard_container"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="user_input_session_leaderboard" name="Survey User Input Leaderboard">
|
||||
<div t-if="leaderboard" class="position-relative mb-5" t-attf-style="height: calc(3.8rem * #{len(leaderboard)});">
|
||||
<t t-set="max_score" t-value="max(score.get('scoring_total', 1) for score in leaderboard) or 1" />
|
||||
<t t-set="max_updated_score" t-value="max(score.get('updated_score', 1) for score in leaderboard)" />
|
||||
<t t-foreach="leaderboard" t-as="score">
|
||||
<div class="o_survey_session_leaderboard_item ms-2 d-flex position-absolute"
|
||||
t-attf-style="top: calc(#{score_index} * 3.8rem);"
|
||||
t-att-data-current-position="str(score_index)"
|
||||
t-att-data-new-position="str(score.get('leaderboard_position', score_index))"
|
||||
t-att-data-question-score="str(round(score.get('question_score', 0)))"
|
||||
t-att-data-current-score="str(round(score.get('scoring_total', 0)))"
|
||||
t-att-data-updated-score="str(round(score.get('updated_score', 0)))"
|
||||
t-att-data-max-question-score="round(score.get('max_question_score', 1))"
|
||||
t-att-data-max-updated-score="round(max_updated_score)">
|
||||
<div class="d-inline-block fw-bold align-top">
|
||||
<div class="d-inline-block me-2 o_survey_session_leaderboard_score" t-esc="'%.0f p' % score['scoring_total']" />
|
||||
</div>
|
||||
<!-- We keep "18rem" of space to display the points / nickname.
|
||||
Then, the length of the bar is a percentage of the attendee's score compared to the max_score. -->
|
||||
<t t-set="width_ratio" t-value="round(round(score['scoring_total'], 3) / round(max_score, 3), 3)"/>
|
||||
<t t-set="width_ratio_question" t-value="str(round(round(score.get('question_score', 0), 3) / round(score.get('max_question_score', 1), 3), 3))"/>
|
||||
<div class="o_survey_session_leaderboard_bar ms-2 align-top d-inline-block text-end fw-bold"
|
||||
t-att-style="'width: calc(calc(%s - 18rem) * %s)' % ('100%', width_ratio)"
|
||||
t-att-data-width-ratio="width_ratio">
|
||||
</div>
|
||||
<div class="o_survey_session_leaderboard_bar_question me-2 align-top d-inline-block text-end fw-bold position-relative"
|
||||
style="width: 0px;"
|
||||
t-att-data-width-ratio="width_ratio_question"
|
||||
t-att-data-max-question-score="str(score.get('max_question_score', 1))"
|
||||
t-att-data-question-score="str(score.get('question_score', 0))">
|
||||
<div class="o_survey_session_leaderboard_bar_question_score position-absolute"></div>
|
||||
</div>
|
||||
<div class="o_survey_session_leaderboard_name d-inline-block">
|
||||
<span t-if="score.get('nickname')" t-esc="score['nickname']" />
|
||||
<span t-else="">Anonymous</span>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
</template>
|
||||
</data>
|
||||
</odoo>
|
||||
265
odoo-bringout-oca-ocb-survey/survey/views/survey_user_views.xml
Normal file
265
odoo-bringout-oca-ocb-survey/survey/views/survey_user_views.xml
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- USER INPUTS -->
|
||||
<record id="survey_user_input_view_search" model="ir.ui.view">
|
||||
<field name="name">survey.user_input.view.search</field>
|
||||
<field name="model">survey.user_input</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Survey User Inputs">
|
||||
<field name="email" string="Participant" filter_domain="[
|
||||
'|',
|
||||
('partner_id', 'ilike', self),
|
||||
('email', 'ilike', self)]"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="survey_id"/>
|
||||
<filter name="completed" string="Completed" domain="[('state', '=', 'done')]"/>
|
||||
<filter string="In Progress" name="in_progress" domain="[('state', '=', 'in_progress')]"/>
|
||||
<filter string="New" name="new" domain="[('state', '=', 'new')]"/>
|
||||
<separator/>
|
||||
<filter string="Quizz passed" name="scoring_success" domain="[('scoring_success','=', True)]"/>
|
||||
<separator/>
|
||||
<filter string="Tests Only" name="test" domain="[('test_entry','=', True)]"/>
|
||||
<filter string="Exclude Tests" name="not_test" domain="[('test_entry','=', False)]"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter name="group_by_survey" string="Survey" domain="[]" context="{'group_by': 'survey_id'}"/>
|
||||
<filter string="Email" name="group_by_email" domain="[]" context="{'group_by': 'email'}"/>
|
||||
<filter string="Partner" name="group_by_partner" domain="[]" context="{'group_by': 'partner_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="survey_user_input_view_form" model="ir.ui.view">
|
||||
<field name="name">survey.user_input.view.form</field>
|
||||
<field name="model">survey.user_input</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Survey User inputs" create="false">
|
||||
<header>
|
||||
<button name="action_resend" string="Resend Invitation" type="object" class="oe_highlight"
|
||||
attrs="{'invisible': ['|', ('state', '=', 'done'), '&', ('partner_id', '=', False), ('email', '=', False)]}"/>
|
||||
<button name="action_print_answers" states="done" string="Print" type="object" class="oe_highlight"/>
|
||||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<field name="attempts_count" invisible="1"/>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_redirect_to_attempts"
|
||||
type="object"
|
||||
class="oe_stat_button"
|
||||
attrs="{'invisible': [('attempts_count', '=', 1)]}"
|
||||
icon="fa-files-o">
|
||||
<field string="Attempts" name="attempts_count" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
<field name="test_entry" invisible="1"/>
|
||||
<widget name="web_ribbon" title="Test Entry" bg_color="bg-info"
|
||||
attrs="{'invisible': [('test_entry', '!=', True)]}"/>
|
||||
<widget name="web_ribbon" title="Failed" bg_color="bg-danger"
|
||||
attrs="{'invisible': ['|', '|', ('test_entry', '=', True), ('scoring_type', '=', 'no_scoring'), ('scoring_success', '=', True)]}"/>
|
||||
<widget name="web_ribbon" title="Passed"
|
||||
attrs="{'invisible': ['|', '|', ('test_entry', '=', True), ('scoring_type', '=', 'no_scoring'), ('scoring_success', '=', False)]}"/>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="survey_id"/>
|
||||
<field name="create_date"/>
|
||||
<field name="deadline" attrs="{'invisible': [('state', '=', 'done'), ('deadline', '=', False)]}"/>
|
||||
<field name="is_attempts_limited" invisible="1"/>
|
||||
<label for="attempts_number" string="Attempt n°" attrs="{'invisible': ['|', ('is_attempts_limited', '=', False), '|', ('test_entry', '=', True), ('state', '!=', 'done')]}"/>
|
||||
<div attrs="{'invisible': ['|', ('is_attempts_limited', '=', False), '|', ('test_entry', '=', True), ('state', '!=', 'done')]}" class="d-inline-flex">
|
||||
<field name="attempts_number" nolabel="1"/>
|
||||
/
|
||||
<field name="attempts_limit" nolabel="1"/>
|
||||
</div>
|
||||
<field name="test_entry" groups="base.group_no_one"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="scoring_type" invisible="1"/>
|
||||
<field name="scoring_success" invisible="1"/>
|
||||
<label for="scoring_percentage" string="Score" attrs="{'invisible': [('scoring_type', '=', 'no_scoring')]}"/>
|
||||
<div attrs="{'invisible': [('scoring_type', '=', 'no_scoring')]}" class="d-inline-flex">
|
||||
<field name="scoring_percentage" nolabel="1"/>
|
||||
<span>%</span>
|
||||
</div>
|
||||
<field name="partner_id"/>
|
||||
<field name="email" widget="email"/>
|
||||
<field name="access_token" groups="base.group_no_one"/>
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Answers">
|
||||
<field name="user_input_line_ids" mode="tree" attrs="{'readonly': True}" no_label="1">
|
||||
<tree decoration-muted="skipped == True">
|
||||
<field name="question_sequence" invisible="1"/>
|
||||
<field name="create_date" optional="hidden"/>
|
||||
<field name="page_id" optional="hidden"/>
|
||||
<field name="question_id"/>
|
||||
<field name="answer_type" optional="hidden"/>
|
||||
<field name="skipped" hide="1"/>
|
||||
<field name="display_name" string="Answer"/>
|
||||
<field name="answer_is_correct"/>
|
||||
<field name="answer_score" sum="Score"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
<field name="message_follower_ids"/>
|
||||
<field name="activity_ids"/>
|
||||
<field name="message_ids"/>
|
||||
</div>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="survey_user_input_view_tree" model="ir.ui.view">
|
||||
<field name="name">survey.user_input.view.tree</field>
|
||||
<field name="model">survey.user_input</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Survey User inputs" decoration-muted="test_entry == True" create="false">
|
||||
<field name="create_date"/>
|
||||
<field name="survey_id"/>
|
||||
<field name="nickname" optional="hide"/>
|
||||
<field name="partner_id" optional="show"/>
|
||||
<field name="email" optional="show"/>
|
||||
<field name="attempts_number"/>
|
||||
<field name="deadline"/>
|
||||
<field name="test_entry" invisible="True"/>
|
||||
<field name="scoring_success"/>
|
||||
<field name="scoring_percentage"/>
|
||||
<field name="state" widget="badge"
|
||||
decoration-success="state == 'done'"
|
||||
decoration-warning="state == 'new'"
|
||||
decoration-info="state == 'in_progress'"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="survey_user_input_viuew_kanban" model="ir.ui.view">
|
||||
<field name="name">survey.user_input.view.kanban</field>
|
||||
<field name="model">survey.user_input</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban create="false" group_create="false">
|
||||
<field name="survey_id"/>
|
||||
<field name="create_date"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="email"/>
|
||||
<field name="state"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_global_click">
|
||||
<div class="o_kanban_record_top">
|
||||
<div class="o_kanban_record_headings">
|
||||
<strong class="o_kanban_record_title"><t t-esc="record.survey_id.value"/></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="o_kanban_record_bottom">
|
||||
<div class="oe_kanban_bottom_left">
|
||||
<field name="create_date"/>
|
||||
</div>
|
||||
<div class="oe_kanban_bottom_right mr4">
|
||||
<field name="state" widget="label_selection" options="{'classes': {'new': 'default', 'done': 'success', 'in_progress':'warning'}}"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_survey_user_input">
|
||||
<field name="name">Participations</field>
|
||||
<field name="res_model">survey.user_input</field>
|
||||
<field name="view_mode">tree,kanban,form</field>
|
||||
<field name="view_id" ref="survey_user_input_view_tree"></field>
|
||||
<field name="search_view_id" ref="survey_user_input_view_search"/>
|
||||
<field name="context">{'search_default_group_by_survey': True}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_empty_folder">
|
||||
No answers yet!
|
||||
</p><p>
|
||||
You can share your links through different means: email, invite shortcut, live presentation, ...
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- USER INPUT LINES
|
||||
.. note:: these views are useful mainly for technical users/administrators -->
|
||||
<record id="survey_user_input_line_view_form" model="ir.ui.view">
|
||||
<field name="name">survey.user_input.line.view.form</field>
|
||||
<field name="model">survey.user_input.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="User input line details" create="false">
|
||||
<sheet>
|
||||
<group col="4">
|
||||
<field name="question_id"/>
|
||||
<field name="create_date"/>
|
||||
<field name="answer_type"/>
|
||||
<field name="skipped" />
|
||||
<field name="answer_score" groups="base.group_no_one"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="value_char_box" colspan='2' attrs="{'invisible': [('answer_type','!=','char_box')]}"/>
|
||||
<field name="value_numerical_box" colspan='2' attrs="{'invisible': [('answer_type','!=','numerical_box')]}"/>
|
||||
<field name="value_date" colspan='2' attrs="{'invisible': [('answer_type','!=','date')]}"/>
|
||||
<field name="value_datetime" colspan='2' attrs="{'invisible': [('answer_type','!=','datetime')]}"/>
|
||||
<field name="value_text_box" colspan='2' attrs="{'invisible': [('answer_type','!=','text_box')]}"/>
|
||||
<field name="matrix_row_id" colspan='2' />
|
||||
<field name="suggested_answer_id" colspan='2' attrs="{'invisible': [('answer_type','!=','suggestion')]}"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="survey_response_line_view_tree" model="ir.ui.view">
|
||||
<field name="name">survey.user_input.line.view.tree</field>
|
||||
<field name="model">survey.user_input.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Survey Answer Line" create="false">
|
||||
<field name="survey_id"/>
|
||||
<field name="user_input_id"/>
|
||||
<field name="question_id"/>
|
||||
<field name="create_date"/>
|
||||
<field name="answer_type"/>
|
||||
<field name="skipped"/>
|
||||
<field name="answer_score" groups="base.group_no_one"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="survey_user_input_line_view_search" model="ir.ui.view">
|
||||
<field name="name">survey.user_input.line.view.search</field>
|
||||
<field name="model">survey.user_input.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search User input lines">
|
||||
<field name="user_input_id"/>
|
||||
<field name="survey_id"/>
|
||||
<group expand="1" string="Group By">
|
||||
<filter name="group_by_survey" string="Survey" domain="[]" context="{'group_by':'survey_id'}"/>
|
||||
<filter name="group_by_user_input" string="User Input" domain="[]" context="{'group_by':'user_input_id'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="survey_user_input_line_action" model="ir.actions.act_window">
|
||||
<field name="name">Detailed Answers</field>
|
||||
<field name="res_model">survey.user_input.line</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="survey_user_input_line_view_search"/>
|
||||
<field name="context">{'search_default_group_by_survey': True, 'search_default_group_by_user_input': True}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_empty_folder">
|
||||
No user input lines found
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Participations"
|
||||
id="menu_survey_type_form1"
|
||||
action="action_survey_user_input"
|
||||
parent="menu_surveys"
|
||||
sequence="1"/>
|
||||
</data>
|
||||
</odoo>
|
||||
Loading…
Add table
Add a link
Reference in a new issue