diff options
| author | Christophe Simonis <chs@odoo.com> | 2019-08-13 10:08:12 +0200 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2019-08-13 10:08:12 +0200 |
| commit | b2872e9bab5b84f7a83548d7ea0e864e4aa0d131 (patch) | |
| tree | 8cc57082fd3a1b307e76a46a51eca9a66d55e258 /addons/web/static | |
| parent | 2f90b39a6689607f7b812e648dee966bb37c2190 (diff) | |
| parent | 499d3efa7ce4b7f6756658bff82e4a8b2f57c050 (diff) | |
[MERGE] forward port branch saas-12.3 up to 499d3efa7ce
Diffstat (limited to 'addons/web/static')
8 files changed, 253 insertions, 5 deletions
diff --git a/addons/web/static/src/js/views/control_panel/control_panel_model.js b/addons/web/static/src/js/views/control_panel/control_panel_model.js index 0229daa41ee..02e1c49508b 100644 --- a/addons/web/static/src/js/views/control_panel/control_panel_model.js +++ b/addons/web/static/src/js/views/control_panel/control_panel_model.js @@ -407,7 +407,17 @@ var ControlPanelModel = mvc.Model.extend({ // we need to deactivate all groups when activating a favorite if (filter.type === 'favorite') { this.query.forEach(function (groupId) { - self.groups[groupId].activeFilterIds = []; + var group = self.groups[groupId]; + group.activeFilterIds.forEach(function (id) { + var filter = self.filters[id]; + if (filter.autoCompleteValues) { + filter.autoCompleteValues = []; + } + if (filter.currentOptionId) { + filter.currentOptionId = false; + } + }) + group.activeFilterIds = []; }); this.query = []; } diff --git a/addons/web/static/src/js/views/control_panel/search/add_new_favorite_menu.js b/addons/web/static/src/js/views/control_panel/search/add_new_favorite_menu.js index 421fec3e04b..07c80d38c29 100644 --- a/addons/web/static/src/js/views/control_panel/search/add_new_favorite_menu.js +++ b/addons/web/static/src/js/views/control_panel/search/add_new_favorite_menu.js @@ -40,6 +40,12 @@ var AddNewFavoriteMenu = Widget.extend({ //-------------------------------------------------------------------------- /** + * @param {Object} params + */ + update: function (params) { + this.favorites = params.favorites; + }, + /** * Close the menu and re-render the widget. */ closeMenu: function () { diff --git a/addons/web/static/src/js/views/control_panel/search/favorite_menu.js b/addons/web/static/src/js/views/control_panel/search/favorite_menu.js index 8b9ae4d44d6..0a536820735 100644 --- a/addons/web/static/src/js/views/control_panel/search/favorite_menu.js +++ b/addons/web/static/src/js/views/control_panel/search/favorite_menu.js @@ -49,6 +49,18 @@ var FavoriteMenu = DropdownMenu.extend({ }, //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + /** + * @override + */ + update: function (items) { + this._super.apply(this, arguments); + _.invoke(this.subMenus, 'update', { favorites: this.items }); + }, + + //-------------------------------------------------------------------------- // Private //-------------------------------------------------------------------------- diff --git a/addons/web/static/src/js/widgets/domain_selector.js b/addons/web/static/src/js/widgets/domain_selector.js index ed71679699c..755ee32979e 100644 --- a/addons/web/static/src/js/widgets/domain_selector.js +++ b/addons/web/static/src/js/widgets/domain_selector.js @@ -652,7 +652,7 @@ var DomainLeaf = DomainNode.extend({ this.fieldSelector = new ModelFieldSelector( this, this.model, - this.chain ? this.chain.split(".") : [], + this.chain !== undefined ? this.chain.toString().split(".") : [], this.options ); defs.push(this.fieldSelector.appendTo($("<div/>")).then((function () { diff --git a/addons/web/static/src/js/widgets/model_field_selector.js b/addons/web/static/src/js/widgets/model_field_selector.js index 08a7ae47c81..ed74b2da44a 100644 --- a/addons/web/static/src/js/widgets/model_field_selector.js +++ b/addons/web/static/src/js/widgets/model_field_selector.js @@ -301,11 +301,16 @@ var ModelFieldSelector = Widget.extend({ }).bind(this)); function processChain(chain) { - var field = this._getLastPageField(chain.pop()); + var fieldName = chain.pop(); + var field = this._getLastPageField(fieldName); if (field && field.relation && chain.length > 0) { // Fetch next chain node if any and possible return this._pushPageData(field.relation).then(processChain.bind(this, chain)); } else if (field && chain.length === 0) { // Last node fetched return Promise.resolve(); + } else if (!field && fieldName === "1") { // TRUE_LEAF + this._validate(true); + } else if (!field && fieldName === "0") { // FALSE_LEAF + this._validate(true); } else { // Wrong node chain this._validate(false); } diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index bb744cbdb03..5eff2fb4422 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -650,8 +650,16 @@ <i class="fa fa-chevron-right" role="img" aria-label="Followed by" title="Followed by"/> </t> <span class="o_field_selector_chain_part"> - <t t-set="fieldInfo" t-value="_.findWhere(pages[fieldName_index], {'name': fieldName})"/> - <t t-esc="fieldInfo && fieldInfo.string || '?'"/> + <t t-if="fieldName === '1'"> + <t t-esc="fieldName"/> + </t> + <t t-elif="fieldName === '0'"> + <t t-esc="fieldName"/> + </t> + <t t-else=""> + <t t-set="fieldInfo" t-value="_.findWhere(pages[fieldName_index], {'name': fieldName})"/> + <t t-esc="fieldInfo && fieldInfo.string || '?'"/> + </t> </span> </t> </t> diff --git a/addons/web/static/tests/views/search_view_tests.js b/addons/web/static/tests/views/search_view_tests.js index ccf5bf5b50d..fc225818ad6 100644 --- a/addons/web/static/tests/views/search_view_tests.js +++ b/addons/web/static/tests/views/search_view_tests.js @@ -8,6 +8,7 @@ var createActionManager = testUtils.createActionManager; var createControlPanel = testUtils.createControlPanel; var createView = testUtils.createView; var patchDate = testUtils.mock.patchDate; +var session = require('web.session'); var controlPanelViewParameters = require('web.controlPanelViewParameters'); var PERIOD_OPTIONS_IDS = controlPanelViewParameters.PERIOD_OPTIONS.map(function (option) {return option.optionId;}); @@ -119,6 +120,14 @@ QUnit.module('Search View', { type: 'ir.actions.act_window', views: [[2, 'list']], search_view_id: [8, 'search'], + }, + { + id: 12, + name: 'Partners Action 12', + res_model: 'partner', + type: 'ir.actions.act_window', + views: [[2, 'list']], + search_view_id: [9, 'search'], } ]; @@ -198,6 +207,11 @@ QUnit.module('Search View', { '<filter string="Date Field Filter" name="positive" date="date_field"/>' + '<filter string="Date Field Groupby" name="coolName" context="{\'group_by\': \'date_field:day\'}"/>' + '</search>', + 'partner,9,search': '<search>'+ + '<field string="Foo" name="foo"/>' + + '<filter string="Date Field Filter" name="positive" date="date_field"/>' + + '<filter string="Date Field Groupby" name="coolName" context="{\'group_by\': \'date_field:day\'}"/>' + + '</search>', }; @@ -959,6 +973,159 @@ QUnit.module('Search View', { controlPanel.destroy(); }); + QUnit.test('toggle favorite correctly clears filter, groupbys and field "options"', async function (assert) { + assert.expect(8); + + const actionManager = await createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + intercepts: { + load_filters: function (event) { + return Promise.resolve([{ + context: "{}", + domain: "[]", + id: 7, + is_default: false, + name: "My favorite", + sort: "[]", + user_id: [2, "Mitchell Admin"], + }]).then(event.data.on_success); + }, + }, + }); + + await actionManager.doAction(12); + + // activate Foo a + await testUtils.fields.triggerKey('press', $('.o_searchview_input'), 97); + await testUtils.fields.triggerKey('up', $('.o_searchview_input'), 'enter'); + + // activate Date Filter with This Month + await testUtils.dom.click($('button .fa-filter')); + await testUtils.dom.click($('.o_filters_menu .o_menu_item a')); + await testUtils.dom.click($('.o_item_option[data-option_id="this_month"]')); + + // activate Date Groupby with Year + await testUtils.dom.click($('button .fa-bars')); + await testUtils.dom.click($('.o_group_by_menu .o_menu_item a')); + await testUtils.dom.click($('.o_item_option[data-option_id="year"]')); + + assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(0).text().trim(), + "a", + "There should be a filter Foo a"); + + assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(1).text().trim(), + "Date Field Filter: This Month", + "There should be a filter facet with label 'Date Field Filter: This Month'"); + + assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(2).text().trim(), + "Date Field Groupby: Year", + "There should be a groupby facet with label 'Date Field Groupby: Year'"); + + // activate the favorite + await testUtils.dom.click($('button .fa-star')); + await testUtils.dom.click($('.o_favorites_menu .o_menu_item a')); + + assert.containsOnce(actionManager, '.o_searchview_input_container .o_facet_values', + "There should be a unique facet in the search bar"); + assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(0).text().trim(), + "My favorite", + "There should be a facet with label 'My favorite''"); + + await testUtils.dom.click($('button .fa-filter')); + await testUtils.dom.click($('.o_filters_menu .o_menu_item a')); + assert.doesNotHaveClass($('.o_item_option[data-option_id="this_month"]'), 'selected', + "The Date Filter option 'This Month' should be deactivated"); + + await testUtils.dom.click($('button .fa-bars')); + await testUtils.dom.click($('.o_group_by_menu .o_menu_item a')); + assert.doesNotHaveClass($('.o_item_option[data-option_id="year"]'), 'selected', + "The Date Groupby option 'Year' should be deactivated"); + + await testUtils.fields.triggerKey('press', $('.o_searchview_input'), 98); + await testUtils.fields.triggerKey('up', $('.o_searchview_input'), 'enter'); + assert.strictEqual($('.o_searchview_input_container .o_facet_values').eq(1).text().trim(), + "b", + "There should be a filter Foo b"); + + actionManager.destroy(); + }); + + QUnit.test('favorites have unique descriptions (the submenus of the favorite menu are correctly updated)', async function (assert) { + assert.expect(7); + + const UID = session.uid; + + const actionManager = await createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + intercepts: { + load_filters: function (event) { + return Promise.resolve([{ + context: "{}", + domain: "[]", + id: 7, + is_default: false, + name: "My favorite", + sort: "[]", + user_id: [2, "Mitchell Admin"], + }]).then(event.data.on_success); + }, + create_filter: function (event) { + assert.step('create_filter'); + assert.deepEqual(event.data.filter, { + "action_id": 1, + "context": {}, + "domain": "[]", + "is_default": false, + "model_id": "partner", + "name": "My favorite 2", + "sort": "[]", + "user_id": UID, + }); + return Promise.resolve(1).then(event.data.on_success); + } + }, + }); + testUtils.mock.intercept(actionManager, 'call_service', function (ev) { + if (ev.data.service === 'notification') { + // A notification alerting that another favorite with same name exists + // should be triggered + assert.step('notification'); + assert.deepEqual(ev.data.args[0], { + "className": undefined, + "message": "Filter with same name already exists.", + "sticky": undefined, + "title": "Error", + "type": "warning" + }); + } + }, true); + + await actionManager.doAction(1); + await testUtils.dom.click($('button .fa-star')); + await testUtils.dom.click($('.o_favorites_menu .o_add_favorite')); + await testUtils.fields.editInput($('div.o_favorite_name input'), 'My favorite'); + await testUtils.dom.click($('.o_favorites_menu div.o_save_favorite button')); + + await testUtils.fields.editInput($('div.o_favorite_name input'), 'My favorite 2'); + await testUtils.dom.click($('.o_favorites_menu div.o_save_favorite button')); + + await testUtils.dom.click($('.o_favorites_menu .o_add_favorite')); + await testUtils.fields.editInput($('div.o_favorite_name input'), 'My favorite 2'); + await testUtils.dom.click($('.o_favorites_menu div.o_save_favorite button')); + + assert.verifySteps([ + 'notification', + 'create_filter', + 'notification' + ]) + + actionManager.destroy(); + }); + QUnit.module('Search Arch'); QUnit.test('arch order of groups of filters preserved', async function (assert) { diff --git a/addons/web/static/tests/widgets/model_field_selector_tests.js b/addons/web/static/tests/widgets/model_field_selector_tests.js index 76c18b91f5b..c45bcb9dabe 100644 --- a/addons/web/static/tests/widgets/model_field_selector_tests.js +++ b/addons/web/static/tests/widgets/model_field_selector_tests.js @@ -248,6 +248,46 @@ QUnit.module('ModelFieldSelector', { fieldSelector.destroy(); }); + + QUnit.test("create a field chain with value 1 i.e. TRUE_LEAF", async function (assert) { + assert.expect(1); + + var $target = $("#qunit-fixture"); + + //create the field selector with domain value ["1"] + var fieldSelector = new ModelFieldSelector(null, "partner", ["1"], { + readonly: false, + showSearchInput: false, + }); + testUtils.mock.addMockEnvironment(fieldSelector, {data: this.data}); + await fieldSelector.appendTo($target); + + var $fieldName = fieldSelector.$('.o_field_selector_chain_part'); + assert.strictEqual($fieldName.text().trim(), "1", + "field name value should be 1."); + + fieldSelector.destroy(); + }); + + QUnit.test("create a field chain with value 0 i.e. FALSE_LEAF", async function (assert) { + assert.expect(1); + + var $target = $("#qunit-fixture"); + + //create the field selector with domain value ["0"] + var fieldSelector = new ModelFieldSelector(null, "partner", ["0"], { + readonly: false, + showSearchInput: false, + }); + testUtils.mock.addMockEnvironment(fieldSelector, {data: this.data}); + await fieldSelector.appendTo($target); + + var $fieldName = fieldSelector.$('.o_field_selector_chain_part'); + assert.strictEqual($fieldName.text().trim(), "0", + "field name value should be 0."); + + fieldSelector.destroy(); + }); }); }); }); |
