[ADD] is_default custom filters

* Second checkbox when creating a custom filter, unchecked by default
* Global is_default filter overrides action defaults
* Personal is_default filter overrides global is_default
* Extracted sections of CustomFilter's behavior into methods to make
them usable from the SearchView and easier to understand

Hack note: CustomFilters#facet_for_defaults is weird stuff, it never
fetches an actual facet, but it forces the SearchView's defaults
handling to wait until CustomFilters is ready before executing,
meaning SearchView#setup_default_query can run safe in the knowledge
that custom filters are filled and everything.
      
That this hidden dependency exists bugs me, though there's a comment.

bzr revid: xmo@openerp.com-20120523112314-618hfttpegn39qey
This commit is contained in:
Xavier Morel 2012-05-23 13:23:14 +02:00
parent c54383d4e5
commit 9168a66d6a
2 changed files with 80 additions and 17 deletions

View File

@ -632,7 +632,7 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
// 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 @@ instance.web.SearchView = instance.web.Widget.extend(/** @lends instance.web.Sea
// 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,6 +1563,10 @@ instance.web.search.ManyToOneField = instance.web.search.CharField.extend({
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');
@ -1548,7 +1579,18 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
// 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
@ -1567,6 +1609,30 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
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 = this.key_for(filter);
@ -1597,16 +1663,7 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
}
$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) {
@ -1615,7 +1672,10 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
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', {
@ -1631,7 +1691,8 @@ instance.web.search.CustomFilters = instance.web.search.Input.extend({
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) {

View File

@ -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">