[FIX] web, calendar: reintroduce many2manyattendee fields widget

This widget behaviour hadn't been correctly implemented with the new views.
This commit also introduces some tests.
This commit is contained in:
Martin Geubelle
2017-04-27 16:56:47 +02:00
parent 776cd64aa3
commit e4ac74450f
5 changed files with 145 additions and 12 deletions
+43 -6
View File
@@ -2,6 +2,7 @@ odoo.define('base_calendar.base_calendar', function (require) {
"use strict";
var bus = require('bus.bus').bus;
var BasicModel = require('web.BasicModel');
var field_registry = require('web.field_registry');
var Notification = require('web.notification').Notification;
var relational_fields = require('web.relational_fields');
@@ -104,14 +105,50 @@ WebClient.include({
},
});
BasicModel.include({
/**
* @private
* @param {Object} record
* @param {string} fieldName
* @returns {Deferred}
*/
_fetchSpecialAttendeeStatus: function (record, fieldName) {
var context = record.getContext({fieldName: fieldName});
var attendeeIDs = record.data[fieldName] ? this.localData[record.data[fieldName]].res_ids : [];
var meetingID = _.isNumber(record.res_id) ? record.res_id : false;
return this._rpc({
model: 'res.partner',
method: 'get_attendee_detail',
args: [attendeeIDs, meetingID],
context: context,
}).then(function (result) {
return _.map(result, function (d) {
return _.object(['id', 'display_name', 'status', 'color'], d);
});
});
},
});
var Many2ManyAttendee = FieldMany2ManyTags.extend({
supported_field_types: [],
// as this widget is model dependant (rpc on res.partner), use it in another
// context probably won't work
// supportedFieldTypes: ['many2many'],
tag_template: "Many2ManyAttendeeTag",
// FIXME: This widget used to refetch the relational data fields needed to
// its rendering. Basically, all usual fields for tags plus "status".
// This can't currently be done with the current implementation of
// the new view. For now, the attendee tags will be missing the
// status indicator in studio mode.
specialData: "_fetchSpecialAttendeeStatus",
//--------------------------------------------------------------------------
// Private
//--------------------------------------------------------------------------
/**
* @override
* @private
*/
_getRenderTagsContext: function () {
var result = this._super.apply(this, arguments);
result.attendeesData = this.record.specialData.partner_ids;
return result;
},
});
field_registry.add('many2manyattendee', Many2ManyAttendee);
@@ -2,7 +2,7 @@
<template>
<t t-name="Many2ManyAttendeeTag" t-extend="FieldMany2ManyTag">
<t t-jquery="span:first" t-operation="prepend">
<span t-attf-class="o_calendar_invitation #{el['status']}"/>
<span t-attf-class="o_calendar_invitation #{attendeesData[el_index].status}"/>
</t>
</t>
@@ -0,0 +1,80 @@
odoo.define('calendar.tests', function (require) {
"use strict";
var FormView = require('web.FormView');
var testUtils = require("web.test_utils");
var createView = testUtils.createView;
QUnit.module('calendar', {
beforeEach: function () {
this.data = {
event: {
fields: {
partner_ids: {string: "Partners", type: "many2many", relation: "partner"},
},
records: [{
id: 14,
partner_ids: [1, 2],
}],
},
partner: {
fields: {
name: {string: "Name", type: "char"},
},
records: [{
id: 1,
name: "Jesus",
}, {
id: 2,
name: "Mahomet",
}],
},
};
},
}, function () {
QUnit.test("many2manyattendee widget: basic rendering", function (assert) {
assert.expect(9);
var form = createView({
View: FormView,
model: 'event',
data: this.data,
res_id: 14,
arch:
'<form>' +
'<field name="partner_ids" widget="many2manyattendee"/>' +
'</form>',
mockRPC: function (route, args) {
if (args.method === 'get_attendee_detail') {
assert.strictEqual(args.model, 'res.partner',
"the method should only be called on res.partner");
assert.deepEqual(args.args[0], [1, 2],
"the partner ids should be passed as argument");
assert.strictEqual(args.args[1], 14,
"the event id should be passed as argument");
return $.when([
[1, "Jesus", "accepted", 0],
[2, "Mahomet", "needsAction", 0],
]);
}
return this._super.apply(this, arguments);
},
});
assert.ok(form.$('.o_form_field[name="partner_ids"]').hasClass('o_form_field_many2manytags'));
assert.strictEqual(form.$('.o_form_field[name="partner_ids"] > span').length, 2,
"there should be 2 tags");
assert.strictEqual(form.$('.o_form_field[name="partner_ids"] > span:first').text().trim(), "Jesus",
"the tag should be correctly named");
assert.ok(form.$('.o_form_field[name="partner_ids"] > span:first .o_calendar_invitation').hasClass('accepted'),
"Jesus should attend the meeting");
assert.strictEqual(form.$('.o_form_field[name="partner_ids"] > span[data-id="2"]').text().trim(), "Mahomet",
"the tag should be correctly named");
assert.ok(form.$('.o_form_field[name="partner_ids"] > span[data-id="2"] .o_calendar_invitation').hasClass('needsAction'),
"Mohamet should still confirm his attendance to the meeting");
form.destroy();
});
});
});
@@ -7,6 +7,12 @@
</xpath>
</template>
<template id="qunit_suite" inherit_id="web.qunit_suite">
<xpath expr="//script[last()]" position="after">
<script type="text/javascript" src="/calendar/static/tests/calendar_tests.js"/>
</xpath>
</template>
<!-- Template rendered in route auth=None, for anonymous user. This allow them to see meeting details -->
<template id="invitation_page_anonymous" name="Calendar Invitation Page for anonymous users">
<t t-call="web.layout">
@@ -1201,6 +1201,20 @@ var FieldMany2ManyTags = AbstractField.extend({
});
}
},
/**
* Get the QWeb rendering context used by the tag template; this computation
* is placed in a separate function for other tags to override it.
*
* @private
* @returns {Object}
*/
_getRenderTagsContext: function () {
var elements = this.value ? _.pluck(this.value.data, 'data') : [];
return {
elements: elements,
readonly: this.mode === "readonly",
};
},
/**
* @private
* @param {any} id
@@ -1246,11 +1260,7 @@ var FieldMany2ManyTags = AbstractField.extend({
* @private
*/
_renderTags: function () {
var elements = this.value ? _.pluck(this.value.data, 'data') : [];
this.$el.html(qweb.render(this.tag_template, {
elements: elements,
readonly: this.mode === "readonly",
}));
this.$el.html(qweb.render(this.tag_template, this._getRenderTagsContext()));
},
//--------------------------------------------------------------------------