diff --git a/addons/calendar/views/calendar_views.xml b/addons/calendar/views/calendar_views.xml
index 0bf7f52984c..d15b7f6f356 100644
--- a/addons/calendar/views/calendar_views.xml
+++ b/addons/calendar/views/calendar_views.xml
@@ -263,7 +263,7 @@
event_limit="5"
color="partner_id">
-
+
diff --git a/addons/web/static/src/js/views/calendar/calendar_model.js b/addons/web/static/src/js/views/calendar/calendar_model.js
index 2f2c6339ac6..9635fc5ffc4 100644
--- a/addons/web/static/src/js/views/calendar/calendar_model.js
+++ b/addons/web/static/src/js/views/calendar/calendar_model.js
@@ -579,6 +579,8 @@ return AbstractModel.extend({
var self = this;
var new_filters = {};
var to_read = {};
+ var defs = [];
+ var color_filter = {};
_.each(this.data.filters, function (filter, fieldName) {
var field = self.fields[fieldName];
@@ -620,7 +622,7 @@ return AbstractModel.extend({
});
});
_.each(_.union(fs, undefined_fs), function (f) {
- var f1 = _.findWhere(filter.filters, f);
+ var f1 = _.findWhere(filter.filters, _.omit(f, 'color_index'));
if (f1) {
f1.display = true;
} else {
@@ -628,9 +630,32 @@ return AbstractModel.extend({
filter.filters.push(f);
}
});
+
+ if (filter.color_model && filter.field_color) {
+ var ids = filter.filters.reduce((acc, f) => {
+ if (!f.color_index && f.value) {
+ acc.push(f.value);
+ }
+ return acc;
+ }, []);
+ if (!color_filter[filter.color_model]) {
+ color_filter[filter.color_model] = {};
+ }
+ if (ids.length) {
+ defs.push(self._rpc({
+ model: filter.color_model,
+ method: 'read',
+ args: [_.uniq(ids), [filter.field_color]],
+ })
+ .then(function (res) {
+ _.each(res, function (c) {
+ color_filter[filter.color_model][c.id] = c[filter.field_color];
+ });
+ }));
+ }
+ }
});
- var defs = [];
_.each(to_read, function (ids, model) {
defs.push(self._rpc({
model: model,
@@ -651,6 +676,13 @@ return AbstractModel.extend({
f.label = to_read[f.avatar_model][f.value];
});
}
+ if (filter.color_model && filter.field_color) {
+ _.each(filter.filters, function (f) {
+ if (!f.color_index) {
+ f.color_index = color_filter[filter.color_model] && color_filter[filter.color_model][f.value];
+ }
+ });
+ }
});
});
},
diff --git a/addons/web/static/src/js/views/calendar/calendar_renderer.js b/addons/web/static/src/js/views/calendar/calendar_renderer.js
index f563f793203..7755097d412 100644
--- a/addons/web/static/src/js/views/calendar/calendar_renderer.js
+++ b/addons/web/static/src/js/views/calendar/calendar_renderer.js
@@ -284,6 +284,9 @@ return AbstractRenderer.extend({
if (typeof key === 'string' && key.match(/^((#[A-F0-9]{3})|(#[A-F0-9]{6})|((hsl|rgb)a?\(\s*(?:(\s*\d{1,3}%?\s*),?){3}(\s*,[0-9.]{1,4})?\))|)$/i)) {
return this.color_map[key] = key;
}
+ if (typeof key === 'number' && !(key in this.color_map)) {
+ return this.color_map[key] = key;
+ }
var index = (((_.keys(this.color_map).length + 1) * 5) % 24) + 1;
this.color_map[key] = index;
return index;
diff --git a/addons/web/static/src/js/views/calendar/calendar_view.js b/addons/web/static/src/js/views/calendar/calendar_view.js
index 9c9355145ee..b68a134a00a 100644
--- a/addons/web/static/src/js/views/calendar/calendar_view.js
+++ b/addons/web/static/src/js/views/calendar/calendar_view.js
@@ -92,23 +92,29 @@ var CalendarView = AbstractView.extend({
modelFilters.push(fields[fieldName].relation);
}
+ if (child.attrs.filter) {
+ filters[fieldName] = filters[fieldName] || {
+ 'title': fields[fieldName].string,
+ 'fieldName': fieldName,
+ 'filters': [],
+ };
+ if (child.attrs.color) {
+ filters[fieldName].field_color = child.attrs.color;
+ filters[fieldName].color_model = fields[fieldName].relation;
+ }
+ if (!child.attrs.avatar_field && fields[fieldName].relation) {
+ if (fields[fieldName].relation.includes(['res.users', 'res.partner', 'hr.employee'])) {
+ filters[fieldName].avatar_field = 'image_128';
+ }
+ filters[fieldName].avatar_model = fields[fieldName].relation;
+ }
+ }
}
});
if (attrs.color) {
var fieldName = attrs.color;
fieldNames.push(fieldName);
- filters[fieldName] = {
- 'title': fields[fieldName].string,
- 'fieldName': fieldName,
- 'filters': [],
- };
- if (fields[fieldName].relation) {
- if (['res.users', 'res.partner', 'hr.employee'].indexOf(fields[fieldName].relation) !== -1) {
- filters[fieldName].avatar_field = 'image_128';
- }
- filters[fieldName].avatar_model = fields[fieldName].relation;
- }
}
//if quick_add = False, we don't allow quick_add
diff --git a/addons/web/static/src/scss/web_calendar.scss b/addons/web/static/src/scss/web_calendar.scss
index 6f7c569feb6..c81bf92ec47 100644
--- a/addons/web/static/src/scss/web_calendar.scss
+++ b/addons/web/static/src/scss/web_calendar.scss
@@ -588,7 +588,7 @@ $o-cw-filter-avatar-size: 20px;
$color: nth($o-colors-complete, $i);
.o_calendar_view .fc-view {
- .fc-event.o_calendar_color_#{$i} {
+ .fc-event.o_calendar_color_#{$i - 1} {
border-color: $color;
color: darken($color, 35%);
opacity: 0.8;
@@ -616,7 +616,7 @@ $o-cw-filter-avatar-size: 20px;
}
}
- .o_cw_filter_color_#{$i} {
+ .o_cw_filter_color_#{$i - 1} {
.o_cw_filter_input_bg {
border-color: $color;
background: $color;
@@ -624,7 +624,7 @@ $o-cw-filter-avatar-size: 20px;
}
}
- .o_cw_popover.o_calendar_color_#{$i} {
+ .o_cw_popover.o_calendar_color_#{$i - 1} {
$color-subdle: mix(white, $color, 90%);
.card-header, .card-header .popover-header {
diff --git a/addons/web/static/tests/views/calendar_tests.js b/addons/web/static/tests/views/calendar_tests.js
index 0bdddb7bfae..8286bb6b4cc 100644
--- a/addons/web/static/tests/views/calendar_tests.js
+++ b/addons/web/static/tests/views/calendar_tests.js
@@ -54,6 +54,8 @@ QUnit.module('Views', {
allday: {string: "allday", type: "boolean"},
partner_ids: {string: "attendees", type: "one2many", relation: 'partner', default: [[6, 0, [1]]]},
type: {string: "type", type: "integer"},
+ event_type_id: {string: "Event_Type", type: "many2one", relation: 'event_type'},
+ color: {string: "Color", type: "integer", related: 'event_type_id.color'},
},
records: [
{id: 1, user_id: session.uid, partner_id: 1, name: "event 1", start: "2016-12-11 00:00:00", stop: "2016-12-11 00:00:00", allday: false, partner_ids: [1,2,3], type: 1},
@@ -92,6 +94,18 @@ QUnit.module('Views', {
{id: 4, display_name: "partner 4", image: 'DDD'}
]
},
+ event_type: {
+ fields: {
+ id: {string: "ID", type: "integer"},
+ display_name: {string: "Displayed name", type: "char"},
+ color: {string: "Color", type: "integer"},
+ },
+ records: [
+ {id: 1, display_name: "Event Type 1", color: 1},
+ {id: 2, display_name: "Event Type 2", color: 2},
+ {id: 3, display_name: "Event Type 3 (color 4)", color: 4},
+ ]
+ },
filter_partner: {
fields: {
id: {string: "ID", type: "integer"},
@@ -1973,6 +1987,47 @@ QUnit.module('Views', {
calendar.destroy();
});
+ QUnit.test('Add filters and specific color', async function (assert) {
+ assert.expect(5);
+
+ this.data.event.records.push(
+ {id: 7, user_id: 4, partner_id: 1, name: "event 7", start: "2016-12-11 09:00:00", stop: "2016-12-11 10:00:00", allday: false, partner_ids: [1,2,3], event_type_id: 3, color: 4},
+ {id: 8, user_id: 4, partner_id: 1, name: "event 8", start: "2016-12-11 19:00:00", stop: "2016-12-11 20:00:00", allday: false, partner_ids: [1,2,3], event_type_id: 1, color: 1},
+ );
+
+ var calendar = await createCalendarView({
+ View: CalendarView,
+ model: 'event',
+ data: this.data,
+ arch:
+ ''+
+ ''+
+ ''+
+ '',
+ viewOptions: {
+ initialDate: initialDate,
+ },
+ });
+
+ assert.containsN(calendar, '.o_calendar_filter', 2, "should display 2 filters");
+
+ var $typeFilter = calendar.$('.o_calendar_filter:has(h5:contains(Event_Type))');
+ assert.ok($typeFilter.length, "should display 'Event Type' filter");
+ assert.containsN($typeFilter, '.o_calendar_filter_item', 3, "should display 3 filter items for 'Event Type'");
+
+ assert.containsOnce($typeFilter, '.o_calendar_filter_item[data-value=3].o_cw_filter_color_4', "Filter for event type 3 must have the color 4");
+
+ assert.containsOnce(calendar, '.fc-event[data-event-id=7].o_calendar_color_4', "Event of event type 3 must have the color 4");
+
+ calendar.destroy();
+ });
+
QUnit.test('create event with filters', async function (assert) {
assert.expect(7);
diff --git a/doc/reference/views.rst b/doc/reference/views.rst
index af84421ea91..4a4ab2f1206 100644
--- a/doc/reference/views.rst
+++ b/doc/reference/views.rst
@@ -927,6 +927,9 @@ calendar view are:
``write_model`` and ``write_field``
you can add a filter and save the result in the defined model, the
filter is added in the sidebar
+ ``filter`` and ``color``
+ use "True" to add this field in filter in the sidebar. You can specify
+ a color field used to colorize the checkbox.
``templates``
defines the :ref:`reference/qweb` template ``calendar-box``. Cards definition