diff --git a/addons/mail/static/src/components/chat_window/chat_window.js b/addons/mail/static/src/components/chat_window/chat_window.js index e25598b1879..76114f7e831 100644 --- a/addons/mail/static/src/components/chat_window/chat_window.js +++ b/addons/mail/static/src/components/chat_window/chat_window.js @@ -293,6 +293,10 @@ class ChatWindow extends Component { * CTRL-C & CTRL-V when on the home menu. */ ev.stopPropagation(); + if (!this.chatWindow) { + // prevent crash during delete + return; + } switch (ev.key) { case 'Tab': ev.preventDefault(); diff --git a/addons/mail/static/src/components/message/message_tests.js b/addons/mail/static/src/components/message/message_tests.js index ce01dab0c7c..f7b4210f128 100644 --- a/addons/mail/static/src/components/message/message_tests.js +++ b/addons/mail/static/src/components/message/message_tests.js @@ -346,7 +346,7 @@ QUnit.test("'channel_fetch' notification received is correctly handled", async f assert.expect(3); await this.start(); - const currentPartner = this.env.models['mail.partner'].create({ + const currentPartner = this.env.models['mail.partner'].insert({ id: this.env.session.partner_id, display_name: "Demo User", }); @@ -402,7 +402,7 @@ QUnit.test("'channel_seen' notification received is correctly handled", async fu assert.expect(3); await this.start(); - const currentPartner = this.env.models['mail.partner'].create({ + const currentPartner = this.env.models['mail.partner'].insert({ id: this.env.session.partner_id, display_name: "Demo User", }); @@ -457,7 +457,7 @@ QUnit.test("'channel_fetch' notification then 'channel_seen' received are corre assert.expect(4); await this.start(); - const currentPartner = this.env.models['mail.partner'].create({ + const currentPartner = this.env.models['mail.partner'].insert({ id: this.env.session.partner_id, display_name: "Demo User", }); @@ -537,10 +537,12 @@ QUnit.test('do not show messaging seen indicator if not authored by me', async f id: 11, partnerSeenInfos: [['create', [ { + id: this.env.session.partner_id, lastFetchedMessage: [['insert', {id: 100}]], partner: [['insert', {id: this.env.session.partner_id}]], }, { + id: 100, lastFetchedMessage: [['insert', {id: 100}]], partner: [['link', author]], }, @@ -548,7 +550,7 @@ QUnit.test('do not show messaging seen indicator if not authored by me', async f model: 'mail.channel', }); const threadViewer = this.env.models['mail.thread_viewer'].create({ thread: [['link', thread]] }); - const message = this.env.models['mail.message'].create({ + const message = this.env.models['mail.message'].insert({ author: [['link', author]], body: "
Test
", id: 100, @@ -572,7 +574,7 @@ QUnit.test('do not show messaging seen indicator if before last seen by all mess assert.expect(3); await this.start(); - const currentPartner = this.env.models['mail.partner'].create({ + const currentPartner = this.env.models['mail.partner'].insert({ id: this.env.session.partner_id, display_name: "Demo User", }); @@ -591,7 +593,7 @@ QUnit.test('do not show messaging seen indicator if before last seen by all mess id: 100, originThread: [['link', thread]], }); - const message = this.env.models['mail.message'].create({ + const message = this.env.models['mail.message'].insert({ author: [['link', currentPartner]], body: "Test
", id: 99, @@ -600,10 +602,12 @@ QUnit.test('do not show messaging seen indicator if before last seen by all mess thread.update({ partnerSeenInfos: [['create', [ { + id: currentPartner.id, lastSeenMessage: [['link', lastSeenMessage]], partner: [['link', currentPartner]], }, { + id: 100, lastSeenMessage: [['link', lastSeenMessage]], partner: [['insert', {id: 100}]], }, @@ -632,18 +636,19 @@ QUnit.test('only show messaging seen indicator if authored by me, after last see assert.expect(3); await this.start(); - const currentPartner = this.env.models['mail.partner'].create({ + const currentPartner = this.env.models['mail.partner'].insert({ id: this.env.session.partner_id, - display_name: "Demo User" }); const thread = this.env.models['mail.thread'].create({ id: 11, partnerSeenInfos: [['create', [ { + id: currentPartner.id, lastSeenMessage: [['insert', {id: 100}]], partner: [['link', currentPartner]], }, { + id: 100, partner: [['insert', {id: 100}]], lastFetchedMessage: [['insert', {id: 100}]], lastSeenMessage: [['insert', {id: 99}]], @@ -656,7 +661,7 @@ QUnit.test('only show messaging seen indicator if authored by me, after last see model: 'mail.channel', }); const threadViewer = this.env.models['mail.thread_viewer'].create({ thread: [['link', thread]] }); - const message = this.env.models['mail.message'].create({ + const message = this.env.models['mail.message'].insert({ author: [['link', currentPartner]], body: "Test
", id: 100, @@ -677,8 +682,8 @@ QUnit.test('only show messaging seen indicator if authored by me, after last see assert.containsN( document.body, '.o_MessageSeenIndicator_icon', - 2, - "message component should have two checks (V)" + 1, + "message component should have one check (V) because the message was fetched by everyone but no other member than author has seen the message" ); }); diff --git a/addons/mail/static/src/components/message_seen_indicator/message_seen_indicator_tests.js b/addons/mail/static/src/components/message_seen_indicator/message_seen_indicator_tests.js index ece69bbdad9..3f95a1d5407 100644 --- a/addons/mail/static/src/components/message_seen_indicator/message_seen_indicator_tests.js +++ b/addons/mail/static/src/components/message_seen_indicator/message_seen_indicator_tests.js @@ -60,10 +60,12 @@ QUnit.test('rendering when just one has received the message', async function (a model: 'mail.channel', partnerSeenInfos: [['create', [ { + id: 10, partner: [['create', {id: 10}]], lastFetchedMessage: [['insert', {id: 100}]] }, { + id: 100, partner: [['create', {id: 100}]], }, ]]], @@ -72,7 +74,7 @@ QUnit.test('rendering when just one has received the message', async function (a message: [['insert', {id: 100}]], }]], }); - const message = this.env.models['mail.message'].create({ + const message = this.env.models['mail.message'].insert({ author: [['insert', { id: this.env.session.partner_id, display_name: "Demo User" }]], body: "Test
", id: 100, @@ -105,10 +107,12 @@ QUnit.test('rendering when everyone have received the message', async function ( model: 'mail.channel', partnerSeenInfos: [['create', [ { + id: 10, partner: [['create', {id: 10}]], lastFetchedMessage: [['insert', {id: 100}]], }, { + id: 100, partner: [['create', {id: 100}]], lastFetchedMessage: [['insert', {id: 99}]], }, @@ -118,7 +122,7 @@ QUnit.test('rendering when everyone have received the message', async function ( message: [['insert', {id: 100}]], }]], }); - const message = this.env.models['mail.message'].create({ + const message = this.env.models['mail.message'].insert({ author: [['insert', { id: this.env.session.partner_id, display_name: "Demo User" }]], body: "Test
", id: 100, @@ -151,11 +155,13 @@ QUnit.test('rendering when just one has seen the message', async function (asser model: 'mail.channel', partnerSeenInfos: [['create', [ { + id: 10, partner: [['create', {id: 10}]], lastFetchedMessage: [['insert', {id: 100}]], lastSeenMessage: [['insert', {id: 100}]], }, { + id: 100, partner: [['create', {id: 100}]], lastFetchedMessage: [['insert', {id: 99}]], }, @@ -165,7 +171,7 @@ QUnit.test('rendering when just one has seen the message', async function (asser message: [['insert', {id: 100}]], }]], }); - const message = this.env.models['mail.message'].create({ + const message = this.env.models['mail.message'].insert({ author: [['insert', { id: this.env.session.partner_id, display_name: "Demo User" }]], body: "Test
", id: 100, @@ -199,11 +205,13 @@ QUnit.test('rendering when just one has seen & received the message', async func model: 'mail.channel', partnerSeenInfos: [['create', [ { + id: 10, partner: [['create', {id: 10}]], lastFetchedMessage: [['insert', {id: 100}]], lastSeenMessage: [['insert', {id: 100}]], }, { + id: 100, partner: [['create', {id: 100}]], }, ]]], @@ -212,7 +220,7 @@ QUnit.test('rendering when just one has seen & received the message', async func message: [['insert', {id: 100}]], }]], }); - const message = this.env.models['mail.message'].create({ + const message = this.env.models['mail.message'].insert({ author: [['insert', { id: this.env.session.partner_id, display_name: "Demo User" }]], body: "Test
", id: 100, @@ -246,11 +254,13 @@ QUnit.test('rendering when just everyone has seen the message', async function ( model: 'mail.channel', partnerSeenInfos: [['create', [ { + id: 10, partner: [['create', {id: 10}]], lastFetchedMessage: [['insert', {id: 100}]], lastSeenMessage: [['insert', {id: 100}]], }, { + id: 100, partner: [['create', {id: 100}]], lastFetchedMessage: [['insert', {id: 100}]], lastSeenMessage: [['insert', {id: 100}]], @@ -261,7 +271,7 @@ QUnit.test('rendering when just everyone has seen the message', async function ( message: [['insert', {id: 100}]], }]], }); - const message = this.env.models['mail.message'].create({ + const message = this.env.models['mail.message'].insert({ author: [['insert', { id: this.env.session.partner_id, display_name: "Demo User" }]], body: "Test
", id: 100, diff --git a/addons/mail/static/src/model/model_manager.js b/addons/mail/static/src/model/model_manager.js index 815a3c05409..91bd65c58bc 100644 --- a/addons/mail/static/src/model/model_manager.js +++ b/addons/mail/static/src/model/model_manager.js @@ -126,7 +126,10 @@ class ModelManager { const res = dataList.map(data => { const record = new Model({ valid: true }); Object.defineProperty(record, 'env', { get: () => Model.env }); - record.localId = record._createRecordLocalId(data); + record.localId = Model._createRecordLocalId(data); + if (Model.get(record.localId)) { + throw Error(`A record already exists for model "${Model.modelName}" with localId "${record.localId}".`); + } // Contains field values of record. record.__values = {}; // Contains revNumber of record for checking record update in useStore. @@ -207,7 +210,6 @@ class ModelManager { } record.update(data); delete this._records[record.localId]; - delete this.env.store.state[record.localId]; }); } @@ -277,7 +279,8 @@ class ModelManager { const isMulti = typeof data[Symbol.iterator] === 'function'; const dataList = isMulti ? data : [data]; const res = dataList.map(data => { - let record = Model.find(Model._findFunctionFromData(data)); + const localId = Model._createRecordLocalId(data); + let record = Model.get(localId); if (!record) { record = Model.create(data); } else { diff --git a/addons/mail/static/src/models/activity/activity.js b/addons/mail/static/src/models/activity/activity.js index f500579f04e..d370b686973 100644 --- a/addons/mail/static/src/models/activity/activity.js +++ b/addons/mail/static/src/models/activity/activity.js @@ -209,6 +209,13 @@ function factory(dependencies) { // Private //---------------------------------------------------------------------- + /** + * @override + */ + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; + } + /** * @private * @returns {boolean} diff --git a/addons/mail/static/src/models/activity_type/activity_type.js b/addons/mail/static/src/models/activity_type/activity_type.js index 7af2ae74095..f8a621a8569 100644 --- a/addons/mail/static/src/models/activity_type/activity_type.js +++ b/addons/mail/static/src/models/activity_type/activity_type.js @@ -6,7 +6,20 @@ const { attr, one2many } = require('mail/static/src/model/model_field.js'); function factory(dependencies) { - class ActivityType extends dependencies['mail.model'] {} + class ActivityType extends dependencies['mail.model'] { + + //---------------------------------------------------------------------- + // Private + //---------------------------------------------------------------------- + + /** + * @override + */ + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; + } + + } ActivityType.fields = { activities: one2many('mail.activity', { diff --git a/addons/mail/static/src/models/attachment/attachment.js b/addons/mail/static/src/models/attachment/attachment.js index 3bfbbef0cb9..d4dcfb20fac 100644 --- a/addons/mail/static/src/models/attachment/attachment.js +++ b/addons/mail/static/src/models/attachment/attachment.js @@ -49,6 +49,20 @@ function factory(dependencies) { return data2; } + /** + * @override + */ + static create(data) { + const isMulti = typeof data[Symbol.iterator] === 'function'; + const dataList = isMulti ? data : [data]; + for (const data of dataList) { + if (!data.id) { + data.id = getAttachmentNextTemporaryId(); + } + } + return super.create(...arguments); + } + /** * View provided attachment(s), with given attachment initially. Prompts * the attachment viewer. @@ -94,6 +108,13 @@ function factory(dependencies) { // Private //---------------------------------------------------------------------- + /** + * @override + */ + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; + } + /** * @private * @returns {mail.composer[]} @@ -185,17 +206,6 @@ function factory(dependencies) { return match[1]; } - /** - * @private - * @returns {integer} - */ - _computeId() { - if (this.isTemporary && (this.id === undefined || this.id > 0)) { - return getAttachmentNextTemporaryId(); - } - return this.id; - } - /** * @private * @returns {boolean} @@ -236,18 +246,6 @@ function factory(dependencies) { return this.mimetype && this.mimetype.split('/').shift(); } - /** - * @override - */ - _createRecordLocalId(data) { - const { id, isTemporary = false } = data; - const Attachment = this.env.models['mail.attachment']; - if (isTemporary) { - return `${Attachment.modelName}_${nextTemporaryId}`; - } - return `${Attachment.modelName}_${id}`; - } - } Attachment.fields = { @@ -291,10 +289,7 @@ function factory(dependencies) { 'url', ], }), - id: attr({ - compute: '_computeId', - dependencies: ['isTemporary'], - }), + id: attr(), isLinkedToComposer: attr({ compute: '_computeIsLinkedToComposer', dependencies: ['composers'], diff --git a/addons/mail/static/src/models/country/country.js b/addons/mail/static/src/models/country/country.js index 8fe6b282a31..2e44f54712d 100644 --- a/addons/mail/static/src/models/country/country.js +++ b/addons/mail/static/src/models/country/country.js @@ -6,7 +6,20 @@ const { attr } = require('mail/static/src/model/model_field.js'); function factory(dependencies) { - class Country extends dependencies['mail.model'] {} + class Country extends dependencies['mail.model'] { + + //---------------------------------------------------------------------- + // Private + //---------------------------------------------------------------------- + + /** + * @override + */ + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; + } + + } Country.fields = { id: attr(), diff --git a/addons/mail/static/src/models/follower/follower.js b/addons/mail/static/src/models/follower/follower.js index 78667ed755c..42e7216392e 100644 --- a/addons/mail/static/src/models/follower/follower.js +++ b/addons/mail/static/src/models/follower/follower.js @@ -153,6 +153,13 @@ function factory(dependencies) { // Private //---------------------------------------------------------------------- + /** + * @override + */ + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; + } + /** * @private * @returns {string} diff --git a/addons/mail/static/src/models/follower_subtype/follower_subtype.js b/addons/mail/static/src/models/follower_subtype/follower_subtype.js index 37e65129c61..68c16fce189 100644 --- a/addons/mail/static/src/models/follower_subtype/follower_subtype.js +++ b/addons/mail/static/src/models/follower_subtype/follower_subtype.js @@ -43,6 +43,17 @@ function factory(dependencies) { return data2; } + //---------------------------------------------------------------------- + // Private + //---------------------------------------------------------------------- + + /** + * @override + */ + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; + } + } FollowerSubtype.fields = { diff --git a/addons/mail/static/src/models/mail_template/mail_template.js b/addons/mail/static/src/models/mail_template/mail_template.js index 69d2b4c18b1..75b7b8fe4cd 100644 --- a/addons/mail/static/src/models/mail_template/mail_template.js +++ b/addons/mail/static/src/models/mail_template/mail_template.js @@ -56,6 +56,17 @@ function factory(dependencies) { } } + //---------------------------------------------------------------------- + // Private + //---------------------------------------------------------------------- + + /** + * @override + */ + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; + } + } MailTemplate.fields = { diff --git a/addons/mail/static/src/models/message/message.js b/addons/mail/static/src/models/message/message.js index 889ddef8306..d38b50a3083 100644 --- a/addons/mail/static/src/models/message/message.js +++ b/addons/mail/static/src/models/message/message.js @@ -315,6 +315,13 @@ function factory(dependencies) { // Private //---------------------------------------------------------------------- + /** + * @override + */ + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; + } + /** * @returns {boolean} */ @@ -432,14 +439,6 @@ function factory(dependencies) { return [['replace', threads]]; } - /** - * @override - */ - _createRecordLocalId(data) { - const Message = this.env.models['mail.message']; - return `${Message.modelName}_${data.id}`; - } - } Message.fields = { diff --git a/addons/mail/static/src/models/message_seen_indicator/message_seen_indicator.js b/addons/mail/static/src/models/message_seen_indicator/message_seen_indicator.js index 9ad56eb8da0..19b4706ba1f 100644 --- a/addons/mail/static/src/models/message_seen_indicator/message_seen_indicator.js +++ b/addons/mail/static/src/models/message_seen_indicator/message_seen_indicator.js @@ -67,6 +67,13 @@ function factory(dependencies) { // Private //---------------------------------------------------------------------- + /** + * @override + */ + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; + } + /** * Manually called as not always called when necessary * diff --git a/addons/mail/static/src/models/model/model.js b/addons/mail/static/src/models/model/model.js index 6ee5125426d..6511cafa658 100644 --- a/addons/mail/static/src/models/model/model.js +++ b/addons/mail/static/src/models/model/model.js @@ -39,9 +39,9 @@ function factory() { */ init() {} - //-------------------------------------------------------------------------- + //---------------------------------------------------------------------- // Public - //-------------------------------------------------------------------------- + //---------------------------------------------------------------------- /** * Returns all records of this model that match provided criteria. @@ -154,20 +154,9 @@ function factory() { this.env.modelManager.update(this, data); } - //-------------------------------------------------------------------------- + //---------------------------------------------------------------------- // Private - //-------------------------------------------------------------------------- - - /** - * @static - * @private - * @param {Object} data - * @param {any} data.id - * @return {function} - */ - static _findFunctionFromData(data) { - return record => record.id === data.id; - } + //---------------------------------------------------------------------- /** * This method generates a local id for this record that is @@ -180,12 +169,13 @@ function factory() { * track relations and records in the system instead of arbitrary * number to differenciate them. * + * @static * @private * @param {Object} data * @returns {string} */ - _createRecordLocalId(data) { - return _.uniqueId(`${this.constructor.modelName}_`); + static _createRecordLocalId(data) { + return _.uniqueId(`${this.modelName}_`); } /** diff --git a/addons/mail/static/src/models/notification/notification.js b/addons/mail/static/src/models/notification/notification.js index 95e8a013876..c8e9078b046 100644 --- a/addons/mail/static/src/models/notification/notification.js +++ b/addons/mail/static/src/models/notification/notification.js @@ -46,6 +46,17 @@ function factory(dependencies) { return data2; } + //---------------------------------------------------------------------- + // Private + //---------------------------------------------------------------------- + + /** + * @override + */ + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; + } + } Notification.fields = { diff --git a/addons/mail/static/src/models/notification_group/notification_group.js b/addons/mail/static/src/models/notification_group/notification_group.js index 9fdbefc4979..415350332cc 100644 --- a/addons/mail/static/src/models/notification_group/notification_group.js +++ b/addons/mail/static/src/models/notification_group/notification_group.js @@ -63,9 +63,8 @@ function factory(dependencies) { /** * @override */ - _createRecordLocalId(data) { - const NotificationGroup = this.env.models['mail.notification_group']; - return `${NotificationGroup.modelName}_${data.id}`; + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; } /** diff --git a/addons/mail/static/src/models/partner/partner.js b/addons/mail/static/src/models/partner/partner.js index 32b02e6e60c..c78eef51289 100644 --- a/addons/mail/static/src/models/partner/partner.js +++ b/addons/mail/static/src/models/partner/partner.js @@ -156,6 +156,13 @@ function factory(dependencies) { // Private //---------------------------------------------------------------------- + /** + * @override + */ + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; + } + /** * @static * @private @@ -211,14 +218,6 @@ function factory(dependencies) { return this.name || this.display_name; } - /** - * @override - */ - _createRecordLocalId(data) { - const Partner = this.env.models['mail.partner']; - return `${Partner.modelName}_${data.id}`; - } - } Partner.fields = { diff --git a/addons/mail/static/src/models/thread/thread.js b/addons/mail/static/src/models/thread/thread.js index ceb4a366ec3..4459912d6f6 100644 --- a/addons/mail/static/src/models/thread/thread.js +++ b/addons/mail/static/src/models/thread/thread.js @@ -764,8 +764,13 @@ function factory(dependencies) { /** * @override */ - static _findFunctionFromData(data) { - return record => record.id === data.id && record.model === data.model; + static _createRecordLocalId(data) { + const { channel_type, id, model } = data; + let threadModel = model; + if (!threadModel && channel_type) { + threadModel = 'mail.channel'; + } + return `${this.modelName}_${threadModel}_${id}`; } /** @@ -1006,22 +1011,6 @@ function factory(dependencies) { ); } - /** - * @override - */ - _createRecordLocalId(data) { - const { channel_type, id, isTemporary = false, model } = data; - let threadModel = model; - if (!threadModel && channel_type) { - threadModel = 'mail.channel'; - } - const Thread = this.env.models['mail.thread']; - if (isTemporary) { - return `${Thread.modelName}_${id}`; - } - return `${Thread.modelName}_${threadModel}_${id}`; - } - /** * @private * @param {Object} param0 diff --git a/addons/mail/static/src/models/thread_cache/thread_cache.js b/addons/mail/static/src/models/thread_cache/thread_cache.js index b4fe3ca28c3..9d0b4e98e57 100644 --- a/addons/mail/static/src/models/thread_cache/thread_cache.js +++ b/addons/mail/static/src/models/thread_cache/thread_cache.js @@ -94,6 +94,17 @@ function factory(dependencies) { // Private //---------------------------------------------------------------------- + /** + * @override + */ + static _createRecordLocalId(data) { + const { + stringifiedDomain = '[]', + thread: [[commandInsert, thread]], + } = data; + return `${this.modelName}_[${thread.localId}]_<${stringifiedDomain}>`; + } + /** * @private */ @@ -204,18 +215,6 @@ function factory(dependencies) { )]]; } - /** - * @override - */ - _createRecordLocalId(data) { - const { - stringifiedDomain = '[]', - thread: [[commandInsert, thread]], - } = data; - const ThreadCache = this.env.models['mail.thread_cache']; - return `${ThreadCache.modelName}_[${thread.localId}]_<${stringifiedDomain}>`; - } - /** * @private * @param {Array} domain diff --git a/addons/mail/static/src/models/thread_partner_seen_info/thread_partner_seen_info.js b/addons/mail/static/src/models/thread_partner_seen_info/thread_partner_seen_info.js index 6ea0148d6d0..1a2d19480a3 100644 --- a/addons/mail/static/src/models/thread_partner_seen_info/thread_partner_seen_info.js +++ b/addons/mail/static/src/models/thread_partner_seen_info/thread_partner_seen_info.js @@ -6,7 +6,20 @@ const { attr, many2one } = require('mail/static/src/model/model_field.js'); function factory(dependencies) { - class ThreadPartnerSeenInfo extends dependencies['mail.model'] {} + class ThreadPartnerSeenInfo extends dependencies['mail.model'] { + + //---------------------------------------------------------------------- + // Private + //---------------------------------------------------------------------- + + /** + * @override + */ + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; + } + + } ThreadPartnerSeenInfo.modelName = 'mail.thread_partner_seen_info'; diff --git a/addons/mail/static/src/models/user/user.js b/addons/mail/static/src/models/user/user.js index 2e6206c79f5..20495e25aa1 100644 --- a/addons/mail/static/src/models/user/user.js +++ b/addons/mail/static/src/models/user/user.js @@ -42,8 +42,8 @@ function factory(dependencies) { /** * @override */ - _createRecordLocalId(data) { - return `${this.env.models['mail.user'].modelName}_${data.id}`; + static _createRecordLocalId(data) { + return `${this.modelName}_${data.id}`; } /**