mirror of
https://github.com/bringout/oca-dms.git
synced 2026-04-20 05:41:59 +02:00
Add oca-dms submodule with 10 DMS modules
🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
c674eb0508
commit
ae2c6775ba
569 changed files with 63341 additions and 0 deletions
|
|
@ -0,0 +1,57 @@
|
|||
odoo.define("dms.tour", function (require) {
|
||||
"use strict";
|
||||
|
||||
var tour = require("web_tour.tour");
|
||||
|
||||
tour.register(
|
||||
"dms_portal_mail_tour",
|
||||
{
|
||||
test: true,
|
||||
url: "/my",
|
||||
},
|
||||
[
|
||||
{
|
||||
content: "Go /my/dms url",
|
||||
trigger: 'a[href*="/my/dms"]',
|
||||
},
|
||||
{
|
||||
content: "Go to Mails directory",
|
||||
extra_trigger: "li.breadcrumb-item:contains('Documents')",
|
||||
trigger: ".tr_dms_directory_link:contains('Mails')",
|
||||
},
|
||||
{
|
||||
content: "Go to Mail_01.eml",
|
||||
extra_trigger: "li.breadcrumb-item:contains('Mails')",
|
||||
trigger: ".tr_dms_file_link:contains('Mail_01.eml')",
|
||||
},
|
||||
]
|
||||
);
|
||||
tour.register(
|
||||
"dms_portal_partners_tour",
|
||||
{
|
||||
test: true,
|
||||
url: "/my",
|
||||
},
|
||||
[
|
||||
{
|
||||
content: "Go /my/dms url",
|
||||
trigger: 'a[href*="/my/dms"]',
|
||||
},
|
||||
{
|
||||
content: "Go to Partners directory",
|
||||
extra_trigger: "li.breadcrumb-item:contains('Documents')",
|
||||
trigger: ".tr_dms_directory_link:contains('Partners')",
|
||||
},
|
||||
{
|
||||
content: "Go to Joel Willis",
|
||||
extra_trigger: "li.breadcrumb-item:contains('Partners')",
|
||||
trigger: ".tr_dms_directory_link:contains('Joel Willis')",
|
||||
},
|
||||
{
|
||||
content: "Go to test.txt",
|
||||
extra_trigger: "li.breadcrumb-item:contains('Joel Willis')",
|
||||
trigger: ".tr_dms_file_link:contains('test.txt')",
|
||||
},
|
||||
]
|
||||
);
|
||||
});
|
||||
81
odoo-bringout-oca-dms-dms/dms/static/src/js/fields/path.js
Normal file
81
odoo-bringout-oca-dms-dms/dms/static/src/js/fields/path.js
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/** ********************************************************************************
|
||||
Copyright 2020 Creu Blanca
|
||||
Copyright 2017-2019 MuK IT GmbH
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
**********************************************************************************/
|
||||
|
||||
odoo.define("dms.fields_path", function (require) {
|
||||
"use strict";
|
||||
|
||||
var fields = require("web.basic_fields");
|
||||
var registry = require("web.field_registry");
|
||||
|
||||
var FieldPathJson = fields.FieldText.extend({
|
||||
events: _.extend({}, fields.FieldText.prototype.events, {
|
||||
"click a": "_onNodeClicked",
|
||||
}),
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this.max_width = this.nodeOptions.width || 500;
|
||||
this.seperator = this.nodeOptions.seperator || "/";
|
||||
this.prefix = this.nodeOptions.prefix || false;
|
||||
this.suffix = this.nodeOptions.suffix || false;
|
||||
},
|
||||
_renderReadonly: function () {
|
||||
this.$el.empty();
|
||||
this._renderPath();
|
||||
},
|
||||
_renderPath: function () {
|
||||
var text_width_measure = "";
|
||||
var path = JSON.parse(this.value || "[]");
|
||||
$.each(
|
||||
_.clone(path).reverse(),
|
||||
function (index, element) {
|
||||
text_width_measure += element.name + "/";
|
||||
if (text_width_measure.length >= this.max_width) {
|
||||
this.$el.prepend($("<span/>").text(".."));
|
||||
} else if (index === 0) {
|
||||
if (this.suffix) {
|
||||
this.$el.prepend($("<span/>").text(this.seperator));
|
||||
}
|
||||
this.$el.prepend($("<span/>").text(element.name));
|
||||
this.$el.prepend($("<span/>").text(this.seperator));
|
||||
} else {
|
||||
this.$el.prepend(
|
||||
$("<a/>", {
|
||||
class: "oe_form_uri",
|
||||
"data-model": element.model,
|
||||
"data-id": element.id,
|
||||
href: "#",
|
||||
text: element.name,
|
||||
})
|
||||
);
|
||||
if (index !== path.length - 1) {
|
||||
this.$el.prepend($("<span/>").text(this.seperator));
|
||||
} else if (this.prefix) {
|
||||
this.$el.prepend($("<span/>").text(this.seperator));
|
||||
}
|
||||
}
|
||||
return text_width_measure.length < this.max_width;
|
||||
}.bind(this)
|
||||
);
|
||||
},
|
||||
_onNodeClicked: function (event) {
|
||||
event.preventDefault();
|
||||
this.do_action({
|
||||
type: "ir.actions.act_window",
|
||||
res_model: $(event.currentTarget).data("model"),
|
||||
res_id: $(event.currentTarget).data("id"),
|
||||
views: [[false, "form"]],
|
||||
target: "current",
|
||||
context: {},
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
registry.add("path_json", FieldPathJson);
|
||||
|
||||
return {
|
||||
FieldPathJson: FieldPathJson,
|
||||
};
|
||||
});
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import {registry} from "@web/core/registry";
|
||||
import {Component, onWillUpdateProps} from "@odoo/owl";
|
||||
import {useService} from "@web/core/utils/hooks";
|
||||
|
||||
class DmsPathField extends Component {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.action = useService("action");
|
||||
this.formatData(this.props);
|
||||
onWillUpdateProps((nextProps) => this.formatData(nextProps));
|
||||
}
|
||||
|
||||
formatData(props) {
|
||||
this.data = JSON.parse(props.value || "[]");
|
||||
}
|
||||
|
||||
_onNodeClicked(event) {
|
||||
event.preventDefault();
|
||||
this.action.doAction({
|
||||
type: "ir.actions.act_window",
|
||||
res_model: $(event.currentTarget).data("model"),
|
||||
res_id: $(event.currentTarget).data("id"),
|
||||
views: [[false, "form"]],
|
||||
target: "current",
|
||||
context: {},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
DmsPathField.supportedTypes = ["text"];
|
||||
DmsPathField.template = "dms.DmsPathField";
|
||||
registry.category("fields").add("path_json", DmsPathField);
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates>
|
||||
<t t-name="dms.DmsPathField" owl="1">
|
||||
|
||||
<t t-set="path_length" t-value="data.length - 1" />
|
||||
<t t-foreach="data" t-as="elem" t-key="elem_index" style="display: inline">
|
||||
<t t-if="elem_index !== path_length">
|
||||
<span style="display: inline">/</span>
|
||||
<a
|
||||
class="oe_form_uri"
|
||||
data-model="dms.directory"
|
||||
t-att-data-id="elem.id"
|
||||
href="#"
|
||||
t-on-click.prevent="(ev) => this._onNodeClicked(ev)"
|
||||
>
|
||||
<t t-esc="elem.name" />
|
||||
</a>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<span style="display: inline">/</span>
|
||||
<span style="display: inline">
|
||||
<t t-esc="elem.name" />
|
||||
</span>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
/** @odoo-module */
|
||||
|
||||
import {useBus, useService} from "@web/core/utils/hooks";
|
||||
import {_t} from "web.core";
|
||||
|
||||
const {useRef, useEffect, useState} = owl;
|
||||
|
||||
export const FileDropZone = {
|
||||
setup() {
|
||||
this._super();
|
||||
this.dragState = useState({
|
||||
showDragZone: false,
|
||||
});
|
||||
this.root = useRef("root");
|
||||
this.rpc = useService("rpc");
|
||||
|
||||
useEffect(
|
||||
(el) => {
|
||||
if (!el) {
|
||||
return;
|
||||
}
|
||||
const highlight = this.highlight.bind(this);
|
||||
const unhighlight = this.unhighlight.bind(this);
|
||||
const drop = this.onDrop.bind(this);
|
||||
el.addEventListener("dragover", highlight);
|
||||
el.addEventListener("dragleave", unhighlight);
|
||||
el.addEventListener("drop", drop);
|
||||
return () => {
|
||||
el.removeEventListener("dragover", highlight);
|
||||
el.removeEventListener("dragleave", unhighlight);
|
||||
el.removeEventListener("drop", drop);
|
||||
};
|
||||
},
|
||||
|
||||
() => [document.querySelector(".o_content")]
|
||||
);
|
||||
},
|
||||
|
||||
highlight(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.dragState.showDragZone = true;
|
||||
},
|
||||
|
||||
unhighlight(ev) {
|
||||
ev.stopPropagation();
|
||||
ev.preventDefault();
|
||||
this.dragState.showDragZone = false;
|
||||
},
|
||||
|
||||
async onDrop(ev) {
|
||||
ev.preventDefault();
|
||||
await this.env.bus.trigger("change_file_input", {
|
||||
files: ev.dataTransfer.files,
|
||||
});
|
||||
},
|
||||
};
|
||||
|
||||
export const FileUpload = {
|
||||
setup() {
|
||||
this._super();
|
||||
this.actionService = useService("action");
|
||||
this.notification = useService("notification");
|
||||
this.orm = useService("orm");
|
||||
this.http = useService("http");
|
||||
this.fileInput = useRef("fileInput");
|
||||
this.root = useRef("root");
|
||||
|
||||
this.rpc = useService("rpc");
|
||||
|
||||
useBus(this.env.bus, "change_file_input", async (ev) => {
|
||||
this.fileInput.el.files = ev.detail.files;
|
||||
await this.onChangeFileInput();
|
||||
});
|
||||
},
|
||||
|
||||
uploadDocument() {
|
||||
this.fileInput.el.click();
|
||||
},
|
||||
|
||||
async onChangeFileInput() {
|
||||
const params = {
|
||||
csrf_token: odoo.csrf_token,
|
||||
ufile: [...this.fileInput.el.files],
|
||||
model: "dms.file",
|
||||
id: 0,
|
||||
};
|
||||
|
||||
const fileData = await this.http.post(
|
||||
"/web/binary/upload_attachment",
|
||||
params,
|
||||
"text"
|
||||
);
|
||||
const attachments = JSON.parse(fileData);
|
||||
if (attachments.error) {
|
||||
throw new Error(attachments.error);
|
||||
}
|
||||
|
||||
this.onUpload(attachments);
|
||||
},
|
||||
|
||||
async onUpload(attachments) {
|
||||
const self = this;
|
||||
const attachmentIds = attachments.map((a) => a.id);
|
||||
const ctx = Object.assign(
|
||||
{},
|
||||
this.actionService.currentController.props.context,
|
||||
this.props.context
|
||||
);
|
||||
const controllerID = this.actionService.currentController.jsId;
|
||||
|
||||
if (!attachmentIds.length) {
|
||||
this.notification.add(_t("An error occurred during the upload"));
|
||||
return;
|
||||
}
|
||||
// Search the correct directory_id value according to the domain
|
||||
if (this.props.domain) {
|
||||
for (const domain_item of this.props.domain) {
|
||||
if (domain_item.length === 3) {
|
||||
if (domain_item[0] === "directory_id" && domain_item[1] === "=") {
|
||||
ctx.default_directory_id = domain_item[2];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!ctx.default_directory_id) {
|
||||
self.actionService.restore(controllerID);
|
||||
return self.notification.add(
|
||||
this.env._t("You must select a directory first"),
|
||||
{
|
||||
type: "danger",
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
const attachment_datas = await this.orm.call(
|
||||
"dms.file",
|
||||
"get_dms_files_from_attachments",
|
||||
["", attachmentIds]
|
||||
);
|
||||
|
||||
const attachments_args = [];
|
||||
|
||||
attachment_datas.forEach((attachment_data) => {
|
||||
attachments_args.push({
|
||||
name: attachment_data.name,
|
||||
content: attachment_data.datas,
|
||||
mimetype: attachment_data.mimetype,
|
||||
});
|
||||
});
|
||||
|
||||
this.orm
|
||||
.call("dms.file", "create", [attachments_args], {
|
||||
context: ctx,
|
||||
})
|
||||
.then(() => {
|
||||
self.actionService.restore(controllerID);
|
||||
})
|
||||
.catch((error) => {
|
||||
self.notification.add(error.data.message, {
|
||||
type: "danger",
|
||||
});
|
||||
self.actionService.restore(controllerID);
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import {registry} from "@web/core/registry";
|
||||
import {BinaryField} from "@web/views/fields/binary/binary_field";
|
||||
import {useService} from "@web/core/utils/hooks";
|
||||
|
||||
export class PreviewRecordField extends BinaryField {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.messaging = useService("messaging");
|
||||
this.dialog = useService("dialog");
|
||||
}
|
||||
|
||||
onFilePreview() {
|
||||
const self = this;
|
||||
this.messaging.get().then((messaging) => {
|
||||
const attachmentList = messaging.models.AttachmentList.insert({
|
||||
selectedAttachment: messaging.models.Attachment.insert({
|
||||
id: self.props.record.resId,
|
||||
filename: self.props.record.data.display_name || "",
|
||||
name: self.props.record.data.display_name || "",
|
||||
mimetype: self.props.record.data.mimetype,
|
||||
model_name: self.props.record.resModel,
|
||||
}),
|
||||
});
|
||||
this.dialog = messaging.models.Dialog.insert({
|
||||
attachmentListOwnerAsAttachmentView: attachmentList,
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PreviewRecordField.template = "dms.FilePreviewField";
|
||||
registry.category("fields").add("preview_binary", PreviewRecordField);
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates id="template" xml:space="preserve">
|
||||
|
||||
<t
|
||||
t-name="dms.FilePreviewField"
|
||||
t-inherit="web.BinaryField"
|
||||
t-inherit-mode="primary"
|
||||
owl="1"
|
||||
>
|
||||
<xpath expr="//div[hasclass('d-inline-flex')]" position="inside">
|
||||
<t
|
||||
t-set="readable_types"
|
||||
t-value="[
|
||||
'image/bmp',
|
||||
'image/gif',
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/svg+xml',
|
||||
'image/tiff',
|
||||
'image/x-icon',
|
||||
'application/pdf',
|
||||
'audio/mpeg',
|
||||
'video/x-matroska',
|
||||
'video/mp4',
|
||||
'video/webm',
|
||||
]"
|
||||
/>
|
||||
<t t-if="readable_types.includes(props.record.data.mimetype)">
|
||||
<button
|
||||
class="btn btn-secondary fa fa-search preview_file"
|
||||
data-tooltip="Preview"
|
||||
aria-label="Preview"
|
||||
t-on-click="onFilePreview"
|
||||
/>
|
||||
</t>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
// /** ********************************************************************************
|
||||
// Copyright 2020 Creu Blanca
|
||||
// Copyright 2017-2019 MuK IT GmbH
|
||||
// License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
// **********************************************************************************/
|
||||
|
||||
import {KanbanController} from "@web/views/kanban/kanban_controller";
|
||||
export class FileKanbanController extends KanbanController {
|
||||
setup() {
|
||||
super.setup();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates>
|
||||
<t
|
||||
t-name="dms.FileKanbanView.Buttons"
|
||||
t-inherit="web.KanbanView.Buttons"
|
||||
t-inherit-mode="primary"
|
||||
owl="1"
|
||||
>
|
||||
<div role="toolbar" position="inside">
|
||||
<input
|
||||
type="file"
|
||||
multiple="true"
|
||||
t-ref="uploadFileInput"
|
||||
class="o_input_file o_hidden"
|
||||
t-on-change.stop="onFileInputChange"
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
t-attf-class="btn btn-primary o_file_kanban_upload"
|
||||
t-on-click.stop.prevent="() => this.uploadFileInputRef.el.click()"
|
||||
>
|
||||
Upload
|
||||
</button>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import {KanbanRecord} from "@web/views/kanban/kanban_record";
|
||||
import {useService} from "@web/core/utils/hooks";
|
||||
|
||||
const videoReadableTypes = ["x-matroska", "mp4", "webm"];
|
||||
const audioReadableTypes = ["mp3", "ogg", "wav", "aac", "mpa", "flac", "m4a"];
|
||||
|
||||
export class FileKanbanRecord extends KanbanRecord {
|
||||
setup() {
|
||||
super.setup();
|
||||
this.messaging = useService("messaging");
|
||||
this.dialog = useService("dialog");
|
||||
}
|
||||
|
||||
isVideo(mimetype) {
|
||||
return videoReadableTypes.includes(mimetype);
|
||||
}
|
||||
|
||||
isAudio(mimetype) {
|
||||
return audioReadableTypes.includes(mimetype);
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
*
|
||||
* Override to open the preview upon clicking the image, if compatible.
|
||||
*/
|
||||
onGlobalClick(ev) {
|
||||
const self = this;
|
||||
|
||||
if (ev.target.closest(".o_kanban_dms_file_preview")) {
|
||||
this.messaging.get().then((messaging) => {
|
||||
const file_type = self.props.record.data.name.split(".")[1];
|
||||
let mimetype = "";
|
||||
|
||||
if (self.isVideo(file_type)) {
|
||||
mimetype = `video/${file_type}`;
|
||||
} else if (self.isAudio(file_type)) {
|
||||
mimetype = "audio/mpeg";
|
||||
} else {
|
||||
mimetype = self.props.record.data.mimetype;
|
||||
}
|
||||
|
||||
const attachmentList = messaging.models.AttachmentList.insert({
|
||||
selectedAttachment: messaging.models.Attachment.insert({
|
||||
id: self.props.record.data.id,
|
||||
filename: self.props.record.data.name,
|
||||
name: self.props.record.data.name,
|
||||
mimetype: mimetype,
|
||||
model_name: self.props.record.resModel,
|
||||
}),
|
||||
});
|
||||
this.dialog = messaging.models.Dialog.insert({
|
||||
attachmentListOwnerAsAttachmentView: attachmentList,
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
return super.onGlobalClick(...arguments);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/** @odoo-module */
|
||||
|
||||
// /** ********************************************************************************
|
||||
// Copyright 2020 Creu Blanca
|
||||
// License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
// **********************************************************************************/
|
||||
import {KanbanRenderer} from "@web/views/kanban/kanban_renderer";
|
||||
|
||||
import {FileKanbanRecord} from "./file_kanban_record.esm";
|
||||
|
||||
export class FileKanbanRenderer extends KanbanRenderer {
|
||||
setup() {
|
||||
super.setup();
|
||||
}
|
||||
}
|
||||
|
||||
FileKanbanRenderer.components = {
|
||||
...KanbanRenderer.components,
|
||||
KanbanRecord: FileKanbanRecord,
|
||||
};
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<t
|
||||
t-name="dms.KanbanRenderer"
|
||||
t-inherit="web.KanbanRenderer"
|
||||
t-inherit-mode="primary"
|
||||
owl="1"
|
||||
>
|
||||
<xpath expr="//div[hasclass('o_kanban_renderer')]" position="before">
|
||||
<div t-if="dragState.showDragZone" class="o_dropzone">
|
||||
<i class="fa fa-cloud-upload fa-10x" />
|
||||
</div>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t
|
||||
t-name="dms.KanbanButtons"
|
||||
t-inherit="web.KanbanView.Buttons"
|
||||
t-inherit-mode="primary"
|
||||
owl="1"
|
||||
>
|
||||
<xpath expr="//t[@t-if='canCreate']" position="after">
|
||||
<button
|
||||
type="button"
|
||||
class="d-none d-md-inline btn btn-primary mx-1"
|
||||
t-on-click.prevent="uploadDocument"
|
||||
>
|
||||
Upload
|
||||
</button>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//t[@t-if='canCreate']" position="before">
|
||||
<button
|
||||
type="button"
|
||||
class="d-inline d-md-none btn btn-primary mx-1"
|
||||
t-on-click.prevent="uploadDocument"
|
||||
>
|
||||
Scan
|
||||
</button>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div" position="inside">
|
||||
<input
|
||||
type="file"
|
||||
name="ufile"
|
||||
class="d-none"
|
||||
t-ref="fileInput"
|
||||
multiple="1"
|
||||
accept="*"
|
||||
t-on-change="onChangeFileInput"
|
||||
/>
|
||||
</xpath>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
// /** ********************************************************************************
|
||||
// Copyright 2020 Creu Blanca
|
||||
// Copyright 2017-2019 MuK IT GmbH
|
||||
// License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
// **********************************************************************************/
|
||||
|
||||
import {registry} from "@web/core/registry";
|
||||
import {patch} from "@web/core/utils/patch";
|
||||
import {kanbanView} from "@web/views/kanban/kanban_view";
|
||||
import {FileKanbanRenderer} from "./file_kanban_renderer.esm";
|
||||
import {FileKanbanController} from "./file_kanban_controller.esm";
|
||||
|
||||
import {FileDropZone, FileUpload} from "./dms_file_upload.esm";
|
||||
|
||||
patch(FileKanbanRenderer.prototype, "file_kanban_renderer_dzone", FileDropZone);
|
||||
patch(FileKanbanController.prototype, "filee_kanban_controller_upload", FileUpload);
|
||||
FileKanbanRenderer.template = "dms.KanbanRenderer";
|
||||
|
||||
export const FileKanbanView = {
|
||||
...kanbanView,
|
||||
buttonTemplate: "dms.KanbanButtons",
|
||||
Controller: FileKanbanController,
|
||||
Renderer: FileKanbanRenderer,
|
||||
};
|
||||
|
||||
registry.category("views").add("file_kanban", FileKanbanView);
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
// /** ********************************************************************************
|
||||
// Copyright 2020 Creu Blanca
|
||||
// Copyright 2017-2019 MuK IT GmbH
|
||||
// License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
// **********************************************************************************/
|
||||
|
||||
import {ListController} from "@web/views/list/list_controller";
|
||||
|
||||
export class FileListController extends ListController {
|
||||
setup() {
|
||||
super.setup();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/** @odoo-module */
|
||||
|
||||
// /** ********************************************************************************
|
||||
// Copyright 2020 Creu Blanca
|
||||
// License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
// **********************************************************************************/
|
||||
|
||||
import {ListRenderer} from "@web/views/list/list_renderer";
|
||||
|
||||
export class FileListRenderer extends ListRenderer {
|
||||
setup() {
|
||||
super.setup();
|
||||
}
|
||||
}
|
||||
|
||||
FileListRenderer.components = {
|
||||
...FileListRenderer.components,
|
||||
};
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<templates xml:space="preserve">
|
||||
<t
|
||||
t-name="dms.ListRenderer"
|
||||
t-inherit="web.ListRenderer"
|
||||
t-inherit-mode="primary"
|
||||
owl="1"
|
||||
>
|
||||
<xpath expr="//div[hasclass('o_list_renderer')]" position="before">
|
||||
<div t-if="dragState.showDragZone" class="o_dropzone">
|
||||
<i class="fa fa-cloud-upload fa-10x" />
|
||||
</div>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
<t
|
||||
t-name="dms.ListButtons"
|
||||
t-inherit="web.ListView.Buttons"
|
||||
t-inherit-mode="primary"
|
||||
owl="1"
|
||||
>
|
||||
<xpath expr="//div[hasclass('o_list_buttons')]" position="inside">
|
||||
<button
|
||||
type="button"
|
||||
class="d-none d-md-inline o_button_upload_expense btn btn-primary mx-1"
|
||||
t-on-click.prevent="uploadDocument"
|
||||
>
|
||||
Upload
|
||||
</button>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div[hasclass('o_list_buttons')]" position="inside">
|
||||
<button
|
||||
type="button"
|
||||
class="d-inline d-md-none o_button_upload_expense btn btn-primary mx-1"
|
||||
t-on-click.prevent="uploadDocument"
|
||||
>
|
||||
Scan
|
||||
</button>
|
||||
</xpath>
|
||||
|
||||
<xpath expr="//div" position="inside">
|
||||
<input
|
||||
type="file"
|
||||
name="ufile"
|
||||
class="d-none"
|
||||
t-ref="fileInput"
|
||||
multiple="1"
|
||||
accept="*"
|
||||
t-on-change="onChangeFileInput"
|
||||
/>
|
||||
</xpath>
|
||||
</t>
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
// /** ********************************************************************************
|
||||
// Copyright 2020 Creu Blanca
|
||||
// Copyright 2017-2019 MuK IT GmbH
|
||||
// License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
// **********************************************************************************/
|
||||
|
||||
import {registry} from "@web/core/registry";
|
||||
import {patch} from "@web/core/utils/patch";
|
||||
import {listView} from "@web/views/list/list_view";
|
||||
import {FileListRenderer} from "./file_list_renderer.esm";
|
||||
import {FileListController} from "./file_list_controller.esm";
|
||||
|
||||
import {FileDropZone, FileUpload} from "./dms_file_upload.esm";
|
||||
|
||||
patch(FileListRenderer.prototype, "file_list_renderer_dzone", FileDropZone);
|
||||
patch(FileListController.prototype, "file_list_controller_upload", FileUpload);
|
||||
FileListRenderer.template = "dms.ListRenderer";
|
||||
|
||||
export const FileListView = {
|
||||
...listView,
|
||||
buttonTemplate: "dms.ListButtons",
|
||||
Controller: FileListController,
|
||||
Renderer: FileListRenderer,
|
||||
};
|
||||
|
||||
registry.category("views").add("file_list", FileListView);
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/* global base64js*/
|
||||
/* Copyright 2020 Creu Blanca
|
||||
* Copyright 2021 Tecnativa - Alexandre D. Díaz
|
||||
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). */
|
||||
odoo.define("dms.DragDrop", function (require) {
|
||||
"use strict";
|
||||
|
||||
const DropTargetMixin = require("web_drop_target");
|
||||
const core = require("web.core");
|
||||
const _t = core._t;
|
||||
|
||||
return _.extend({}, DropTargetMixin.DropTargetMixin, {
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
this._get_directory_id(
|
||||
this._searchPanel ? this._searchPanel.getDomain() : []
|
||||
);
|
||||
},
|
||||
_drop_zone_selector: ".o_kanban_view",
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_handle_drop_items: function (drop_items) {
|
||||
_.each(drop_items, this._handle_file_drop_attach, this);
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_get_record_id: function () {
|
||||
// Don't need the record id to work
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_create_attachment: function (file, reader, res_model) {
|
||||
// Helper to upload an attachment and update the sidebar
|
||||
const ctx = this.renderer.state.getContext();
|
||||
console.log(ctx);
|
||||
if (this.directory_id) {
|
||||
ctx.default_directory_id = this.directory_id;
|
||||
}
|
||||
console.log(ctx);
|
||||
if (typeof ctx.default_directory_id === "undefined") {
|
||||
return this.displayNotification({
|
||||
message: _t("You must select a directory first"),
|
||||
type: "danger",
|
||||
});
|
||||
}
|
||||
return this._rpc({
|
||||
model: res_model,
|
||||
method: "create",
|
||||
args: [
|
||||
{
|
||||
name: file.name,
|
||||
content: base64js.fromByteArray(new Uint8Array(reader.result)),
|
||||
},
|
||||
],
|
||||
kwargs: {
|
||||
context: ctx,
|
||||
},
|
||||
}).then(() => this.reload());
|
||||
},
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @param {Array} domain
|
||||
*/
|
||||
_get_directory_id: function (domain) {
|
||||
let directory_id = false;
|
||||
_.each(domain, (leaf) => {
|
||||
if (
|
||||
leaf[0] === "directory_id" &&
|
||||
(leaf[1] === "child_of" || leaf[1] === "=")
|
||||
) {
|
||||
directory_id = leaf[2];
|
||||
}
|
||||
});
|
||||
this.directory_id = directory_id;
|
||||
},
|
||||
|
||||
/**
|
||||
* @override
|
||||
*/
|
||||
_update: function (state, params) {
|
||||
this._get_directory_id(params.domain);
|
||||
return this._super.apply(this, arguments).then((result) => {
|
||||
this._update_overlay();
|
||||
return result;
|
||||
});
|
||||
},
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/** @odoo-module **/
|
||||
/* Copyright 2021-2024 Tecnativa - Víctor Martínez
|
||||
* License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */
|
||||
|
||||
import {SearchModel} from "@web/search/search_model";
|
||||
import {patch} from "@web/core/utils/patch";
|
||||
|
||||
patch(SearchModel.prototype, "dms.SearchPanel", {
|
||||
setup() {
|
||||
this._super(...arguments);
|
||||
},
|
||||
|
||||
_getCategoryDomain(excludedCategoryId) {
|
||||
const domain = this._super.apply(this, arguments);
|
||||
for (const category of this.categories) {
|
||||
if (category.id === excludedCategoryId) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Make sure to filter selected category only for DMS hierarchies,
|
||||
// not other Odoo models such as product categories
|
||||
// where child_of could be better than "=" operator
|
||||
if (category.activeValueId && this.resModel.startsWith("dms")) {
|
||||
domain.push([category.fieldName, "=", category.activeValueId]);
|
||||
}
|
||||
if (domain.length === 0 && this.resModel === "dms.directory") {
|
||||
domain.push([category.fieldName, "=", false]);
|
||||
}
|
||||
}
|
||||
return domain;
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import {registerPatch} from "@mail/model/model_core";
|
||||
import {attr} from "@mail/model/model_field";
|
||||
|
||||
registerPatch({
|
||||
name: "Attachment",
|
||||
fields: {
|
||||
defaultSource: {
|
||||
compute() {
|
||||
if (this.isImage) {
|
||||
if (this.model_name && this.model_name === "dms.file") {
|
||||
return `/web/content?id=${this.id}&field=content&model=dms.file&filename_field=name&download=false`;
|
||||
}
|
||||
return `/web/image/${this.id}?signature=${this.checksum}`;
|
||||
}
|
||||
if (this.isPdf) {
|
||||
if (this.model_name && this.model_name === "dms.file") {
|
||||
return (
|
||||
"/web/content?id=" +
|
||||
this.id +
|
||||
"&field=content&model=dms.file" +
|
||||
"&filename_field=name"
|
||||
);
|
||||
}
|
||||
const pdf_lib = `/web/static/lib/pdfjs/web/viewer.html?file=`;
|
||||
if (
|
||||
!this.accessToken &&
|
||||
this.originThread &&
|
||||
this.originThread.model === "mail.channel"
|
||||
) {
|
||||
return `${pdf_lib}/mail/channel/${this.originThread.id}/attachment/${this.id}#pagemode=none`;
|
||||
}
|
||||
const accessToken = this.accessToken
|
||||
? `?access_token%3D${this.accessToken}`
|
||||
: "";
|
||||
return `${pdf_lib}/web/content/${this.id}${accessToken}#pagemode=none`;
|
||||
}
|
||||
if (this.isUrlYoutube) {
|
||||
const urlArr = this.url.split("/");
|
||||
let token = urlArr[urlArr.length - 1];
|
||||
if (token.includes("watch")) {
|
||||
token = token.split("v=")[1];
|
||||
const amp = token.indexOf("&");
|
||||
if (amp !== -1) {
|
||||
token = token.substring(0, amp);
|
||||
}
|
||||
}
|
||||
return `https://www.youtube.com/embed/${token}`;
|
||||
}
|
||||
if (
|
||||
!this.accessToken &&
|
||||
this.originThread &&
|
||||
this.originThread.model === "mail.channel"
|
||||
) {
|
||||
return `/mail/channel/${this.originThread.id}/attachment/${this.id}`;
|
||||
}
|
||||
const accessToken = this.accessToken
|
||||
? `?access_token=${this.accessToken}`
|
||||
: "";
|
||||
|
||||
if (this.model_name && this.model_name === "dms.file") {
|
||||
return `/web/content?id=${this.id}&field=content&model=dms.file&filename_field=name`;
|
||||
}
|
||||
return `/web/content/${this.id}${accessToken}`;
|
||||
},
|
||||
},
|
||||
model_name: attr(),
|
||||
downloadUrl: {
|
||||
compute() {
|
||||
if (
|
||||
!this.accessToken &&
|
||||
this.originThread &&
|
||||
this.originThread.model === "mail.channel"
|
||||
) {
|
||||
return `/mail/channel/${this.originThread.id}/attachment/${this.id}?download=true`;
|
||||
}
|
||||
if (this.model_name && this.model_name === "dms.file") {
|
||||
return `/web/content?id=${this.id}&field=content&model=dms.file&filename_field=name&download=true`;
|
||||
}
|
||||
const accessToken = this.accessToken
|
||||
? `access_token=${this.accessToken}&`
|
||||
: "";
|
||||
return `/web/content/ir.attachment/${this.id}/datas?${accessToken}download=true`;
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import {registerPatch} from "@mail/model/model_core";
|
||||
|
||||
registerPatch({
|
||||
name: "AttachmentImage",
|
||||
fields: {
|
||||
imageUrl: {
|
||||
compute() {
|
||||
if (!this.attachment) {
|
||||
return;
|
||||
}
|
||||
if (
|
||||
!this.attachment.accessToken &&
|
||||
this.attachment.originThread &&
|
||||
this.attachment.originThread.model === "mail.channel"
|
||||
) {
|
||||
return `/mail/channel/${this.attachment.originThread.id}/image/${this.attachment.id}/${this.width}x${this.height}`;
|
||||
}
|
||||
const accessToken = this.attachment.accessToken
|
||||
? `?access_token=${this.attachment.accessToken}`
|
||||
: "";
|
||||
if (
|
||||
this.attachment.model_name &&
|
||||
this.attachment.model_name === "dms.file"
|
||||
) {
|
||||
return `/web/content?id=${this.attachment.id}&field=content&model=dms.file&filename_field=name&download=false`;
|
||||
}
|
||||
return `/web/image/${this.attachment.id}/${this.width}x${this.height}${accessToken}`;
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/** @odoo-module **/
|
||||
|
||||
import {registerPatch} from "@mail/model/model_core";
|
||||
|
||||
registerPatch({
|
||||
name: "AttachmentViewerViewable",
|
||||
fields: {
|
||||
imageUrl: {
|
||||
compute() {
|
||||
if (
|
||||
!this.attachmentOwner.accessToken &&
|
||||
this.attachmentOwner.originThread &&
|
||||
this.attachmentOwner.originThread.model === "mail.channel"
|
||||
) {
|
||||
return `/mail/channel/${this.attachmentOwner.originThread.id}/image/${this.attachmentOwner.id}`;
|
||||
}
|
||||
const accessToken = this.attachmentOwner.accessToken
|
||||
? `?access_token=${this.attachmentOwner.accessToken}`
|
||||
: "";
|
||||
if (
|
||||
this.attachmentOwner.model_name &&
|
||||
this.attachmentOwner.model_name === "dms.file"
|
||||
) {
|
||||
return `/web/content?id=${this.attachmentOwner.id}&field=content&model=dms.file&filename_field=name&download=false`;
|
||||
}
|
||||
return `/web/image/${this.attachmentOwner.id}${accessToken}`;
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/**********************************************************************************
|
||||
*
|
||||
* Copyright 2017-2019 MuK IT GmbH
|
||||
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
*
|
||||
**********************************************************************************/
|
||||
|
||||
.mk_directory_kanban_view {
|
||||
height: 100%;
|
||||
.o_kanban_record {
|
||||
> div:nth-child(1) {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
padding: 0;
|
||||
max-height: $o-kanban-image-width + 1;
|
||||
.mk_directory_kanban_actions {
|
||||
float: left;
|
||||
border-right: solid 1px $gray-400;
|
||||
.mk_directory_kanban_actions_wrapper {
|
||||
min-height: $o-kanban-image-width;
|
||||
.btn-outline-primary {
|
||||
display: flex;
|
||||
border-radius: 0;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-color: transparent;
|
||||
min-width: $o-kanban-image-width / 2;
|
||||
min-height: $o-kanban-image-width / 2;
|
||||
&.mk_directory_kanban_directories {
|
||||
border-bottom: solid 1px $gray-400;
|
||||
}
|
||||
}
|
||||
span.total_items {
|
||||
margin-left: 3px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.o_kanban_image {
|
||||
width: $o-kanban-image-width - 1;
|
||||
border-right: solid 1px $gray-400;
|
||||
+ div {
|
||||
padding-left: $o-kanban-image-width + $o-kanban-inside-hgutter +
|
||||
$o-kanban-image-width / 2;
|
||||
@include media-breakpoint-down(sm) {
|
||||
padding-left: $o-kanban-image-width +
|
||||
$o-kanban-inside-hgutter-mobile + $o-kanban-image-width / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
.o_kanban_details .o_kanban_details_wrapper {
|
||||
padding: 4px 4px 4px 0;
|
||||
.o_kanban_record_title {
|
||||
font-weight: bold;
|
||||
padding-right: 16px;
|
||||
}
|
||||
.o_kanban_record_body {
|
||||
max-height: 12px;
|
||||
.o_kanban_tags {
|
||||
@include o-text-overflow;
|
||||
}
|
||||
}
|
||||
.oe_kanban_avatar {
|
||||
margin-left: 0px;
|
||||
}
|
||||
.favorite_sign_button {
|
||||
margin-top: 1px;
|
||||
font-size: 1.5rem;
|
||||
line-height: 20px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
.o_dropdown_kanban {
|
||||
.dropdown-menu {
|
||||
min-width: 22rem;
|
||||
.mk_directory_kanban_views {
|
||||
padding-right: 8px;
|
||||
}
|
||||
.mk_directory_kanban_actions {
|
||||
padding-left: 8px;
|
||||
border-right: none;
|
||||
}
|
||||
.fa {
|
||||
min-width: 12px;
|
||||
padding-right: 2px;
|
||||
text-align: center;
|
||||
}
|
||||
.oe_kanban_colorpicker {
|
||||
max-width: none;
|
||||
margin: 5px 5px;
|
||||
padding: 10px 0 0 25px;
|
||||
border-top: 1px solid gray("300");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/**********************************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2019 MuK IT GmbH.
|
||||
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
*
|
||||
**********************************************************************************/
|
||||
|
||||
.mk_file_kanban_view {
|
||||
height: 100%;
|
||||
.o_kanban_record {
|
||||
> div:nth-child(1) {
|
||||
padding: 0 5px !important;
|
||||
}
|
||||
|
||||
padding: 0;
|
||||
max-height: $o-kanban-image-width + 1;
|
||||
.o_kanban_image {
|
||||
width: $o-kanban-image-width + 1;
|
||||
border-right: solid 1px $gray-400;
|
||||
}
|
||||
.o_kanban_details .o_kanban_details_wrapper {
|
||||
padding: 4px 4px 4px 0;
|
||||
.o_kanban_record_title {
|
||||
font-weight: bold;
|
||||
padding-right: 16px;
|
||||
}
|
||||
.o_kanban_record_body {
|
||||
max-height: 12px;
|
||||
.o_kanban_tags {
|
||||
@include o-text-overflow;
|
||||
}
|
||||
}
|
||||
.oe_kanban_avatar {
|
||||
margin-left: 0px;
|
||||
}
|
||||
.mk_file_kanban_lock {
|
||||
margin-top: 2px;
|
||||
font-size: 1.2rem;
|
||||
line-height: 20px;
|
||||
margin-right: 6px;
|
||||
}
|
||||
}
|
||||
.o_dropdown_kanban {
|
||||
.dropdown-menu {
|
||||
min-width: 22rem;
|
||||
.mk_file_kanban_operations {
|
||||
padding-right: 8px;
|
||||
}
|
||||
.mk_file_kanban_actions {
|
||||
padding-left: 8px;
|
||||
}
|
||||
.fa {
|
||||
min-width: 12px;
|
||||
padding-right: 2px;
|
||||
text-align: center;
|
||||
}
|
||||
.oe_kanban_colorpicker {
|
||||
max-width: none;
|
||||
margin: 5px 5px;
|
||||
padding: 10px 0 0 25px;
|
||||
border-top: 1px solid gray("300");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.o_dropzone {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
background-color: #aaaa;
|
||||
z-index: 2;
|
||||
left: 0;
|
||||
top: 0;
|
||||
i {
|
||||
justify-content: center;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/**********************************************************************************
|
||||
*
|
||||
* Copyright (c) 2017-2019 MuK IT GmbH.
|
||||
* License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
*
|
||||
**********************************************************************************/
|
||||
|
||||
$mk-file-kanban-sidebar-width: 200px;
|
||||
$mk-file-kanban-sidebar-padding: 8px;
|
||||
72
odoo-bringout-oca-dms-dms/dms/static/src/xml/views.xml
Normal file
72
odoo-bringout-oca-dms-dms/dms/static/src/xml/views.xml
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
|
||||
Copyright 2020 CreuBlanca
|
||||
License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
|
||||
|
||||
-->
|
||||
<templates xml:space="preserve">
|
||||
<t t-name="FieldBinaryPreview.Content" t-extend="DocumentViewer.Content">
|
||||
<!-- We need to replace in order to change all the called options,
|
||||
the new item will contain the same elements than the original one
|
||||
-->
|
||||
<t t-jquery=".o_viewer_zoomer" t-operation="replace">
|
||||
<div class="o_viewer_zoomer">
|
||||
<div
|
||||
t-if="widget.activeAttachment.fileType == 'image'"
|
||||
class="o_loading_img text-center"
|
||||
>
|
||||
<i
|
||||
class="fa fa-circle-o-notch fa-spin text-gray-light fa-3x fa-fw"
|
||||
role="img"
|
||||
aria-label="Loading"
|
||||
title="Loading"
|
||||
/>
|
||||
</div>
|
||||
<img
|
||||
t-if="widget.activeAttachment.fileType === 'image'"
|
||||
class="o_viewer_img"
|
||||
t-attf-src="/web/image/#{model}/#{widget.activeAttachment.id}/#{widget.fieldName}?unique=1&signature=#{widget.activeAttachment.checksum}&model=#{model}"
|
||||
alt="Viewer"
|
||||
/>
|
||||
<iframe
|
||||
t-if="widget.activeAttachment.fileType == 'application/pdf'"
|
||||
class="mt32 o_viewer_pdf"
|
||||
t-attf-src="/web/static/lib/pdfjs/web/viewer.html?file=/web/content/#{model}/#{widget.activeAttachment.id}/#{widget.fieldName}"
|
||||
/>
|
||||
<iframe
|
||||
t-if="(widget.activeAttachment.fileType || '').indexOf('text') !== -1"
|
||||
class="mt32 o_viewer_text"
|
||||
t-attf-src="/web/content/#{model}/#{widget.activeAttachment.id}/#{widget.fieldName}"
|
||||
/>
|
||||
<iframe
|
||||
t-if="widget.activeAttachment.fileType == 'youtu'"
|
||||
class="mt32 o_viewer_text"
|
||||
allow="autoplay; encrypted-media"
|
||||
width="560"
|
||||
height="315"
|
||||
t-attf-src="https://www.youtube.com/embed/#{widget.activeAttachment.youtube}"
|
||||
/>
|
||||
<video
|
||||
t-if="widget.activeAttachment.fileType == 'video'"
|
||||
class="o_viewer_video"
|
||||
controls="controls"
|
||||
>
|
||||
<source
|
||||
t-attf-src="/web/image/#{model}/#{widget.activeAttachment.id}/#{widget.fieldName}"
|
||||
t-att-data-type="widget.activeAttachment.mimetype"
|
||||
/>
|
||||
</video>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
<t t-name="FieldBinaryPreview" t-extend="DocumentViewer">
|
||||
<!-- We need to replace in order to change the called options-->
|
||||
<t t-jquery=".o_document_viewer_content_call" t-operation="replace">
|
||||
<t
|
||||
class="o_document_viewer_content_call"
|
||||
t-call="FieldBinaryPreview.Content"
|
||||
/>
|
||||
</t>
|
||||
</t>
|
||||
</templates>
|
||||
Loading…
Add table
Add a link
Reference in a new issue