From 2023d5f683a484bd5a098482052041d86f657dd0 Mon Sep 17 00:00:00 2001 From: Arnaud Joset Date: Fri, 18 Aug 2023 10:22:17 +0200 Subject: [PATCH] [IMP] calendar: allow to open document action in calendar popover Before this commit, it was not possible to display a link to the linked document in the calendar popover. closes odoo/odoo#135061 Taskid: 3380101 Signed-off-by: Arnaud Joset (arj) --- addons/calendar/models/calendar_event.py | 1 + .../attendee_calendar_common_popover.js | 10 + .../attendee_calendar_common_popover.xml | 10 + .../tests/attendee_calendar_views_tests.js | 242 ++++++++++++++++++ addons/calendar/views/calendar_views.xml | 7 +- 5 files changed, 268 insertions(+), 2 deletions(-) create mode 100644 addons/calendar/static/tests/attendee_calendar_views_tests.js diff --git a/addons/calendar/models/calendar_event.py b/addons/calendar/models/calendar_event.py index 7d9fee82036..2242b7b9f10 100644 --- a/addons/calendar/models/calendar_event.py +++ b/addons/calendar/models/calendar_event.py @@ -176,6 +176,7 @@ class Meeting(models.Model): res_model_id = fields.Many2one('ir.model', 'Document Model', ondelete='cascade') res_model = fields.Char( 'Document Model Name', related='res_model_id.model', readonly=True, store=True) + res_model_name = fields.Char(related='res_model_id.name') # messaging activity_ids = fields.One2many('mail.activity', 'calendar_event_id', string='Activities') # attendees diff --git a/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.js b/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.js index 12f53dab45f..04857c04169 100644 --- a/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.js +++ b/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.js @@ -12,6 +12,7 @@ export class AttendeeCalendarCommonPopover extends CalendarCommonPopover { super.setup(); this.user = useService("user"); this.orm = useService("orm"); + this.actionService = useService("action"); this.askRecurrenceUpdatePolicy = useAskRecurrenceUpdatePolicy(); onWillStart(this.onWillStart); @@ -67,6 +68,15 @@ export class AttendeeCalendarCommonPopover extends CalendarCommonPopover { get isEventArchivable() { return false; } + + async onClickOpenRecord() { + const action = await this.orm.call( + 'calendar.event', + 'action_open_calendar_event', + [this.props.record.id] + ); + this.actionService.doAction(action); + } /** * @override diff --git a/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.xml b/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.xml index 44243f47dc4..f069e13da56 100644 --- a/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.xml +++ b/addons/calendar/static/src/views/attendee_calendar/common/attendee_calendar_common_popover.xml @@ -4,6 +4,16 @@ isEventDetailsVisible + + !fieldInfo.options.shouldOpenRecord + + + + + + + + diff --git a/addons/calendar/static/tests/attendee_calendar_views_tests.js b/addons/calendar/static/tests/attendee_calendar_views_tests.js new file mode 100644 index 00000000000..3c3420c0fbb --- /dev/null +++ b/addons/calendar/static/tests/attendee_calendar_views_tests.js @@ -0,0 +1,242 @@ +/** @odoo-module **/ + +import { + getFixture, + patchDate, + patchWithCleanup, +} from "@web/../tests/helpers/utils"; + +import { + changeScale, + clickEvent, +} from "@web/../tests/views/calendar/helpers"; +import { makeView, setupViewRegistries } from "@web/../tests/views/helpers"; +import { browser } from "@web/core/browser/browser"; +import { registry } from "@web/core/registry"; +import { userService } from "@web/core/user_service"; +const serviceRegistry = registry.category("services"); + +let target; +let serverData; +const uid = -1; + +QUnit.module("CalendarView", ({ beforeEach }) => { + beforeEach(() => { + // 2016-12-12 08:00:00 + patchDate(2016, 11, 12, 8, 0, 0); + + patchWithCleanup(browser, { + setTimeout: (fn) => fn(), + clearTimeout: () => { }, + }); + + target = getFixture(); + setupViewRegistries(); + + serviceRegistry.add( + "user", + { + ...userService, + start() { + const fakeUserService = userService.start(...arguments); + Object.defineProperty(fakeUserService, "userId", { + get: () => uid, + }); + return fakeUserService; + }, + }, + { force: true } + ); + + serverData = { + models: { + event: { + fields: { + id: { string: "ID", type: "integer" }, + user_id: { + string: "user", + type: "many2one", + relation: "user", + default: uid, + }, + partner_id: { + string: "user", + type: "many2one", + relation: "partner", + related: "user_id.partner_id", + default: 1, + }, + name: { string: "name", type: "char" }, + start_date: { string: "start date", type: "date" }, + stop_date: { string: "stop date", type: "date" }, + start: { string: "start datetime", type: "datetime" }, + stop: { string: "stop datetime", type: "datetime" }, + delay: { string: "delay", type: "float" }, + duration: { string: "Duration", type: "float", default: 1 }, + 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_event: { + string: "Color", + type: "integer", + related: "event_type_id.color_event_type", + }, + is_hatched: { string: "Hatched", type: "boolean" }, + is_striked: { string: "Striked", type: "boolean" }, + res_model_name: { string: "Linked Model Name", type: "char" } + }, + records: [ + { + id: 1, + user_id: 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, + is_hatched: false, + }, + { + id: 2, + user_id: uid, + partner_id: 1, + name: "event 2", + start: "2016-12-12 10:55:05", + stop: "2016-12-12 14:55:05", + allday: false, + partner_ids: [1, 2], + type: 3, + is_hatched: false, + }, + ], + methods: { + check_access_rights() { + return Promise.resolve(true); + } + }, + }, + user: { + fields: { + id: { string: "ID", type: "integer" }, + display_name: { string: "Displayed name", type: "char" }, + partner_id: { + string: "partner", + type: "many2one", + relation: "partner", + }, + }, + records: [ + { id: uid, display_name: "user 1", partner_id: 1 }, + { id: 4, display_name: "user 4", partner_id: 4 }, + ], + }, + partner: { + fields: { + id: { string: "ID", type: "integer" }, + display_name: { string: "Displayed name", type: "char" }, + image: { string: "image", type: "integer" }, + }, + records: [ + { id: 1, display_name: "partner 1", image: "AAA" }, + { id: 2, display_name: "partner 2", image: "BBB" }, + { id: 3, display_name: "partner 3", image: "CCC" }, + { id: 4, display_name: "partner 4", image: "DDD" }, + ], + }, + filter_partner: { + fields: { + id: { string: "ID", type: "integer" }, + user_id: { string: "user", type: "many2one", relation: "user" }, + partner_id: { + string: "partner", + type: "many2one", + relation: "partner", + }, + partner_checked: { string: "checked", type: "boolean" }, + }, + records: [ + { id: 1, user_id: uid, partner_id: 1, partner_checked: true }, + { id: 2, user_id: uid, partner_id: 2, partner_checked: true }, + { id: 3, user_id: 4, partner_id: 3, partner_checked: true }, + ], + } + } + }; + }); + + QUnit.test(`Linked record rendering`, async (assert) => { + assert.expect(3); + + serverData.models.event.records.push({ + id: 3, + user_id: 4, + partner_id: 1, + name: "event With record", + start: "2016-12-11 09:00:00", + stop: "2016-12-11 10:00:00", + allday: false, + partner_ids: [1, 2, 3], + res_model_name: 'Time Off', + + }); + + await makeView({ + type: "calendar", + resModel: "event", + serverData, + arch: ` + + + + + + + + + + `, + mockRPC(route, args) { + if (route === "/web/dataset/call_kw/res.users/has_group") { + return Promise.resolve(true); + } else if (route === "/web/dataset/call_kw/res.partner/get_attendee_detail") { + return Promise.resolve([]); + } + }, + }); + assert.containsOnce( + target, + ".o_calendar_renderer .fc-view-container", + "should instance of fullcalendar" + ); + await changeScale(target, 'week'); + await clickEvent(target, 3); + assert.containsOnce( + target, + ".fa-link", + "A link icon should be present" + ); + assert.strictEqual(target.querySelector("li a[href='#']").textContent, "Time Off"); + }); +}); diff --git a/addons/calendar/views/calendar_views.xml b/addons/calendar/views/calendar_views.xml index 5fd4bf88798..e52afaa6c42 100644 --- a/addons/calendar/views/calendar_views.xml +++ b/addons/calendar/views/calendar_views.xml @@ -108,10 +108,11 @@
-
- @@ -375,6 +376,8 @@ +