diff --git a/addons/calendar/__manifest__.py b/addons/calendar/__manifest__.py index 410b6400c6f..c9b612747fe 100644 --- a/addons/calendar/__manifest__.py +++ b/addons/calendar/__manifest__.py @@ -39,8 +39,7 @@ If you need to manage your meetings, you should install the CRM module. 'auto_install': False, 'assets': { 'web.assets_backend': [ - 'calendar/static/src/models/activity/activity.js', - 'calendar/static/src/components/activity/activity.js', + 'calendar/static/src/models/*/*.js', 'calendar/static/src/scss/calendar.scss', 'calendar/static/src/js/base_calendar.js', 'calendar/static/src/js/calendar_renderer.js', @@ -55,7 +54,7 @@ If you need to manage your meetings, you should install the CRM module. ], 'web.assets_qweb': [ 'calendar/static/src/xml/base_calendar.xml', - 'calendar/static/src/components/activity/activity.xml', + 'calendar/static/src/components/*/*.xml', ], }, 'license': 'LGPL-3', diff --git a/addons/calendar/static/src/components/activity/activity.js b/addons/calendar/static/src/components/activity/activity.js deleted file mode 100644 index a49260c49f4..00000000000 --- a/addons/calendar/static/src/components/activity/activity.js +++ /dev/null @@ -1,35 +0,0 @@ -/** @odoo-module */ - -import { Activity } from '@mail/components/activity/activity'; -import { patch } from 'web.utils'; -import Dialog from 'web.Dialog'; -import core from 'web.core'; -const _t = core._t; - -patch(Activity.prototype, 'calendar/static/src/components/activity/activity.js', { - //-------------------------------------------------------------------------- - // Handlers - //-------------------------------------------------------------------------- - - /** - * Small override that asks for confirmation in case there is a meeting linked to this activity. - * - * @override - */ - _onClickCancel(ev) { - const superMethod = this._super; - if (!this.activity.calendar_event_id){ - this._super(ev); - } else { - Dialog.confirm( - this, - _t("The activity is linked to a meeting. Deleting it will remove the meeting as well. Do you want to proceed ?"), { - confirm_callback: function () { - superMethod(ev); - }, - } - ); - } - } - -}); diff --git a/addons/calendar/static/src/components/activity/activity.xml b/addons/calendar/static/src/components/activity/activity.xml index 5cffc8e2415..52377809d24 100644 --- a/addons/calendar/static/src/components/activity/activity.xml +++ b/addons/calendar/static/src/components/activity/activity.xml @@ -3,11 +3,11 @@ - !activity.calendar_event_id + !activityView.activity.calendar_event_id - - diff --git a/addons/calendar/static/src/models/activity_view/activity_view.js b/addons/calendar/static/src/models/activity_view/activity_view.js new file mode 100644 index 00000000000..b7c7ff78f8b --- /dev/null +++ b/addons/calendar/static/src/models/activity_view/activity_view.js @@ -0,0 +1,28 @@ +/** @odoo-module **/ + +import { patchRecordMethods } from '@mail/model/model_core'; +// ensure that the model definition is loaded before the patch +import '@mail/models/activity_view/activity_view'; + +import Dialog from 'web.Dialog'; + +patchRecordMethods('ActivityView', { + /** + * @override + */ + async onClickCancel(ev) { + if (this.activity.calendar_event_id) { + await new Promise(resolve => { + Dialog.confirm( + this, + this.env._t("The activity is linked to a meeting. Deleting it will remove the meeting as well. Do you want to proceed?"), + { confirm_callback: resolve }, + ); + }); + } + if (!this.exists()) { + return; + } + await this._super(); + } +}); diff --git a/addons/mail/static/src/components/activity/activity.js b/addons/mail/static/src/components/activity/activity.js index 687b4eaf797..2f445ef7d07 100644 --- a/addons/mail/static/src/components/activity/activity.js +++ b/addons/mail/static/src/components/activity/activity.js @@ -1,6 +1,7 @@ /** @odoo-module **/ import { registerMessagingComponent } from '@mail/utils/messaging_component'; +import { useRefToModel } from '@mail/component_hooks/use_ref_to_model/use_ref_to_model'; import { auto_str_to_date, @@ -8,8 +9,7 @@ import { getLangDatetimeFormat, } from 'web.time'; -const { Component, useState } = owl; -const { useRef } = owl.hooks; +const { Component } = owl; export class Activity extends Component { @@ -18,15 +18,7 @@ export class Activity extends Component { */ setup() { super.setup(); - this.state = useState({ - areDetailsVisible: false, - }); - /** - * Reference of the file uploader. - * Useful to programmatically prompts the browser file uploader. - */ - this._fileUploaderRef = useRef('fileUploader'); - this._onAttachmentCreated = this._onAttachmentCreated.bind(this); + useRefToModel({ fieldName: 'fileUploaderRef', modelName: 'ActivityView', propNameAsRecordLocalId: 'activityViewLocalId', refName: 'fileUploader' }); } //-------------------------------------------------------------------------- @@ -34,17 +26,17 @@ export class Activity extends Component { //-------------------------------------------------------------------------- /** - * @returns {Activity} + * @returns {ActivityView} */ - get activity() { - return this.messaging && this.messaging.models['Activity'].get(this.props.activityLocalId); + get activityView() { + return this.messaging && this.messaging.models['ActivityView'].get(this.props.activityViewLocalId); } /** * @returns {string} */ get assignedUserText() { - return _.str.sprintf(this.env._t("for %s"), this.activity.assignee.nameOrDisplayName); + return _.str.sprintf(this.env._t("for %s"), this.activityView.activity.assignee.nameOrDisplayName); } /** @@ -52,7 +44,7 @@ export class Activity extends Component { */ get delayLabel() { const today = moment().startOf('day'); - const momentDeadlineDate = moment(auto_str_to_date(this.activity.dateDeadline)); + const momentDeadlineDate = moment(auto_str_to_date(this.activityView.activity.dateDeadline)); // true means no rounding const diff = momentDeadlineDate.diff(today, 'days', true); if (diff === 0) { @@ -72,7 +64,7 @@ export class Activity extends Component { * @returns {string} */ get formattedCreateDatetime() { - const momentCreateDate = moment(auto_str_to_date(this.activity.dateCreate)); + const momentCreateDate = moment(auto_str_to_date(this.activityView.activity.dateCreate)); const datetimeFormat = getLangDatetimeFormat(); return momentCreateDate.format(datetimeFormat); } @@ -81,7 +73,7 @@ export class Activity extends Component { * @returns {string} */ get formattedDeadlineDate() { - const momentDeadlineDate = moment(auto_str_to_date(this.activity.dateDeadline)); + const momentDeadlineDate = moment(auto_str_to_date(this.activityView.activity.dateDeadline)); const datetimeFormat = getLangDateFormat(); return momentDeadlineDate.format(datetimeFormat); } @@ -97,79 +89,14 @@ export class Activity extends Component { * @returns {string} */ get summary() { - return _.str.sprintf(this.env._t("ā€œ%sā€"), this.activity.summary); - } - - //-------------------------------------------------------------------------- - // Handlers - //-------------------------------------------------------------------------- - - /** - * @private - * @param {Object} detail - * @param {Attachment} detail.attachment - */ - _onAttachmentCreated(detail) { - this.activity.markAsDone({ attachments: [detail.attachment] }); - } - - /** - * @private - * @param {MouseEvent} ev - */ - _onClick(ev) { - if ( - ev.target.tagName === 'A' && - ev.target.dataset.oeId && - ev.target.dataset.oeModel - ) { - this.messaging.openProfile({ - id: Number(ev.target.dataset.oeId), - model: ev.target.dataset.oeModel, - }); - // avoid following dummy href - ev.preventDefault(); - } - } - - /** - * @private - * @param {MouseEvent} ev - */ - async _onClickCancel(ev) { - ev.preventDefault(); - await this.activity.deleteServerRecord(); - this.trigger('reload', { keepChanges: true }); - } - - /** - * @private - */ - _onClickDetailsButton() { - this.state.areDetailsVisible = !this.state.areDetailsVisible; - } - - /** - * @private - * @param {MouseEvent} ev - */ - _onClickEdit(ev) { - this.activity.edit(); - } - - /** - * @private - * @param {MouseEvent} ev - */ - _onClickUploadDocument(ev) { - this._fileUploaderRef.comp.openBrowserFileUploader(); + return _.str.sprintf(this.env._t("ā€œ%sā€"), this.activityView.activity.summary); } } Object.assign(Activity, { props: { - activityLocalId: String, + activityViewLocalId: String, }, template: 'mail.Activity', }); diff --git a/addons/mail/static/src/components/activity/activity.xml b/addons/mail/static/src/components/activity/activity.xml index 406b1355578..38711ff703c 100644 --- a/addons/mail/static/src/components/activity/activity.xml +++ b/addons/mail/static/src/components/activity/activity.xml @@ -2,21 +2,21 @@ -
- +
+
- - + +
- +
@@ -24,68 +24,68 @@
- +
- +
- +
- +
- +
- +
- +
Activity type
- +
- +
Created
- + - +
- +
Assigned to
- - + +
Due on
@@ -95,51 +95,51 @@
- +
- +
- +
- +
- +
- + - + - - -
diff --git a/addons/mail/static/src/components/activity/tests/activity_tests.js b/addons/mail/static/src/components/activity/tests/activity_tests.js index 39fe49d3546..03465f16527 100644 --- a/addons/mail/static/src/components/activity/tests/activity_tests.js +++ b/addons/mail/static/src/components/activity/tests/activity_tests.js @@ -557,7 +557,7 @@ QUnit.test('activity details layout', async function (assert) { assert.strictEqual( document.querySelector('.o_Activity_details .o_Activity_type').textContent, "Email", - "activity details type should be 'Fake type'" + "activity details type should be 'Email'" ); assert.strictEqual( document.querySelectorAll('.o_Activity_detailsCreation').length, diff --git a/addons/mail/static/src/components/activity_box/activity_box.js b/addons/mail/static/src/components/activity_box/activity_box.js index 2aca33c6041..e7c22670339 100644 --- a/addons/mail/static/src/components/activity_box/activity_box.js +++ b/addons/mail/static/src/components/activity_box/activity_box.js @@ -14,7 +14,7 @@ export class ActivityBox extends Component { * @returns {Chatter} */ get activityBoxView() { - return this.messaging.models['ActivityBoxView'].get(this.props.activityBoxViewLocalId); + return this.messaging && this.messaging.models['ActivityBoxView'].get(this.props.activityBoxViewLocalId); } } diff --git a/addons/mail/static/src/components/activity_box/activity_box.xml b/addons/mail/static/src/components/activity_box/activity_box.xml index a12cc6baae2..94731bae602 100644 --- a/addons/mail/static/src/components/activity_box/activity_box.xml +++ b/addons/mail/static/src/components/activity_box/activity_box.xml @@ -33,8 +33,8 @@
- - + +
diff --git a/addons/mail/static/src/components/chatter/chatter.js b/addons/mail/static/src/components/chatter/chatter.js index d051108799b..b1b1449bed2 100644 --- a/addons/mail/static/src/components/chatter/chatter.js +++ b/addons/mail/static/src/components/chatter/chatter.js @@ -1,6 +1,7 @@ /** @odoo-module **/ import { registerMessagingComponent } from '@mail/utils/messaging_component'; +import { useComponentToModel } from '@mail/component_hooks/use_component_to_model/use_component_to_model'; import { useUpdate } from '@mail/component_hooks/use_update/use_update'; import { useRefToModel } from '@mail/component_hooks/use_ref_to_model/use_ref_to_model'; @@ -15,6 +16,7 @@ export class Chatter extends Component { setup() { super.setup(); useUpdate({ func: () => this._update() }); + useComponentToModel({ fieldName: 'component', modelName: 'Chatter', propNameAsRecordLocalId: 'chatterLocalId' }); useRefToModel({ fieldName: 'threadRef', modelName: 'Chatter', propNameAsRecordLocalId: 'chatterLocalId', refName: 'thread' }); /** * Reference of the scroll Panel (Real scroll element). Useful to pass the Scroll element to diff --git a/addons/mail/static/src/components/chatter_topbar/chatter_topbar.js b/addons/mail/static/src/components/chatter_topbar/chatter_topbar.js index 263db6b4fe6..4e851f6b120 100644 --- a/addons/mail/static/src/components/chatter_topbar/chatter_topbar.js +++ b/addons/mail/static/src/components/chatter_topbar/chatter_topbar.js @@ -1,24 +1,11 @@ /** @odoo-module **/ import { registerMessagingComponent } from '@mail/utils/messaging_component'; -import { useComponentToModel } from '@mail/component_hooks/use_component_to_model/use_component_to_model'; const { Component } = owl; export class ChatterTopbar extends Component { - /** - * @override - */ - setup() { - super.setup(); - useComponentToModel({ fieldName: 'componentChatterTopbar', modelName: 'Chatter', propNameAsRecordLocalId: 'chatterLocalId' }); - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - /** * @returns {Chatter} */ diff --git a/addons/mail/static/src/components/follow_button/follow_button.xml b/addons/mail/static/src/components/follow_button/follow_button.xml index 64b17d266cb..9b19438f8fe 100644 --- a/addons/mail/static/src/components/follow_button/follow_button.xml +++ b/addons/mail/static/src/components/follow_button/follow_button.xml @@ -3,20 +3,22 @@
- - - - - + + + + + + +
diff --git a/addons/mail/static/src/components/follower_list_menu/follower_list_menu.xml b/addons/mail/static/src/components/follower_list_menu/follower_list_menu.xml index c8104e7e104..f57a57deb08 100644 --- a/addons/mail/static/src/components/follower_list_menu/follower_list_menu.xml +++ b/addons/mail/static/src/components/follower_list_menu/follower_list_menu.xml @@ -3,32 +3,34 @@
-
- + +
+ - - +
diff --git a/addons/mail/static/src/model/model_core.js b/addons/mail/static/src/model/model_core.js index 1799f5fb7b5..988144f0a4d 100644 --- a/addons/mail/static/src/model/model_core.js +++ b/addons/mail/static/src/model/model_core.js @@ -65,7 +65,7 @@ export function addLifecycleHooks(modelName, hooks) { assertIsFunction(handler); assertIsValidHookName(name); assertSectionDoesNotHaveKey('lifecycleHooks', name, definition); - }, `Cannot add lifecycle hook "${name}" to model "${modelName}":`); + }, `Cannot add lifecycle hook "${name}" to model "${modelName}": `); definition.get('lifecycleHooks').set(name, handler); } } @@ -281,6 +281,7 @@ export function patchLifecycleHooks(modelName, hooks) { for (const [name, handler] of Object.entries(hooks)) { addContextToErrors(() => { assertIsFunction(handler); + assertIsValidHookName(name); assertSectionHasKey('lifecycleHooks', name, definition); }, `Cannot patch lifecycle hook "${name}" on model "${modelName}": `); const hookBeforePatch = definition.get('lifecycleHooks').get(name); diff --git a/addons/mail/static/src/models/activity/activity.js b/addons/mail/static/src/models/activity/activity.js index 7468207a95e..f6ad557cd9c 100644 --- a/addons/mail/static/src/models/activity/activity.js +++ b/addons/mail/static/src/models/activity/activity.js @@ -1,7 +1,7 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; -import { attr, many2many, many2one } from '@mail/model/model_field'; +import { attr, many2many, many2one, one2many } from '@mail/model/model_field'; import { clear, insert, unlink, unlinkAll } from '@mail/model/model_field_command'; registerModel({ @@ -232,6 +232,10 @@ registerModel({ }, }, fields: { + activityViews: one2many('ActivityView', { + inverse: 'activity', + isCausal: true, + }), assignee: many2one('User'), attachments: many2many('Attachment', { inverse: 'activities', diff --git a/addons/mail/static/src/models/activity_box_view/activity_box_view.js b/addons/mail/static/src/models/activity_box_view/activity_box_view.js index abcad2f7a74..6ee73580078 100644 --- a/addons/mail/static/src/models/activity_box_view/activity_box_view.js +++ b/addons/mail/static/src/models/activity_box_view/activity_box_view.js @@ -1,7 +1,8 @@ /** @odoo-module **/ import { registerModel } from '@mail/model/model_core'; -import { attr, one2one } from '@mail/model/model_field'; +import { attr, one2many, one2one } from '@mail/model/model_field'; +import { insertAndReplace, replace } from '@mail/model/model_field_command'; registerModel({ name: 'ActivityBoxView', @@ -19,8 +20,22 @@ registerModel({ onClickActivityBoxTitle() { this.update({ isActivityListVisible: !this.isActivityListVisible }); }, + /** + * @private + * @returns {FieldCommand} + */ + _computeActivityViews() { + return insertAndReplace(this.chatter.thread.activities.map(activity => { + return { activity: replace(activity) }; + })); + }, }, fields: { + activityViews: one2many('ActivityView', { + compute: '_computeActivityViews', + inverse: 'activityBoxView', + isCausal: true, + }), chatter: one2one('Chatter', { inverse: 'activityBoxView', readonly: true, @@ -29,6 +44,6 @@ registerModel({ isActivityListVisible: attr({ default: true, }), - }, + }, }); diff --git a/addons/mail/static/src/models/activity_view/activity_view.js b/addons/mail/static/src/models/activity_view/activity_view.js new file mode 100644 index 00000000000..a5b9c60cbf5 --- /dev/null +++ b/addons/mail/static/src/models/activity_view/activity_view.js @@ -0,0 +1,96 @@ +/** @odoo-module **/ + +import { registerModel } from '@mail/model/model_core'; +import { attr, many2one } from '@mail/model/model_field'; + +registerModel({ + name: 'ActivityView', + identifyingFields: ['activityBoxView', 'activity'], + lifecycleHooks: { + _created() { + this.onAttachmentCreated = this.onAttachmentCreated.bind(this); + this.onClickActivity = this.onClickActivity.bind(this); + this.onClickCancel = this.onClickCancel.bind(this); + this.onClickDetailsButton = this.onClickDetailsButton.bind(this); + this.onClickEdit = this.onClickEdit.bind(this); + this.onClickUploadDocument = this.onClickUploadDocument.bind(this); + } + }, + recordMethods: { + /** + * @param {Object} detail + * @param {Attachment} detail.attachment + */ + onAttachmentCreated(detail) { + this.activity.markAsDone({ attachments: [detail.attachment] }); + }, + /** + * Handles the click on a link inside the activity. + * + * @param {MouseEvent} ev + */ + onClickActivity(ev) { + if ( + ev.target.tagName === 'A' && + ev.target.dataset.oeId && + ev.target.dataset.oeModel + ) { + this.messaging.openProfile({ + id: Number(ev.target.dataset.oeId), + model: ev.target.dataset.oeModel, + }); + // avoid following dummy href + ev.preventDefault(); + } + }, + /** + * Handles the click on the cancel button + */ + async onClickCancel() { + const { chatter } = this.activityBoxView; // save value before deleting activity + await this.activity.deleteServerRecord(); + chatter.reloadParentView(); + }, + /** + * Handles the click on the detail button + */ + onClickDetailsButton() { + this.update({ areDetailsVisible: !this.areDetailsVisible }); + }, + /** + * Handles the click on the edit button + */ + onClickEdit() { + this.activity.edit(); + }, + /** + * Handles the click on the upload document button. This open the file + * explorer for upload. + */ + onClickUploadDocument() { + this.fileUploaderRef.comp.openBrowserFileUploader(); + }, + }, + fields: { + activity: many2one('Activity', { + inverse: 'activityViews', + required: true, + readonly: true, + }), + activityBoxView: many2one('ActivityBoxView', { + inverse: 'activityViews', + readonly: true, + required: true, + }), + /** + * Determines whether the details are visible. + */ + areDetailsVisible: attr({ + default: false, + }), + /** + * States the OWL FileUploader component of this activity view. + */ + fileUploaderRef: attr(), + }, +}); diff --git a/addons/mail/static/src/models/chatter/chatter.js b/addons/mail/static/src/models/chatter/chatter.js index 9bf94069fbf..f19f7475ee6 100644 --- a/addons/mail/static/src/models/chatter/chatter.js +++ b/addons/mail/static/src/models/chatter/chatter.js @@ -60,7 +60,7 @@ registerModel({ * @param {MouseEvent} ev */ onClickChatterTopbarClose(ev) { - this.componentChatterTopbar.trigger('o-close-chatter'); + this.component.trigger('o-close-chatter'); }, /** * Handles click on "log note" button. @@ -96,12 +96,7 @@ registerModel({ return this.env.bus.trigger('do-action', { action, options: { - on_close: () => { - if (!this.componentChatterTopbar) { - return; - } - this.componentChatterTopbar.trigger('reload', { keepChanges: true }); - }, + on_close: () => this.reloadParentView(), }, }); }, @@ -140,6 +135,11 @@ registerModel({ this.thread.refresh(); } }, + reloadParentView() { + if (this.component) { + this.component.trigger('reload', { keepChanges: true }); + } + }, showLogNote() { this.update({ composerView: insertAndReplace() }); this.composerView.composer.update({ isLog: true }); @@ -296,9 +296,9 @@ registerModel({ readonly: true, }), /** - * States the OWL component of this chatter top bar. + * States the OWL Chatter component of this chatter. */ - componentChatterTopbar: attr(), + component: attr(), /** * Determines the composer view used to post in this chatter (if any). */ diff --git a/addons/website_slides/__manifest__.py b/addons/website_slides/__manifest__.py index f7fc5a58eb0..43904f7b787 100644 --- a/addons/website_slides/__manifest__.py +++ b/addons/website_slides/__manifest__.py @@ -67,9 +67,9 @@ Featuring 'web.assets_backend': [ 'website_slides/static/src/scss/rating_rating_views.scss', 'website_slides/static/src/scss/slide_views.scss', - 'website_slides/static/src/components/activity/activity.js', 'website_slides/static/src/js/slide_category_one2many.js', 'website_slides/static/src/js/rating_field_backend.js', + 'website_slides/static/src/models/*/*.js', ], 'web.assets_frontend': [ 'website_slides/static/src/scss/website_slides.scss', @@ -114,10 +114,10 @@ Featuring 'website_slides/static/src/tests/helpers/mock_models.js', ], 'web.qunit_suite_tests': [ - 'website_slides/static/src/components/activity/activity_tests.js', + 'website_slides/static/src/components/*/tests/*.js', ], 'web.assets_qweb': [ - 'website_slides/static/src/components/activity/activity.xml', + 'website_slides/static/src/components/*/*.xml', ], }, 'license': 'LGPL-3', diff --git a/addons/website_slides/static/src/components/activity/activity.js b/addons/website_slides/static/src/components/activity/activity.js deleted file mode 100644 index 55fb6485651..00000000000 --- a/addons/website_slides/static/src/components/activity/activity.js +++ /dev/null @@ -1,43 +0,0 @@ -/** @odoo-module **/ - -import { Activity } from '@mail/components/activity/activity'; - -import { patch } from 'web.utils'; - -patch(Activity.prototype, 'website_slides/static/src/components/activity/activity.js', { - - //-------------------------------------------------------------------------- - // Handlers - //-------------------------------------------------------------------------- - - /** - * @private - */ - async _onGrantAccess(ev) { - await this.env.services.rpc({ - model: 'slide.channel', - method: 'action_grant_access', - args: [[this.activity.thread.id]], - kwargs: { partner_id: this.activity.requestingPartner.id }, - }); - if (this.activity) { - this.activity.delete(); - } - this.trigger('reload', { keepChanges: true }); - }, - /** - * @private - */ - async _onRefuseAccess(ev) { - await this.env.services.rpc({ - model: 'slide.channel', - method: 'action_refuse_access', - args: [[this.activity.thread.id]], - kwargs: { partner_id: this.activity.requestingPartner.id }, - }); - if (this.activity) { - this.activity.delete(); - } - this.trigger('reload', { keepChanges: true }); - }, -}); diff --git a/addons/website_slides/static/src/components/activity/activity.xml b/addons/website_slides/static/src/components/activity/activity.xml index e3d7d6fe89c..4678f5b6e27 100644 --- a/addons/website_slides/static/src/components/activity/activity.xml +++ b/addons/website_slides/static/src/components/activity/activity.xml @@ -2,12 +2,12 @@ - +
- -
diff --git a/addons/website_slides/static/src/components/activity/activity_tests.js b/addons/website_slides/static/src/components/activity/tests/activity_tests.js similarity index 100% rename from addons/website_slides/static/src/components/activity/activity_tests.js rename to addons/website_slides/static/src/components/activity/tests/activity_tests.js diff --git a/addons/website_slides/static/src/models/activity_view/activity_view.js b/addons/website_slides/static/src/models/activity_view/activity_view.js new file mode 100644 index 00000000000..791669c7a9d --- /dev/null +++ b/addons/website_slides/static/src/models/activity_view/activity_view.js @@ -0,0 +1,48 @@ +/** @odoo-module **/ + +import { addRecordMethods, patchLifecycleHooks } from '@mail/model/model_core'; +// ensure that the model definition is loaded before the patch +import '@mail/models/activity_view/activity_view'; + +patchLifecycleHooks('ActivityView', { + _created() { + this._super(); + this.onGrantAccess = this.onGrantAccess.bind(this); + this.onRefuseAccess = this.onRefuseAccess.bind(this); + }, +}); + +addRecordMethods('ActivityView', { + /** + * Handles click on the "grant access" button. + */ + async onGrantAccess(ev) { + const { chatter } = this.activityBoxView; // save value before deleting activity + await this.env.services.rpc({ + model: 'slide.channel', + method: 'action_grant_access', + args: [[this.activity.thread.id]], + kwargs: { partner_id: this.activity.requestingPartner.id }, + }); + if (this.activity) { + this.activity.delete(); + } + chatter.reloadParentView(); + }, + /** + * Handles click on the "refuse access" button. + */ + async onRefuseAccess(ev) { + const { chatter } = this.activityBoxView; // save value before deleting activity + await this.env.services.rpc({ + model: 'slide.channel', + method: 'action_refuse_access', + args: [[this.activity.thread.id]], + kwargs: { partner_id: this.activity.requestingPartner.id }, + }); + if (this.activity) { + this.activity.delete(); + } + chatter.reloadParentView(); + }, +});