[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:
@@ -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()));
|
||||
},
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user