[REF] web: convert many2manyattendee to owl
closes odoo/odoo#99676 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
This commit is contained in:
@@ -50,7 +50,7 @@ If you need to manage your meetings, you should install the CRM module.
|
||||
'calendar/static/src/js/calendar_model.js',
|
||||
'calendar/static/src/js/calendar_view.js',
|
||||
'calendar/static/src/js/services/calendar_notification_service.js',
|
||||
'calendar/static/src/views/*',
|
||||
'calendar/static/src/views/**/*',
|
||||
],
|
||||
'web.qunit_suite_tests': [
|
||||
'calendar/static/tests/**/*',
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { registry } from "@web/core/registry";
|
||||
import { Many2ManyTagsAvatarField } from "@web/views/fields/many2many_tags_avatar/many2many_tags_avatar_field";
|
||||
|
||||
export class Many2ManyAttendee extends Many2ManyTagsAvatarField {
|
||||
get tags() {
|
||||
const { partner_ids: partnerIds } = this.props.record.preloadedData;
|
||||
const tags = super.tags.map((tag) => {
|
||||
const partner = partnerIds.find((partner) => tag.resId === partner.id);
|
||||
if (partner) {
|
||||
tag.className = `o_attendee_border o_attendee_border_${partner.status}`;
|
||||
}
|
||||
return tag;
|
||||
});
|
||||
|
||||
const organizer = partnerIds.find((partner) => partner.is_organizer);
|
||||
if (organizer) {
|
||||
const orgId = organizer.id;
|
||||
// sort elements according to the partner id
|
||||
tags.sort((a, b) => {
|
||||
const a_org = a.id === orgId;
|
||||
return a_org ? -1 : 1;
|
||||
});
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
}
|
||||
|
||||
registry.category("fields").add("many2manyattendee", Many2ManyAttendee);
|
||||
@@ -1,86 +1,129 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import FormView from 'web.FormView';
|
||||
import testUtils from "web.test_utils";
|
||||
import { getFixture } from "@web/../tests/helpers/utils";
|
||||
import { makeView, setupViewRegistries } from "@web/../tests/views/helpers";
|
||||
|
||||
var createView = testUtils.createView;
|
||||
let serverData;
|
||||
let target;
|
||||
|
||||
QUnit.module('calendar', {
|
||||
beforeEach: function () {
|
||||
this.data = {
|
||||
event: {
|
||||
fields: {
|
||||
partner_ids: {string: "Partners", type: "many2many", relation: "partner"},
|
||||
QUnit.module(
|
||||
"calendar",
|
||||
{
|
||||
beforeEach: function () {
|
||||
target = getFixture();
|
||||
serverData = {
|
||||
models: {
|
||||
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",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
records: [{
|
||||
id: 14,
|
||||
partner_ids: [1, 2],
|
||||
}],
|
||||
},
|
||||
partner: {
|
||||
fields: {
|
||||
name: {string: "Name", type: "char"},
|
||||
},
|
||||
records: [{
|
||||
id: 1,
|
||||
name: "Jesus",
|
||||
}, {
|
||||
id: 2,
|
||||
name: "Mahomet",
|
||||
}],
|
||||
},
|
||||
};
|
||||
};
|
||||
setupViewRegistries();
|
||||
},
|
||||
},
|
||||
}, function () {
|
||||
QUnit.test("many2manyattendee widget: basic rendering", async function (assert) {
|
||||
assert.expect(12);
|
||||
function () {
|
||||
QUnit.test("Many2ManyAttendee: basic rendering", async function (assert) {
|
||||
await makeView({
|
||||
type: "form",
|
||||
resModel: "event",
|
||||
serverData,
|
||||
resId: 14,
|
||||
arch: `
|
||||
<form>
|
||||
<field name="partner_ids" widget="many2manyattendee"/>
|
||||
</form>`,
|
||||
mockRPC(route, args) {
|
||||
if (args.method === "get_attendee_detail") {
|
||||
assert.step(args.method);
|
||||
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.deepEqual(
|
||||
args.args[1],
|
||||
[14],
|
||||
"the event id should be passed as argument"
|
||||
);
|
||||
return Promise.resolve([
|
||||
{ id: 1, name: "Jesus", status: "accepted", color: 0 },
|
||||
{ id: 2, name: "Mahomet", status: "tentative", color: 0 },
|
||||
]);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
var form = await 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.deepEqual(args.args[1], [14],
|
||||
"the event id should be passed as argument");
|
||||
return Promise.resolve([
|
||||
{id: 1, name: "Jesus", status: "accepted", color: 0},
|
||||
{id: 2, name: "Mahomet", status: "tentative", color: 0},
|
||||
]);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
assert.hasClass(
|
||||
target.querySelector('.o_field_widget[name="partner_ids"] div'),
|
||||
"o_field_tags"
|
||||
);
|
||||
assert.containsN(
|
||||
target,
|
||||
'.o_field_widget[name="partner_ids"] .badge',
|
||||
2,
|
||||
"there should be 2 tags"
|
||||
);
|
||||
const badges = target.querySelectorAll('.o_field_widget[name="partner_ids"] .badge');
|
||||
assert.strictEqual(
|
||||
badges[0].textContent.trim(),
|
||||
"Jesus",
|
||||
"the tag should be correctly named"
|
||||
);
|
||||
assert.hasClass(
|
||||
badges[0].querySelector("img"),
|
||||
"o_attendee_border_accepted",
|
||||
"Jesus should attend the meeting"
|
||||
);
|
||||
assert.strictEqual(
|
||||
badges[1].textContent.trim(),
|
||||
"Mahomet",
|
||||
"the tag should be correctly named"
|
||||
);
|
||||
assert.hasClass(
|
||||
badges[1].querySelector("img"),
|
||||
"o_attendee_border_tentative",
|
||||
"Mohamet should still confirm his attendance to the meeting"
|
||||
);
|
||||
assert.containsOnce(badges[0], "img", "should have img tag");
|
||||
assert.hasAttrValue(
|
||||
badges[0].querySelector("img"),
|
||||
"data-src",
|
||||
"/web/image/partner/1/avatar_128",
|
||||
"should have correct avatar image"
|
||||
);
|
||||
assert.verifySteps(["get_attendee_detail"]);
|
||||
});
|
||||
|
||||
assert.hasClass(form.$('.o_field_widget[name="partner_ids"]'), 'o_field_many2manytags');
|
||||
assert.containsN(form, '.o_field_widget[name="partner_ids"] .badge', 2,
|
||||
"there should be 2 tags");
|
||||
assert.strictEqual(form.$('.o_field_widget[name="partner_ids"] .badge:first').text().trim(), "Jesus",
|
||||
"the tag should be correctly named");
|
||||
assert.hasClass(form.$('.o_field_widget[name="partner_ids"] .badge:first img'),'o_attendee_border_accepted',
|
||||
"Jesus should attend the meeting");
|
||||
assert.strictEqual(form.$('.o_field_widget[name="partner_ids"] .badge[data-id="2"]').text().trim(), "Mahomet",
|
||||
"the tag should be correctly named");
|
||||
assert.hasClass(form.el.querySelector('.o_field_widget[name="partner_ids"] .badge[data-id="2"] img'), 'o_attendee_border_tentative',
|
||||
"Mohamet should still confirm his attendance to the meeting");
|
||||
assert.hasClass(form.el.querySelector('.o_field_many2manytags'), 'avatar',
|
||||
"should have avatar class");
|
||||
assert.containsOnce(form, '.o_field_many2manytags.avatar.o_field_widget .badge:first img',
|
||||
"should have img tag");
|
||||
assert.hasAttrValue(form.$('.o_field_many2manytags.avatar.o_field_widget .badge:first img'),
|
||||
'data-src',
|
||||
'/web/image/partner/1/avatar_128',
|
||||
"should have correct avatar image");
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import FormView from "web.FormView";
|
||||
import testUtils from "web.test_utils";
|
||||
|
||||
var createView = testUtils.createView;
|
||||
|
||||
QUnit.module(
|
||||
"Legacy 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", async function (assert) {
|
||||
assert.expect(12);
|
||||
|
||||
var form = await createView({
|
||||
View: FormView,
|
||||
model: "event",
|
||||
data: this.data,
|
||||
res_id: 14,
|
||||
debug: 1,
|
||||
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.deepEqual(
|
||||
args.args[1],
|
||||
[14],
|
||||
"the event id should be passed as argument"
|
||||
);
|
||||
return Promise.resolve([
|
||||
{ id: 1, name: "Jesus", status: "accepted", color: 0 },
|
||||
{ id: 2, name: "Mahomet", status: "tentative", color: 0 },
|
||||
]);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
});
|
||||
|
||||
assert.hasClass(form.$('.o_field_widget[name="partner_ids"]'), "o_field_many2manytags");
|
||||
assert.containsN(
|
||||
form,
|
||||
'.o_field_widget[name="partner_ids"] .badge',
|
||||
2,
|
||||
"there should be 2 tags"
|
||||
);
|
||||
assert.strictEqual(
|
||||
form.$('.o_field_widget[name="partner_ids"] .badge:first').text().trim(),
|
||||
"Jesus",
|
||||
"the tag should be correctly named"
|
||||
);
|
||||
assert.hasClass(
|
||||
form.$('.o_field_widget[name="partner_ids"] .badge:first img'),
|
||||
"o_attendee_border_accepted",
|
||||
"Jesus should attend the meeting"
|
||||
);
|
||||
assert.strictEqual(
|
||||
form.$('.o_field_widget[name="partner_ids"] .badge[data-id="2"]').text().trim(),
|
||||
"Mahomet",
|
||||
"the tag should be correctly named"
|
||||
);
|
||||
assert.hasClass(
|
||||
form.el.querySelector(
|
||||
'.o_field_widget[name="partner_ids"] .badge[data-id="2"] img'
|
||||
),
|
||||
"o_attendee_border_tentative",
|
||||
"Mohamet should still confirm his attendance to the meeting"
|
||||
);
|
||||
assert.hasClass(
|
||||
form.el.querySelector(".o_field_many2manytags"),
|
||||
"avatar",
|
||||
"should have avatar class"
|
||||
);
|
||||
assert.containsOnce(
|
||||
form,
|
||||
".o_field_many2manytags.avatar.o_field_widget .badge:first img",
|
||||
"should have img tag"
|
||||
);
|
||||
assert.hasAttrValue(
|
||||
form.$(".o_field_many2manytags.avatar.o_field_widget .badge:first img"),
|
||||
"data-src",
|
||||
"/web/image/partner/1/avatar_128",
|
||||
"should have correct avatar image"
|
||||
);
|
||||
|
||||
form.destroy();
|
||||
});
|
||||
}
|
||||
);
|
||||
@@ -4,7 +4,7 @@
|
||||
<t t-name="web.TagsList" owl="1">
|
||||
<t t-foreach="visibleTags" t-as="tag" t-key="tag.id or tag_index">
|
||||
<span t-attf-class="{{`o_tag_color_${ tag.colorIndex or 0 } ${props.displayBadge ? 'badge rounded-pill' : ''}`}} o_tag d-inline-flex align-items-center h-100" tabindex="-1" t-att-data-color="tag.colorIndex" t-att-title="tag.text" t-on-click="(ev) => tag.onClick and tag.onClick(ev)" t-on-keydown="tag.onKeydown">
|
||||
<img t-if="tag.img" t-att-src="tag.img" class="o_m2m_avatar rounded-circle"/>
|
||||
<img t-if="tag.img" t-att-src="tag.img" class="o_m2m_avatar rounded-circle" t-att-class="tag.className"/>
|
||||
<div t-if="props.displayBadge" class="o_tag_badge_text" t-esc="tag.text" />
|
||||
<t t-else="">
|
||||
<span />
|
||||
|
||||
Reference in New Issue
Block a user