diff options
| author | Christophe Simonis <chs@odoo.com> | 2018-07-13 14:32:05 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2018-07-13 14:32:05 +0200 |
| commit | f3929aa0f75c2d3ac039bfc5bd41194516ae5571 (patch) | |
| tree | 6ef909a475e4e99d1e9eb9c3d2e6c891fc7ad892 /addons/web/static | |
| parent | e8fc62ec74f94fd1bfea105a15082dfede4dc987 (diff) | |
| parent | 87dadc5bc83714cb0e748824f57e4cd35d02bbbf (diff) | |
[MERGE] forward port branch saas-11.2 up to 87dadc5bc83
Diffstat (limited to 'addons/web/static')
4 files changed, 114 insertions, 4 deletions
diff --git a/addons/web/static/src/js/chrome/control_panel.js b/addons/web/static/src/js/chrome/control_panel.js index 4104f37bd3e..0913b574a3d 100644 --- a/addons/web/static/src/js/chrome/control_panel.js +++ b/addons/web/static/src/js/chrome/control_panel.js @@ -148,15 +148,25 @@ var ControlPanel = Widget.extend({ } // Detach control_panel old content and attach new elements + var toDetach = this.nodes; + if (status.searchview && this.searchview === status.searchview) { + // If the searchview is the same as before, don't detach it s.t. + // we don't loose any floating content, nor the focus + toDetach = _.omit(toDetach, '$searchview'); + new_cp_content = _.omit(new_cp_content, '$searchview'); + } if (options.clear) { - this._detach_content(this.nodes); + this._detach_content(toDetach); // Show the searchview buttons area, which might have been hidden by // the searchview, as client actions may insert elements into it this.nodes.$searchview_buttons.show(); } else { - this._detach_content(_.pick(this.nodes, _.keys(new_cp_content))); + this._detach_content(_.pick(toDetach, _.keys(new_cp_content))); } this._attach_content(new_cp_content); + if (options.clear || status.searchview) { + this.searchview = status.searchview; + } // Update the searchview and switch buttons if (status.searchview || options.clear) { diff --git a/addons/web/static/src/js/views/list/list_editable_renderer.js b/addons/web/static/src/js/views/list/list_editable_renderer.js index a12b85abdd0..a0ce8d31af4 100644 --- a/addons/web/static/src/js/views/list/list_editable_renderer.js +++ b/addons/web/static/src/js/views/list/list_editable_renderer.js @@ -861,8 +861,16 @@ ListRenderer.include({ */ _onRemoveIconClick: function (event) { event.stopPropagation(); - var id = $(event.target).closest('tr').data('id'); - this.trigger_up('list_record_remove', {id: id}); + var $row = $(event.target).closest('tr'); + var id = $row.data('id'); + if ($row.hasClass('o_selected_row')) { + this.trigger_up('list_record_remove', {id: id}); + } else { + var self = this; + this.unselectRow().then(function () { + self.trigger_up('list_record_remove', {id: id}); + }); + } }, /** * If the list view editable, just let the event bubble. We don't want to diff --git a/addons/web/static/tests/chrome/action_manager_tests.js b/addons/web/static/tests/chrome/action_manager_tests.js index dee1b0dbb3f..95e5742e95f 100644 --- a/addons/web/static/tests/chrome/action_manager_tests.js +++ b/addons/web/static/tests/chrome/action_manager_tests.js @@ -3431,6 +3431,62 @@ QUnit.module('ActionManager', { actionManager.destroy(); }); + + QUnit.module('Search View Action'); + + QUnit.test('search view should keep focus during do_search', function (assert) { + assert.expect(5); + + /* One should be able to type something in the search view, press on enter to + * make the facet and trigger the search, then do this process + * over and over again seamlessly. + * Verifying the input's value is a lot trickier than verifying the search_read + * because of how native events are handled in tests + */ + + var searchDeferred = $.Deferred(); + + var actionManager = createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + mockRPC: function (route, args) { + if (route === '/web/dataset/search_read') { + assert.step('search_read ' + args.domain); + if ( _.isEqual(args.domain, [['foo', 'ilike', 'm']])) { + return searchDeferred.then(this._super.bind(this, route, args)); + } + } + return this._super.apply(this, arguments); + } + }); + + actionManager.doAction(3); + + var $searchInput = $('.o_searchview input'); + $searchInput.trigger($.Event('keypress', {key: 'm', which: 109, keyCode: 109})); + $searchInput.trigger($.Event('keydown', {key: 'Enter', which: 13, keyCode: 13})); + + assert.verifySteps(["search_read ", + "search_read foo,ilike,m"]); + + // Triggering the do_search above will kill the current searchview Input + $searchInput = $('.o_searchview input'); + $searchInput.trigger($.Event('keypress', {key: 'o', which: 111, keyCode: 111})); + + // We have something in the input of the search view. Making the search_read + // return at this point will trigger the redraw of the view. + // However we want to hold on to what we just typed + searchDeferred.resolve(); + + $searchInput.trigger($.Event('keydown', {key: 'Enter', which: 13, keyCode: 13})); + + assert.verifySteps(["search_read ", + "search_read foo,ilike,m", + "search_read |,foo,ilike,m,foo,ilike,o"]); + + actionManager.destroy(); + }); }); }); diff --git a/addons/web/static/tests/views/form_tests.js b/addons/web/static/tests/views/form_tests.js index f53bac54e3a..a6176ab4328 100644 --- a/addons/web/static/tests/views/form_tests.js +++ b/addons/web/static/tests/views/form_tests.js @@ -3117,6 +3117,42 @@ QUnit.module('Views', { form.destroy(); }); + QUnit.test('delete a line in a one2many while editing another line triggers a warning', function (assert) { + assert.expect(3); + + this.data.partner.records[0].p = [1, 2]; + + var form = createView({ + View: FormView, + model: 'partner', + data: this.data, + arch: '<form>' + + '<field name="p">' + + '<tree editable="bottom">' + + '<field name="display_name" required="True"/>' + + '</tree>' + + '</field>' + + '</form>', + res_id: 1, + }); + + form.$buttons.find('.o_form_button_edit').click(); + form.$('.o_data_cell').first().click(); // edit first row + form.$('input').val('').trigger('input'); + form.$('.fa-trash-o').eq(1).click(); // delete second row + + assert.strictEqual($('.modal').find('.modal-title').first().text(), "Warning", + "Clicking out of a dirty line while editing should trigger a warning modal."); + + $('.modal').find('.btn-primary').click(); // discard changes + + assert.strictEqual(form.$('.o_data_cell').first().text(), "first record", + "Value should have been reset to what it was before editing began."); + assert.strictEqual(form.$('.o_data_row').length, 1, + "The other line should have been deleted."); + form.destroy(); + }); + QUnit.test('properly apply onchange on many2many fields', function (assert) { assert.expect(14); |
