[FIX] web_editor: onAttachmentChange only composer
Due to a previous fix, attachments uploaded through media dialog would appear in the attachments of mail marketting. That fix prevents attachments from 'dangling' and being garbage collected later. That fix is now limited to the mail composer in this commit as attachments are only garbage collected for that model, for now. related commit: c112361bf9e2f5e7b087c5e5b9a31879856b1da4 task 3003939 closes odoo/odoo#103038 X-original-commit: 69fdca133b06eb66443635bc52d380233580ef51 Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
@@ -16,37 +16,38 @@ const { useEffect } = owl;
|
||||
QUnit.module('field html file upload', {
|
||||
beforeEach: function () {
|
||||
this.data = weTestUtils.wysiwygData({
|
||||
'note.note': {
|
||||
'mail.compose.message': {
|
||||
fields: {
|
||||
display_name: {
|
||||
string: "Displayed name",
|
||||
type: "char"
|
||||
},
|
||||
header: {
|
||||
string: "Header",
|
||||
type: "html",
|
||||
required: true,
|
||||
},
|
||||
body: {
|
||||
string: "Message",
|
||||
string: "Message Body inline (to send)",
|
||||
type: "html"
|
||||
},
|
||||
attachment_ids: {
|
||||
string: "Attachments",
|
||||
type: "many2many",
|
||||
relation: "ir.attachment",
|
||||
}
|
||||
},
|
||||
records: [{
|
||||
id: 1,
|
||||
display_name: "first record",
|
||||
header: "<p> <br> </p>",
|
||||
body: "<p>toto toto toto</p><p>tata</p>",
|
||||
display_name: "Some Composer",
|
||||
body: "Hello",
|
||||
attachment_ids: [],
|
||||
}],
|
||||
},
|
||||
});
|
||||
},
|
||||
}, function () {
|
||||
QUnit.test('media dialog: upload', async function (assert) {
|
||||
assert.expect(3);
|
||||
assert.expect(4);
|
||||
const onAttachmentChangeTriggered = testUtils.makeTestPromise();
|
||||
patchWithCleanup(HtmlField.prototype, {
|
||||
'_onAttachmentChange': function (event) {
|
||||
this._super(event);
|
||||
onAttachmentChangeTriggered.resolve(true);
|
||||
}
|
||||
});
|
||||
@@ -75,16 +76,17 @@ QUnit.module('field html file upload', {
|
||||
1: {
|
||||
id: 1,
|
||||
name: "test",
|
||||
res_model: "note.note",
|
||||
res_model: "mail.compose.message",
|
||||
type: "ir.actions.act_window",
|
||||
views: [[false, "form"]],
|
||||
},
|
||||
};
|
||||
serverData.views = {
|
||||
"note.note,false,search": "<search></search>",
|
||||
"note.note,false,form": `
|
||||
"mail.compose.message,false,search": "<search></search>",
|
||||
"mail.compose.message,false,form": `
|
||||
<form>
|
||||
<field name="body" type="html"/>
|
||||
<field name="attachment_ids" widget="many2many_binary"/>
|
||||
</form>`,
|
||||
};
|
||||
const mockRPC = (route, args) => {
|
||||
@@ -122,9 +124,14 @@ QUnit.module('field html file upload', {
|
||||
fileInputs.forEach(input => {
|
||||
input.dispatchEvent(new Event('change', {}));
|
||||
});
|
||||
|
||||
assert.ok(await Promise.race([onChangeTriggered, new Promise((res, _) => setTimeout(() => res(false), 400))]),
|
||||
"File change event was not triggered");
|
||||
assert.ok(await Promise.race([onAttachmentChangeTriggered, new Promise((res, _) => setTimeout(() => res(false), 400))]),
|
||||
"_onAttachmentChange was not called with the new attachment, necessary for unsused upload cleanup on backend");
|
||||
|
||||
// wait to check that dom is properly updated
|
||||
await new Promise((res, _) => setTimeout(() => res(false), 400));
|
||||
assert.ok(fixture.querySelector('.o_attachment[title="test.jpg"]'));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2370,8 +2370,6 @@ var FieldMany2ManyBinaryMultiFiles = AbstractField.extend({
|
||||
fieldsToFetch: {
|
||||
name: {type: 'char'},
|
||||
mimetype: {type: 'char'},
|
||||
res_id: {type: 'number'},
|
||||
access_token: {type: 'char'},
|
||||
},
|
||||
events: {
|
||||
'click .o_attach': '_onAttach',
|
||||
|
||||
@@ -1338,7 +1338,7 @@
|
||||
<t t-name="FieldBinaryFileUploader.attachment_preview">
|
||||
<t t-set="url" t-value="widget.metadata[file.id] ? widget.metadata[file.id].url : false"/>
|
||||
<t t-if="file.data" t-set="file" t-value="file.data"/>
|
||||
<t t-set="editable" t-value="widget.mode === 'edit' and !(file.res_id === 0 and file.access_token)"/>
|
||||
<t t-set="editable" t-value="widget.mode === 'edit'"/>
|
||||
<t t-if="file.mimetype" t-set="mimetype" t-value="file.mimetype"/>
|
||||
<div t-attf-class="o_attachment o_attachment_many2many #{ editable ? 'o_attachment_editable' : '' } #{upload ? 'o_attachment_uploading' : ''}" t-att-title="file.name">
|
||||
<div class="o_attachment_wrap">
|
||||
|
||||
@@ -59,8 +59,6 @@ Many2ManyBinaryField.supportedTypes = ["many2many"];
|
||||
Many2ManyBinaryField.fieldsToFetch = {
|
||||
name: { type: "char" },
|
||||
mimetype: { type: "char" },
|
||||
res_id: { type: "number" },
|
||||
access_token: { type: "char" },
|
||||
};
|
||||
|
||||
Many2ManyBinaryField.isEmpty = () => false;
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</t>
|
||||
|
||||
<t t-name="Many2ManyBinaryField.attachment_preview" owl="1">
|
||||
<t t-set="editable" t-value="!props.readonly and !(file.res_id === 0 and file.access_token)"/>
|
||||
<t t-set="editable" t-value="!props.readonly"/>
|
||||
<div t-attf-class="o_attachment o_attachment_many2many #{ editable ? 'o_attachment_editable' : '' } #{upload ? 'o_attachment_uploading' : ''}" t-att-title="file.name">
|
||||
<div class="o_attachment_wrap">
|
||||
<t t-set="ext" t-value="getExtension(file)"/>
|
||||
|
||||
@@ -2977,14 +2977,11 @@ QUnit.module('Legacy relational_fields', {
|
||||
fields: {
|
||||
name: {string:"Name", type: "char"},
|
||||
mimetype: {string: "Mimetype", type: "char"},
|
||||
res_id: {type: "number"},
|
||||
access_token: {type: "char"}
|
||||
},
|
||||
records: [{
|
||||
id: 17,
|
||||
name: 'Marley&Me.jpg',
|
||||
mimetype: 'jpg',
|
||||
res_id: 1, //non-zero to avoid transiant model editor attachment protection
|
||||
}],
|
||||
};
|
||||
this.data.turtle.fields.picture_ids = {
|
||||
@@ -3008,7 +3005,7 @@ QUnit.module('Legacy relational_fields', {
|
||||
mockRPC: function (route, args) {
|
||||
assert.step(route);
|
||||
if (route === '/web/dataset/call_kw/ir.attachment/read') {
|
||||
assert.deepEqual(args.args[1], ['name', 'mimetype', 'res_id', 'access_token']);
|
||||
assert.deepEqual(args.args[1], ['name', 'mimetype']);
|
||||
}
|
||||
return this._super.apply(this, arguments);
|
||||
},
|
||||
|
||||
@@ -96,7 +96,7 @@ QUnit.module("Fields", (hooks) => {
|
||||
assert.step(route);
|
||||
}
|
||||
if (route === "/web/dataset/call_kw/ir.attachment/read") {
|
||||
assert.deepEqual(args.args[1], ["name", "mimetype", "res_id", "access_token"]);
|
||||
assert.deepEqual(args.args[1], ["name", "mimetype"]);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
@@ -334,10 +334,11 @@ var FieldHtml = basic_fields.DebouncedField.extend(DynamicPlaceholderFieldMixin)
|
||||
* @param {Object} event the event containing attachment data
|
||||
*/
|
||||
_onAttachmentChange: function (event) {
|
||||
const attachments = event.data;
|
||||
if (!this.fieldNameAttachment) {
|
||||
// This only needs to happen for the composer for now
|
||||
if (!this.fieldNameAttachment || this.model !== 'mail.compose.message') {
|
||||
return;
|
||||
}
|
||||
const attachments = event.data;
|
||||
this.trigger_up('field_changed', {
|
||||
dataPointID: this.dataPointID,
|
||||
changes: _.object([this.fieldNameAttachment], [{
|
||||
|
||||
@@ -497,7 +497,8 @@ export class HtmlField extends Component {
|
||||
return getWysiwygClass();
|
||||
}
|
||||
_onAttachmentChange(attachment) {
|
||||
if (!this.props.record.fieldNames.includes('attachment_ids')) {
|
||||
// This only needs to happen for the composer for now
|
||||
if (!(this.props.record.fieldNames.includes('attachment_ids') && this.props.record.resModel === 'mail.compose.message')) {
|
||||
return;
|
||||
}
|
||||
this.props.record.update(_.object(['attachment_ids'], [{
|
||||
|
||||
Reference in New Issue
Block a user