[IMP] mail: attachments list design
With this commit, the attachments displayed in a thread (typically a chatter) are properly styled.
This commit is contained in:
committed by
Géry Debongnie
parent
3820b56c07
commit
6e12372f95
@@ -132,6 +132,13 @@ var Thread = Widget.extend({
|
|||||||
} else {
|
} else {
|
||||||
msg.display_author = !options.squash_close_messages;
|
msg.display_author = !options.squash_close_messages;
|
||||||
}
|
}
|
||||||
|
if (msg.attachment_ids) {
|
||||||
|
var sortedAttachments = _.partition(msg.attachment_ids, function (att) {
|
||||||
|
return att.mimetype && att.mimetype.split('/')[0] === 'image';
|
||||||
|
});
|
||||||
|
msg.images = sortedAttachments[0];
|
||||||
|
msg.others = sortedAttachments[1];
|
||||||
|
}
|
||||||
prev_msg = msg;
|
prev_msg = msg;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -230,106 +230,164 @@
|
|||||||
|
|
||||||
// Attachment Icons (common for chat thread and chat composer)
|
// Attachment Icons (common for chat thread and chat composer)
|
||||||
// ------------------------------------------------------------------
|
// ------------------------------------------------------------------
|
||||||
@-webkit-keyframes oe_mail_attach_loading_anim {
|
@o-mail-attachment-image-size: 38px;
|
||||||
0% { background: @odoo-brand-optional }
|
@o-mail-attachment-margin: 5px;
|
||||||
50% { background: darken(@odoo-brand-optional, 10%) }
|
|
||||||
100% { background: @odoo-brand-optional }
|
.o_attachments_list, .o_attachments_previews {
|
||||||
}
|
margin: 0 -@o-mail-attachment-margin 0;
|
||||||
@-moz-keyframes oe_mail_attach_loading_anim {
|
.o-flex-display();
|
||||||
0% { background: @odoo-brand-optional }
|
.o-flex-flow(row, wrap);
|
||||||
50% { background: darken(@odoo-brand-optional, 10%) }
|
|
||||||
100% { background: @odoo-brand-optional }
|
|
||||||
}
|
|
||||||
@-o-keyframes oe_mail_attach_loading_anim {
|
|
||||||
0% { background: @odoo-brand-optional }
|
|
||||||
50% { background: darken(@odoo-brand-optional, 10%) }
|
|
||||||
100% { background: @odoo-brand-optional }
|
|
||||||
}
|
|
||||||
@keyframes oe_mail_attach_loading_anim {
|
|
||||||
0% { background: @odoo-brand-optional }
|
|
||||||
50% { background: darken(@odoo-brand-optional, 10%) }
|
|
||||||
100% { background: @odoo-brand-optional }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@o-mail-attachment-image-size: 100px;
|
|
||||||
.o_attachment {
|
.o_attachment {
|
||||||
position: relative;
|
position: relative;
|
||||||
vertical-align: top;
|
width: 100%;
|
||||||
display: inline-block;
|
padding: @o-mail-attachment-margin;
|
||||||
text-align: center;
|
|
||||||
width: @o-mail-attachment-image-size;
|
@media (min-width: @screen-sm-min) {
|
||||||
margin: 5px;
|
width: 50%;
|
||||||
.o_image_box {
|
|
||||||
position: relative;
|
|
||||||
img {
|
|
||||||
width: @o-mail-attachment-image-size;
|
|
||||||
height: @o-mail-attachment-image-size;
|
|
||||||
image-orientation: from-image; // Only supported in Firefox
|
|
||||||
}
|
|
||||||
.o_image_overlay{
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
&:hover .o_image_overlay {
|
|
||||||
display: block;
|
|
||||||
.o-position-absolute(@top: 0, @left: 0, @right:0, @bottom:0);
|
|
||||||
z-index: 20;
|
|
||||||
background: rgba(0, 0, 0, 0.5);
|
|
||||||
overflow: hidden;
|
|
||||||
cursor: pointer;
|
|
||||||
.o_attachment_download {
|
|
||||||
.o-position-absolute(@left: 10px, @bottom:5px);
|
|
||||||
}
|
|
||||||
.o_attachment_play {
|
|
||||||
.o-position-absolute(@top: 50%, @left: 50%);
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
.o_overlay_download {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
i {
|
|
||||||
color: #FFFFFF;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.caption {
|
@media (min-width: @screen-md-min) {
|
||||||
text-overflow: ellipsis;
|
width: percentage(1/4);
|
||||||
white-space: nowrap;
|
}
|
||||||
|
|
||||||
|
.o_attachment_wrap {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
padding: 5px;
|
position: relative;
|
||||||
a {
|
border-bottom: 1px solid fade(black, 10%);
|
||||||
color: @odoo-main-text-color;
|
border-radius: 2px;
|
||||||
|
padding: 4px 6px 0 4px;
|
||||||
|
background-color: fade(black, 5%);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.o_attachment_editable .o_attachment_wrap {
|
||||||
|
padding-right: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.o_image {
|
||||||
|
.square(@o-mail-attachment-image-size);
|
||||||
|
image-orientation: from-image; // Only supported in Firefox
|
||||||
|
&.o_hover {
|
||||||
|
.o-hover-opacity(@default-opacity: 1, @hover-opacity: 0.7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.o_attachment_view {
|
||||||
|
cursor: zoom-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
.caption {
|
||||||
|
.o-text-overflow(block);
|
||||||
|
|
||||||
|
a {
|
||||||
|
.o-hover-text-color(@default-color: @odoo-main-text-color, @hover-color: @headings-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.o_attachment_progress_bar {
|
.o_attachment_progress_bar {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
.o_attachment_delete {
|
|
||||||
.o-position-absolute(@top: -10px, @right: -8px);
|
.o_attachment_uploaded, .o_attachment_delete {
|
||||||
color: @odoo-main-text-color;
|
.o-position-absolute(0,0,0, @left: auto);
|
||||||
cursor: pointer;
|
.o-flex-display();
|
||||||
opacity: 0;
|
.o-align-items(center);
|
||||||
.o-transition(opacity, 0.2s, linear);
|
.o-justify-content(center);
|
||||||
|
width: 45px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.o_attachment_delete {
|
||||||
|
background: desaturate(@brand-primary, 50%);
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 20px;
|
||||||
|
.o-transform(translateX(100%));
|
||||||
|
.o-transition(all, 0.3s);
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: @brand-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.o_attachment_uploading {
|
&.o_attachment_uploading {
|
||||||
.o_attachment_progress_bar {
|
.o_attachment_progress_bar {
|
||||||
display: block;
|
display: inline-block;
|
||||||
.o-position-absolute(@top: 18px, @left: 16px, @right: 16px);
|
margin: 0 0 0 8px;
|
||||||
height: 17px;
|
border-radius: 2px;
|
||||||
line-height: 13px;
|
vertical-align: bottom;
|
||||||
color: white;
|
|
||||||
border-radius: @border-radius-base;
|
> div {
|
||||||
border: solid 1px grey;
|
font-size: 11px;
|
||||||
box-shadow: 0px 1px 10px @odoo-shadow-color;
|
padding: 0 7px;
|
||||||
.o-animation(@name: oe_mail_attach_loading_anim, @duration: 1s, @timing-function: linear, @iteration-count: infinite);
|
}
|
||||||
}
|
}
|
||||||
.o_attachment_delete {
|
|
||||||
|
.o_attachment_delete, .o_attachment_uploaded {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover .o_attachment_delete {
|
&:hover .o_attachment_delete {
|
||||||
opacity: 1;
|
.o-transition(all, 0.1s);
|
||||||
.o-transition(opacity, 0.2s, linear);
|
.o-transform(translateX(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.o_attachments_previews {
|
||||||
|
> .o_attachment {
|
||||||
|
width: 50%;
|
||||||
|
|
||||||
|
@media (min-width: @screen-sm-min) {
|
||||||
|
width: percentage(1/3);
|
||||||
|
}
|
||||||
|
@media (min-width: @screen-md-min) {
|
||||||
|
width: percentage(1/4);
|
||||||
|
}
|
||||||
|
@media (min-width: @screen-lg-min) {
|
||||||
|
width: percentage(1/6);
|
||||||
|
}
|
||||||
|
|
||||||
|
.o_attachment_wrap {
|
||||||
|
padding: 0;
|
||||||
|
border-radius: 2px;
|
||||||
|
border: 1px solid @gray-lighter-darker;
|
||||||
|
}
|
||||||
|
|
||||||
|
.o_image_box {
|
||||||
|
overflow: hidden;
|
||||||
|
padding-top: 75%;
|
||||||
|
|
||||||
|
.o_attachment_image {
|
||||||
|
.o-position-absolute(0,0,0,0);
|
||||||
|
background-size: cover;
|
||||||
|
background-position: center;
|
||||||
|
.o-transform(scale(1.05));
|
||||||
|
.o-transition(all, 0.3s);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover .o_attachment_image {
|
||||||
|
.o-transform(scale(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.o_image_overlay {
|
||||||
|
.o-position-absolute(@top: 0, @left: 0, @right:0, @bottom:0);
|
||||||
|
.o-hover-opacity(@default-opacity: 0, @hover-opacity: 1);
|
||||||
|
.o-linear-gradient(180deg, fade(black, 20%), fade(black, 90%));
|
||||||
|
.o-transition(all, 0.3s);
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
.o_attachment_title {
|
||||||
|
.o-position-absolute(@bottom: 7px);
|
||||||
|
width: 80%;
|
||||||
|
.o-text-overflow(inline-block);
|
||||||
|
font-size: @font-size-small;
|
||||||
|
}
|
||||||
|
|
||||||
|
.o_attachment_download {
|
||||||
|
.o-position-absolute(@right: 7px, @bottom:7px);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -177,6 +177,12 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.o_attachments_list, .o_attachments_previews {
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: @grid-gutter-width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.o_thread_tooltip_container {
|
.o_thread_tooltip_container {
|
||||||
display: inline;
|
display: inline;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|||||||
@@ -207,9 +207,18 @@
|
|||||||
<t t-if="!(message.tracking_value_ids and message.tracking_value_ids.length > 0)">
|
<t t-if="!(message.tracking_value_ids and message.tracking_value_ids.length > 0)">
|
||||||
<t t-raw="message.body"/>
|
<t t-raw="message.body"/>
|
||||||
</t>
|
</t>
|
||||||
<t t-foreach="message.attachment_ids" t-as="attachment">
|
<t t-if="message.attachment_ids.length > 0">
|
||||||
<t t-call="mail.Attachment"/>
|
<div t-if="message.images.length > 0" class="o_attachments_previews">
|
||||||
</t>
|
<t t-foreach="message.images" t-as="attachment">
|
||||||
|
<t t-call="mail.AttachmentPreview"/>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
|
<div t-if="message.others.length > 0" class="o_attachments_list">
|
||||||
|
<t t-foreach="message.others" t-as="attachment">
|
||||||
|
<t t-call="mail.Attachment"/>
|
||||||
|
</t>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -242,7 +251,7 @@
|
|||||||
</t>
|
</t>
|
||||||
|
|
||||||
<t t-name="mail.ChatComposer.Attachments">
|
<t t-name="mail.ChatComposer.Attachments">
|
||||||
<div t-if="attachments.length > 0" class="o_attachments">
|
<div t-if="attachments.length > 0" class="o_attachments o_attachments_list">
|
||||||
<t t-foreach="attachments" t-as='attachment'>
|
<t t-foreach="attachments" t-as='attachment'>
|
||||||
<t t-call="mail.Attachment">
|
<t t-call="mail.Attachment">
|
||||||
<t t-set="editable" t-value="true"/>
|
<t t-set="editable" t-value="true"/>
|
||||||
@@ -251,68 +260,58 @@
|
|||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
|
|
||||||
|
<t t-name="mail.AttachmentPreview">
|
||||||
|
<div class="o_attachment" t-att-title="attachment.name">
|
||||||
|
<div class="o_attachment_wrap">
|
||||||
|
<div class="o_image_box">
|
||||||
|
<div class="o_attachment_image" t-attf-style="background-image:url('/web/image/#{attachment.id}/160x160/?crop=true')"/>
|
||||||
|
<div t-attf-class="o_image_overlay o_attachment_view" t-att-data-id="attachment.id">
|
||||||
|
<span class="o_attachment_title text-white"><t t-esc="attachment.name"/></span>
|
||||||
|
<a class="o_attachment_download" t-att-href='attachment.url'>
|
||||||
|
<i t-attf-class="fa fa-download text-white" t-att-title="'Download ' + attachment.name" aria-hidden="true"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</t>
|
||||||
|
|
||||||
<t t-name="mail.Attachment">
|
<t t-name="mail.Attachment">
|
||||||
<t t-set="type" t-value="attachment.mimetype and attachment.mimetype.split('/').shift()"/>
|
<t t-set="type" t-value="attachment.mimetype and attachment.mimetype.split('/').shift()"/>
|
||||||
<div t-attf-class="o_attachment #{attachment.upload ? 'o_attachment_uploading' : ''}" t-att-title="attachment.name">
|
<div t-attf-class="o_attachment #{ editable ? 'o_attachment_editable' : '' } #{attachment.upload ? 'o_attachment_uploading' : ''}" t-att-title="attachment.name">
|
||||||
<t t-if="type == 'image'">
|
<div class="o_attachment_wrap">
|
||||||
<div class="o_image_box">
|
<t t-set="has_preview" t-value="type == 'image' or type == 'video' or attachment.mimetype == 'application/pdf'"/>
|
||||||
<img t-attf-src="/web/image/#{attachment.id}/200x200/?crop=True"/>
|
|
||||||
<div t-attf-class="o_image_overlay o_attachment_view" t-att-data-id="attachment.id">
|
<div t-attf-class="o_image_box pull-left #{has_preview ? 'o_attachment_view' : ''}" t-att-data-id="attachment.id">
|
||||||
<a class="o_attachment_download" t-att-href='attachment.url' target="_blank">
|
<div t-if="has_preview"
|
||||||
<i t-attf-class="fa fa-2x fa-arrow-circle-o-down" title="Download this attachment" aria-hidden="true"></i>
|
class="o_image o_hover"
|
||||||
</a>
|
t-att-style="type == 'image' ? 'background-image:url(/web/image/' + attachment.id + '/38x38/?crop=true' : '' "
|
||||||
|
t-att-data-mimetype="attachment.mimetype">
|
||||||
|
</div>
|
||||||
|
<a t-elif="!editable" t-att-href='attachment.url' t-att-title="'Download ' + attachment.name">
|
||||||
|
<span class="o_image o_hover" t-att-data-mimetype="attachment.mimetype"/>
|
||||||
|
</a>
|
||||||
|
<span t-else="" class="o_image" t-att-data-mimetype="attachment.mimetype"/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="caption">
|
||||||
|
<span t-if="has_preview or editable" t-attf-class="ml4 #{has_preview? 'o_attachment_view' : ''}" t-att-data-id="attachment.id"><t t-esc='attachment.name'/></span>
|
||||||
|
<a t-else="" class="ml4" t-att-href="attachment.url" t-att-title="'Download ' + attachment.name"><t t-esc='attachment.name'/></a>
|
||||||
|
</div>
|
||||||
|
<div t-if="editable" class="caption small">
|
||||||
|
<b t-attf-class="ml4 small text-uppercase #{has_preview? 'o_attachment_view' : ''}" t-att-data-id="attachment.id"><t t-esc="ext"/></b>
|
||||||
|
<div class="progress o_attachment_progress_bar">
|
||||||
|
<div class="progress-bar progress-bar-striped active" style="width: 100%">Uploading</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</t>
|
<div t-if="!editable" class="caption small">
|
||||||
<t t-elif="type == 'video'">
|
<b t-if="has_preview" class="ml4 small text-uppercase o_attachment_view" t-att-data-id="attachment.id"><t t-esc="ext"/></b>
|
||||||
<div class="o_image_box o_image_preview">
|
<a t-else="" class="ml4 small text-uppercase" t-att-href="attachment.url" t-att-title="'Download ' + attachment.name"><b><t t-esc='ext'/></b></a>
|
||||||
<img class="o_image" t-att-data-mimetype="attachment.mimetype"/>
|
<a class="ml4 o_attachment_download pull-right" t-att-title="'Download ' + attachment.name" t-att-href='attachment.url'><i t-attf-class="fa fa-download"/></a>
|
||||||
<div t-attf-class="o_image_overlay o_attachment_view" t-att-data-id="attachment.id">
|
|
||||||
<a class="o_attachment_play">
|
|
||||||
<i t-attf-class="fa fa-2x fa-play-circle" title="Play this video" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
<a class="o_attachment_download" t-att-href='attachment.url' target="_blank">
|
|
||||||
<i t-attf-class="fa fa-2x fa-arrow-circle-o-down" title="Download this attachment" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</t>
|
<div t-if="editable" class="o_attachment_uploaded"><i class="text-success fa fa-check"/></div>
|
||||||
<t t-elif="attachment.mimetype == 'application/pdf'">
|
<div t-if="editable" class="o_attachment_delete" t-att-data-id="attachment.id"><span class="text-white">×</span></div>
|
||||||
<div class="o_image_box">
|
|
||||||
<div class="o_image_box">
|
|
||||||
<img src="/web/static/src/img/mimetypes/pdf.png"/>
|
|
||||||
<div class="o_image_overlay o_attachment_view" t-att-data-id="attachment.id">
|
|
||||||
<a class="o_attachment_download" t-att-href='attachment.url' target="_blank">
|
|
||||||
<i t-attf-class="fa fa-2x fa-arrow-circle-o-down" title="Download this PDF" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</t>
|
|
||||||
<t t-else="">
|
|
||||||
<div class="o_image_box">
|
|
||||||
<img class="o_image" t-att-data-mimetype="attachment.mimetype"/>
|
|
||||||
<div t-attf-class="o_image_overlay">
|
|
||||||
<a class="o_overlay_download" t-att-href='attachment.url' target="_blank"/>
|
|
||||||
<a class="o_attachment_download" t-att-href='attachment.url' target="_blank">
|
|
||||||
<i t-attf-class="fa fa-2x fa-arrow-circle-o-down" title="Download this attachment" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</t>
|
|
||||||
<div class="caption">
|
|
||||||
<a t-att-href='attachment.url' target="_blank">
|
|
||||||
<t t-esc='attachment.name'/>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
<t t-if="editable">
|
|
||||||
<div class="o_attachment_delete">
|
|
||||||
<i class='fa fa-times-circle' title="Delete this attachment" t-att-data-id="attachment.id"/>
|
|
||||||
</div>
|
|
||||||
<div class="o_attachment_progress_bar">
|
|
||||||
Uploading
|
|
||||||
</div>
|
|
||||||
</t>
|
|
||||||
</div>
|
</div>
|
||||||
</t>
|
</t>
|
||||||
|
|
||||||
|
|||||||
@@ -684,7 +684,7 @@ QUnit.test('chatter: Attachment viewer', function (assert) {
|
|||||||
});
|
});
|
||||||
assert.strictEqual(form.$('.o_thread_message .o_attachment').length, 4,
|
assert.strictEqual(form.$('.o_thread_message .o_attachment').length, 4,
|
||||||
"there should be three attachment on message");
|
"there should be three attachment on message");
|
||||||
assert.strictEqual(form.$('.o_thread_message .o_attachment .caption a').first().attr('href'), '/web/content/1?download=true',
|
assert.strictEqual(form.$('.o_thread_message .o_attachment a').first().attr('href'), '/web/content/1?download=true',
|
||||||
"image caption should have correct download link");
|
"image caption should have correct download link");
|
||||||
// click on first image attachement
|
// click on first image attachement
|
||||||
form.$('.o_thread_message .o_attachment .o_image_box .o_image_overlay').first().click();
|
form.$('.o_thread_message .o_attachment .o_image_box .o_image_overlay').first().click();
|
||||||
@@ -699,7 +699,7 @@ QUnit.test('chatter: Attachment viewer', function (assert) {
|
|||||||
// close attachment popup
|
// close attachment popup
|
||||||
$('.o_modal_fullscreen .o_viewer-header .o_close_btn').click();
|
$('.o_modal_fullscreen .o_viewer-header .o_close_btn').click();
|
||||||
// click on pdf attachement
|
// click on pdf attachement
|
||||||
form.$('.o_thread_message .o_attachment .o_image_box .o_image_overlay').eq(3).click();
|
form.$('span:contains(Test PDF 1)').click();
|
||||||
assert.strictEqual($('.o_modal_fullscreen iframe[data-src*="/web/content/4"]').length, 1,
|
assert.strictEqual($('.o_modal_fullscreen iframe[data-src*="/web/content/4"]').length, 1,
|
||||||
"Modal popup should open with the pdf preview");
|
"Modal popup should open with the pdf preview");
|
||||||
// close attachment popup
|
// close attachment popup
|
||||||
|
|||||||
Reference in New Issue
Block a user