Xavier (Open ERP) has proposed merging
lp:~openerp-dev/openerp-web/trunk-default-filter-xmo into lp:openerp-web.
Requested reviews:
OpenERP R&D Web Team (openerp-dev-web)
For more details, see:
https://code.launchpad.net/~openerp-dev/openerp-web/trunk-default-filter-xmo/+merge/107018
Implementation of default filter per model for the new search view (new feature)
--
https://code.launchpad.net/~openerp-dev/openerp-web/trunk-default-filter-xmo/+merge/107018
Your team OpenERP R&D Team is subscribed to branch
lp:~openerp-dev/openerp-web/trunk-default-filter-xmo.
=== modified file 'addons/web/static/src/js/search.js'
--- addons/web/static/src/js/search.js 2012-05-22 06:46:07 +0000
+++ addons/web/static/src/js/search.js 2012-05-23 13:51:20 +0000
@@ -632,7 +632,7 @@
// add Filters to this.inputs, need view.controls filled
(new instance.web.search.Filters(this));
// add custom filters to this.inputs
- (new instance.web.search.CustomFilters(this));
+ this.custom_filters = new instance.web.search.CustomFilters(this);
// add Advanced to this.inputs
(new instance.web.search.Advanced(this));
@@ -643,13 +643,40 @@
// load defaults
var defaults_fetched = $.when.apply(null, _(this.inputs).invoke(
- 'facet_for_defaults', this.defaults)).then(function () {
- self.query.reset(_(arguments).compact(), {preventSearch: true});
- });
+ 'facet_for_defaults', this.defaults))
+ .pipe(this.proxy('setup_default_query'));
return $.when(drawer_started, defaults_fetched)
.then(function () { self.ready.resolve(); })
},
+ setup_default_query: function () {
+ // Hacky implementation of CustomFilters#facet_for_defaults ensure
+ // CustomFilters will be ready (and CustomFilters#filters will be
+ // correctly filled) by the time this method executes.
+ var custom_filters = this.custom_filters.filters;
+ if (!_(custom_filters).isEmpty()) {
+ // Check for any is_default custom filter
+ var personal_filter = _(custom_filters).find(function (filter) {
+ return filter.user_id && filter.is_default;
+ });
+ if (personal_filter) {
+ this.query.reset([this.custom_filters.facet_for(personal_filter)],
+ {preventSearch: true});
+ return;
+ }
+
+ var global_filter = _(custom_filters).find(function (filter) {
+ return !filter.user_id && filter.is_default;
+ });
+ if (global_filter) {
+ this.query.reset([this.custom_filters.facet_for(global_filter)],
+ {preventSearch: true});
+ return;
+ }
+ }
+ // No custom filter, or no is_default custom filter, apply view defaults
+ this.query.reset(_(arguments).compact(), {preventSearch: true});
+ },
/**
* Handle event when the user make a selection in the filters management select box.
*/
@@ -1536,10 +1563,15 @@
instance.web.search.CustomFilters = instance.web.search.Input.extend({
template: 'SearchView.CustomFilters',
_in_drawer: true,
+ init: function () {
+ this.is_ready = $.Deferred();
+ this._super.apply(this, arguments);
+ },
start: function () {
var self = this;
this.model = new instance.web.Model('ir.filters');
this.filters = {};
+ this.$filters = {};
this.$element.on('submit', 'form', this.proxy('save_current'));
this.$element.on('click', 'h4', function () {
self.$element.toggleClass('oe_opened');
@@ -1547,18 +1579,71 @@
// FIXME: local eval of domain and context to get rid of special endpoint
return this.rpc('/web/searchview/get_filters', {
model: this.view.model
- }).pipe(this.proxy('set_filters'));
+ }).pipe(this.proxy('set_filters'))
+ .then(function () {
+ self.is_ready.resolve(null);
+ }, function () {
+ self.is_ready.reject();
+ });
+ },
+ /**
+ * Special implementation delaying defaults until CustomFilters is loaded
+ */
+ facet_for_defaults: function () {
+ return this.is_ready;
+ },
+ /**
+ * Generates a mapping key (in the filters and $filter mappings) for the
+ * filter descriptor object provided (as returned by ``get_filters``).
+ *
+ * The mapping key is guaranteed to be unique for a given (user_id, name)
+ * pair.
+ *
+ * @param {Object} filter
+ * @param {String} filter.name
+ * @param {Number|Pair<Number, String>} [filter.user_id]
+ * @return {String} mapping key corresponding to the filter
+ */
+ key_for: function (filter) {
+ var user_id = filter.user_id;
+ var uid = (user_id instanceof Array) ? user_id[0] : user_id;
+ return _.str.sprintf('(%s)%s', uid, filter.name);
+ },
+ /**
+ * Generates a :js:class:`~instance.web.search.Facet` descriptor from a
+ * filter descriptor
+ *
+ * @param {Object} filter
+ * @param {String} filter.name
+ * @param {Object} [filter.context]
+ * @param {Array} [filter.domain]
+ * @return {Object}
+ */
+ facet_for: function (filter) {
+ return {
+ category: _("Custom Filter"),
+ icon: 'M',
+ field: {
+ get_context: function () { return filter.context; },
+ get_groupby: function () { return [filter.context]; },
+ get_domain: function () { return filter.domain; }
+ },
+ values: [
+ {label: filter.name, value: null}
+ ]
+ };
},
append_filter: function (filter) {
var self = this;
- var key = _.str.sprintf('(%s)%s', filter.user_id, filter.name);
+ var key = this.key_for(filter);
var $filter;
- if (key in this.filters) {
- $filter = this.filters[key];
+ if (key in this.$filters) {
+ $filter = this.$filters[key];
} else {
var id = filter.id;
- $filter = this.filters[key] = $('<li></li>')
+ this.filters[key] = filter;
+ $filter = this.$filters[key] = $('<li></li>')
.appendTo(this.$element.find('.oe_searchview_custom_list'))
.addClass(filter.user_id ? 'oe_searchview_custom_private'
: 'oe_searchview_custom_public')
@@ -1570,22 +1655,15 @@
e.stopPropagation();
self.model.call('unlink', [id]).then(function () {
$filter.remove();
+ delete self.$filters[key];
+ delete self.filters[key];
});
})
.appendTo($filter);
}
$filter.unbind('click').click(function () {
- self.view.query.reset([{
- category: _("Custom Filter"),
- icon: 'M',
- field: {
- get_context: function () { return filter.context; },
- get_groupby: function () { return [filter.context]; },
- get_domain: function () { return filter.domain; }
- },
- values: [{label: filter.name, value: null}]
- }]);
+ self.view.query.reset([self.facet_for(filter)]);
});
},
set_filters: function (filters) {
@@ -1594,7 +1672,10 @@
save_current: function () {
var self = this;
var $name = this.$element.find('input:first');
- var private_filter = !this.$element.find('input:last').prop('checked');
+ var private_filter = !this.$element.find(
+ 'input#oe_searchview_custom_public').prop('checked');
+ var set_as_default = this.$element.find(
+ 'input#oe_searchview_custom_default').prop('checked');
var search = this.view.build_search_data();
this.rpc('/web/session/eval_domain_and_context', {
@@ -1610,7 +1691,8 @@
user_id: private_filter ? instance.connection.uid : false,
model_id: self.view.model,
context: results.context,
- domain: results.domain
+ domain: results.domain,
+ is_default: set_as_default
};
// FIXME: current context?
return self.model.call('create_or_replace', [filter]).then(function (id) {
=== modified file 'addons/web/static/src/xml/base.xml'
--- addons/web/static/src/xml/base.xml 2012-05-22 16:13:14 +0000
+++ addons/web/static/src/xml/base.xml 2012-05-23 13:51:20 +0000
@@ -1487,6 +1487,8 @@
<button>Save</button><br/>
<label for="oe_searchview_custom_public">Share with all users:</label>
<input id="oe_searchview_custom_public" type="checkbox"/>
+ <label for="oe_searchview_custom_default">Use by default:</label>
+ <input id="oe_searchview_custom_default" type="checkbox"/>
</form>
</div>
<div t-name="SearchView.advanced" class="oe_searchview_advanced">
_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help : https://help.launchpad.net/ListHelp