From d14093dcb7fc67b9653b9b14b0b4c92a3bdd1c74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Hennecart?= Date: Mon, 27 May 2019 06:58:38 +0000 Subject: [PATCH] [IMP] survey: Create pages without modal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit customizes the one2many field so that every questions with the flag "is_page" are editable inline directly in the tree view with no modal on the survey form. Questions who don't have that flag are still created the same way as it was before. TaskID:1999109 PR: #35170 Signed-off-by: Thibault Delavallee (tde) Co-authored-by: Jérémy Hennecart Co-authored-by: Quentin Mourrier --- .../static/src/js/fields_section_one2many.js | 180 ++++++++++++++++++ .../survey/static/src/scss/survey_views.scss | 7 + addons/survey/views/assets.xml | 1 + addons/survey/views/survey_question_views.xml | 9 +- addons/survey/views/survey_survey_views.xml | 12 +- 5 files changed, 198 insertions(+), 11 deletions(-) create mode 100644 addons/survey/static/src/js/fields_section_one2many.js diff --git a/addons/survey/static/src/js/fields_section_one2many.js b/addons/survey/static/src/js/fields_section_one2many.js new file mode 100644 index 00000000000..590d98913d8 --- /dev/null +++ b/addons/survey/static/src/js/fields_section_one2many.js @@ -0,0 +1,180 @@ +odoo.define('survey.question_page_one2many', function (require){ +"use strict"; + +var Context = require('web.Context'); +var FieldOne2Many = require('web.relational_fields').FieldOne2Many; +var FieldRegistry = require('web.field_registry'); +var ListRenderer = require('web.ListRenderer'); + +var SectionListRenderer = ListRenderer.extend({ + init: function (parent, state, params) { + this.sectionFieldName = "is_page"; + this._super.apply(this, arguments); + }, + _checkIfRecordIsSection: function (id){ + var record = this._findRecordById(id); + return record && record.data[this.sectionFieldName]; + }, + _findRecordById: function (id){ + return _.find(this.state.data, function (record){ + return record.id === id; + }); + }, + /** + * Allows to hide specific field in case the record is a section + * and, in this case, makes the 'title' field take the space of all the other + * fields + * @private + * @override + * @param {*} record + * @param {*} node + * @param {*} index + * @param {*} options + */ + _renderBodyCell: function (record, node, index, options){ + var $cell = this._super.apply(this, arguments); + + var isSection = record.data[this.sectionFieldName]; + + if (isSection){ + if (node.attrs.widget === "handle"){ + return $cell; + } else if (node.attrs.name === "title"){ + var nbrColumns = this._getNumberOfCols(); + if (this.handleField){ + nbrColumns--; + } + if (this.addTrashIcon){ + nbrColumns--; + } + $cell.attr('colspan', nbrColumns); + } else { + $cell.removeClass('o_invisible_modifier'); + return $cell.addClass('o_hidden'); + } + } + return $cell; + }, + /** + * Adds specific classes to rows that are sections + * to apply custom css on them + * @private + * @override + * @param {*} record + * @param {*} index + */ + _renderRow: function (record, index){ + var $row = this._super.apply(this, arguments); + if (record.data[this.sectionFieldName]) { + $row.addClass("o_is_section"); + } + return $row; + }, + /** + * Adding this class after the view is rendered allows + * us to limit the custom css scope to this particular case + * and no other + * @private + * @override + */ + _renderView: function (){ + var def = this._super.apply(this, arguments); + var self = this; + return def.then(function () { + self.$('table.o_list_table').addClass('o_section_list_view'); + }); + }, + // Handlers + /** + * Overriden to allow different behaviours depending on + * the row the user clicked on. + * If the row is a section: edit inline + * else use a normal modal + * @private + * @override + * @param {*} ev + */ + _onRowClicked: function (ev){ + var parent = this.getParent(); + var recordId = $(ev.currentTarget).data('id'); + var is_section = this._checkIfRecordIsSection(recordId); + if (is_section && parent.mode === "edit"){ + this.editable = "bottom"; + } else { + this.editable = null; + } + this._super.apply(this, arguments); + }, + /** + * Overriden to allow different behaviours depending on + * the cell the user clicked on. + * If the cell is part of a section: edit inline + * else use a normal edit modal + * @private + * @override + * @param {*} ev + */ + _onCellClick: function (ev){ + var parent = this.getParent(); + var recordId = $(ev.currentTarget.parentElement).data('id'); + var is_section = this._checkIfRecordIsSection(recordId); + if (is_section && parent.mode === "edit"){ + this.editable = "bottom"; + } else { + this.editable = null; + this.unselectRow(); + } + this._super.apply(this, arguments); + }, + /** + * In this case, navigating in the list caused issues. + * For example, editing a section then pressing enter would trigger + * the inline edition of the next element in the list. Which is not desired + * if the next element ends up being a question and not a section + * @override + * @param {*} ev + */ + _onNavigationMove: function (ev){ + this.unselectRow(); + }, +}); + +var SectionFieldOne2Many = FieldOne2Many.extend({ + init: function (parent, name, record, options){ + this._super.apply(this, arguments); + this.sectionFieldName = "is_page"; + this.rendered = false; + }, + /** + * Overriden to use our custom renderer + * @private + * @override + */ + _getRenderer: function (){ + if (this.view.arch.tag === 'tree'){ + return SectionListRenderer; + } + return this._super.apply(this, arguments); + }, + /** + * Overriden to allow different behaviours depending on + * the object we want to add. Adding a section would be done inline + * while adding a question would render a modal. + * @private + * @override + * @param {*} ev + */ + _onAddRecord: function (ev) { + var context_str = ev.data.context && ev.data.context[0]; + var context = new Context(context_str).eval(); + if (context['default_' + this.sectionFieldName]){ + this.editable = "bottom"; + } else { + this.editable = null; + } + this._super.apply(this, arguments); + }, +}); + +FieldRegistry.add('question_page_one2many', SectionFieldOne2Many); +}); \ No newline at end of file diff --git a/addons/survey/static/src/scss/survey_views.scss b/addons/survey/static/src/scss/survey_views.scss index 92f4dd73a31..520efd97799 100644 --- a/addons/survey/static/src/scss/survey_views.scss +++ b/addons/survey/static/src/scss/survey_views.scss @@ -3,3 +3,10 @@ font-size: 20px; } } + +table.o_section_list_view tr.o_data_row.o_is_section { + font-weight: bold; + background-color: #DDD; + border-top: 1px solid #BBB; + border-bottom: 1px solid #BBB; +} diff --git a/addons/survey/views/assets.xml b/addons/survey/views/assets.xml index 59dd9448fd6..b4b042a61e1 100644 --- a/addons/survey/views/assets.xml +++ b/addons/survey/views/assets.xml @@ -25,6 +25,7 @@