Skip to content

Commit b7f83ed

Browse files
committed
[MIG] attachment_preview: Migration to 18.0
Increased code coverage Changed layout of attachment_preview buttons Updates Minor updates
1 parent ba7e2f5 commit b7f83ed

File tree

18 files changed

+473
-787
lines changed

18 files changed

+473
-787
lines changed

attachment_preview/README.rst

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -89,14 +89,6 @@ Contributors
8989
- Holger Brunn <mail@hunki-enterprises.com>
9090
- Dennis Sluijk <d.sluijk@onestein.nl>
9191

92-
Other credits
93-
-------------
94-
95-
Addon icon
96-
~~~~~~~~~~
97-
98-
- courtesy of http://commons.wikimedia.org/wiki/Crystal_Clear
99-
10092
Maintainers
10193
-----------
10294

attachment_preview/__manifest__.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
{
55
"name": "Preview attachments",
6-
"version": "15.0.1.0.0",
6+
"version": "18.0.1.0.0",
77
"author": "Therp BV," "Onestein," "Odoo Community Association (OCA)",
88
"website": "https://github.com/OCA/knowledge",
99
"license": "AGPL-3",
@@ -15,15 +15,16 @@
1515
"assets": {
1616
"web._assets_primary_variables": [],
1717
"web.assets_backend": [
18-
"attachment_preview/static/src/js/models/attachment_card/attachment_card.esm.js",
1918
"attachment_preview/static/src/js/attachmentPreviewWidget.esm.js",
20-
"attachment_preview/static/src/js/components/chatter/chatter.esm.js",
19+
"attachment_preview/static/src/js/utils.esm.js",
20+
"attachment_preview/static/src/js/mail_core/attachment_list.esm.js",
21+
"attachment_preview/static/src/js/web_views/fields/binary_field.esm.js",
22+
"attachment_preview/static/src/js/web_views/form/form_compiler.esm.js",
23+
"attachment_preview/static/src/js/web_views/form/form_controller.esm.js",
24+
"attachment_preview/static/src/js/web_views/form/form_renderer.esm.js",
2125
"attachment_preview/static/src/scss/attachment_preview.scss",
26+
"attachment_preview/static/src/xml/attachment_preview.xml",
2227
],
23-
"web.assets_frontend": [],
24-
"web.assets_tests": [],
25-
"web.qunit_suite_tests": [],
26-
"web.assets_qweb": ["attachment_preview/static/src/xml/attachment_preview.xml"],
2728
},
2829
"installable": True,
2930
}

attachment_preview/models/ir_attachment.py

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ def get_binary_extension(self, model, ids, binary_field, filename_field=None):
2525
for this in (
2626
self.env[model].with_context(bin_size=True).browse(ids_to_browse)
2727
):
28-
result[this.id] = False
2928
extension = ""
30-
if this[filename_field]:
29+
if hasattr(this, filename_field) and this[filename_field]:
3130
filename, extension = os.path.splitext(this[filename_field])
3231
if this[binary_field] and extension:
3332
result[this.id] = extension
@@ -41,28 +40,32 @@ def get_binary_extension(self, model, ids, binary_field, filename_field=None):
4140
ids_to_browse = [_id for _id in ids_to_browse if _id not in result]
4241
for this in self.env[model].with_context(bin_size=True).browse(ids_to_browse):
4342
result[this.id] = False
43+
mimetype = False
4444
try:
4545
import magic
4646

