summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--addons/mail/static/src/scss/composer.scss106
-rw-r--r--addons/web/static/src/js/fields/relational_fields.js4
-rw-r--r--addons/web/static/src/scss/attachment_preview.scss113
-rw-r--r--addons/web/static/src/scss/form_view.scss13
-rw-r--r--addons/web/static/src/xml/base.xml63
-rw-r--r--addons/web/static/tests/fields/relational_fields_tests.js9
-rw-r--r--addons/web/views/webclient_templates.xml1
7 files changed, 159 insertions, 150 deletions
diff --git a/addons/mail/static/src/scss/composer.scss b/addons/mail/static/src/scss/composer.scss
index 75c62bbeae0..3eae93b03cd 100644
--- a/addons/mail/static/src/scss/composer.scss
+++ b/addons/mail/static/src/scss/composer.scss
@@ -284,116 +284,12 @@
}
// Attachment Icons (common for chat thread and chat composer)
-// ------------------------------------------------------------------
-$o-mail-attachment-image-size: 38px;
-$o-mail-attachment-margin: 5px;
-
.o_attachments_list, .o_attachments_previews {
- margin: 0 (-$o-mail-attachment-margin) 0;
+ margin: 0 (-$o-attachment-margin) 0;
display: flex;
flex-flow: row wrap;
}
-.o_attachment {
- position: relative;
- width: 100%;
- padding: $o-mail-attachment-margin;
-
- @include media-breakpoint-up(md) {
- width: 50%;
- }
- @include media-breakpoint-up(lg) {
- width: 25%;
- }
-
- .o_attachment_wrap {
- overflow: hidden;
- position: relative;
- border-bottom: 1px solid rgba(black, 0.1);
- border-radius: 2px;
- padding: 4px 6px 0 4px;
- background-color: rgba(black, 0.05);
-
- .o_attachment_delete_cross {
- float: right;
- cursor: pointer;
- }
- }
-
- &.o_attachment_editable .o_attachment_wrap {
- padding-right: 40px;
- }
-
- .o_image {
- width: $o-mail-attachment-image-size;
- height: $o-mail-attachment-image-size;
- image-orientation: from-image; // Only supported in Firefox
- &.o_hover {
- @include o-hover-opacity($default-opacity: 1, $hover-opacity: 0.7);
- }
- }
-
- .o_attachment_view {
- cursor: zoom-in;
- }
-
- .caption {
- @include o-text-overflow(block);
-
- a {
- @include o-hover-text-color($default-color: $o-main-text-color, $hover-color: $headings-color);
- }
- }
-
- .o_attachment_progress_bar {
- display: none;
- }
-
- .o_attachment_uploaded, .o_attachment_delete {
- @include o-position-absolute(0, 0, 0, $left: auto);
- display: flex;
- align-items: center;
- justify-content: center;
- width: 45px;
- }
-
- .o_attachment_delete {
- background: desaturate(theme-color('primary'), 50%);
- color: white;
- cursor: pointer;
- font-size: 20px;
- transform: translateX(100%);
- transition: all 0.3s ease 0s;
-
- &:hover {
- background: theme-color('primary');
- }
- }
-
- &.o_attachment_uploading {
- .o_attachment_progress_bar {
- display: inline-block;
- margin: 0 0 0 8px;
- border-radius: 2px;
- vertical-align: bottom;
-
- > div {
- font-size: 11px;
- padding: 0 7px;
- }
- }
-
- .o_attachment_delete, .o_attachment_uploaded {
- display: none;
- }
- }
-
- &:hover .o_attachment_delete {
- transition: all 0.1s ease 0s;
- transform: translateX(0);
- }
-}
-
.o_attachments_previews {
> .o_attachment {
width: 50%;
diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js
index 0f247ba3a8d..642fa55b33e 100644
--- a/addons/web/static/src/js/fields/relational_fields.js
+++ b/addons/web/static/src/js/fields/relational_fields.js
@@ -1752,7 +1752,7 @@ var FieldMany2ManyBinaryMultiFiles = AbstractField.extend({
},
events: {
'click .o_attach': '_onAttach',
- 'click .oe_delete': '_onDelete',
+ 'click .o_attachment_delete': '_onDelete',
'change .o_input_file': '_onFileChanged',
},
/**
@@ -1817,7 +1817,7 @@ var FieldMany2ManyBinaryMultiFiles = AbstractField.extend({
// render the attachments ; as the attachments will changes after each
// _setValue, we put the rendering here to ensure they will be updated
this._generatedMetadata();
- this.$('.oe_placeholder_files, .oe_attachments')
+ this.$('.oe_placeholder_files, .o_attachments')
.replaceWith($(qweb.render(this.template_files, {
widget: this,
})));
diff --git a/addons/web/static/src/scss/attachment_preview.scss b/addons/web/static/src/scss/attachment_preview.scss
new file mode 100644
index 00000000000..eca2527f523
--- /dev/null
+++ b/addons/web/static/src/scss/attachment_preview.scss
@@ -0,0 +1,113 @@
+// Attachment Icons (common for many2many_binary widget and chat thread and chat composer)
+// ------------------------------------------------------------------
+$o-attachment-image-size: 38px;
+$o-attachment-margin: 5px;
+
+.o_attachment {
+ position: relative;
+ width: 100%;
+ padding: $o-attachment-margin;
+
+ @include media-breakpoint-up(md) {
+ width: 50%;
+ }
+ @include media-breakpoint-up(lg) {
+ width: 25%;
+ }
+ // many2many_binary widget for send mail with attachment
+ &.o_attachment_many2many {
+ @include media-breakpoint-up(md) {
+ width: 50%;
+ }
+ @include media-breakpoint-up(lg) {
+ width: 62%;
+ }
+ }
+
+ .o_attachment_wrap {
+ overflow: hidden;
+ position: relative;
+ border-bottom: 1px solid rgba(black, 0.1);
+ border-radius: 2px;
+ padding: 4px 6px 0 4px;
+ background-color: rgba(black, 0.05);
+
+ .o_attachment_delete_cross {
+ float: right;
+ cursor: pointer;
+ }
+ }
+
+ &.o_attachment_editable .o_attachment_wrap {
+ padding-right: 40px;
+ }
+
+ .o_image {
+ width: $o-attachment-image-size;
+ height: $o-attachment-image-size;
+ image-orientation: from-image; // Only supported in Firefox
+ &.o_hover {
+ @include o-hover-opacity($default-opacity: 1, $hover-opacity: 0.7);
+ }
+ }
+
+ .o_attachment_view {
+ cursor: zoom-in;
+ }
+
+ .caption {
+ @include o-text-overflow(block);
+
+ a {
+ @include o-hover-text-color($default-color: $o-main-text-color, $hover-color: $headings-color);
+ }
+ }
+
+ .o_attachment_progress_bar {
+ display: none;
+ }
+
+ .o_attachment_uploaded, .o_attachment_delete {
+ @include o-position-absolute(0, 0, 0, $left: auto);
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 45px;
+ }
+
+ .o_attachment_delete {
+ background: desaturate(theme-color('primary'), 50%);
+ color: white;
+ cursor: pointer;
+ font-size: 20px;
+ transform: translateX(100%);
+ transition: all 0.3s ease 0s;
+
+ &:hover {
+ background: theme-color('primary');
+ }
+ }
+
+ &.o_attachment_uploading {
+ .o_attachment_progress_bar {
+ display: inline-block;
+ margin: 0 0 0 8px;
+ border-radius: 2px;
+ vertical-align: bottom;
+
+ > div {
+ font-size: 11px;
+ padding: 0 7px;
+ }
+ }
+
+ .o_attachment_delete, .o_attachment_uploaded {
+ display: none;
+ }
+ }
+
+ &:hover .o_attachment_delete {
+ transition: all 0.1s ease 0s;
+ transform: translateX(0);
+ }
+}
diff --git a/addons/web/static/src/scss/form_view.scss b/addons/web/static/src/scss/form_view.scss
index bf909bc915e..8bcaba31ee3 100644
--- a/addons/web/static/src/scss/form_view.scss
+++ b/addons/web/static/src/scss/form_view.scss
@@ -574,19 +574,6 @@
display: none; // Hide the handler on readonly fields
}
- // Attachments
- .oe_attachment {
- display: inline-block;
- border: 1px solid $o-brand-lightsecondary;
- margin: 0 $o-form-spacing-unit $o-form-spacing-unit 0;
- padding: $o-form-spacing-unit;
- width:45%;
- background-color: rgba(black, 0.05);
- .caption {
- @include o-text-overflow(block);
- }
- }
-
&.oe_form_configuration {
.o_group .o_form_label {
white-space: nowrap;
diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml
index f2b7c9653c6..6d00f21ab6f 100644
--- a/addons/web/static/src/xml/base.xml
+++ b/addons/web/static/src/xml/base.xml
@@ -1089,33 +1089,46 @@
</t>
</div>
</div>
-<div t-name="FieldBinaryFileUploader.files" class="oe_attachments" aria-atomic="true">
- <t t-if="widget.mode === 'readonly'">
- <div t-foreach="widget.value.data" t-as="file">
- <a target="_blank" t-att-href="widget.metadata[file.id].url" t-attf-title="#{(file.data.name || file.data.filename) + (file.data.date?' \n('+file.data.date+')':'' )}"><t t-raw="file.data.name || file.data.filename"/></a>
- </div>
- </t>
- <t t-else="1">
- <div t-foreach="widget.value.data" t-as="file" class="oe_attachment">
- <t t-if="!file.data.upload">
- <div>
- <a href="#" class="fa fa-times float-right oe_delete" title="Delete this file" aria-label="Delete this file" t-att-data-id="file.data.id"/>
- <div class="caption"><t t-raw="file.data.name || file.data.filename"/></div>
+
+<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'"/>
+ <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">
+ <t t-set="ext" t-value="file.name.replace(/^.*\./, '')"/>
+ <div class="o_image_box float-left" t-att-data-id="file.id">
+ <a t-att-href="url" t-att-title="'Download ' + file.name" aria-label="Download">
+ <span class="o_image o_hover" t-att-data-mimetype="mimetype" t-att-data-ext="ext" role="img"/>
+ </a>
+ </div>
+
+ <div class="caption">
+ <a class="ml4" t-att-href="url" t-att-title="'Download ' + file.name"><t t-esc='file.name'/></a>
+ </div>
+ <div class="caption small">
+ <a class="ml4 small text-uppercase" t-att-href="url" t-att-title="'Download ' + file.name"><b><t t-esc='ext'/></b></a>
+ <div t-if="editable" class="progress o_attachment_progress_bar">
+ <div class="progress-bar progress-bar-striped active" style="width: 100%">Uploading</div>
</div>
- <a class="o_image" target="_blank" t-att-href="widget.metadata[file.id] ? widget.metadata[file.id].url : false"
- t-att-title="file.data.name"
- t-att-aria-label="file.data.name"
- t-att-data-mimetype="file.data.mimetype"
- t-attf-data-src="/web/image/#{file.data.id}/100x80"/>
- </t>
- </div>
- <div t-foreach="widget.uploadingFiles" t-as="file" class="oe_attachment">
- <div>Uploading...</div>
- <a t-att-title="file.name" t-att-aria-label="file.name" t-att-name="file.name" class="o_image">
- <i class="fa fa-spinner fa-spin fa-5x fa-fw" role="img" aria-label="Loading, please wait..." title="Loading, please wait..."></i>
- </a>
- <div><t t-esc="file.name"/></div>
+ </div>
+
+ <div t-if="editable" class="o_attachment_uploaded"><i class="text-success fa fa-check" role="img" aria-label="Uploaded" title="Uploaded"/></div>
+ <div t-if="editable" class="o_attachment_delete" t-att-data-id="file.id"><span class="text-white" role="img" aria-label="Delete" title="Delete">×</span></div>
</div>
+ </div>
+</t>
+
+<div t-name="FieldBinaryFileUploader.files" class="o_attachments" aria-atomic="true">
+ <!-- uploaded files -->
+ <t t-foreach="widget.value.data" t-as="file">
+ <t t-if="!file.data.upload" t-call="FieldBinaryFileUploader.attachment_preview"/>
+ </t>
+ <!-- uploading files -->
+ <t t-foreach="widget.uploadingFiles" t-as="file">
+ <t t-set="upload" t-value="true"/>
+ <t t-call="FieldBinaryFileUploader.attachment_preview"/>
</t>
</div>
diff --git a/addons/web/static/tests/fields/relational_fields_tests.js b/addons/web/static/tests/fields/relational_fields_tests.js
index 406370b0a2b..6f72b827cae 100644
--- a/addons/web/static/tests/fields/relational_fields_tests.js
+++ b/addons/web/static/tests/fields/relational_fields_tests.js
@@ -2253,11 +2253,11 @@ QUnit.module('relational_fields', {
assert.containsOnce(form, 'div.o_field_widget.oe_fileupload',
"there should be the attachment widget");
- assert.strictEqual(form.$('div.o_field_widget.oe_fileupload .oe_attachments').children().length, 1,
+ assert.strictEqual(form.$('div.o_field_widget.oe_fileupload .o_attachments').children().length, 1,
"there should be no attachment");
assert.containsNone(form, 'div.o_field_widget.oe_fileupload .o_attach',
"there should not be an Add button (readonly)");
- assert.containsNone(form, 'div.o_field_widget.oe_fileupload .oe_attachment .oe_delete',
+ assert.containsNone(form, 'div.o_field_widget.oe_fileupload .o_attachment .o_attachment_delete',
"there should not be a Delete button (readonly)");
// to edit mode
@@ -2273,8 +2273,7 @@ QUnit.module('relational_fields', {
// no idea how to test this
// delete the attachment
- await testUtils.dom.click(form.$('div.o_field_widget.oe_fileupload .oe_attachment .oe_delete'));
-
+ await testUtils.dom.click(form.$('div.o_field_widget.oe_fileupload .o_attachment .o_attachment_delete'));
assert.verifySteps([
'/web/dataset/call_kw/turtle/read',
@@ -2283,7 +2282,7 @@ QUnit.module('relational_fields', {
await testUtils.form.clickSave(form);
- assert.strictEqual(form.$('div.o_field_widget.oe_fileupload .oe_attachments').children().length, 0,
+ assert.strictEqual(form.$('div.o_field_widget.oe_fileupload .o_attachments').children().length, 0,
"there should be no attachment");
assert.verifySteps([
diff --git a/addons/web/views/webclient_templates.xml b/addons/web/views/webclient_templates.xml
index 5e5a19a85ba..47ab9a9af15 100644
--- a/addons/web/views/webclient_templates.xml
+++ b/addons/web/views/webclient_templates.xml
@@ -185,6 +185,7 @@
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/search_view_extra.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/data_export.scss"/>
<link rel="stylesheet" type="text/scss" href="/base/static/src/scss/onboarding.scss"/>
+ <link rel="stylesheet" type="text/scss" href="/web/static/src/scss/attachment_preview.scss"/>
<link rel="stylesheet" type="text/scss" href="/web/static/src/scss/base_settings.scss"/>
<script type="text/javascript" src="/base/static/src/js/res_config_settings.js"></script>