You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

245 lines
8.7 KiB

//-*- coding: utf-8 -*-
//Copyright 2018 Therp BV <https://therp.nl>
//License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
odoo.define('web_widget_date_interval', function(require) {
var core = require('web.core'),
pyeval = require('web.pyeval'),
Widget = require('web.Widget'),
SearchView = require('web.SearchView');
var SearchWidgetDateInterval = Widget.extend({
template: 'SearchView.DateInterval',
events: {
'click [data-id]': 'on_click_interval',
},
_option_defaults: {
iso_week: {
lookbehind: 1,
lookahead: 10,
exclusive: false,
cycle: false,
},
},
options: {
type: 'iso_week',
dropdown: true,
},
init: function(parent, field_name, string, options) {
this.searchview = parent;
this.string = string;
this.options = _.extend(
{}, this.options, this._option_defaults[options.type] || {},
options
);
this.field = field_name;
return this._super.apply(this, arguments);
},
start: function() {
this.searchview.query.on(
'add change remove reset', this.proxy('on_searchview_change')
);
return this._super.apply(this, arguments);
},
get_intervals: function() {
var interval_function = _.str.sprintf(
'get_intervals_%s', this.options.type
);
if(!this[interval_function]) {
throw new Error('Unknown interval type given');
}
return this[interval_function]();
},
get_intervals_iso_week: function() {
var existing = this.searchview.query.findWhere({
category: this.string,
}),
reference_date = moment(
!existing || !this.options.cycle
? this.options.date
: existing.get('field').get_domain().slice(-2, -1)[0][2]
),
start_date = reference_date.clone().startOf('isoWeek')
.subtract(this.options.lookbehind, 'weeks'),
stop_date = reference_date.clone().endOf('isoWeek')
.add(this.options.lookahead, 'weeks'),
current_date = start_date.clone(),
result = [];
while(current_date.isBefore(stop_date)) {
result.push({
name: current_date.year() === moment().year()
? _.str.sprintf(core._t('%s'), current_date.isoWeek())
: _.str.sprintf(
core._t('%s / %s'), current_date.isoWeek(),
current_date.isoWeekYear()
),
_id: _.str.sprintf(
'%s-%s', this.field, current_date.format('YYYY-MM-DD')
),
start: current_date.format('YYYY-MM-DD'),
stop: current_date.add(1, 'weeks').format('YYYY-MM-DD'),
});
}
return result;
},
on_click_interval: function(e) {
var $this = jQuery(e.currentTarget);
return this._update_searchview(
$this.data('start'), $this.data('stop'), $this.text().trim()
);
},
_create_facet: function(date_start, date_stop, label) {
var self = this;
return {
field: {
get_domain: function() {
return [
'&',
[self.field, '>=', date_start],
[self.field, '<', date_stop],
];
},
// eslint-disable-next-line no-empty-function
get_context: function() {},
// eslint-disable-next-line no-empty-function
get_groupby: function() {},
},
category: this.string,
icon: 'fa-calendar',
values: [
{
label: _.str.sprintf(
'%s: %s', this.string, label
),
value: null,
},
],
_id: _.str.sprintf(
'%s-%s', self.field, date_start
),
};
},
_update_searchview: function(date_start, date_stop, label, options) {
var facet = this._create_facet(date_start, date_stop, label),
existing = this.searchview.query.findWhere({
category: this.string,
});
if(existing) {
var is_removal = existing.get('_id').includes(facet._id);
this.searchview.query.remove(existing, {silent: !is_removal});
if(!this.options.exclusive) {
// concatenate existing facet with ours
var domain = [].concat(
['|'], facet.field.get_domain(),
existing.get('field').get_domain()
);
facet._id = _.str.sprintf(
'%s %s', facet._id, existing.get('_id')
);
facet.values = facet.values.concat(existing.get('values'));
facet.field.get_domain = function() {
return domain;
};
}
if(is_removal) {
return;
}
}
this.searchview.query.add(facet, options);
},
on_searchview_change: function() {
var self = this;
this.$('[data-id]').removeClass('selected');
if(this.options.cycle) {
this.renderElement();
}
this.searchview.query.each(function(facet) {
if(facet.get('category') === self.string) {
self.$(
_.map(
facet.get('_id').split(' '), function(x) {
return _.str.sprintf('[data-id="%s"]', x);
}
).join(',')
).addClass('selected');
}
});
},
facet_for_defaults: function(values) {
var self = this,
default_value = values[_.str.sprintf(
'date_interval_%s', this.field
)],
facet = false;
if(!default_value) {
return;
}
default_value = moment(default_value);
_(this.get_intervals()).each(function(interval) {
if(
!moment(interval.start).isBefore(default_value) ||
!moment(interval.stop).isAfter(default_value)
) {
return;
}
facet = self._create_facet(
interval.start, interval.stop, interval.name
);
});
return facet;
},
visible: function() {
return false;
},
});
SearchView.include({
init: function() {
this._super.apply(this, arguments);
this.date_intervals = [];
},
start: function() {
var self = this,
deferreds = [this._super.apply(this, arguments)];
if(this.$buttons && !this.options.disable_date_interval) {
_(this.date_intervals).each(function(widget) {
deferreds.push(widget.appendTo(self.$buttons));
});
}
return jQuery.when.apply(jQuery, deferreds);
},
prepare_search_inputs: function() {
this._super.apply(this, arguments);
var self = this;
_.chain(this.fields_view.arch.children)
.filter(function(x) {
return x.tag === 'field' && x.attrs.widget === 'date_interval';
})
.each(function(x) {
var widget = new SearchWidgetDateInterval(
self, x.attrs.name, core._t(x.attrs.string) ||
self.ViewManager.search_fields_view.fields[x.attrs.name]
.string, pyeval.py_eval(x.attrs.options || '{}')
);
self.date_intervals.push(widget);
self.search_fields.push(widget);
});
},
});
return {
search_widget_date_interval: SearchWidgetDateInterval,
};
});