diff options
| author | Mohammed Shekha <msh@odoo.com> | 2020-04-20 09:36:05 +0000 |
|---|---|---|
| committer | Aaron Bohy <aab@odoo.com> | 2020-05-08 11:38:59 +0000 |
| commit | 051a094838e4f27df91d66498ac03a3bd7b86358 (patch) | |
| tree | 00950e07df2e711b370157104b5b246e2ef381c6 | |
| parent | 8ca96078dbeb61678f8c0656f90b09ab8a82981a (diff) | |
[IMP] web: list and kanban: highlight create button
... when there is no data and user clicks anywhere in the no content
helper.
Task 2239617
Co-authored-by: Jinal Patel <jip@odoo.com>
Co-authored-by: Aaron Bohy <aab@odoo.com>
| -rw-r--r-- | addons/web/static/src/js/views/basic/basic_controller.js | 28 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/form/form_controller.js | 17 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/form/form_renderer.js | 11 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/kanban/kanban_controller.js | 36 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/list/list_controller.js | 7 | ||||
| -rw-r--r-- | addons/web/static/tests/views/form_tests.js | 12 | ||||
| -rw-r--r-- | addons/web/static/tests/views/kanban_tests.js | 31 | ||||
| -rw-r--r-- | addons/web/static/tests/views/list_tests.js | 26 |
8 files changed, 118 insertions, 50 deletions
diff --git a/addons/web/static/src/js/views/basic/basic_controller.js b/addons/web/static/src/js/views/basic/basic_controller.js index bbfee26e51f..f652820e814 100644 --- a/addons/web/static/src/js/views/basic/basic_controller.js +++ b/addons/web/static/src/js/views/basic/basic_controller.js @@ -16,6 +16,9 @@ var TranslationDialog = require('web.TranslationDialog'); var _t = core._t; var BasicController = AbstractController.extend(FieldManagerMixin, { + events: Object.assign({}, AbstractController.prototype.events, { + 'click .o_content': '_onContentClicked', + }), custom_events: _.extend({}, AbstractController.prototype.custom_events, FieldManagerMixin.custom_events, { discard_changes: '_onDiscardChanges', pager_changed: '_onPagerChanged', @@ -602,6 +605,18 @@ var BasicController = AbstractController.extend(FieldManagerMixin, { return Promise.resolve(); }, /** + * To override such that it returns true iff the primary action button must + * bounce when the user clicked on the given element, according to the + * current state of the view. + * + * @private + * @param {HTMLElement} element the node the user clicked on + * @returns {boolean} + */ + _shouldBounceOnClick: function (/* element */) { + return false; + }, + /** * Helper method, to get the current environment variables from the model * and notifies the component chain (by bubbling an event up) * @@ -623,6 +638,19 @@ var BasicController = AbstractController.extend(FieldManagerMixin, { //-------------------------------------------------------------------------- /** + * Called when the user clicks on the 'content' part of the controller + * (typically the renderer area). Makes the first primary button in the + * control panel bounce, in some situations (see _shouldBounceOnClick). + * + * @private + * @param {MouseEvent} ev + */ + _onContentClicked(ev) { + if (this.$buttons && this._shouldBounceOnClick(ev.target)) { + this.$buttons.find('.btn-primary:visible:first').odooBounce(); + } + }, + /** * Called when a list element asks to discard the changes made to one of * its rows. It can happen with a x2many (if we are in a form view) or with * a list view. diff --git a/addons/web/static/src/js/views/form/form_controller.js b/addons/web/static/src/js/views/form/form_controller.js index 7147f7aee66..eeb1153b16f 100644 --- a/addons/web/static/src/js/views/form/form_controller.js +++ b/addons/web/static/src/js/views/form/form_controller.js @@ -11,7 +11,6 @@ var qweb = core.qweb; var FormController = BasicController.extend({ custom_events: _.extend({}, BasicController.prototype.custom_events, { - bounce_edit: '_onBounceEdit', button_clicked: '_onButtonClicked', edited_list: '_onEditedList', open_one2many_record: '_onOpenOne2ManyRecord', @@ -431,22 +430,18 @@ var FormController = BasicController.extend({ } return this._super.apply(this, arguments); }, + /** + * @override + */ + _shouldBounceOnClick(element) { + return this.mode === 'readonly' && !!element.closest('.oe_title, .o_inner_group'); + }, //-------------------------------------------------------------------------- // Handlers //-------------------------------------------------------------------------- /** - * Bounce the 'Edit' button. - * - * @private - */ - _onBounceEdit: function () { - if (this.$buttons) { - this.$buttons.find('.o_form_button_edit').odooBounce(); - } - }, - /** * @private * @param {OdooEvent} ev */ diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js index 1b672bdee19..4a5cc2d3f94 100644 --- a/addons/web/static/src/js/views/form/form_renderer.js +++ b/addons/web/static/src/js/views/form/form_renderer.js @@ -15,7 +15,6 @@ var FormRenderer = BasicRenderer.extend({ events: _.extend({}, BasicRenderer.prototype.events, { 'click .o_notification_box .oe_field_translate': '_onTranslate', 'click .o_notification_box .close': '_onTranslateNotificationClose', - 'click .oe_title, .o_inner_group': '_onClick', 'shown.bs.tab a[data-toggle="tab"]': '_onNotebookTabChanged', }), custom_events: _.extend({}, BasicRenderer.prototype.custom_events, { @@ -1068,16 +1067,6 @@ var FormRenderer = BasicRenderer.extend({ this._activateNextFieldWidget(this.state, index); }, /** - * Makes the Edit button bounce in readonly - * - * @private - */ - _onClick: function () { - if (this.mode === 'readonly') { - this.trigger_up('bounce_edit'); - } - }, - /** * @override * @private * @param {OdooEvent} ev diff --git a/addons/web/static/src/js/views/kanban/kanban_controller.js b/addons/web/static/src/js/views/kanban/kanban_controller.js index a7ee449299b..e1cd80c7546 100644 --- a/addons/web/static/src/js/views/kanban/kanban_controller.js +++ b/addons/web/static/src/js/views/kanban/kanban_controller.js @@ -34,9 +34,6 @@ var KanbanController = BasicController.extend({ column_toggle_fold: '_onToggleColumn', kanban_column_records_toggle_active: '_onToggleActiveRecords', }), - events: _.extend({}, BasicController.prototype.events, { - click: '_onClick', - }), /** * @override * @param {Object} params @@ -203,6 +200,22 @@ var KanbanController = BasicController.extend({ var self = this; return this.model.resequence(this.modelName, ids, column_id); }, + /** + * @override + */ + _shouldBounceOnClick(element) { + const state = this.model.get(this.handle, {raw: true}); + if (!state.count) { + const classesList = [ + 'o_kanban_view', + 'o_kanban_group', + 'o_column_quick_create', + 'o_view_nocontent_smiling_face' + ]; + return classesList.some(c => element.classList.contains(c)); + } + return false; + }, //-------------------------------------------------------------------------- // Handlers @@ -333,23 +346,6 @@ var KanbanController = BasicController.extend({ } }, /** - * Bounce the 'Create' button. - * - * @private - * @param {MouseEvent} ev - **/ - _onClick: function (ev) { - var state = this.model.get(this.handle, {raw: true}); - if (!state.count && this.buttons) { - var classesList = ['o_kanban_view', 'o_kanban_group', 'o_column_quick_create', 'o_view_nocontent_smiling_face']; - var $target = $(ev.target); - var hasClassList = _.map(classesList, function(klass){ return $target.hasClass(klass) }); - if (_.some(hasClassList)) { - this.$buttons.find('.o-kanban-button-new').odooBounce(); - } - } - }, - /** * @private * @param {OdooEvent} ev */ diff --git a/addons/web/static/src/js/views/list/list_controller.js b/addons/web/static/src/js/views/list/list_controller.js index 110fab8e897..a79f027cd27 100644 --- a/addons/web/static/src/js/views/list/list_controller.js +++ b/addons/web/static/src/js/views/list/list_controller.js @@ -519,6 +519,13 @@ var ListController = BasicController.extend({ } }, /** + * @override + */ + _shouldBounceOnClick() { + const state = this.model.get(this.handle, {raw: true}); + return !state.count; + }, + /** * Called when clicking on 'Archive' or 'Unarchive' in the sidebar. * * @private diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index def58359e2f..77df0909de4 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -7499,7 +7499,7 @@ QUnit.module('Views', { }); QUnit.test('bounce edit button in readonly mode', async function (assert) { - assert.expect(3); + assert.expect(2); var form = await createView({ View: FormView, @@ -7511,21 +7511,17 @@ QUnit.module('Views', { '</div>' + '</form>', res_id: 1, - intercepts: { - bounce_edit: function() { - assert.step('bounce'); - }, - }, }); // in readonly await testUtils.dom.click(form.$('[name="display_name"]')); - assert.verifySteps(['bounce']); + assert.hasClass(form.$('.o_form_button_edit'), 'o_catch_attention'); // in edit await testUtils.form.clickEdit(form); await testUtils.dom.click(form.$('[name="display_name"]')); - assert.verifySteps([]); + // await testUtils.nextTick(); + assert.containsNone(form, 'button.o_catch_attention:visible'); form.destroy(); }); diff --git a/addons/web/static/tests/views/kanban_tests.js b/addons/web/static/tests/views/kanban_tests.js index da636bc64e2..0b261317446 100644 --- a/addons/web/static/tests/views/kanban_tests.js +++ b/addons/web/static/tests/views/kanban_tests.js @@ -3985,6 +3985,37 @@ QUnit.module('Views', { kanban.destroy(); }); + QUnit.test('bounce create button when no data and click on empty area', async function (assert) { + assert.expect(2); + + const kanban = await createView({ + View: KanbanView, + model: 'partner', + data: this.data, + arch: `<kanban class="o_kanban_test"><templates><t t-name="kanban-box"> + <div> + <t t-esc="record.foo.value"/> + <field name="foo"/> + </div> + </t></templates></kanban>`, + viewOptions: { + action: { + help: '<p class="hello">click to add a partner</p>' + } + }, + }); + + await testUtils.dom.click(kanban.$('.o_kanban_view')); + assert.doesNotHaveClass(kanban.$('.o-kanban-button-new'), 'o_catch_attention'); + + await kanban.reload({ domain: [['id', '<', 0]] }); + + await testUtils.dom.click(kanban.$('.o_kanban_view')); + assert.hasClass(kanban.$('.o-kanban-button-new'), 'o_catch_attention'); + + kanban.destroy(); + }); + QUnit.test('buttons with modifiers', async function (assert) { assert.expect(2); diff --git a/addons/web/static/tests/views/list_tests.js b/addons/web/static/tests/views/list_tests.js index 2ad91dcae40..3c9a887f461 100644 --- a/addons/web/static/tests/views/list_tests.js +++ b/addons/web/static/tests/views/list_tests.js @@ -3409,6 +3409,32 @@ QUnit.module('Views', { list.destroy(); }); + QUnit.test('bounce create button when no data and click on empty area', async function (assert) { + assert.expect(4); + + const list = await createView({ + View: ListView, + model: 'foo', + data: this.data, + arch: '<tree><field name="foo"/></tree>', + viewOptions: { + action: { + help: '<p class="hello">click to add a record</p>' + } + }, + }); + + assert.containsNone(list, '.o_view_nocontent'); + await testUtils.dom.click(list.$('.o_list_view')); + assert.doesNotHaveClass(list.$('.o_list_button_add'), 'o_catch_attention'); + + await list.reload({ domain: [['id', '<', 0]] }); + assert.containsOnce(list, '.o_view_nocontent'); + await testUtils.dom.click(list.$('.o_view_nocontent')); + assert.hasClass(list.$('.o_list_button_add'), 'o_catch_attention'); + list.destroy(); + }); + QUnit.test('no content helper when no data', async function (assert) { assert.expect(5); |
