[IMP] calendar: Improve color and filters
Now in a calendar view, if we use the color, attribute, it will use the same color as Gantt views and the color picker widget. The attribute color isn't more set as default in filter because it make, in most situation, no sense to filter by color. Now, we can add new filters in the right panel. To do that, we must add the attribute "filter='1'" in the corresponding field line. And if the filter has no direct link with the color of the model, we can specify an attribute 'color' for this filter line block. (for example color='color', and the color of the related model will be used) TaskID: 2153249
This commit is contained in:
committed by
Yannick Tivisse
parent
d39fc89324
commit
fa48e05f42
@@ -263,7 +263,7 @@
|
||||
event_limit="5"
|
||||
color="partner_id">
|
||||
<field name="attendee_status"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="partner_id" filter="1"/>
|
||||
<field name="partner_ids" widget="many2many_tags_avatar" write_model="calendar.contacts" write_field="partner_id" avatar_field="image_128"/>
|
||||
<field name="is_highlighted" invisible="1"/>
|
||||
<field name="description"/>
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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:
|
||||
'<calendar class="o_calendar_test" '+
|
||||
'event_open_popup="true" '+
|
||||
'date_start="start" '+
|
||||
'date_stop="stop" '+
|
||||
'all_day="allday" '+
|
||||
'mode="week" '+
|
||||
'color="color">'+
|
||||
'<field name="partner_ids" write_model="filter_partner" write_field="partner_id"/>'+
|
||||
'<field name="event_type_id" filters="1" color="color"/>'+
|
||||
'</calendar>',
|
||||
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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user