summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
authorGéry Debongnie <ged@odoo.com>2018-05-18 10:02:04 +0200
committerGéry Debongnie <ged@odoo.com>2018-05-23 10:48:36 +0200
commitd01787c19d4631a1de56f9873586e44ae06318f1 (patch)
treed212f930156e4aa076308e3c33aaef4e9c968666 /addons
parent4232eb7bcd4dd895b86db728a2b689ae9568f951 (diff)
[IMP] web,mail: improve search view for mobile devices
With this commit, we introduce a better screen to manipulate the search view in a mobile device. Note: most of this work was initially done by suh-odoo, then was adapted and moved to community by myself. task 31464
Diffstat (limited to 'addons')
-rw-r--r--addons/mail/static/src/js/discuss_mobile.js24
-rw-r--r--addons/mail/static/src/scss/discuss.scss29
-rw-r--r--addons/mail/static/src/xml/discuss.xml1
-rw-r--r--addons/mail/static/tests/discuss_mobile_tests.js6
-rw-r--r--addons/web/static/src/js/chrome/search_menus.js6
-rw-r--r--addons/web/static/src/js/chrome/search_view.js34
-rw-r--r--addons/web/static/src/js/chrome/search_view_mobile.js96
-rw-r--r--addons/web/static/src/scss/control_panel.scss2
-rw-r--r--addons/web/static/src/scss/search_view.scss128
-rw-r--r--addons/web/static/src/scss/search_view_mobile.scss88
-rw-r--r--addons/web/static/src/xml/base.xml27
-rw-r--r--addons/web/static/tests/chrome/search_view_mobile_tests.js83
-rw-r--r--addons/web/static/tests/helpers/test_utils.js3
-rw-r--r--addons/web/views/webclient_templates.xml3
-rw-r--r--addons/website/static/src/xml/website.backend.xml3
15 files changed, 400 insertions, 133 deletions
diff --git a/addons/mail/static/src/js/discuss_mobile.js b/addons/mail/static/src/js/discuss_mobile.js
index 556651ec67e..531553e6804 100644
--- a/addons/mail/static/src/js/discuss_mobile.js
+++ b/addons/mail/static/src/js/discuss_mobile.js
@@ -14,7 +14,6 @@ if (!config.device.isMobile) {
Discuss.include({
template: 'mail.discuss_mobile',
- need_control_panel: false, // in mobile, we use a custom control panel
events: _.extend(Discuss.prototype.events, {
'click .o_mail_mobile_tab': '_onMobileTabClicked',
'click .o_channel_inbox_item': '_onMobileInboxButtonClicked',
@@ -123,14 +122,6 @@ Discuss.include({
}
},
/**
- * @private
- */
- _toggleSearchView: function () {
- this.searchviewDisplayed = !this.searchviewDisplayed;
- this.searchview.$el.toggleClass('o_hidden', !this.searchviewDisplayed);
- this.$buttons.toggleClass('o_hidden', this.searchviewDisplayed);
- },
- /**
* Overrides to toggle the visibility of the tabs when a message is unselected
*
* @override
@@ -198,10 +189,6 @@ Discuss.include({
self.$buttons.find('.o_mail_chat_button_' + type).removeClass('o_hidden');
self.$buttons.find('.o_mail_chat_button_mark_read').toggleClass('o_hidden', type !== 'channel_inbox');
self.$buttons.find('.o_mail_chat_button_unstar_all').toggleClass('o_hidden', type !== 'channel_starred');
- self.$('.o_enable_searchview').toggleClass('o_hidden', !inInbox);
- if (!inInbox && self.searchviewDisplayed) {
- self._toggleSearchView(); // close the searchview when leaving Inbox
- }
// update Inbox page buttons
if (inInbox) {
@@ -219,17 +206,6 @@ Discuss.include({
self.$('.o_mail_mobile_tab[data-type=' + type + ']').addClass('active');
});
},
- /**
- * @override
- */
- _updateControlPanel: function () {
- this.$buttons.appendTo(this.$('.o_mail_chat_mobile_control_panel'));
- this.searchview.$el.appendTo(this.$('.o_mail_chat_mobile_control_panel'));
- var $enable_searchview = $('<button/>', {type: 'button'})
- .addClass('o_enable_searchview btn fa fa-search')
- .on('click', this._toggleSearchView.bind(this));
- $enable_searchview.insertAfter(this.searchview.$el);
- },
//--------------------------------------------------------------------------
// Handlers
diff --git a/addons/mail/static/src/scss/discuss.scss b/addons/mail/static/src/scss/discuss.scss
index de129eaee4c..8bada8804cb 100644
--- a/addons/mail/static/src/scss/discuss.scss
+++ b/addons/mail/static/src/scss/discuss.scss
@@ -271,35 +271,6 @@
@include o-flex-flow(column, nowrap);
background: white;
- .o_mail_chat_mobile_control_panel {
- @include o-flex(0, 0, auto);
- padding: 5px;
- min-height: 44px;
- border-bottom: 1px solid #ebebeb;
- box-shadow: 0px 0px 10px #afafaf;
- z-index: 1; // so that box shaddow is above thread's images
- .o_searchview {
- border: none;
- padding: 5px 5px 0px 5px;
- .o_searchview_input {
- font-size: 15px;
- }
- .o_searchview_more {
- display: none;
- }
- }
- .o_enable_searchview, .o_enable_searchview:focus,
- .o_enable_searchview:hover, .o_enable_searchview:active {
- @include o-position-absolute($right: 5px, $top: 5px);
- color: gray;
- background: none;
- font-size: 15px;
- &:active {
- box-shadow: none;
- }
- }
- }
-
.o_mail_chat_mobile_inbox_buttons {
@include o-flex-display;
@include o-flex(0, 0, auto);
diff --git a/addons/mail/static/src/xml/discuss.xml b/addons/mail/static/src/xml/discuss.xml
index 744d624d564..b0a3bfe1ba9 100644
--- a/addons/mail/static/src/xml/discuss.xml
+++ b/addons/mail/static/src/xml/discuss.xml
@@ -149,7 +149,6 @@
<!-- Mobile templates -->
<t t-name="mail.discuss_mobile">
<div class="o_mail_chat">
- <div class="o_mail_chat_mobile_control_panel"/>
<div class="o_mail_chat_mobile_inbox_buttons">
<button type="button" class="btn btn-primary btn-sm visible-xs-inline o_channel_inbox_item" title="Inbox" data-type="channel_inbox">
Inbox
diff --git a/addons/mail/static/tests/discuss_mobile_tests.js b/addons/mail/static/tests/discuss_mobile_tests.js
index 921436d4657..e7a7162a03d 100644
--- a/addons/mail/static/tests/discuss_mobile_tests.js
+++ b/addons/mail/static/tests/discuss_mobile_tests.js
@@ -26,7 +26,7 @@ QUnit.test('mobile basic rendering', function (assert) {
// /mail/client_action route is always called when the test suite is
// launched), and we must wait for this RPC to be done before starting to
// test the interface. This should be refactored to facilitate the testing.
- assert.expect(9);
+ assert.expect(8);
var done = assert.async();
createDiscuss({
@@ -37,8 +37,6 @@ QUnit.test('mobile basic rendering', function (assert) {
services: this.services,
}).then(function (discuss) {
// test basic rendering in mobile
- assert.strictEqual(discuss.$('.o_mail_chat_mobile_control_panel').length, 1,
- "should have rendered a control panel");
assert.strictEqual(discuss.$('.o_mail_chat_content .o_mail_no_content').length, 1,
"should display the no content message");
assert.strictEqual(discuss.$('.o_mail_mobile_tabs').length, 1,
@@ -56,7 +54,7 @@ QUnit.test('mobile basic rendering', function (assert) {
"should be in DMs tab");
assert.strictEqual(discuss.$('.o_mail_chat_content .o_mail_no_content').length, 0,
"should display the no content message");
- discuss.$('.o_mail_chat_button_dm').click(); // click to add a channel
+ $('.o_mail_chat_button_dm').click(); // click to add a channel
assert.strictEqual(discuss.$('.o_mail_add_channel input:visible').length, 1,
"should display the input to add a channel");
diff --git a/addons/web/static/src/js/chrome/search_menus.js b/addons/web/static/src/js/chrome/search_menus.js
index d33cdce6500..a6548b051f4 100644
--- a/addons/web/static/src/js/chrome/search_menus.js
+++ b/addons/web/static/src/js/chrome/search_menus.js
@@ -1,6 +1,7 @@
odoo.define('web.FavoriteMenu', function (require) {
"use strict";
+var config = require('web.config');
var core = require('web.core');
var data_manager = require('web.data_manager');
var pyeval = require('web.pyeval');
@@ -38,6 +39,7 @@ return Widget.extend({
this.action = action;
this.action_id = action.id;
this.filters = {};
+ this.isMobile = config.device.isMobile;
_.each(filters, this.add_filter.bind(this));
},
start: function () {
@@ -305,6 +307,7 @@ return Widget.extend({
odoo.define('web.FilterMenu', function (require) {
"use strict";
+var config = require('web.config');
var search_filters = require('web.search_filters');
var search_inputs = require('web.search_inputs');
var Widget = require('web.Widget');
@@ -333,6 +336,7 @@ return Widget.extend({
},
init: function (parent, filters, fields) {
this._super(parent);
+ this.isMobile = config.device.isMobile;
this.filters = filters || [];
this.searchview = parent;
this.propositions = [];
@@ -409,6 +413,7 @@ return Widget.extend({
odoo.define('web.GroupByMenu', function (require) {
"use strict";
+var config = require('web.config');
var core = require('web.core');
var search_inputs = require('web.search_inputs');
var Widget = require('web.Widget');
@@ -433,6 +438,7 @@ return Widget.extend({
var self = this;
this._super(parent);
this.searchview = parent;
+ this.isMobile = config.device.isMobile;
this.groups = groups || [];
this.groupableFields = [];
var groupable_types = ['many2one', 'char', 'boolean', 'selection', 'date', 'datetime'];
diff --git a/addons/web/static/src/js/chrome/search_view.js b/addons/web/static/src/js/chrome/search_view.js
index 94087c999b6..8fc3cd73a2b 100644
--- a/addons/web/static/src/js/chrome/search_view.js
+++ b/addons/web/static/src/js/chrome/search_view.js
@@ -326,18 +326,19 @@ var SearchView = Widget.extend({
.toggleClass('fa-search-plus', !this.visible_filters);
var menu_defs = [];
this.prepare_search_inputs();
- if (this.$buttons) {
+ var $buttons = this._getButtonsElement();
+ if ($buttons) {
if (!this.options.disable_filters) {
this.filter_menu = new FilterMenu(this, this.filters, this.fields);
- menu_defs.push(this.filter_menu.appendTo(this.$buttons));
+ menu_defs.push(this.filter_menu.appendTo($buttons));
}
if (!this.options.disable_groupby) {
this.groupby_menu = new GroupByMenu(this, this.groupbys, this.fields);
- menu_defs.push(this.groupby_menu.appendTo(this.$buttons));
+ menu_defs.push(this.groupby_menu.appendTo($buttons));
}
if (!this.options.disable_favorites) {
this.favorite_menu = new FavoriteMenu(this, this.query, this.dataset.model, this.action, this.favorite_filters);
- menu_defs.push(this.favorite_menu.appendTo(this.$buttons));
+ menu_defs.push(this.favorite_menu.appendTo($buttons));
}
}
return $.when.apply($, menu_defs).then(this.set_default_filters.bind(this));
@@ -454,7 +455,7 @@ var SearchView = Widget.extend({
return self.$('.o_searchview_input').val().trim();
},
});
- this.autocomplete.appendTo(this.$el);
+ this.autocomplete.appendTo(this.$('.o_searchview_input_container'));
},
/**
* Provide auto-completion result for req.term (an array to `resp`)
@@ -528,11 +529,11 @@ var SearchView = Widget.extend({
this.query.each(function (facet) {
var f = new FacetView(this, facet);
- started.push(f.appendTo(self.$el));
+ started.push(f.appendTo(self.$('.o_searchview_input_container')));
self.input_subviews.push(f);
}, this);
var i = new InputView(this);
- started.push(i.appendTo(self.$el));
+ started.push(i.appendTo(self.$('.o_searchview_input_container')));
self.input_subviews.push(i);
_.each(this.input_subviews, function (childView) {
childView.on('focused', self, self.proxy('childFocused'));
@@ -540,7 +541,12 @@ var SearchView = Widget.extend({
});
$.when.apply(null, started).then(function () {
- _.last(self.input_subviews).$el.focus();
+ if (!config.device.isMobile) {
+ // in mobile mode, we would rathor not focusing manually the
+ // input, because it opens up the integrated keyboard, which is
+ // not what you expect when you just selected a filter.
+ _.last(self.input_subviews).$el.focus();
+ }
});
},
childFocused: function () {
@@ -666,6 +672,18 @@ var SearchView = Widget.extend({
// Private
//--------------------------------------------------------------------------
+
+ /**
+ * Will return $element where Filters, Group By and Favorite buttons are
+ * going to be pushed. This method is overriden by the mobile search view
+ * to add these buttons somewhere else in the dom.
+ *
+ * @private
+ * @returns {jQueryElement}
+ */
+ _getButtonsElement: function () {
+ return this.$buttons;
+ },
/**
* Processes a fieldsView in place. In particular, parses its arch.
*
diff --git a/addons/web/static/src/js/chrome/search_view_mobile.js b/addons/web/static/src/js/chrome/search_view_mobile.js
new file mode 100644
index 00000000000..852a65c0a37
--- /dev/null
+++ b/addons/web/static/src/js/chrome/search_view_mobile.js
@@ -0,0 +1,96 @@
+ odoo.define('web.SearchViewMobile', function (require) {
+"use strict";
+
+var config = require('web.config');
+var SearchView = require('web.SearchView');
+
+if (!config.device.isMobile) {
+ return;
+}
+
+SearchView.include({
+ template:'SearchViewMobile',
+ events:_.extend({}, SearchView.prototype.events, {
+ 'click .o_mobile_search_close, .o_mobile_search_show_result, .o_enable_searchview': '_toggleMobileSearchView',
+ 'click': '_onOpenMobileSearchView',
+ 'click .o_mobile_search_clear_facets': '_onEmptyAll',
+ 'show.bs.dropdown .o_mobile_search_filter .o_dropdown': '_onDropdownToggle',
+ 'hide.bs.dropdown .o_mobile_search_filter .o_dropdown': '_onDropdownToggle',
+ }),
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ renderFacets: function () {
+ this._super.apply(this, arguments);
+ this.$('.o_mobile_search_clear_facets')
+ .toggleClass('o_hidden', !this.query.length);
+ },
+ /**
+ * @override
+ */
+ toggle_visibility: function (is_visible) {
+ // Do not do anything, toggling visibility of searchview is handled
+ // explicitly for mobile
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * @override
+ */
+ _getButtonsElement: function () {
+ return this.$('.o_mobile_search_filter');
+ },
+ /**
+ * Toggle mobile search view screen
+ *
+ * @private
+ */
+ _toggleMobileSearchView: function () {
+ this.$('.o_enable_searchview').toggleClass('btn-default', !!this.query.length);
+ this.$('.o_mobile_search').toggleClass('o_hidden');
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * Toggle the little arrow in main buttons
+ *
+ * @private
+ * @param {BootstrapEvent} ev
+ */
+ _onDropdownToggle: function (ev) {
+ $(ev.currentTarget).find('.fa-chevron-right').toggleClass('fa-chevron-down');
+ },
+ /**
+ * Clears all filters from the search view
+ *
+ * @private
+ * @param {MouseEvent} event
+ */
+ _onEmptyAll: function () {
+ this.query.reset();
+ },
+ /**
+ * Open the mobile search view screen
+ *
+ * @private
+ * @param {MouseEvent} ev
+ */
+ _onOpenMobileSearchView: function (ev) {
+ if (ev.target === this.el) {
+ this._toggleMobileSearchView();
+ }
+ },
+});
+
+}); \ No newline at end of file
diff --git a/addons/web/static/src/scss/control_panel.scss b/addons/web/static/src/scss/control_panel.scss
index f883631c713..ef94b4c0f17 100644
--- a/addons/web/static/src/scss/control_panel.scss
+++ b/addons/web/static/src/scss/control_panel.scss
@@ -30,9 +30,9 @@
}
.btn.o_enable_searchview {
- width: 10%;
margin-left: 2%;
padding: 0px;
+ background: white;
}
> .o_cp_left {
diff --git a/addons/web/static/src/scss/search_view.scss b/addons/web/static/src/scss/search_view.scss
index f2b0f7fd14f..be6cb0b3f5b 100644
--- a/addons/web/static/src/scss/search_view.scss
+++ b/addons/web/static/src/scss/search_view.scss
@@ -5,84 +5,90 @@
}
.o_searchview {
- @include o-flex-display;
- @include o-flex-flow(row, wrap);
@include o-align-items(flex-end);
position: relative;
padding: 0 20px 1px 0;
- .o_searchview_facet {
- $o-searchview-facet-remove-width: 18px;
+ .o_searchview_more {
+ font-size: 16px;
+ cursor: pointer;
+ }
- @include o-flex(0, 0, auto);
- max-width: 100%;
+ .o_searchview_input_container {
@include o-flex-display;
- position: relative;
- margin: 1px 3px 0 0;
+ @include o-flex-flow(row, wrap);
- .o_searchview_facet_label {
+ .o_searchview_facet {
+ $o-searchview-facet-remove-width: 18px;
@include o-flex(0, 0, auto);
- @include o-text-overflow;
- padding: 0 3px;
- color: white;
-
+ max-width: 100%;
@include o-flex-display;
- @include o-align-items(center);
- }
+ position: relative;
+ margin: 1px 3px 0 0;
- .o_facet_values {
- padding: 0 $o-searchview-facet-remove-width 0 5px;
- .o_facet_values_sep {
- font-style: italic;
+ .o_searchview_facet_label {
+ @include o-flex(0, 0, auto);
+ @include o-text-overflow;
+ padding: 0 3px;
+ color: white;
+
+ @include o-flex-display;
+ @include o-align-items(center);
+ }
+
+ .o_facet_values {
+ padding: 0 $o-searchview-facet-remove-width 0 5px;
+ .o_facet_values_sep {
+ font-style: italic;
+ }
+ }
+ .o_facet_remove {
+ @include o-flex(0, 0, auto);
+ @include o-flex-display;
+ @include o-justify-content(center);
+ @include o-align-items(center);
+ @include o-position-absolute(0, 0, 0);
+ width: $o-searchview-facet-remove-width;
+ cursor: pointer;
}
}
- .o_facet_remove {
- @include o-flex(0, 0, auto);
- @include o-flex-display;
- @include o-justify-content(center);
- @include o-align-items(center);
- @include o-position-absolute(0, 0, 0);
- width: $o-searchview-facet-remove-width;
- cursor: pointer;
+ .o_searchview_input {
+ width: 100px;
+ @include o-flex(1, 0, auto);
}
- }
-
- .o_searchview_input {
- width: 100px;
- @include o-flex(1, 0, auto);
- }
- .o_searchview_more {
- font-size: 16px;
- cursor: pointer;
- }
+ .o_searchview_more {
+ font-size: 16px;
+ cursor: pointer;
+ }
- .o_searchview_autocomplete {
- @include o-position-absolute(100%, $left: auto);
- width: 100%;
+ .o_searchview_autocomplete {
+ @include o-position-absolute(100%, $left: auto);
+ width: 100%;
- li {
- padding-left: 25px;
- position: relative;
- &.o-indent {
- padding-left: 50px;
- }
- a {
- display: inline-block;
- padding-left: 0px;
- padding-right: 0px;
- &:hover {
- background-color: inherit;
- }
- &.o-expand, &.o-expanded { // caret
- @include o-position-absolute($left: 6px);
- padding: 3px;
- }
- &.o-expand:before {
- @include o-caret-right;
+ li {
+ padding-left: 25px;
+ position: relative;
+ &.o-indent {
+ padding-left: 50px;
}
- &.o-expanded:before {
- @include o-caret-down;
+ a {
+ display: inline-block;
+ padding-left: 0px;
+ padding-right: 0px;
+ &:hover {
+ background-color: inherit;
+ }
+ &.o-expand, &.o-expanded { // caret
+ @include o-position-absolute($left: 6px);
+ padding: 3px;
+ }
+ &.o-expand:before {
+ @include o-caret-right;
+ }
+ &.o-expanded:before {
+ @include o-caret-down;
+ }
}
}
}
diff --git a/addons/web/static/src/scss/search_view_mobile.scss b/addons/web/static/src/scss/search_view_mobile.scss
new file mode 100644
index 00000000000..2f0a3c3fc90
--- /dev/null
+++ b/addons/web/static/src/scss/search_view_mobile.scss
@@ -0,0 +1,88 @@
+.o_web_client.o_touch_device {
+ .o_mobile_search {
+ position: fixed;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ padding: 0;
+ width: 100%;
+ background-color: white;
+ z-index: 1000;
+ overflow: auto;
+ .o_mobile_search_header {
+ height: 46px;
+ margin-bottom: 10px;
+ width: 100%;
+ background-color: $o-brand-primary;
+ color: white;
+ span:active {
+ background-color: darken($o-brand-primary, 10%);
+ }
+ }
+ .o_searchview_input_container {
+ display: flex;
+ padding: 15px 20px 0 20px;
+ position: relative;
+ .o_searchview_input {
+ width: 100%;
+ margin-bottom: 15px;
+ border-bottom: 1px solid $o-brand-secondary;
+ }
+ .o_searchview_facet {
+ border-radius: 10px;
+ display: inline-flex;
+ order:1;
+ .o_searchview_facet_label {
+ border-radius: 2em 0em 0em 2em;
+ }
+ }
+ .o_searchview_autocomplete {
+ top:100%;
+ > li {
+ margin: 5px 0px;
+ }
+ }
+ }
+ .o_mobile_search_filter {
+ padding-bottom: 15%;
+ .o_dropdown {
+ width: 100%;
+ margin: 15px 5px 0px 5px;
+ border: solid 1px darken($gray-lighter, 20%);
+
+ }
+ .o_dropdown_toggler_btn {
+ width: 100%;
+ text-align: left;
+ }
+
+ // We disable the backdrop in this case because it prevents any
+ // interaction outside of a dropdown while it is open.
+ .dropdown-backdrop {
+ z-index: -1;
+ }
+ ul {
+ position: relative;
+ width: 100%;
+ box-shadow: none;
+ border: none;
+ color: $gray-light;
+ .divider {
+ margin: 0px;
+ }
+ > li > a {
+ padding: 10px 26px;
+ }
+ }
+ }
+ .o_mobile_search_show_result {
+ position: fixed;
+ bottom: 0;
+ left: 0;
+ right: 0;
+ padding: 15px;
+ font-size: 17px;
+ z-index: 1000;
+ }
+ }
+} \ No newline at end of file
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index 20fee925a0f..0debc65dc54 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -1013,7 +1013,26 @@
</div>
<div t-name="SearchView" class="o_searchview">
<span class="o_searchview_more fa" title="Advanced Search..."/>
+ <div class="o_searchview_input_container"/>
</div>
+<t t-name="SearchViewMobile">
+ <div class="o_searchview">
+ <button class="o_enable_searchview btn btn-sm fa fa-search"/>
+ <div class="o_mobile_search o_hidden">
+ <div class="o_mobile_search_header">
+ <span class="o_mobile_search_close pull-left mt16 mb16 mr8 ml16">
+ <i class="fa fa-arrow-left"/>
+ <strong class="pull-right ml8">FILTER</strong>
+ </span>
+ <span class="pull-right o_mobile_search_clear_facets mt16 mr16">CLEAR</span>
+ </div>
+ <div class="o_searchview_input_container"/>
+ <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>
+
<input t-name="SearchView.InputView" type="text" class="o_searchview_input" accesskey="Q" placeholder="Search..."/>
<div t-name="SearchView.FacetView" tabindex="0" class="o_searchview_facet">
<span t-if="widget.model.has('icon')" t-att-class="'fa ' + widget.model.get('icon') + ' o_searchview_facet_label'"/>
@@ -1031,7 +1050,7 @@
</t>
<div t-name="SearchView.FilterMenu" class="btn-group o_dropdown">
<button class="o_dropdown_toggler_btn btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="-1">
- <span class="fa fa-filter"/> Filters <span class="caret"/>
+ <span class="fa fa-filter"/> Filters <span t-attf-class="#{widget.isMobile ? 'fa fa-chevron-right pull-right mt4' : 'caret'}"/>
</button>
<ul class="dropdown-menu o_filters_menu" role="menu">
<li class="o_add_filter o_closed_menu">
@@ -1141,9 +1160,9 @@
</option>
</select>
</t>
-<div t-name="SearchView.GroupByMenu" class="btn-group hidden-xs o_dropdown">
+<div t-name="SearchView.GroupByMenu" class="btn-group o_dropdown">
<button class="o_dropdown_toggler_btn btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="-1">
- <span class="fa fa-bars"/> Group By <span class="caret"/>
+ <span class="fa fa-bars"/> Group By <span t-attf-class="#{widget.isMobile ? 'fa fa-chevron-right pull-right mt4' : 'caret'}"/>
</button>
<ul class="dropdown-menu o_group_by_menu" role="menu">
<li class="divider"/>
@@ -1164,7 +1183,7 @@
</t>
<div t-name="SearchView.FavoriteMenu" class="btn-group o_dropdown">
<button class="o_dropdown_toggler_btn btn btn-sm btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false" tabindex="-1">
- <span class="fa fa-star"/> Favorites <span class="caret"/>
+ <span class="fa fa-star"/> Favorites <span t-attf-class="#{widget.isMobile ? 'fa fa-chevron-right pull-right mt4' : 'caret'}"/>
</button>
<ul class="dropdown-menu o_favorites_menu" role="menu">
<li class="divider user_filter"/>
diff --git a/addons/web/static/tests/chrome/search_view_mobile_tests.js b/addons/web/static/tests/chrome/search_view_mobile_tests.js
new file mode 100644
index 00000000000..1508f45952c
--- /dev/null
+++ b/addons/web/static/tests/chrome/search_view_mobile_tests.js
@@ -0,0 +1,83 @@
+odoo.define('web.search_tests', function (require) {
+"use strict";
+
+var testUtils = require('web.test_utils');
+
+var createActionManager = testUtils.createActionManager;
+
+QUnit.module('Mobile Search view Screen', {
+ beforeEach: function () {
+ this.data = {
+ partner: {
+ fields: {
+ foo: {string: "Foo", type: "char"},
+ boolean_field: {string: "I am a boolean", type: "boolean"},
+ },
+ records: [
+ {id: 1, display_name: "First record", foo: "yop"},
+ ],
+ },
+ };
+
+ this.actions = [{
+ id: 1,
+ name: 'Partners Action 1',
+ res_model: 'partner',
+ type: 'ir.actions.act_window',
+ views: [[false, 'list']],
+ }];
+
+ this.archs = {
+ // list views
+ 'partner,false,list': '<tree><field name="foo"/></tree>',
+
+ // search views
+ 'partner,false,search': '<search>' +
+ '<filter string="Active" name="my_projects" domain="[(\'boolean_field\', \'=\', True)]"/>' +
+ '<field name="foo" string="Foo"/>' +
+ '</search>',
+ };
+ },
+}, function () {
+ QUnit.test('can activate a filter with mobile search view', function (assert) {
+ assert.expect(3);
+
+ var filterActiveFlag = false;
+
+ var actionManager = createActionManager({
+ actions: this.actions,
+ archs: this.archs,
+ data: this.data,
+ mockRPC: function (route, args) {
+ if (filterActiveFlag) {
+ assert.deepEqual(args.domain, [['boolean_field', '=', true]],
+ "domain should have been properly transferred to list view");
+ }
+ return this._super.apply(this, arguments);
+ },
+ });
+
+ actionManager.doAction(1);
+
+ assert.ok(!$('.o_mobile_search').is(':visible'),
+ 'mobile search view is not visible');
+ // open the search view
+ $('button.o_enable_searchview').click();
+
+ assert.ok($('.o_mobile_search').is(':visible'),
+ 'mobile search view is visible');
+
+ // open filter sub menu
+ $('button.o_dropdown_toggler_btn').first().click();
+
+ filterActiveFlag = true;
+
+ // click on Active filter
+ $('.o_filters_menu a:contains(Active)').click();
+
+ actionManager.destroy();
+ });
+
+});
+
+});
diff --git a/addons/web/static/tests/helpers/test_utils.js b/addons/web/static/tests/helpers/test_utils.js
index f993a2f9250..2da3eb5ddd9 100644
--- a/addons/web/static/tests/helpers/test_utils.js
+++ b/addons/web/static/tests/helpers/test_utils.js
@@ -100,6 +100,9 @@ var createActionManager = function (params) {
addMockEnvironment(widget, _.defaults(params, {debounce: false}));
widget.appendTo($target);
widget.$el.addClass('o_web_client');
+ if (config.device.isMobile) {
+ widget.$el.addClass('o_touch_device');
+ }
var userContext = params.context && params.context.user_context || {};
var actionManager = new ActionManager(widget, userContext);
diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml
index 6bd1bcfa12b..8e13b294952 100644
--- a/addons/web/views/webclient_templates.xml
+++ b/addons/web/views/webclient_templates.xml
@@ -155,6 +155,7 @@
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/kanban_view_mobile.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/web_calendar.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/search_view.scss"/>
+ <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/search_view_mobile.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/search_view_extra.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/data_export.scss"/>
@@ -211,6 +212,7 @@
<script type="text/javascript" src="/web/static/src/js/chrome/user_menu.js"></script>
<script type="text/javascript" src="/web/static/src/js/chrome/menu.js"></script>
<script type="text/javascript" src="/web/static/src/js/chrome/search_view.js"></script>
+ <script type="text/javascript" src="/web/static/src/js/chrome/search_view_mobile.js"></script>
<script type="text/javascript" src="/web/static/src/js/chrome/search_filters.js"></script>
<script type="text/javascript" src="/web/static/src/js/chrome/search_inputs.js"></script>
<script type="text/javascript" src="/web/static/src/js/chrome/search_menus.js"></script>
@@ -579,6 +581,7 @@
<script type="text/javascript" src="/base/static/tests/base_settings_mobile_tests.js"></script>
<script type="text/javascript" src="/web/static/tests/chrome/action_manager_mobile_tests.js"></script>
+ <script type="text/javascript" src="/web/static/tests/chrome/search_view_mobile_tests.js"></script>
<script type="text/javascript" src="/web/static/tests/views/calendar_mobile_tests.js"></script>
<script type="text/javascript" src="/web/static/tests/views/kanban_mobile_tests.js"></script>
</t>
diff --git a/addons/website/static/src/xml/website.backend.xml b/addons/website/static/src/xml/website.backend.xml
index d9095b806a0..347402caf57 100644
--- a/addons/website/static/src/xml/website.backend.xml
+++ b/addons/website/static/src/xml/website.backend.xml
@@ -61,7 +61,8 @@
</div>
<t t-name="website.DateRangeButtons">
- <div class="btn-group btn-group-sm o_date_range_buttons pull-right">
+ <!-- TODO: Applied hidden-xs class as it is going to push in control panel and it breaks UI, maybe we will improve it in future -->
+ <div class="btn-group btn-group-sm o_date_range_buttons hidden-xs pull-right">
<button class="btn btn-sm btn-default js_date_range active" data-date="week">Last Week</button>
<button class="btn btn-sm btn-default js_date_range" data-date="month">Last Month</button>
<button class="btn btn-sm btn-default js_date_range" data-date="year">Last Year</button>