diff --git a/addons/mail/static/src/model/model_manager.js b/addons/mail/static/src/model/model_manager.js index f4d45f084dc..0613ea38c88 100644 --- a/addons/mail/static/src/model/model_manager.js +++ b/addons/mail/static/src/model/model_manager.js @@ -138,8 +138,7 @@ export class ModelManager { /** * Create the messaging singleton record. */ - const messaging = this.models['Messaging'].insert(values); - Object.assign(odoo.__DEBUG__, { messaging }); + this.models['Messaging'].insert(values); this.messagingCreatedPromise.resolve(); await this.messaging.start(); this.messagingInitializedPromise.resolve(); @@ -204,8 +203,7 @@ export class ModelManager { * @returns {boolean} */ exists(model, record) { - const existingRecord = model.__records[record.localId]; - return Boolean(existingRecord && existingRecord === record); + return Boolean(record.localId); } /** @@ -655,7 +653,7 @@ export class ModelManager { get: function getFromProxy(record, prop) { if ( !model.__fieldMap[prop] && - !['_super', 'then'].includes(prop) && + !['_super', 'then', 'localId'].includes(prop) && typeof prop !== 'symbol' && !(prop in record) ) { @@ -736,6 +734,9 @@ export class ModelManager { if (field.fieldType === 'relation') { // ensure inverses are properly unlinked field.parseAndExecuteCommands(record, unlinkAll(), { allowWriteReadonly: true }); + if (!record.exists()) { + return; // current record might have been deleted from causality + } } } this._createdRecordsComputes.delete(record); @@ -756,7 +757,10 @@ export class ModelManager { infoList, }); } + delete record.__values; + delete record.__listeners; delete model.__records[record.localId]; + delete record.localId; } /** @@ -1215,6 +1219,10 @@ export class ModelManager { for (const field of model.__fieldList) { Object.defineProperty(model.prototype, field.fieldName, { get: function getFieldValue() { // this is bound to record + if (!this.exists()) { + // Deprecated, allows reading fields on deleted records. Use exists() instead. + return undefined; + } if (this.modelManager._listeners.size) { if (!this.modelManager._listenersObservingLocalId.has(this.localId)) { this.modelManager._listenersObservingLocalId.set(this.localId, new Map()); diff --git a/addons/mail/static/src/models/drop_zone_view.js b/addons/mail/static/src/models/drop_zone_view.js index b15607bb8f5..df4410abfef 100644 --- a/addons/mail/static/src/models/drop_zone_view.js +++ b/addons/mail/static/src/models/drop_zone_view.js @@ -65,9 +65,11 @@ registerModel({ if (this._isDragSourceExternalFile(ev.dataTransfer)) { if (this.chatterOwner) { await this.chatterOwner.fileUploader.uploadFiles(ev.dataTransfer.files); + return; } if (this.composerViewOwner) { await this.composerViewOwner.fileUploader.uploadFiles(ev.dataTransfer.files); + return; } } }, diff --git a/addons/mail/static/src/models/messaging.js b/addons/mail/static/src/models/messaging.js index b7d39ebdbf6..64a592f398b 100644 --- a/addons/mail/static/src/models/messaging.js +++ b/addons/mail/static/src/models/messaging.js @@ -14,10 +14,14 @@ registerModel({ name: 'Messaging', identifyingFields: [], lifecycleHooks: { + _created() { + odoo.__DEBUG__.messaging = this; + }, _willDelete() { if (this.env.services['legacy_bus_service']) { this.env.services['legacy_bus_service'].off('window_focus', null, this._handleGlobalWindowFocus); } + delete odoo.__DEBUG__.messaging; }, }, recordMethods: { diff --git a/addons/mail/static/src/models/thread_cache.js b/addons/mail/static/src/models/thread_cache.js index 0aaa201cb77..5c13e236a0a 100644 --- a/addons/mail/static/src/models/thread_cache.js +++ b/addons/mail/static/src/models/thread_cache.js @@ -292,6 +292,9 @@ registerModel({ return; } const fetchedMessages = await this._loadMessages(); + if (!this.exists()) { + return; + } for (const threadView of this.threadViews) { threadView.addComponentHint('messages-loaded', { fetchedMessages }); }