[FIX] mail: split attachments list to improve style
There is now two lists of attachments : first one with images and second one with non-images. Attachment viewer allows to navigate through previews of all viewable attachments in the order they're shown. task-2272587 task-2401325 closes odoo/odoo#62719 Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
@@ -307,11 +307,11 @@ QUnit.test('remove attachment should ask for confirmation', async function (asse
|
||||
);
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_Attachment_actionUnlink',
|
||||
'.o_Attachment_asideItemUnlink',
|
||||
"attachment should have a delete button"
|
||||
);
|
||||
|
||||
await afterNextRender(() => document.querySelector('.o_Attachment_actionUnlink').click());
|
||||
await afterNextRender(() => document.querySelector('.o_Attachment_asideItemUnlink').click());
|
||||
assert.containsOnce(
|
||||
document.body,
|
||||
'.o_AttachmentDeleteConfirmDialog',
|
||||
|
||||
@@ -4,10 +4,63 @@ odoo.define('mail/static/src/components/attachment_list/attachment_list.js', fun
|
||||
const components = {
|
||||
Attachment: require('mail/static/src/components/attachment/attachment.js'),
|
||||
};
|
||||
const useStore = require('mail/static/src/component_hooks/use_store/use_store.js');
|
||||
|
||||
const { Component } = owl;
|
||||
|
||||
class AttachmentList extends Component {}
|
||||
class AttachmentList extends Component {
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
useStore(props => {
|
||||
const attachments = this.env.models['mail.attachment'].all().filter(attachment =>
|
||||
props.attachmentLocalIds.includes(attachment.localId)
|
||||
);
|
||||
return {
|
||||
attachments: attachments
|
||||
? attachments.map(attachment => attachment.__state)
|
||||
: undefined,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------
|
||||
// Public
|
||||
//--------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @returns {mail.attachment[]}
|
||||
*/
|
||||
get attachments() {
|
||||
return this.env.models['mail.attachment'].all().filter(attachment =>
|
||||
this.props.attachmentLocalIds.includes(attachment.localId)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {mail.attachment[]}
|
||||
*/
|
||||
get imageAttachments() {
|
||||
return this.attachments.filter(attachment => attachment.fileType === 'image');
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {mail.attachment[]}
|
||||
*/
|
||||
get nonImageAttachments() {
|
||||
return this.attachments.filter(attachment => attachment.fileType !== 'image');
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {mail.attachment[]}
|
||||
*/
|
||||
get viewableAttachments() {
|
||||
return this.attachments.filter(attachment => attachment.isViewable);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Object.assign(AttachmentList, {
|
||||
components,
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
|
||||
.o_AttachmentList {
|
||||
display: flex;
|
||||
flex-flow: wrap;
|
||||
flex-flow: column;
|
||||
justify-content: flex-start;
|
||||
margin: map-get($spacers, 1);
|
||||
}
|
||||
|
||||
/* Avoid overflow of long attachment text */
|
||||
@@ -17,3 +16,14 @@
|
||||
margin-inline-start: map-get($spacers, 0);
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.o_AttachmentList_partialList {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-flow: wrap;
|
||||
}
|
||||
|
||||
.o_AttachmentList_partialListNonImages {
|
||||
margin: map-get($spacers, 1);
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
@@ -3,19 +3,36 @@
|
||||
|
||||
<t t-name="mail.AttachmentList" owl="1">
|
||||
<div class="o_AttachmentList">
|
||||
<t t-foreach="props.attachmentLocalIds" t-as="attachmentLocalId" t-key="attachmentLocalId">
|
||||
<Attachment
|
||||
class="o_AttachmentList_attachment"
|
||||
attachmentLocalId="attachmentLocalId"
|
||||
attachmentLocalIds="props.attachmentLocalIds"
|
||||
detailsMode="props.attachmentsDetailsMode"
|
||||
imageSize="props.attachmentsImageSize"
|
||||
isDownloadable="props.areAttachmentsDownloadable"
|
||||
isEditable="props.areAttachmentsEditable"
|
||||
showExtension="props.showAttachmentsExtensions"
|
||||
showFilename="props.showAttachmentsFilenames"
|
||||
/>
|
||||
</t>
|
||||
<div class="o_AttachmentList_partialList o_AttachmentList_partialListImages">
|
||||
<t t-foreach="imageAttachments" t-as="attachment" t-key="attachment.localId">
|
||||
<Attachment
|
||||
class="o_AttachmentList_attachment o_AttachmentList_imageAttachment"
|
||||
attachmentLocalId="attachment.localId"
|
||||
attachmentLocalIds="viewableAttachments.map(attachment => attachment.localId)"
|
||||
detailsMode="props.attachmentsDetailsMode"
|
||||
imageSize="props.attachmentsImageSize"
|
||||
isDownloadable="props.areAttachmentsDownloadable"
|
||||
isEditable="props.areAttachmentsEditable"
|
||||
showExtension="props.showAttachmentsExtensions"
|
||||
showFilename="props.showAttachmentsFilenames"
|
||||
/>
|
||||
</t>
|
||||
</div>
|
||||
<div class="o_AttachmentList_partialList o_AttachmentList_partialListNonImages">
|
||||
<t t-foreach="nonImageAttachments" t-as="attachment" t-key="attachment.localId">
|
||||
<Attachment
|
||||
class="o_AttachmentList_attachment o_AttachmentList_nonImageAttachment"
|
||||
attachmentLocalId="attachment.localId"
|
||||
attachmentLocalIds="viewableAttachments.map(attachment => attachment.localId)"
|
||||
detailsMode="'card'"
|
||||
imageSize="props.attachmentsImageSize"
|
||||
isDownloadable="props.areAttachmentsDownloadable"
|
||||
isEditable="props.areAttachmentsEditable"
|
||||
showExtension="props.showAttachmentsExtensions"
|
||||
showFilename="props.showAttachmentsFilenames"
|
||||
/>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
t-att-class="{ 'o-composer-is-compact': props.isCompact }"
|
||||
areAttachmentsEditable="true"
|
||||
attachmentsDetailsMode="props.attachmentsDetailsMode"
|
||||
attachmentsImageSize="'small'"
|
||||
attachmentLocalIds="composer.attachments.map(attachment => attachment.localId)"
|
||||
showAttachmentsExtensions="props.showAttachmentsExtensions"
|
||||
showAttachmentsFilenames="props.showAttachmentsFilenames"
|
||||
|
||||
@@ -155,13 +155,6 @@ class Message extends Component {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {mail.attachment[]}
|
||||
*/
|
||||
get imageAttachments() {
|
||||
return this.message.attachments.filter(attachment => attachment.fileType === 'image');
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell whether the bottom of this message is visible or not.
|
||||
*
|
||||
@@ -222,14 +215,6 @@ class Message extends Component {
|
||||
get message() {
|
||||
return this.env.models['mail.message'].get(this.props.messageLocalId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {mail.attachment[]}
|
||||
*/
|
||||
get nonImageAttachments() {
|
||||
return this.message.attachments.filter(attachment => attachment.fileType !== 'image');
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string}
|
||||
*/
|
||||
|
||||
@@ -183,25 +183,13 @@
|
||||
</t>
|
||||
<t t-if="message.attachments and message.attachments.length > 0">
|
||||
<div class="o_Message_footer">
|
||||
<!-- TODO XDU This does not allow to preview all attachments at once, find somethind else -->
|
||||
<t t-if="imageAttachments and imageAttachments.length > 0">
|
||||
<AttachmentList
|
||||
class="o_Message_attachmentList"
|
||||
areAttachmentsDownloadable="true"
|
||||
areAttachmentsEditable="message.author === env.messaging.currentPartner"
|
||||
attachmentLocalIds="imageAttachments.map(attachment => attachment.localId)"
|
||||
attachmentsDetailsMode="props.attachmentsDetailsMode"
|
||||
/>
|
||||
</t>
|
||||
<t t-if="nonImageAttachments and nonImageAttachments.length > 0">
|
||||
<AttachmentList
|
||||
class="o_Message_attachmentList"
|
||||
areAttachmentsDownloadable="true"
|
||||
areAttachmentsEditable="message.author === env.messaging.currentPartner"
|
||||
attachmentLocalIds="nonImageAttachments.map(attachment => attachment.localId)"
|
||||
attachmentsDetailsMode="props.attachmentsDetailsMode"
|
||||
/>
|
||||
</t>
|
||||
<AttachmentList
|
||||
class="o_Message_attachmentList"
|
||||
areAttachmentsDownloadable="true"
|
||||
areAttachmentsEditable="message.author === env.messaging.currentPartner"
|
||||
attachmentLocalIds="message.attachments.map(attachment => attachment.localId)"
|
||||
attachmentsDetailsMode="props.attachmentsDetailsMode"
|
||||
/>
|
||||
</div>
|
||||
</t>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user