diff --git a/addons/mail/static/src/attachments/attachment_list.js b/addons/mail/static/src/attachments/attachment_list.js
index 2365359eb4f..827d315ac7e 100644
--- a/addons/mail/static/src/attachments/attachment_list.js
+++ b/addons/mail/static/src/attachments/attachment_list.js
@@ -5,7 +5,7 @@ import { Component } from "@odoo/owl";
import { ConfirmationDialog } from "@web/core/confirmation_dialog/confirmation_dialog";
import { useService } from "@web/core/utils/hooks";
import { sprintf } from "@web/core/utils/strings";
-import { useAttachmentViewer } from "@web/core/attachment_viewer/attachment_viewer_hook";
+import { useFileViewer } from "@web/core/file_viewer/file_viewer_hook";
import { _t } from "@web/core/l10n/translation";
import { url } from "@web/core/utils/urls";
@@ -25,7 +25,7 @@ export class AttachmentList extends Component {
// Arbitrary high value, this is effectively a max-width.
this.imagesWidth = 1920;
this.dialog = useService("dialog");
- this.attachmentViewer = useAttachmentViewer();
+ this.fileViewer = useFileViewer();
}
/**
diff --git a/addons/mail/static/src/attachments/attachment_list.xml b/addons/mail/static/src/attachments/attachment_list.xml
index 13ec8c3b765..c71a8c35f22 100644
--- a/addons/mail/static/src/attachments/attachment_list.xml
+++ b/addons/mail/static/src/attachments/attachment_list.xml
@@ -19,7 +19,7 @@
aria-label="View image"
role="menuitem"
t-att-data-mimetype="attachment.mimetype"
- t-on-click="() => this.attachmentViewer.open(attachment, props.attachments)"
+ t-on-click="() => this.fileViewer.open(attachment, props.attachments)"
>
diff --git a/addons/mail/static/src/attachments/attachment_view.scss b/addons/mail/static/src/attachments/attachment_view.scss
index b24db8e0eb7..259eca6f276 100644
--- a/addons/mail/static/src/attachments/attachment_view.scss
+++ b/addons/mail/static/src/attachments/attachment_view.scss
@@ -13,7 +13,7 @@
.arrow {
width: 5%;
@include o-position-absolute(50%, 0);
- @include o-AttachmentViewer-arrow;
+ @include o-FileViewer-arrow;
transition: width 0.3s;
padding-top: 30px;
height: 75px;
diff --git a/addons/mail/static/src/core_ui/primary_variables.scss b/addons/mail/static/src/core_ui/primary_variables.scss
index 9c214c79448..88cb5851a9e 100644
--- a/addons/mail/static/src/core_ui/primary_variables.scss
+++ b/addons/mail/static/src/core_ui/primary_variables.scss
@@ -15,7 +15,7 @@ $o-mail-Chatter-minWidth: 530px !default;
$o-mail-Discuss-inspector: 250px !default;
$o-mail-Discuss-headerHeight: 48px !default;
-@mixin o-AttachmentViewer-arrow {
+@mixin o-FileViewer-arrow {
background-color: rgba(black, 0.4);
color: rgba(map-get($theme-colors, 'light'), 0.7);
diff --git a/addons/mail/static/src/scss/composer.scss b/addons/mail/static/src/scss/composer.scss
index 0e7a5c0550f..261b7a5ac7e 100644
--- a/addons/mail/static/src/scss/composer.scss
+++ b/addons/mail/static/src/scss/composer.scss
@@ -27,7 +27,7 @@
@include o-position-absolute(50%, $grid-gutter-width*0.5);
border-radius: 100%;
padding: 12px 16px 11px 18px;
- @include o-AttachmentViewer-arrow;
+ @include o-FileViewer-arrow;
}
.arrow-left {
diff --git a/addons/mail/static/src/views/form/form_compiler.js b/addons/mail/static/src/views/form/form_compiler.js
index b460cf96eb8..70b648ea0fc 100644
--- a/addons/mail/static/src/views/form/form_compiler.js
+++ b/addons/mail/static/src/views/form/form_compiler.js
@@ -109,12 +109,12 @@ patch(FormCompiler.prototype, "mail", {
if (webClientViewAttachmentViewHookXml) {
// in sheet bg (attachment viewer present)
setAttributes(webClientViewAttachmentViewHookXml, {
- "t-if": `__comp__.hasAttachmentViewer() and __comp__.uiService.size >= ${SIZES.XXL}`,
+ "t-if": `__comp__.hasFileViewer() and __comp__.uiService.size >= ${SIZES.XXL}`,
});
const sheetBgChatterContainerHookXml = chatterContainerHookXml.cloneNode(true);
sheetBgChatterContainerHookXml.classList.add("o-isInFormSheetBg");
setAttributes(sheetBgChatterContainerHookXml, {
- "t-if": `__comp__.hasAttachmentViewer() and __comp__.uiService.size >= ${SIZES.XXL}`,
+ "t-if": `__comp__.hasFileViewer() and __comp__.uiService.size >= ${SIZES.XXL}`,
});
append(formSheetBgXml, sheetBgChatterContainerHookXml);
const sheetBgChatterContainerXml = sheetBgChatterContainerHookXml.querySelector(
@@ -128,12 +128,12 @@ patch(FormCompiler.prototype, "mail", {
// after sheet bg (standard position, either aside or below)
if (webClientViewAttachmentViewHookXml) {
setAttributes(chatterContainerHookXml, {
- "t-if": `!(__comp__.hasAttachmentViewer() and __comp__.uiService.size >= ${SIZES.XXL})`,
- "t-attf-class": `{{ __comp__.uiService.size >= ${SIZES.XXL} and !(__comp__.hasAttachmentViewer() and __comp__.uiService.size >= ${SIZES.XXL}) ? "o-aside" : "" }}`,
+ "t-if": `!(__comp__.hasFileViewer() and __comp__.uiService.size >= ${SIZES.XXL})`,
+ "t-attf-class": `{{ __comp__.uiService.size >= ${SIZES.XXL} and !(__comp__.hasFileViewer() and __comp__.uiService.size >= ${SIZES.XXL}) ? "o-aside" : "" }}`,
});
setAttributes(chatterContainerXml, {
- isInFormSheetBg: "__comp__.hasAttachmentViewer()",
- hasMessageListScrollAdjust: `__comp__.uiService.size >= ${SIZES.XXL} and !(__comp__.hasAttachmentViewer() and __comp__.uiService.size >= ${SIZES.XXL})`,
+ isInFormSheetBg: "__comp__.hasFileViewer()",
+ hasMessageListScrollAdjust: `__comp__.uiService.size >= ${SIZES.XXL} and !(__comp__.hasFileViewer() and __comp__.uiService.size >= ${SIZES.XXL})`,
});
} else {
setAttributes(chatterContainerXml, {
diff --git a/addons/mail/static/src/views/form/form_renderer.js b/addons/mail/static/src/views/form/form_renderer.js
index 0648f0dd0f4..3750b27f311 100644
--- a/addons/mail/static/src/views/form/form_renderer.js
+++ b/addons/mail/static/src/views/form/form_renderer.js
@@ -33,7 +33,7 @@ patch(FormRenderer.prototype, "mail", {
/**
* @returns {boolean}
*/
- hasAttachmentViewer() {
+ hasFileViewer() {
if (!this.threadService || this.uiService.size < SIZES.XXL || !this.props.record.resId) {
return false;
}
diff --git a/addons/mail/static/tests/thread/attachment_list_tests.js b/addons/mail/static/tests/thread/attachment_list_tests.js
index f11a0759ad1..c73dc9e47ec 100644
--- a/addons/mail/static/tests/thread/attachment_list_tests.js
+++ b/addons/mail/static/tests/thread/attachment_list_tests.js
@@ -115,7 +115,7 @@ QUnit.test("view attachment", async (assert) => {
await openDiscuss(channelId);
assert.containsOnce($, ".o-mail-AttachmentImage img");
await click(".o-mail-AttachmentImage");
- assert.containsOnce($, ".o-AttachmentViewer");
+ assert.containsOnce($, ".o-FileViewer");
});
QUnit.test("close attachment viewer", async (assert) => {
@@ -140,10 +140,10 @@ QUnit.test("close attachment viewer", async (assert) => {
assert.containsOnce($, ".o-mail-AttachmentImage img");
await click(".o-mail-AttachmentImage");
- assert.containsOnce($, ".o-AttachmentViewer");
+ assert.containsOnce($, ".o-FileViewer");
- await click(".o-AttachmentViewer div[aria-label='Close']");
- assert.containsNone($, ".o-AttachmentViewer");
+ await click(".o-FileViewer div[aria-label='Close']");
+ assert.containsNone($, ".o-FileViewer");
});
QUnit.test(
@@ -177,8 +177,8 @@ QUnit.test(
const { openDiscuss } = await start();
await openDiscuss(channelId);
await click(".o-mail-AttachmentImage");
- const image = $(".o-AttachmentViewer-viewImage")[0];
- await click(".o-AttachmentViewer div[aria-label='Close']");
+ const image = $(".o-FileViewer-viewImage")[0];
+ await click(".o-FileViewer div[aria-label='Close']");
// Simulate image becoming loaded.
let successfulLoad;
try {
@@ -314,10 +314,10 @@ QUnit.test(
click(".o-mail-AttachmentCard:contains(test.odt)").catch(() => {});
await nextTick();
- assert.containsNone($, ".o-AttachmentViewer");
+ assert.containsNone($, ".o-FileViewer");
await click(".o-mail-AttachmentImage[title='test.png']");
- assert.containsOnce($, ".o-AttachmentViewer");
+ assert.containsOnce($, ".o-FileViewer");
}
);
diff --git a/addons/mail/static/tests/web/attachment_box_tests.js b/addons/mail/static/tests/web/attachment_box_tests.js
index a1d2da58c39..8953eb1c03d 100644
--- a/addons/mail/static/tests/web/attachment_box_tests.js
+++ b/addons/mail/static/tests/web/attachment_box_tests.js
@@ -136,16 +136,16 @@ QUnit.test("view attachments", async (assert) => {
views: [[false, "form"]],
});
await click('.o-mail-AttachmentCard[aria-label="Blah.txt"] .o-mail-AttachmentCard-image');
- assert.containsOnce($, ".o-AttachmentViewer");
- assert.containsOnce($, ".o-AttachmentViewer-header:contains(Blah.txt)");
- assert.containsOnce($, ".o-AttachmentViewer div[aria-label='Next']");
+ assert.containsOnce($, ".o-FileViewer");
+ assert.containsOnce($, ".o-FileViewer-header:contains(Blah.txt)");
+ assert.containsOnce($, ".o-FileViewer div[aria-label='Next']");
- await click(".o-AttachmentViewer div[aria-label='Next']");
- assert.containsOnce($, ".o-AttachmentViewer-header:contains(Blu.txt)");
- assert.containsOnce($, ".o-AttachmentViewer div[aria-label='Next']");
+ await click(".o-FileViewer div[aria-label='Next']");
+ assert.containsOnce($, ".o-FileViewer-header:contains(Blu.txt)");
+ assert.containsOnce($, ".o-FileViewer div[aria-label='Next']");
- await click(".o-AttachmentViewer div[aria-label='Next']");
- assert.containsOnce($, ".o-AttachmentViewer-header:contains(Blah.txt)");
+ await click(".o-FileViewer div[aria-label='Next']");
+ assert.containsOnce($, ".o-FileViewer-header:contains(Blah.txt)");
});
QUnit.test("scroll to attachment box when toggling on", async (assert) => {
diff --git a/addons/mrp/static/src/views/mrp_documents_kanban/mrp_documents_kanban_record.js b/addons/mrp/static/src/views/mrp_documents_kanban/mrp_documents_kanban_record.js
index 119f88b4efe..33661e9047b 100644
--- a/addons/mrp/static/src/views/mrp_documents_kanban/mrp_documents_kanban_record.js
+++ b/addons/mrp/static/src/views/mrp_documents_kanban/mrp_documents_kanban_record.js
@@ -2,13 +2,13 @@
import { CANCEL_GLOBAL_CLICK, KanbanRecord } from "@web/views/kanban/kanban_record";
import { useService } from "@web/core/utils/hooks";
-import { useAttachmentViewer } from "@web/core/attachment_viewer/attachment_viewer_hook";
+import { useFileViewer } from "@web/core/file_viewer/file_viewer_hook";
export class MrpDocumentsKanbanRecord extends KanbanRecord {
setup() {
super.setup();
this.attachmentService = useService("mail.attachment");
- this.attachmentViewer = useAttachmentViewer();
+ this.fileViewer = useFileViewer();
}
/**
* @override
@@ -29,7 +29,7 @@ export class MrpDocumentsKanbanRecord extends KanbanRecord {
name: this.props.record.data.name,
mimetype: this.props.record.data.mimetype,
});
- this.attachmentViewer.open(attachment)
+ this.fileViewer.open(attachment)
return;
}
return super.onGlobalClick(...arguments);
diff --git a/addons/mrp/static/tests/mrp_document_kanban_tests.js b/addons/mrp/static/tests/mrp_document_kanban_tests.js
index 0ec0f93f417..10de8f1755c 100644
--- a/addons/mrp/static/tests/mrp_document_kanban_tests.js
+++ b/addons/mrp/static/tests/mrp_document_kanban_tests.js
@@ -231,12 +231,12 @@ QUnit.module('MrpDocumentsKanbanView', {
assert.containsOnce(target, ".o_kanban_previewer");
await click(target.querySelector(".o_kanban_previewer"));
- await waitUntil('.o-AttachmentViewer');
- assert.containsOnce(target, '.o-AttachmentViewer');
- assert.containsOnce(target, '.o-AttachmentViewer-headerButton .fa-times');
+ await waitUntil('.o-FileViewer');
+ assert.containsOnce(target, '.o-FileViewer');
+ assert.containsOnce(target, '.o-FileViewer-headerButton .fa-times');
- await click(target, '.o-AttachmentViewer-headerButton .fa-times');
- assert.containsNone(target, '.o-AttachmentViewer');
+ await click(target, '.o-FileViewer-headerButton .fa-times');
+ assert.containsNone(target, '.o-FileViewer');
});
});
diff --git a/addons/web/__manifest__.py b/addons/web/__manifest__.py
index 5aef8e805bc..bdb455e6872 100644
--- a/addons/web/__manifest__.py
+++ b/addons/web/__manifest__.py
@@ -185,7 +185,7 @@ This module provides the core of the Odoo Web Client.
('remove', 'web/static/src/webclient/navbar/navbar.scss'), # already in assets_common
('remove', 'web/static/src/webclient/clickbot/clickbot.js'), # lazy loaded
('remove', 'web/static/src/views/form/button_box/*.scss'),
- ('remove', 'web/static/src/core/attachment_viewer/attachment_viewer.dark.scss'),
+ ('remove', 'web/static/src/core/file_viewer/file_viewer.dark.scss'),
# remove the report code and whitelist only what's needed
('remove', 'web/static/src/webclient/actions/reports/**/*'),
@@ -400,7 +400,7 @@ This module provides the core of the Odoo Web Client.
'web/static/src/core/**/*',
('remove', 'web/static/src/core/commands/**/*'),
('remove', 'web/static/src/core/debug/debug_menu.js'),
- ('remove', 'web/static/src/core/attachment_viewer/attachment_viewer.dark.scss'),
+ ('remove', 'web/static/src/core/file_viewer/file_viewer.dark.scss'),
'web/static/src/public/error_notifications.js',
'web/static/src/legacy/utils.js',
@@ -483,7 +483,7 @@ This module provides the core of the Odoo Web Client.
# ---------------------------------------------------------------------
"web.dark_mode_assets_common": [
('include', 'web.assets_common'),
- 'web/static/src/core/attachment_viewer/attachment_viewer.dark.scss',
+ 'web/static/src/core/file_viewer/file_viewer.dark.scss',
],
"web.dark_mode_assets_backend": [
('include', 'web.assets_backend'),
diff --git a/addons/web/static/src/core/attachment_viewer/attachment_viewer.xml b/addons/web/static/src/core/attachment_viewer/attachment_viewer.xml
deleted file mode 100644
index 3a1ccb919d3..00000000000
--- a/addons/web/static/src/core/attachment_viewer/attachment_viewer.xml
+++ /dev/null
@@ -1,77 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
![Viewer]()
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/addons/web/static/src/core/attachment_viewer/attachment_viewer_hook.js b/addons/web/static/src/core/attachment_viewer/attachment_viewer_hook.js
deleted file mode 100644
index 3e2464489ef..00000000000
--- a/addons/web/static/src/core/attachment_viewer/attachment_viewer_hook.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/* @odoo-module */
-
-import { onWillDestroy } from "@odoo/owl";
-import { registry } from "@web/core/registry";
-import { AttachmentViewer } from "./attachment_viewer";
-
-let id = 1;
-
-export function useAttachmentViewer() {
- const attachmentViewerId = `web.attachment_viewer${id++}`;
- /**
- * @param {import("@mail/attachments/attachment_model").Attachment} attachment
- * @param {import("@mail/attachments/attachment_model").Attachment[]} attachments
- */
- function open(attachment, attachments = [attachment]) {
- if (!attachment.isViewable) {
- return;
- }
- if (attachments.length > 0) {
- const viewableAttachments = attachments.filter((attachment) => attachment.isViewable);
- const index = viewableAttachments.indexOf(attachment);
- registry.category("main_components").add(attachmentViewerId, {
- Component: AttachmentViewer,
- props: { attachments: viewableAttachments, startIndex: index, close },
- });
- }
- }
-
- function close() {
- registry.category("main_components").remove(attachmentViewerId);
- }
- onWillDestroy(close);
- return { open, close };
-}
diff --git a/addons/web/static/src/core/attachment_viewer/attachment_viewer.dark.scss b/addons/web/static/src/core/file_viewer/file_viewer.dark.scss
similarity index 57%
rename from addons/web/static/src/core/attachment_viewer/attachment_viewer.dark.scss
rename to addons/web/static/src/core/file_viewer/file_viewer.dark.scss
index b77cb9afbc2..92f0b45dedc 100644
--- a/addons/web/static/src/core/attachment_viewer/attachment_viewer.dark.scss
+++ b/addons/web/static/src/core/file_viewer/file_viewer.dark.scss
@@ -2,6 +2,6 @@
// ============================================================================
// No CSS hacks, variables overrides only
-.o-AttachmentViewer-toolbarButton {
- --web-attachment-viewer-toolbarButton-background-color: #{$o-gray-200};
+.o-FileViewer-toolbarButton {
+ --file-viewer-toolbarButton-background-color: #{$o-gray-200};
}
diff --git a/addons/web/static/src/core/attachment_viewer/attachment_viewer.js b/addons/web/static/src/core/file_viewer/file_viewer.js
similarity index 83%
rename from addons/web/static/src/core/attachment_viewer/attachment_viewer.js
rename to addons/web/static/src/core/file_viewer/file_viewer.js
index 34f420b5124..ceb12f2226e 100644
--- a/addons/web/static/src/core/attachment_viewer/attachment_viewer.js
+++ b/addons/web/static/src/core/file_viewer/file_viewer.js
@@ -4,14 +4,28 @@ import { Component, useExternalListener, useRef, useState } from "@odoo/owl";
import { useService } from "@web/core/utils/hooks";
/**
+ * @typedef {Object} File
+ * @property {string} displayName
+ * @property {string} downloadUrl
+ * @property {boolean} [isImage]
+ * @property {boolean} [isPdf]
+ * @property {boolean} [isVideo]
+ * @property {boolean} [isText]
+ * @property {string} [defaultSource]
+ * @property {boolean} [isUrlYoutube]
+ * @property {string} [mimetype]
+ * @property {boolean} [isViewable]
* @typedef {Object} Props
- * @property {Array} attachments
+ * @property {Array} files
+ * @property {number} startIndex
+ * @property {function} close
+ * @property {boolean} [modal]
* @extends {Component}
*/
-export class AttachmentViewer extends Component {
- static template = "web.AttachmentViewer";
+export class FileViewer extends Component {
+ static template = "web.FileViewer";
static components = {};
- static props = ["attachments", "startIndex", "close", "modal?"];
+ static props = ["files", "startIndex", "close", "modal?"];
static defaultProps = {
modal: true,
};
@@ -37,7 +51,7 @@ export class AttachmentViewer extends Component {
useExternalListener(document, "keydown", this.onKeydown);
this.state = useState({
index: this.props.startIndex,
- attachment: this.props.attachments[this.props.startIndex],
+ file: this.props.files[this.props.startIndex],
imageLoaded: false,
scale: 1,
angle: 0,
@@ -54,18 +68,18 @@ export class AttachmentViewer extends Component {
}
next() {
- const last = this.props.attachments.length - 1;
- this.activateAttachment(this.state.index === last ? 0 : this.state.index + 1);
+ const last = this.props.files.length - 1;
+ this.activateFile(this.state.index === last ? 0 : this.state.index + 1);
}
previous() {
- const last = this.props.attachments.length - 1;
- this.activateAttachment(this.state.index === 0 ? last : this.state.index - 1);
+ const last = this.props.files.length - 1;
+ this.activateFile(this.state.index === 0 ? last : this.state.index - 1);
}
- activateAttachment(index) {
+ activateFile(index) {
this.state.index = index;
- this.state.attachment = this.props.attachments[index];
+ this.state.file = this.props.files[index];
}
onKeydown(ev) {
@@ -228,7 +242,7 @@ export class AttachmentViewer extends Component {
-
+