summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMohammed Shekha <msh@odoo.com>2020-04-20 09:36:05 +0000
committerAaron Bohy <aab@odoo.com>2020-05-08 11:38:59 +0000
commit051a094838e4f27df91d66498ac03a3bd7b86358 (patch)
tree00950e07df2e711b370157104b5b246e2ef381c6
parent8ca96078dbeb61678f8c0656f90b09ab8a82981a (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.js28
-rw-r--r--addons/web/static/src/js/views/form/form_controller.js17
-rw-r--r--addons/web/static/src/js/views/form/form_renderer.js11
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_controller.js36
-rw-r--r--addons/web/static/src/js/views/list/list_controller.js7
-rw-r--r--addons/web/static/tests/views/form_tests.js12
-rw-r--r--addons/web/static/tests/views/kanban_tests.js31
-rw-r--r--addons/web/static/tests/views/list_tests.js26
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);