diff options
| author | Odoo's Mergebot <xmo+roboto@odoo.com> | 2019-09-16 19:13:39 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-09-16 19:13:39 +0200 |
| commit | b995cd47bbc91d62252746c61dcd364dbb3cf43c (patch) | |
| tree | bd8b2b419bd822a54c9f068859ce63b1ba77ad68 | |
| parent | fc5934dc4541aeff4e819a9b3404a3cbb793453f (diff) | |
| parent | 3b3d35e8b91fb8881be848665349828c64642e03 (diff) | |
[IMP] web: SearchView: Allow user to quickly search on mobile
Currently the search panel is nice for a search with filters but
that was not 100% efficient for simple research without filters.
The Search is now integrated in the form view, with the ability
to open the Search panel to apply filters or group by.
Task ID : 1924760
closes odoo/odoo#36183
Signed-off-by: Adrien Dieudonné (adr) <adr@odoo.com>
6 files changed, 143 insertions, 65 deletions
diff --git a/addons/web/static/src/js/views/control_panel/control_panel_renderer.js b/addons/web/static/src/js/views/control_panel/control_panel_renderer.js index 677f0733bc5..bdde2827e96 100644 --- a/addons/web/static/src/js/views/control_panel/control_panel_renderer.js +++ b/addons/web/static/src/js/views/control_panel/control_panel_renderer.js @@ -50,6 +50,7 @@ var ControlPanelRenderer = Renderer.extend({ this.$subMenus = null; this.action = params.action; this.displaySearchMenu = true; + this.isMobile = config.device.isMobile; this.menusSetup = false; this.searchMenuTypes = params.searchMenuTypes || []; this.subMenus = {}; diff --git a/addons/web/static/src/js/views/control_panel/mobile_control_panel_renderer.js b/addons/web/static/src/js/views/control_panel/mobile_control_panel_renderer.js index 23852abcf53..95b5c577587 100644 --- a/addons/web/static/src/js/views/control_panel/mobile_control_panel_renderer.js +++ b/addons/web/static/src/js/views/control_panel/mobile_control_panel_renderer.js @@ -9,9 +9,9 @@ if (!config.device.isMobile) { } ControlPanelRenderer.include({ - template:'MobileControlPanel', events:_.extend({}, ControlPanelRenderer.prototype.events, { - 'click .o_mobile_search_close, .o_mobile_search_show_result, .o_enable_searchview': '_toggleMobileSearchView', + 'click .o_mobile_search_close, .o_mobile_search_show_result, .o_toggle_searchview_full': '_toggleMobileSearchView', + 'click .o_enable_searchview': '_toggleMobileQuickSearchView', 'click': '_onOpenMobileSearchView', 'click .o_mobile_search_clear_facets': '_onEmptyAll', 'show.bs.dropdown .o_mobile_search_filter .o_dropdown': '_onDropdownToggle', @@ -49,17 +49,40 @@ ControlPanelRenderer.include({ _renderSearchBar: function () { var self = this; return this._super.apply(this, arguments).then(function () { - self.searchBar.$el.detach().insertAfter(self.$('.o_mobile_search_header')); + self._renderSearchviewInput(); }); }, + _renderSearchviewInput: function () { + if (this.$('.o_toggle_searchview_full').is(':visible') && !this.$('.o_mobile_search').is(':visible')) { + this.$('.o_toggle_searchview_full').toggleClass('btn-secondary', !!this.state.query.length); + this.searchBar.$el.detach().insertAfter(this.$('.o_mobile_search')); + } else { + this.searchBar.$el.detach().insertAfter(this.$('.o_mobile_search_header')); + } + }, /** * Toggles mobile search view screen. * * @private */ _toggleMobileSearchView: function () { - this.$('.o_enable_searchview').toggleClass('btn-secondary', !!this.state.query.length); this.$('.o_mobile_search').toggleClass('o_hidden'); + this._renderSearchviewInput(); + }, + /** + * Toggles mobile quick search view on screen. + * + * @private + */ + _toggleMobileQuickSearchView: function () { + this.$('.o_cp_searchview').toggleClass('o_searchview_quick'); + this.$('.breadcrumb').toggleClass('o_hidden', + this.$('.o_cp_searchview').hasClass('o_searchview_quick')); + this.$('.o_toggle_searchview_full') + .toggleClass('o_hidden') + .toggleClass('btn-secondary', !!this.state.query.length); + this._renderSearchviewInput(); + this.$('.o_enable_searchview').toggleClass("fa-search").toggleClass("fa-close"); }, //-------------------------------------------------------------------------- diff --git a/addons/web/static/src/scss/control_panel.scss b/addons/web/static/src/scss/control_panel.scss index dd74c8ac010..c08695fc28d 100644 --- a/addons/web/static/src/scss/control_panel.scss +++ b/addons/web/static/src/scss/control_panel.scss @@ -1,13 +1,24 @@ .o_control_panel { - display: flex; - flex-flow: row wrap; border-bottom: 1px solid darken($o-control-panel-background-color, 20%); @include o-webclient-padding($top: 10px, $bottom: 10px); background-color: $o-control-panel-background-color; - > .breadcrumb { - width: 50%; + > div { + display: flex; + justify-content: space-between; + min-height: 30px; + } + + .breadcrumb, .o_cp_left { + flex: 1 1 auto; + } + + .o_cp_searchview, .o_cp_right { + flex: 0 0 50%; + } + + .breadcrumb { font-size: 18px; > li { @@ -19,8 +30,7 @@ } } - > .o_cp_searchview { - width: 50%; + .o_cp_searchview { min-height: $o-cp-breadcrumb-height; } @@ -30,10 +40,9 @@ background: white; } - > .o_cp_left { + .o_cp_left { display: flex; justify-content: space-between; - width: 50%; margin-top: 5px; > .o_cp_sidebar { @@ -65,9 +74,8 @@ } } - > .o_cp_right { + .o_cp_right { display: flex; - width: 50%; margin-top: 5px; > .o_cp_pager { diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 733bd37c211..1e131c9fc8b 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -148,18 +148,22 @@ <t t-name="ControlPanel"> <div class="o_control_panel"> - <ol class="breadcrumb" role="navigation"/> - <div class="o_cp_searchview" role="search"> - <t t-call="SearchView"/> - </div> - <div class="o_cp_left"> - <div class="o_cp_buttons" role="toolbar" aria-label="Control panel toolbar"/> - <aside class="o_cp_sidebar"/> + <div> + <ol class="breadcrumb" role="navigation"/> + <div class="o_cp_searchview" role="search"> + <t t-if="widget.withSearchBar" t-call="SearchView"/> + </div> </div> - <div class="o_cp_right"> - <div class="btn-group o_search_options" role="search"/> - <nav class="o_cp_pager" role="search" aria-label="Pager"/> - <nav class="btn-group o_cp_switch_buttons" role="toolbar" aria-label="View switcher"/> + <div> + <div class="o_cp_left"> + <div class="o_cp_buttons" role="toolbar" aria-label="Control panel toolbar"/> + <aside class="o_cp_sidebar"/> + </div> + <div class="o_cp_right"> + <div class="btn-group o_search_options" role="search"/> + <nav class="o_cp_pager" role="search" aria-label="Pager"/> + <nav class="btn-group o_cp_switch_buttons" role="toolbar" aria-label="View switcher"/> + </div> </div> </div> </t> @@ -1164,7 +1168,14 @@ </div> <div t-name="SearchView" class="o_searchview" role="search" aria-autocomplete="list"> - <span class="o_searchview_more fa" title="Advanced Search..." role="img" aria-label="Advanced Search..."/> + <t t-if="widget.isMobile"> + <t t-call="MobileSearchView"/> + <button class="o_toggle_searchview_full o_hidden btn fa fa-filter"/> + <button class="o_enable_searchview btn btn-link fa fa-search"/> + </t> + <t t-else=""> + <span class="o_searchview_more fa" title="Advanced Search..." role="img" aria-label="Advanced Search..."/> + </t> </div> <div t-name="SearchView.SearchBar" class="o_searchview_input_container"> @@ -1233,40 +1244,17 @@ </select> </t> -<t t-name="MobileControlPanel"> - <div class="o_control_panel"> - <ol class="breadcrumb" role="navigation"/> - <div class="o_cp_searchview" role="search"> - <t t-call="MobileSearchView"/> - </div> - <div class="o_cp_left"> - <div class="o_cp_buttons" role="toolbar" aria-label="Control panel toolbar"/> - <aside class="o_cp_sidebar"/> - </div> - <div class="o_cp_right"> - <div class="btn-group o_search_options" role="search"/> - <nav class="o_cp_pager" role="search" aria-label="Pager"/> - <nav class="btn-group o_cp_switch_buttons" role="toolbar" aria-label="View switcher"/> - </div> - </div> -</t> - -<t t-name="MobileSearchView"> - <div class="o_searchview" role="search" aria-autocomplete="list"> - <button class="o_enable_searchview btn fa fa-search"/> - <div class="o_mobile_search o_hidden"> - <div class="o_mobile_search_header"> - <span class="o_mobile_search_close float-left mt16 mb16 mr8 ml16"> - <i class="fa fa-arrow-left"/> - <strong class="float-right ml8">FILTER</strong> - </span> - <span class="float-right o_mobile_search_clear_facets mt16 mr16">CLEAR</span> - </div> - <div class="o_mobile_search_filter o_search_options mb8 mt8 ml16 mr16"/> - <div class="btn btn-primary o_mobile_search_show_result">SEE RESULT</div> - </div> +<div t-name="MobileSearchView" class="o_mobile_search o_hidden"> + <div class="o_mobile_search_header"> + <span class="o_mobile_search_close float-left mt16 mb16 mr8 ml16"> + <i class="fa fa-arrow-left"/> + <strong class="float-right ml8">FILTER</strong> + </span> + <span class="float-right o_mobile_search_clear_facets mt16 mr16">CLEAR</span> </div> -</t> + <div class="o_mobile_search_filter o_search_options mb8 mt8 ml16 mr16"/> + <div class="btn btn-primary o_mobile_search_show_result">SEE RESULT</div> +</div> <div t-name="AddNewFavoriteMenu"> <button type="button" class="dropdown-item o_generator_menu o_add_favorite o_menu_header">Save Current Search</button> diff --git a/addons/web/static/tests/views/mobile_control_panel_tests.js b/addons/web/static/tests/views/mobile_control_panel_tests.js index 19226741474..be0d197ef44 100644 --- a/addons/web/static/tests/views/mobile_control_panel_tests.js +++ b/addons/web/static/tests/views/mobile_control_panel_tests.js @@ -39,8 +39,61 @@ QUnit.module('Mobile Search view Screen', { }; }, }, function () { - QUnit.test('can activate a filter with mobile search view', async function (assert) { - assert.expect(3); + QUnit.test('can activate a filter with mobile search view in quick search mode', async function (assert) { + assert.expect(7); + + var searchRPCFlag = false; + + var actionManager = await createActionManager({ + actions: this.actions, + archs: this.archs, + data: this.data, + mockRPC: function (route, args) { + if (searchRPCFlag) { + assert.deepEqual(args.domain, [['foo', 'ilike', 'A']], + "domain should have been properly transferred to list view"); + } + return this._super.apply(this, arguments); + }, + }); + + await actionManager.doAction(1); + + assert.strictEqual($('button.o_enable_searchview.fa-search').length, 1, + "should display a button to open the searchview"); + assert.deepEqual($('.o_searchview_input_container:visible').length, 0, + "Quick search input should be hidden"); + + // open the search view + await testUtils.dom.click($('button.o_enable_searchview')); + assert.deepEqual($('.o_toggle_searchview_full:visible').length, 1, + "should display a button to expand the searchview"); + assert.deepEqual($('.o_searchview_input_container:visible').length, 1, + "Quick search input should now be visible"); + + searchRPCFlag = true; + + // use quick search input + $('.o_searchview_input') + .val("A") + .trigger($.Event('keypress', { which: 65, keyCode: 65 })); + await testUtils.nextTick(); + actionManager.$('.o_searchview_input') + .trigger($.Event('keydown', { which: $.ui.keyCode.ENTER, keyCode: $.ui.keyCode.ENTER })); + await testUtils.nextTick(); + + // close quick search + await testUtils.dom.click($('button.o_enable_searchview.fa-close')); + assert.deepEqual($('.o_toggle_searchview_full:visible').length, 0, + "Expand icon shoud be hidden"); + assert.deepEqual($('.o_searchview_input_container:visible').length, 0, + "Quick search input should be hidden"); + + actionManager.destroy(); + }); + + QUnit.test('can activate a filter with mobile search view in full screen mode', async function (assert) { + assert.expect(4); var filterActiveFlag = false; @@ -61,20 +114,25 @@ QUnit.module('Mobile Search view Screen', { assert.ok(!$('.o_mobile_search').is(':visible'), 'mobile search view is not visible'); + // open the search view await testUtils.dom.click($('button.o_enable_searchview')); - + // open it in full screen + await testUtils.dom.click($('.o_toggle_searchview_full')); assert.ok($('.o_mobile_search').is(':visible'), 'mobile search view is visible'); // open filter sub menu await testUtils.dom.click($('button.o_dropdown_toggler_btn').first()); - filterActiveFlag = true; - // click on Active filter await testUtils.dom.click($('.o_filters_menu a:contains(Active)')); + // closing search view + await testUtils.dom.click($('.o_mobile_search_close')); + assert.ok(!$('.o_mobile_search').is(':visible'), + 'mobile search view is not visible'); + actionManager.destroy(); }); diff --git a/odoo/addons/test_main_flows/static/tests/tours/main_flow.js b/odoo/addons/test_main_flows/static/tests/tours/main_flow.js index 1344c41822b..334223e4901 100644 --- a/odoo/addons/test_main_flows/static/tests/tours/main_flow.js +++ b/odoo/addons/test_main_flows/static/tests/tours/main_flow.js @@ -604,7 +604,7 @@ tour.register('main_flow_tour', { position: "bottom" }, { trigger: ".o_data_row:first", - extra_trigger: '.o_control_panel > .breadcrumb:contains("Sales Orders")', + extra_trigger: '.o_control_panel .breadcrumb:contains("Sales Orders")', content: _t("Go to the last sale order"), position: "right" }, { |