47-
if model == self._name and binary_field == "datas" and this.store_fname:
47+
if (
48+
model == self._name and binary_field == "datas" and this.store_fname
49+
): # pragma: no cover
4850
mimetype = magic.from_file(
4951
this._full_path(this.store_fname), mime=True
5052
)
51-
# _logger.debug(
52-
# "Magic determined mimetype %s from file %s",
53-
# mimetype,
54-
# this.store_fname
55-
# )
56-
else:
53+
else: # pragma: no cover
5754
mimetype = magic.from_buffer(this[binary_field], mime=True)
5855
_logger.debug("Magic determined mimetype %s from buffer", mimetype)
59-
except ImportError:
60-
(mimetype, encoding) = mimetypes.guess_type(
61-
"data:;base64," + this[binary_field].decode("utf-8"), strict=False
56+
except (ImportError, Exception):
57+
try:
58+
(mimetype, encoding) = mimetypes.guess_type(
59+
"data:;base64," + this[binary_field].decode("utf-8"),
60+
strict=False,
61+
)
62+
except Exception as e:
63+
_logger.debug("Error when guessing mimetype: %s", str(e))
64+
if mimetype:
65+
extension = mimetypes.guess_extension(
66+
mimetype.split(";")[0], strict=False
6267
)
63-
# _logger.debug("Mimetypes guessed type %s from buffer", mimetype)
64-
extension = mimetypes.guess_extension(mimetype.split(";")[0], strict=False)
65-
result[this.id] = extension
68+
result[this.id] = extension
6669
for _id in result:
6770
result[_id] = (result[_id] or "").lstrip(".").lower()
6871
return result if isinstance(ids, collections.abc.Iterable) else result[ids]

attachment_preview/readme/CREDITS.md

Lines changed: 0 additions & 3 deletions
This file was deleted.

attachment_preview/static/description/index.html

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -383,11 +383,7 @@ <h1 class="title">Preview attachments</h1>
383383
<li><a class="reference internal" href="#credits" id="toc-entry-4">Credits</a><ul>
384384
<li><a class="reference internal" href="#authors" id="toc-entry-5">Authors</a></li>
385385
<li><a class="reference internal" href="#contributors" id="toc-entry-6">Contributors</a></li>
386-
<li><a class="reference internal" href="#other-credits" id="toc-entry-7">Other credits</a><ul>
387-
<li><a class="reference internal" href="#addon-icon" id="toc-entry-8">Addon icon</a></li>
388-
</ul>
389-
</li>
390-
<li><a class="reference internal" href="#maintainers" id="toc-entry-9">Maintainers</a></li>
386+
<li><a class="reference internal" href="#maintainers" id="toc-entry-7">Maintainers</a></li>
391387
</ul>
392388
</li>
393389
</ul>
@@ -432,17 +428,8 @@ <h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
432428
<li>Dennis Sluijk &lt;<a class="reference external" href="mailto:d.sluijk&#64;onestein.nl">d.sluijk&#64;onestein.nl</a>&gt;</li>
433429
</ul>
434430
</div>
435-
<div class="section" id="other-credits">
436-
<h2><a class="toc-backref" href="#toc-entry-7">Other credits</a></h2>
437-
<div class="section" id="addon-icon">
438-
<h3><a class="toc-backref" href="#toc-entry-8">Addon icon</a></h3>
439-
<ul class="simple">
440-
<li>courtesy of <a class="reference external" href="http://commons.wikimedia.org/wiki/Crystal_Clear">http://commons.wikimedia.org/wiki/Crystal_Clear</a></li>
441-
</ul>
442-
</div>
443-
</div>
444431
<div class="section" id="maintainers">
445-
<h2><a class="toc-backref" href="#toc-entry-9">Maintainers</a></h2>
432+
<h2><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h2>
446433
<p>This module is maintained by the OCA.</p>
447434
<a class="reference external image-reference" href="https://odoo-community.org">
448435
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
Lines changed: 73 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,104 @@
1-
/** @odoo-module */
2-
import Widget from "web.Widget";
3-
4-
var active_attachment_index = 0;
5-
var is_first_click = true;
6-
7-
var AttachmentPreviewWidget = Widget.extend({
8-
template: "attachment_preview.AttachmentPreviewWidget",
9-
activeIndex: 0,
10-
11-
events: {
12-
"click .attachment_preview_close": "_onCloseClick",
13-
"click .attachment_preview_previous": "_onPreviousClick",
14-
"click .attachment_preview_next": "_onNextClick",
15-
"click .attachment_preview_popout": "_onPopoutClick",
16-
},
17-
18-
start: function () {
19-
// First_click = true;
20-
var res = this._super.apply(this, arguments);
21-
this.$overlay = $(".attachment_preview_overlay");
22-
this.$iframe = $(".attachment_preview_iframe");
23-
this.$current = $(".attachment_preview_current");
24-
return res;
25-
},
26-
27-
_onCloseClick: function () {
1+
import {Component, onWillStart, useRef, useState} from "@odoo/owl";
2+
import {ensureJQuery} from "@web/core/ensure_jquery";
3+
import {sprintf} from "@web/core/utils/strings";
4+
5+
export class AttachmentPreviewWidget extends Component {
6+
static template = "attachment_preview.AttachmentPreviewWidget";
7+
static props = {};
8+
setup() {
9+
super.setup();
10+
Component.env.bus.addEventListener(
11+
"open_attachment_preview",
12+
({detail: {attachment_id, attachment_info_list}}) =>
13+
this._onAttachmentPreview(attachment_id, attachment_info_list)
14+
);
15+
Component.env.bus.addEventListener("hide_attachment_preview", this.hide);
16+
this.state = useState({activeIndex: 0});
17+
this.currentRef = useRef("current");
18+
this.iframeRef = useRef("iframe");
19+
onWillStart(async () => {
20+
await ensureJQuery();
21+
});
22+
}
23+
24+
_onCloseClick() {
2825
this.hide();
29-
},
26+
}
3027

31-
_onPreviousClick: function () {
28+
_onPreviousClick() {
3229
this.previous();
33-
},
30+
}
3431

35-
_onNextClick: function () {
32+
_onNextClick() {
3633
this.next();
37-
},
34+
}
3835

39-
_onPopoutClick: function () {
40-
if (!this.attachments[this.activeIndex]) {
41-
return;
42-
}
36+
_onPopoutClick() {
37+
if (!this.attachments[this.state.activeIndex]) return;
38+
// eslint-disable-next-line no-undef
39+
window.open(this.attachments[this.state.activeIndex].previewUrl);
40+
}
4341

44-
window.open(this.attachments[this.activeIndex].previewUrl);
45-
},
46-
47-
next: function () {
48-
if (is_first_click) {
49-
is_first_click = !is_first_click;
50-
}
51-
var index = this.activeIndex + 1;
42+
next() {
43+
var index = this.state.activeIndex + 1;
5244
if (index >= this.attachments.length) {
5345
index = 0;
5446
}
55-
this.activeIndex = index;
47+
this.state.activeIndex = index;
5648
this.updatePaginator();
5749
this.loadPreview();
58-
},
50+
}
5951

60-
previous: function () {
61-
if (is_first_click) {
62-
is_first_click = !is_first_click;
63-
}
64-
var index = this.activeIndex - 1;
52+
previous() {
53+
var index = this.state.activeIndex - 1;
6554
if (index < 0) {
6655
index = this.attachments.length - 1;
6756
}
68-
this.activeIndex = index;
57+
this.state.activeIndex = index;
6958
this.updatePaginator();
7059
this.loadPreview();
71-
},
60+
}
7261

73-
show: function () {
74-
this.$el.removeClass("d-none");
75-
this.trigger("shown");
76-
},
62+
show() {
63+
$(".attachment_preview_widget").removeClass("d-none");
64+
}
7765

78-
hide: function () {
79-
is_first_click = true;
80-
this.$el.addClass("d-none");
81-
this.trigger("hidden");
82-
},
66+
hide() {
67+
$(".attachment_preview_widget").addClass("d-none");
68+
}
8369

84-
updatePaginator: function () {
85-
var value = _.str.sprintf(
70+
updatePaginator() {
71+
var value = sprintf(
8672
"%s / %s",
87-
this.activeIndex + 1,
73+
this.state.activeIndex + 1,
8874
this.attachments.length
8975
);
90-
this.$overlay = $(".attachment_preview_overlay");
91-
this.$iframe = $(".attachment_preview_iframe");
92-
this.$current = $(".attachment_preview_current");
93-
this.$current.html(value);
94-
},
76+
$(this.currentRef.el).html(value);
77+
}
9578

96-
loadPreview: function () {
79+
loadPreview() {
9780
if (this.attachments.length === 0) {
98-
this.$iframe.attr("src", "about:blank");
81+
$(this.iframeRef.el).attr("src", "about:blank");
9982
return;
10083
}
101-
102-
if (is_first_click) {
103-
for (let i = 0; i < this.attachments.length; i++) {
104-
if (
105-
parseInt(this.attachments[i].id, 10) === this.active_attachment_id
106-
) {
107-
active_attachment_index = i;
108-
is_first_click = false;
109-
}
84+
var att = this.attachments[this.state.activeIndex];
85+
$(this.iframeRef.el).attr("src", att.previewUrl);
86+
}
87+
88+
setAttachments(attachments, active_attachment_id) {
89+
this.attachments = attachments;
90+
if (!attachments) return;
91+
for (let i = 0; i < attachments.length; ++i) {
92+
if (parseInt(attachments[i].id, 10) === active_attachment_id) {
93+
this.state.activeIndex = i;
11094
}
111-
} else {
112-
active_attachment_index = this.activeIndex;
11395
}
96+
this.updatePaginator();
97+
this.loadPreview();
98+
}
11499

115-
var att = this.attachments[active_attachment_index];
116-
this.$iframe.attr("src", att.previewUrl);
117-
},
118-
119-
setAttachments: function (attachments, active_attachment_id, first_click) {
120-
is_first_click = first_click;
121-
122-
if (active_attachment_id) {
123-
this.active_attachment_id = active_attachment_id;
124-
}
125-
if (attachments) {
126-
this.attachments = attachments;
127-
this.activeIndex = 0;
128-
this.updatePaginator();
129-
this.loadPreview();
130-
}
131-
},
132-
});
133-
134-
export default AttachmentPreviewWidget;
100+
_onAttachmentPreview(attachment_id, attachment_info_list) {
101+
this.setAttachments(attachment_info_list, attachment_id);
102+
this.show();
103+
}
104+
}

0 commit comments

Comments
 (0)