From 05f7c674e9aad1c6e0038df740cd00d9fea350ba Mon Sep 17 00:00:00 2001 From: KB Date: Mon, 18 Sep 2023 18:09:26 +0200 Subject: [PATCH] [MIG] dms: Migration from 15.0 to 16.0 --- dms/README.rst | 8 + dms/__manifest__.py | 26 +- dms/controllers/main.py | 12 +- dms/controllers/portal.py | 4 +- dms/i18n/de.po | 276 ++++++++++-------- dms/i18n/dms.pot | 108 +++++-- dms/models/abstract_dms_mixin.py | 4 +- dms/models/access_groups.py | 4 +- dms/models/category.py | 4 +- dms/models/directory.py | 8 +- dms/models/dms_file.py | 31 +- dms/models/dms_security_mixin.py | 8 +- dms/models/res_company.py | 2 +- dms/static/src/js/fields/path_owl.esm.js | 34 +++ dms/static/src/js/fields/path_owl.xml | 27 ++ .../src/js/views/dms_file_upload.esm.js | 169 +++++++++++ .../views/fields/binary/preview_record.esm.js | 35 +++ .../js/views/fields/binary/preview_record.xml | 39 +++ .../js/views/file_kanban_controller.esm.js | 14 + .../src/js/views/file_kanban_controller.js | 62 ---- .../src/js/views/file_kanban_controller.xml | 26 ++ .../src/js/views/file_kanban_record.esm.js | 62 ++++ .../src/js/views/file_kanban_renderer.esm.js | 20 ++ .../src/js/views/file_kanban_renderer.js | 28 -- .../src/js/views/file_kanban_renderer.xml | 54 ++++ .../src/js/views/file_kanban_view.esm.js | 28 ++ dms/static/src/js/views/file_kanban_view.js | 28 -- .../src/js/views/file_list_controller.esm.js | 15 + .../src/js/views/file_list_controller.js | 16 - .../src/js/views/file_list_renderer.esm.js | 18 ++ .../src/js/views/file_list_renderer.xml | 54 ++++ dms/static/src/js/views/file_list_view.esm.js | 28 ++ dms/static/src/js/views/file_list_view.js | 24 -- dms/static/src/js/views/search_panel.esm.js | 33 +-- dms/static/src/models/attachment.esm.js | 88 ++++++ dms/static/src/models/attachment_image.esm.js | 33 +++ .../models/attachment_viewer_viewable.esm.js | 30 ++ dms/static/src/scss/directory_kanban.scss | 8 + dms/static/src/scss/file_kanban.scss | 20 ++ dms/tests/common.py | 10 +- dms/tests/test_benchmark.py | 1 + dms/tests/test_directory.py | 2 +- dms/tests/test_file_database.py | 2 +- dms/tests/test_portal.py | 8 +- dms/tests/test_storage_attachment.py | 6 +- dms/views/directory.xml | 44 +-- dms/views/dms_file.xml | 24 +- dms/views/res_config_settings.xml | 1 + 48 files changed, 1181 insertions(+), 405 deletions(-) create mode 100644 dms/static/src/js/fields/path_owl.esm.js create mode 100644 dms/static/src/js/fields/path_owl.xml create mode 100644 dms/static/src/js/views/dms_file_upload.esm.js create mode 100644 dms/static/src/js/views/fields/binary/preview_record.esm.js create mode 100644 dms/static/src/js/views/fields/binary/preview_record.xml create mode 100644 dms/static/src/js/views/file_kanban_controller.esm.js delete mode 100644 dms/static/src/js/views/file_kanban_controller.js create mode 100644 dms/static/src/js/views/file_kanban_controller.xml create mode 100644 dms/static/src/js/views/file_kanban_record.esm.js create mode 100644 dms/static/src/js/views/file_kanban_renderer.esm.js delete mode 100644 dms/static/src/js/views/file_kanban_renderer.js create mode 100644 dms/static/src/js/views/file_kanban_renderer.xml create mode 100644 dms/static/src/js/views/file_kanban_view.esm.js delete mode 100644 dms/static/src/js/views/file_kanban_view.js create mode 100644 dms/static/src/js/views/file_list_controller.esm.js delete mode 100644 dms/static/src/js/views/file_list_controller.js create mode 100644 dms/static/src/js/views/file_list_renderer.esm.js create mode 100644 dms/static/src/js/views/file_list_renderer.xml create mode 100644 dms/static/src/js/views/file_list_view.esm.js delete mode 100644 dms/static/src/js/views/file_list_view.js create mode 100644 dms/static/src/models/attachment.esm.js create mode 100644 dms/static/src/models/attachment_image.esm.js create mode 100644 dms/static/src/models/attachment_viewer_viewable.esm.js diff --git a/dms/README.rst b/dms/README.rst index 0030a2990..d27e146ac 100644 --- a/dms/README.rst +++ b/dms/README.rst @@ -153,6 +153,12 @@ Contributors * Pedro M. Baeza * Jairo Llopis +* `Elego `_: + + * Yu Weng + * Philip Witte + * Khanh Bui + Other credits ~~~~~~~~~~~~~ @@ -161,6 +167,8 @@ Some pictures are based on or inspired by: * `Roundicons `_ * `Smashicons `_ +The migration of this module from 15.0 to 16.0 was finanically supported by `AgentERP `_ + Maintainers ~~~~~~~~~~~ diff --git a/dms/__manifest__.py b/dms/__manifest__.py index fe1702dbc..40b0a63c6 100644 --- a/dms/__manifest__.py +++ b/dms/__manifest__.py @@ -4,17 +4,16 @@ { "name": "Document Management System", "summary": """Document Management System for Odoo""", - "version": "15.0.1.8.2", + "version": "16.0.1.0.0", "category": "Document Management", "license": "LGPL-3", "website": "https://github.com/OCA/dms", "author": "MuK IT, Tecnativa, Odoo Community Association (OCA)", "depends": [ - "web_drop_target", "mail", "http_routing", "portal", - "mail_preview_base", + "base", ], "data": [ "security/security.xml", @@ -32,20 +31,17 @@ "views/dms_portal_templates.xml", ], "assets": { + "mail.assets_messaging": [ + ("include", "mail.assets_core_messaging"), + "dms/static/src/models/*.js", + ], "web.assets_backend": [ - "dms/static/src/scss/variables.scss", - "dms/static/src/scss/file_kanban.scss", - "dms/static/src/scss/directory_kanban.scss", - "dms/static/src/js/fields/path.js", - "dms/static/src/js/views/many_drop_target.js", - "dms/static/src/js/views/search_panel.esm.js", - "dms/static/src/js/views/file_list_controller.js", - "dms/static/src/js/views/file_list_view.js", - "dms/static/src/js/views/file_kanban_controller.js", - "dms/static/src/js/views/file_kanban_renderer.js", - "dms/static/src/js/views/file_kanban_view.js", + "dms/static/src/scss/*", + "dms/static/src/js/fields/*", + "dms/static/src/js/views/*.esm.js", + "dms/static/src/js/views/*.xml", + "dms/static/src/js/views/fields/binary/*", ], - "web.assets_qweb": ["dms/static/src/xml/views.xml"], "web.assets_frontend": ["dms/static/src/js/dms_portal_tour.js"], }, "demo": [ diff --git a/dms/controllers/main.py b/dms/controllers/main.py index d8dcf0dce..f2bb55d86 100644 --- a/dms/controllers/main.py +++ b/dms/controllers/main.py @@ -12,13 +12,12 @@ def document_onboarding_directory(self): check = request.env.user.has_group("dms.group_dms_manager") if check and not closed: return { - "html": request.env.ref( - "dms.document_onboarding_directory_panel" - )._render( + "html": request.env["ir.qweb"]._render( + request.env.ref("dms.document_onboarding_directory_panel").id, { "state": company.get_and_update_documents_onboarding_state(), "company": company, - } + }, ) } return {} @@ -30,11 +29,12 @@ def document_onboarding_file(self): check = request.env.user.has_group("dms.group_dms_manager") if check and not closed: return { - "html": request.env.ref("dms.document_onboarding_file_panel")._render( + "html": request.env["ir.qweb"]._render( + request.env.ref("dms.document_onboarding_file_panel").id, { "state": company.get_and_update_documents_onboarding_state(), "company": company, - } + }, ) } return {} diff --git a/dms/controllers/portal.py b/dms/controllers/portal.py index 5113fdd4f..54e4355e3 100644 --- a/dms/controllers/portal.py +++ b/dms/controllers/portal.py @@ -2,11 +2,11 @@ import base64 from odoo import _, http -from odoo.http import request +from odoo.http import content_disposition, request from odoo.osv.expression import OR from odoo.addons.portal.controllers.portal import CustomerPortal -from odoo.addons.web.controllers.main import content_disposition, ensure_db +from odoo.addons.web.controllers.utils import ensure_db class CustomerPortal(CustomerPortal): diff --git a/dms/i18n/de.po b/dms/i18n/de.po index b46d649ac..b74e16e9b 100644 --- a/dms/i18n/de.po +++ b/dms/i18n/de.po @@ -4,53 +4,49 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 14.0\n" +"Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2022-07-18 17:06+0000\n" -"Last-Translator: Maria Sparenberg \n" -"Language-Team: none\n" -"Language: de\n" +"POT-Creation-Date: 2023-09-18 11:18+0000\n" +"PO-Revision-Date: 2023-09-18 11:18+0000\n" +"Last-Translator: \n" +"Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 4.3.2\n" +"Plural-Forms: \n" #. module: dms #: model:ir.model.fields,help:dms.field_dms_directory__alias_process msgid "" " Define how incoming emails are processed:\n" "\n" -" - Single Files: The email gets attached to the directory " -"and\n" +" - Single Files: The email gets attached to the directory and\n" " all attachments are created as files.\n" "\n" -" - Subdirectory: A new subdirectory is created for each " -"email\n" -" and the mail is attached to this subdirectory. The " -"attachments\n" +" - Subdirectory: A new subdirectory is created for each email\n" +" and the mail is attached to this subdirectory. The attachments\n" " are created as files of the subdirectory.\n" " " msgstr "" " Legen Sie fest, wie ankommende E-Mails behandelt werden:\n" "\n" -" - Einzelne Dateien: Die E-Mail wird im Verzeichnis " -"gespeichert und\n" +" - Einzelne Dateien: Die E-Mail wird im Verzeichnis gespeichert und\n" " alle Anhänge werden als Dateien gespeichert.\n" "\n" -" - Unterverzeichnis: Für jede E-Mail wird ein neues " -"Unterverzeichnis erstellt\n" +" - Unterverzeichnis: Für jede E-Mail wird ein neues Unterverzeichnis erstellt\n" " und die E-Mail in dieses gespeichert. Die Anhänge\n" " werden als Dateien in diesem Unterverzeichnis gespeichert.\n" " " #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "%s Files" msgstr "%s Dateien" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "%s Subdirectories" @@ -59,12 +55,12 @@ msgstr "%s Unterverzeichnisse" #. module: dms #: model_terms:ir.ui.view,arch_db:dms.document_onboarding_directory_panel msgid "/dms/static/lib/img/banner/documents_onboarding_directory.png" -msgstr "/dms/static/lib/img/banner/documents_onboarding_directory.png" +msgstr "" #. module: dms #: model_terms:ir.ui.view,arch_db:dms.document_onboarding_file_panel msgid "/dms/static/lib/img/banner/documents_onboarding_file.png" -msgstr "/dms/static/lib/img/banner/documents_onboarding_file.png" +msgstr "" #. module: dms #: model_terms:ir.ui.view,arch_db:dms.view_dms_file_kanban @@ -216,8 +212,7 @@ msgstr "Dateigröße" #: model_terms:ir.ui.view,arch_db:dms.view_dms_directory_form msgid "" "@\n" -" @ " +" @ " msgstr "" #. module: dms @@ -235,18 +230,21 @@ msgstr "" "Datensätze für diesen Alias Standardwerte bereitzustellen." #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "A directory can't be a root and have a parent directory." msgstr "Ein Stammverzeichnis kann kein Oberverzeichnis besitzen." #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "A directory has to have a parent directory." msgstr "Ein Verzeichnis benötigt ein Oberverzeichnis." #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "A directory has to have model in attachment storage." @@ -255,12 +253,14 @@ msgstr "" "gewählt wurde." #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "A directory with the same name already exists." msgstr "Es existiert bereits ein Verzeichnis mit diesem Namen." #. module: dms +#. odoo-python #: code:addons/dms/models/dms_file.py:0 #, python-format msgid "A file must have model and resource ID in attachment storage." @@ -269,12 +269,14 @@ msgstr "" "Speicherort gewählt wurde." #. module: dms +#. odoo-python #: code:addons/dms/models/dms_file.py:0 #, python-format msgid "A file with the same name already exists." msgstr "Es existiert bereits eine Datei mit diesem Namen." #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "A root directory has to have a storage." @@ -370,12 +372,12 @@ msgstr "Neue Datei hinzufügen." #. module: dms #: model:dms.access.group,name:dms.access_group_01_demo msgid "Admin" -msgstr "Admin" +msgstr "" #. module: dms #: model:ir.model.fields,field_description:dms.field_dms_directory__alias_id msgid "Alias" -msgstr "Alias" +msgstr "" #. module: dms #: model:ir.model.fields,field_description:dms.field_dms_directory__alias_contact @@ -398,6 +400,7 @@ msgid "Alias domain" msgstr "Alias-Domain" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "Alias-Mail-Extraction" @@ -419,10 +422,17 @@ msgstr "Alle" msgid "All Files" msgstr "Alle Dateien" +#. module: dms +#. odoo-javascript +#: code:addons/dms/static/src/js/views/dms_file_upload.js:0 +#, python-format +msgid "An error occurred during the upload" +msgstr "Während des Uploads ist ein Fehler aufgetreten" + #. module: dms #: model:dms.tag,name:dms.tag_06_demo msgid "Apps" -msgstr "Apps" +msgstr "Anwendungen" #. module: dms #: model:ir.model.fields,field_description:dms.field_dms_file__active @@ -438,6 +448,7 @@ msgid "Archived Files" msgstr "Archivierte Dateien" #. module: dms +#. odoo-python #: code:addons/dms/models/storage.py:0 #: model:ir.model,name:dms.model_ir_attachment #: model:ir.model.fields.selection,name:dms.selection__dms_storage__save_type__attachment @@ -778,7 +789,7 @@ msgstr "Portal-URL des Kunden" #. module: dms #: model_terms:ir.ui.view,arch_db:dms.portal_my_dms_breadcrumbs msgid "DMS" -msgstr "DMS" +msgstr "" #. module: dms #: model:ir.model,name:dms.model_dms_security_mixin @@ -791,6 +802,7 @@ msgid "DMS thumbnail and icon mixin" msgstr "DMS-Miniaturansicht und Symbol-Mixin" #. module: dms +#. odoo-python #: code:addons/dms/models/storage.py:0 #: model:ir.model.fields.selection,name:dms.selection__dms_storage__save_type__database #, python-format @@ -902,22 +914,22 @@ msgstr "Dokumente" #. module: dms #: model:ir.model.fields,field_description:dms.field_res_company__documents_onboarding_directory_state msgid "Documents Onboarding Directory State" -msgstr "" +msgstr "Dokumente Onboarding-Verzeichnis Status" #. module: dms #: model:ir.model.fields,field_description:dms.field_res_company__documents_onboarding_file_state msgid "Documents Onboarding File State" -msgstr "" +msgstr "Dokumente Onboarding-Dateistatus" #. module: dms #: model:ir.model.fields,field_description:dms.field_res_company__documents_onboarding_state msgid "Documents Onboarding State" -msgstr "" +msgstr "Dokumente Onboarding-Status" #. module: dms #: model:ir.model.fields,field_description:dms.field_res_company__documents_onboarding_storage_state msgid "Documents Onboarding Storage State" -msgstr "" +msgstr "Dokumente Onboarding Speicherstatus" #. module: dms #: model:ir.model.fields.selection,name:dms.selection__res_company__documents_onboarding_directory_state__done @@ -937,7 +949,7 @@ msgstr "Dropdown-Menü" #. module: dms #: model:ir.model.fields,field_description:dms.field_dms_file__is_lock_editor msgid "Editor" -msgstr "Editor" +msgstr "" #. module: dms #: model_terms:ir.ui.view,arch_db:dms.view_dms_directory_form @@ -952,21 +964,24 @@ msgstr "E-Mail-Alias" #. module: dms #: model:ir.model,name:dms.model_mail_thread msgid "Email Thread" -msgstr "E-Mail-Thread" +msgstr "E-Mail Thread" #. module: dms +#. odoo-python #: code:addons/dms/tests/common.py:0 #, python-format msgid "Error has not been raised" msgstr "Es ist ein Fehler aufgetreten." #. module: dms +#. odoo-python #: code:addons/dms/models/category.py:0 #, python-format msgid "Error! You cannot create recursive categories." msgstr "Fehler! Kategorien können nicht rekursiv angelegt werden." #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "Error! You cannot create recursive directories." @@ -1038,11 +1053,12 @@ msgid "Files are used to save content directly in Odoo." msgstr "Dateien werden genutzt, um Inhalte direkt in Odoo zu speichern." #. module: dms +#. odoo-python #: code:addons/dms/models/storage.py:0 #: model:ir.model.fields.selection,name:dms.selection__dms_storage__save_type__file #, python-format msgid "Filestore" -msgstr "Filestore" +msgstr "Dateiablage" #. module: dms #: model:ir.model.fields,field_description:dms.field_dms_directory__message_follower_ids @@ -1119,16 +1135,16 @@ msgstr "Personalwesen" #: model:ir.model.fields,field_description:dms.field_dms_storage__id #: model:ir.model.fields,field_description:dms.field_dms_tag__id msgid "ID" -msgstr "ID" +msgstr "" #. module: dms #: model:ir.model.fields,help:dms.field_dms_directory__alias_parent_thread_id msgid "" -"ID of the parent record holding the alias (example: project holding the task " -"creation alias)" +"ID of the parent record holding the alias (example: project holding the task" +" creation alias)" msgstr "" -"ID des übergeordneten Datensatzes, der den Alias enthält (Beispiel: Projekt, " -"das den Alias für die Aufgabenerstellung enthält)" +"ID des übergeordneten Datensatzes, der den Alias enthält (Beispiel: Projekt," +" das den Alias für die Aufgabenerstellung enthält)" #. module: dms #: model:ir.model.fields,field_description:dms.field_dms_directory__activity_exception_icon @@ -1136,7 +1152,7 @@ msgstr "" #: model_terms:ir.ui.view,arch_db:dms.view_dms_directory_kanban #: model_terms:ir.ui.view,arch_db:dms.view_dms_file_kanban msgid "Icon" -msgstr "Icon" +msgstr "" #. module: dms #: model:ir.model.fields,field_description:dms.field_dms_directory__icon_url @@ -1160,9 +1176,7 @@ msgstr "" #. module: dms #: model:ir.model.fields,help:dms.field_dms_directory__message_needaction -#: model:ir.model.fields,help:dms.field_dms_directory__message_unread #: model:ir.model.fields,help:dms.field_dms_file__message_needaction -#: model:ir.model.fields,help:dms.field_dms_file__message_unread msgid "If checked, new messages require your attention." msgstr "Falls markiert, benötigen neue Nachrichten Ihre Aufmerksamkeit." @@ -1185,8 +1199,8 @@ msgid "" "If set, directories and files will only be available for the selected " "company." msgstr "" -"Wenn diese Option festgelegt ist, sind Verzeichnisse und Dateien nur für das " -"ausgewählte Unternehmen verfügbar." +"Wenn diese Option festgelegt ist, sind Verzeichnisse und Dateien nur für das" +" ausgewählte Unternehmen verfügbar." #. module: dms #: model:ir.model.fields,help:dms.field_dms_directory__alias_bounced_content @@ -1236,9 +1250,9 @@ msgstr "Bild 512" #: model:ir.model.fields,help:dms.field_dms_directory__storage_id_inherit_access_from_parent_record #: model:ir.model.fields,help:dms.field_dms_storage__inherit_access_from_parent_record msgid "" -"Indicate if directories and files access work only with related model access " -"(for example, if some directories are related with any sale, only users with " -"read access to these sale can acess)" +"Indicate if directories and files access work only with related model access" +" (for example, if some directories are related with any sale, only users " +"with read access to these sale can acess)" msgstr "" "Gibt an, ob Verzeichnisse und Dateizugriff nur mit verwandtem Modellzugriff " "funktionieren (z. B. wenn einige Verzeichnisse mit einem Verkauf in " @@ -1248,7 +1262,8 @@ msgstr "" #. module: dms #: model:ir.model.fields,help:dms.field_dms_storage__include_message_attachments msgid "" -"Indicate if directories and files auto-create in mail composition process too" +"Indicate if directories and files auto-create in mail composition process " +"too" msgstr "" "Geben Sie an, ob Verzeichnisse und Dateien auch im E-Mail-" "Kompositionsprozess automatisch erstellt werden" @@ -1259,21 +1274,19 @@ msgstr "" #: model:ir.model.fields,help:dms.field_dms_file__is_hidden #: model:ir.model.fields,help:dms.field_dms_storage__is_hidden msgid "Indicates if directories and files are hidden by default." -msgstr "Gibt an, ob Verzeichnisse und Dateien standardmäßig ausgeblendet sind." +msgstr "" +"Gibt an, ob Verzeichnisse und Dateien standardmäßig ausgeblendet sind." #. module: dms #: model:ir.model.fields,help:dms.field_dms_directory__is_root_directory msgid "" "Indicates if the directory is a root directory.\n" -" A root directory has a settings object, while a directory with a " -"set\n" +" A root directory has a settings object, while a directory with a set\n" " parent inherits the settings form its parent." msgstr "" "Gibt an, ob es sich bei dem Verzeichnis um ein Stammverzeichnis handelt.\n" -" Ein Stammverzeichnis hat ein Einstellungsobjekt, während ein " -"Verzeichnis mit einem gesetzten\n" -" Oberverzeichnis die Einstellungen von seinem übergeordneten Element " -"erbt." +" Ein Stammverzeichnis hat ein Einstellungsobjekt, während ein Verzeichnis mit einem gesetzten\n" +" Oberverzeichnis die Einstellungen von seinem übergeordneten Element erbt." #. module: dms #: model:ir.model.fields,field_description:dms.field_dms_directory__inherit_group_ids @@ -1313,6 +1326,13 @@ msgstr "Intern" msgid "Internal / Human Resource" msgstr "Interne / Personal-Ressource" +#. module: dms +#. odoo-python +#: code:addons/dms/models/dms_file.py:0 +#, python-format +msgid "Invalid attachments!" +msgstr "Ungültige Anhänge!" + #. module: dms #: model_terms:ir.ui.view,arch_db:dms.view_dms_category_form msgid "Invoices" @@ -1330,6 +1350,7 @@ msgid "Is Root Directory" msgstr "Ist ein Stammverzeichnis" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "It is not possible to change parent to other storage." @@ -1338,6 +1359,7 @@ msgstr "" "einzustellen." #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "It is not possible to change the storage." @@ -1407,7 +1429,8 @@ msgid "Linked attachments record ID" msgstr "ID des verknüpften Anhangs-Datensatzes" #. module: dms -#. openerp-web +#. odoo-javascript +#: code:addons/dms/static/src/xml/views.xml:0 #: code:addons/dms/static/src/xml/views.xml:0 #, python-format msgid "Loading" @@ -1437,7 +1460,7 @@ msgstr "Hauptanhang" #. module: dms #: model:res.groups,name:dms.group_dms_manager msgid "Manager" -msgstr "Manager" +msgstr "" #. module: dms #: model_terms:ir.ui.view,arch_db:dms.view_dms_storage_form @@ -1468,6 +1491,7 @@ msgid "Migrate" msgstr "Migrieren" #. module: dms +#. odoo-python #: code:addons/dms/models/dms_file.py:0 #, python-format msgid "Migrate File %(index)s of %(record_count)s [ %(dms_file_migration)s ]" @@ -1481,7 +1505,7 @@ msgstr "Dateien migrieren" #. module: dms #: model:ir.ui.menu,name:dms.menu_dms_file_migration msgid "Migration" -msgstr "Migration" +msgstr "" #. module: dms #: model:ir.model.fields,field_description:dms.field_dms_file__migration @@ -1493,6 +1517,11 @@ msgstr "Migrationsstatus" msgid "Model" msgstr "Modell" +#. module: dms +#: model:ir.model.fields,field_description:dms.field_dms_file__model_name +msgid "Model Name" +msgstr "Modellname" + #. module: dms #: model_terms:ir.ui.view,arch_db:dms.search_dms_directory #: model_terms:ir.ui.view,arch_db:dms.search_dms_file @@ -1521,6 +1550,10 @@ msgid "My Files" msgstr "Meine Dateien" #. module: dms +#. odoo-python +#: code:addons/dms/controllers/portal.py:0 +#: code:addons/dms/controllers/portal.py:0 +#: code:addons/dms/controllers/portal.py:0 #: code:addons/dms/controllers/portal.py:0 #: model:ir.model.fields,field_description:dms.field_abstract_dms_mixin__name #: model:ir.model.fields,field_description:dms.field_dms_category__name @@ -1531,7 +1564,7 @@ msgstr "Meine Dateien" #: model_terms:ir.ui.view,arch_db:dms.portal_my_dms #, python-format msgid "Name" -msgstr "Name" +msgstr "" #. module: dms #: model:ir.actions.act_window,name:dms.action_dms_directory_new @@ -1567,6 +1600,13 @@ msgstr "Zusammenfassung der nächsten Aktivität" msgid "Next Activity Type" msgstr "Typ der nächsten Aktivität" +#. module: dms +#. odoo-python +#: code:addons/dms/models/dms_file.py:0 +#, python-format +msgid "No attachment was provided" +msgstr "Es wurde kein zur Verfügung gestellt" + #. module: dms #: model:ir.model.fields.selection,name:dms.selection__res_company__documents_onboarding_directory_state__not_done #: model:ir.model.fields.selection,name:dms.selection__res_company__documents_onboarding_file_state__not_done @@ -1595,8 +1635,8 @@ msgstr "Anzahl der Fehler" #. module: dms #: model:ir.model.fields,help:dms.field_dms_directory__message_needaction_counter #: model:ir.model.fields,help:dms.field_dms_file__message_needaction_counter -msgid "Number of messages which requires an action" -msgstr "Anzahl der Nachrichten, die eine Aktion erfordern" +msgid "Number of messages requiring action" +msgstr "Anzahl der Meldungen, die Maßnahmen erfordern" #. module: dms #: model:ir.model.fields,help:dms.field_dms_directory__message_has_error_counter @@ -1604,18 +1644,13 @@ msgstr "Anzahl der Nachrichten, die eine Aktion erfordern" msgid "Number of messages with delivery error" msgstr "Anzahl der Nachrichten mit Übertragungsfehler" -#. module: dms -#: model:ir.model.fields,help:dms.field_dms_directory__message_unread_counter -#: model:ir.model.fields,help:dms.field_dms_file__message_unread_counter -msgid "Number of unread messages" -msgstr "Anzahl der ungelesenen Nachrichten" - #. module: dms #: model:dms.access.group,name:dms.access_group_03_demo msgid "Only admin user" msgstr "Nur Admin Benutzer" #. module: dms +#. odoo-python #: code:addons/dms/models/storage.py:0 #, python-format msgid "Only managers can execute this action." @@ -1681,6 +1716,7 @@ msgid "Parent Record Thread ID" msgstr "Thread-ID des übergeordneten Datensatzes" #. module: dms +#. odoo-python #: code:addons/dms/models/access_groups.py:0 #, python-format msgid "Parent group '%(parent)s' is child of '%(current)s'." @@ -1689,8 +1725,8 @@ msgstr "Die übergeordnete Gruppe '%(parent)s' ist ein Kind von '%(current)s'." #. module: dms #: model:ir.model.fields,help:dms.field_dms_directory__alias_parent_model_id msgid "" -"Parent model holding the alias. The model holding the alias reference is not " -"necessarily the model given by alias_model_id (example: project " +"Parent model holding the alias. The model holding the alias reference is not" +" necessarily the model given by alias_model_id (example: project " "(parent_model) and task (model))" msgstr "" "Übergeordnetes Modell, das den Alias enthält. Das Modell, das den Alias-" @@ -1700,7 +1736,7 @@ msgstr "" #. module: dms #: model:dms.tag,name:dms.tag_02_demo msgid "Partner" -msgstr "Partner" +msgstr "" #. module: dms #: model:ir.model.fields,field_description:dms.field_dms_file__path_json @@ -1718,21 +1754,18 @@ msgid "" "Policy to post a message on the document using the mailgateway.\n" "- everyone: everyone can post\n" "- partners: only authenticated partners\n" -"- followers: only followers of the related document or members of following " -"channels\n" +"- followers: only followers of the related document or members of following channels\n" msgstr "" -"Richtlinie zum Veröffentlichen einer Nachricht auf dem Dokument über das " -"Mailgateway.\n" +"Richtlinie zum Veröffentlichen einer Nachricht auf dem Dokument über das Mailgateway.\n" "- Jeder: jeder kann posten\n" "- Partner: nur authentifizierte Partner\n" -"- Abonnenten: nur Abonnenten des entsprechenden Dokuments oder Mitglieder " -"der folgenden Kanäle\n" +"- Abonnenten: nur Abonnenten des entsprechenden Dokuments oder Mitglieder der folgenden Kanäle\n" #. module: dms #: model:dms.access.group,name:dms.access_group_02_demo #: model:dms.tag,name:dms.tag_05_demo msgid "Portal" -msgstr "Portal" +msgstr "" #. module: dms #: model:ir.model.fields,field_description:dms.field_dms_directory__access_url @@ -1740,6 +1773,13 @@ msgstr "Portal" msgid "Portal Access URL" msgstr "URL für Portalzugriff" +#. module: dms +#. odoo-javascript +#: code:addons/dms/static/src/js/views/fields/binary/preview_record.xml:0 +#, python-format +msgid "Preview" +msgstr "Vorschau" + #. module: dms #: model:dms.tag,name:dms.tag_10_demo msgid "Product" @@ -1786,7 +1826,7 @@ msgid "Responsible User" msgstr "Verantwortlicher Benutzer" #. module: dms -#. openerp-web +#. odoo-javascript #: code:addons/dms/static/src/js/views/search_panel.esm.js:0 #, python-format msgid "Root" @@ -1819,6 +1859,15 @@ msgstr "Verkäufe" msgid "Save Type" msgstr "Speichertyp" +#. module: dms +#. odoo-javascript +#: code:addons/dms/static/src/js/views/file_kanban_buttons_template.xml:0 +#: code:addons/dms/static/src/js/views/file_kanban_renderer.xml:0 +#: code:addons/dms/static/src/js/views/file_list_renderer.xml:0 +#, python-format +msgid "Scan" +msgstr "Scannen" + #. module: dms #: model:ir.model.fields,field_description:dms.field_dms_directory__access_token #: model:ir.model.fields,field_description:dms.field_dms_file__access_token @@ -1937,7 +1986,7 @@ msgstr "Unterverzeichnis" #. module: dms #: model:ir.ui.menu,name:dms.cat_menu_dms_config_system msgid "System" -msgstr "System" +msgstr "" #. module: dms #: model_terms:ir.ui.view,arch_db:dms.view_dms_tag_form @@ -1997,24 +2046,28 @@ msgid "The configuration is done!" msgstr "Die Konfiguration ist abgeschlossen!" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "The directory name is invalid." msgstr "Der Name des Verzeichnisses ist ungültig." #. module: dms +#. odoo-python #: code:addons/dms/models/dms_file.py:0 #, python-format msgid "The file has a forbidden file extension." msgstr "Dies ist ein verbotener Dateityp." #. module: dms +#. odoo-python #: code:addons/dms/models/dms_file.py:0 #, python-format msgid "The file name is invalid." msgstr "Der Name der Datei ist ungültig." #. module: dms +#. odoo-python #: code:addons/dms/models/dms_file.py:0 #, python-format msgid "The maximum upload size is %s MB)." @@ -2023,9 +2076,9 @@ msgstr "Die maximale Upload-Größe beträgt %s MB." #. module: dms #: model:ir.model.fields,help:dms.field_dms_directory__alias_model_id msgid "" -"The model (Odoo Document Kind) to which this alias corresponds. Any incoming " -"email that does not reply to an existing record will cause the creation of a " -"new record of this model (e.g. a Project Task)" +"The model (Odoo Document Kind) to which this alias corresponds. Any incoming" +" email that does not reply to an existing record will cause the creation of " +"a new record of this model (e.g. a Project Task)" msgstr "" "Das Modell (Odoo Document Kind), dem dieser Alias entspricht. Jede " "eingehende E-Mail, die nicht auf einen bestehenden Datensatz antwortet, " @@ -2054,11 +2107,11 @@ msgid "" "the sender (From) address, or will use the Administrator account if no " "system user is found for that address." msgstr "" -"Der Eigentümer der Datensätze, die beim Empfang von E-Mails mit diesem Alias " -"erstellt werden. Wenn dieses Feld nicht gesetzt ist, versucht das System, " +"Der Eigentümer der Datensätze, die beim Empfang von E-Mails mit diesem Alias" +" erstellt werden. Wenn dieses Feld nicht gesetzt ist, versucht das System, " "den richtigen Besitzer anhand der Absenderadresse zu finden, oder es " -"verwendet das Administratorkonto, wenn kein Systembenutzer für diese Adresse " -"gefunden wird." +"verwendet das Administratorkonto, wenn kein Systembenutzer für diese Adresse" +" gefunden wird." #. module: dms #: model:ir.model.fields,help:dms.field_abstract_dms_mixin__storage_id_save_type @@ -2071,11 +2124,11 @@ msgid "" " manually by triggering the action." msgstr "" "Der Speichertyp wird verwendet, um zu bestimmen, wie eine Datei vom\n" -" System gespeichert wird. Wenn Sie diese Einstellung ändern, können " -"Sie vorhandene Dateien\n" +" System gespeichert wird. Wenn Sie diese Einstellung ändern, können Sie vorhandene Dateien\n" " manuell migrieren, indem Sie die Aktion auslösen." #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "This directory needs to be associated to a record." @@ -2128,16 +2181,14 @@ msgid "Unpack Emails as" msgstr "E-Mail entpacken als" #. module: dms -#: model:ir.model.fields,field_description:dms.field_dms_directory__message_unread -#: model:ir.model.fields,field_description:dms.field_dms_file__message_unread -msgid "Unread Messages" -msgstr "Ungelesene Nachrichten" - -#. module: dms -#: model:ir.model.fields,field_description:dms.field_dms_directory__message_unread_counter -#: model:ir.model.fields,field_description:dms.field_dms_file__message_unread_counter -msgid "Unread Messages Counter" -msgstr "Anzahl der ungelesenen Nachrichten" +#. odoo-javascript +#: code:addons/dms/static/src/js/views/file_kanban_buttons_template.xml:0 +#: code:addons/dms/static/src/js/views/file_kanban_controller.xml:0 +#: code:addons/dms/static/src/js/views/file_kanban_renderer.xml:0 +#: code:addons/dms/static/src/js/views/file_list_renderer.xml:0 +#, python-format +msgid "Upload" +msgstr "Hochladen" #. module: dms #: model_terms:ir.ui.view,arch_db:dms.onboarding_file_step @@ -2165,7 +2216,7 @@ msgid "Vendor Bill" msgstr "Lieferantenrechnung" #. module: dms -#. openerp-web +#. odoo-javascript #: code:addons/dms/static/src/xml/views.xml:0 #, python-format msgid "Viewer" @@ -2197,7 +2248,8 @@ msgid "Write Access" msgstr "Schreibberechtigung" #. module: dms -#. openerp-web +#. odoo-javascript +#: code:addons/dms/static/src/js/views/dms_file_upload.js:0 #: code:addons/dms/static/src/js/views/many_drop_target.js:0 #, python-format msgid "You must select a directory first" @@ -2207,7 +2259,7 @@ msgstr "Sie müssen zuerst ein Verzeichnis auswählen" #: model_terms:ir.ui.view,arch_db:dms.document_onboarding_directory_panel #: model_terms:ir.ui.view,arch_db:dms.document_onboarding_file_panel msgid "action_close_documents_onboarding" -msgstr "action_close_documents_onboarding" +msgstr "" #. module: dms #: model_terms:ir.ui.view,arch_db:dms.portal_my_dms @@ -2222,38 +2274,20 @@ msgstr "exe, msi" #. module: dms #: model_terms:ir.ui.view,arch_db:dms.view_dms_directory_form msgid "mail.catchall.domain" -msgstr "mail.catchall.domain" +msgstr "" #. module: dms #: model_terms:ir.ui.view,arch_db:dms.document_onboarding_file_panel msgid "o_onboarding_blue" -msgstr "o_onboarding_blue" +msgstr "" #. module: dms #: model_terms:ir.ui.view,arch_db:dms.document_onboarding_directory_panel msgid "o_onboarding_orange" -msgstr "o_onboarding_orange" +msgstr "" #. module: dms #: model_terms:ir.ui.view,arch_db:dms.document_onboarding_directory_panel #: model_terms:ir.ui.view,arch_db:dms.document_onboarding_file_panel msgid "res.company" -msgstr "res.company" - -#~ msgid "Path" -#~ msgstr "Pfad" - -#~ msgid "Search" -#~ msgstr "Suche" - -#~ msgid "Followers (Channels)" -#~ msgstr "Abonnenten (Kanäle)" - -#~ msgid "Locked by" -#~ msgstr "Gesperrt von" - -#~ msgid "Migrate File %s of %s [ %s ]" -#~ msgstr "Migriere Datei %s von %s [%s]" - -#~ msgid "Drop your files here" -#~ msgstr "Dateien hier ablegen" +msgstr "" diff --git a/dms/i18n/dms.pot b/dms/i18n/dms.pot index 92c1ee77a..03cc5de72 100644 --- a/dms/i18n/dms.pot +++ b/dms/i18n/dms.pot @@ -4,8 +4,10 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 15.0\n" +"Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-09-18 11:16+0000\n" +"PO-Revision-Date: 2023-09-18 11:16+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -28,12 +30,14 @@ msgid "" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "%s Files" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "%s Subdirectories" @@ -184,42 +188,49 @@ msgid "" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "A directory can't be a root and have a parent directory." msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "A directory has to have a parent directory." msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "A directory has to have model in attachment storage." msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "A directory with the same name already exists." msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/dms_file.py:0 #, python-format msgid "A file must have model and resource ID in attachment storage." msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/dms_file.py:0 #, python-format msgid "A file with the same name already exists." msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "A root directory has to have a storage." @@ -343,6 +354,7 @@ msgid "Alias domain" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "Alias-Mail-Extraction" @@ -364,6 +376,13 @@ msgstr "" msgid "All Files" msgstr "" +#. module: dms +#. odoo-javascript +#: code:addons/dms/static/src/js/views/dms_file_upload.js:0 +#, python-format +msgid "An error occurred during the upload" +msgstr "" + #. module: dms #: model:dms.tag,name:dms.tag_06_demo msgid "Apps" @@ -383,6 +402,7 @@ msgid "Archived Files" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/storage.py:0 #: model:ir.model,name:dms.model_ir_attachment #: model:ir.model.fields.selection,name:dms.selection__dms_storage__save_type__attachment @@ -736,6 +756,7 @@ msgid "DMS thumbnail and icon mixin" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/storage.py:0 #: model:ir.model.fields.selection,name:dms.selection__dms_storage__save_type__database #, python-format @@ -895,18 +916,21 @@ msgid "Email Thread" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/tests/common.py:0 #, python-format msgid "Error has not been raised" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/category.py:0 #, python-format msgid "Error! You cannot create recursive categories." msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "Error! You cannot create recursive directories." @@ -978,6 +1002,7 @@ msgid "Files are used to save content directly in Odoo." msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/storage.py:0 #: model:ir.model.fields.selection,name:dms.selection__dms_storage__save_type__file #, python-format @@ -1096,9 +1121,7 @@ msgstr "" #. module: dms #: model:ir.model.fields,help:dms.field_dms_directory__message_needaction -#: model:ir.model.fields,help:dms.field_dms_directory__message_unread #: model:ir.model.fields,help:dms.field_dms_file__message_needaction -#: model:ir.model.fields,help:dms.field_dms_file__message_unread msgid "If checked, new messages require your attention." msgstr "" @@ -1232,6 +1255,13 @@ msgstr "" msgid "Internal / Human Resource" msgstr "" +#. module: dms +#. odoo-python +#: code:addons/dms/models/dms_file.py:0 +#, python-format +msgid "Invalid attachments!" +msgstr "" + #. module: dms #: model_terms:ir.ui.view,arch_db:dms.view_dms_category_form msgid "Invoices" @@ -1249,12 +1279,14 @@ msgid "Is Root Directory" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "It is not possible to change parent to other storage." msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "It is not possible to change the storage." @@ -1324,7 +1356,7 @@ msgid "Linked attachments record ID" msgstr "" #. module: dms -#. openerp-web +#. odoo-javascript #: code:addons/dms/static/src/xml/views.xml:0 #: code:addons/dms/static/src/xml/views.xml:0 #, python-format @@ -1386,6 +1418,7 @@ msgid "Migrate" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/dms_file.py:0 #, python-format msgid "Migrate File %(index)s of %(record_count)s [ %(dms_file_migration)s ]" @@ -1411,6 +1444,11 @@ msgstr "" msgid "Model" msgstr "" +#. module: dms +#: model:ir.model.fields,field_description:dms.field_dms_file__model_name +msgid "Model Name" +msgstr "" + #. module: dms #: model_terms:ir.ui.view,arch_db:dms.search_dms_directory #: model_terms:ir.ui.view,arch_db:dms.search_dms_file @@ -1439,6 +1477,7 @@ msgid "My Files" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/controllers/portal.py:0 #: code:addons/dms/controllers/portal.py:0 #: code:addons/dms/controllers/portal.py:0 @@ -1488,6 +1527,13 @@ msgstr "" msgid "Next Activity Type" msgstr "" +#. module: dms +#. odoo-python +#: code:addons/dms/models/dms_file.py:0 +#, python-format +msgid "No attachment was provided" +msgstr "" + #. module: dms #: model:ir.model.fields.selection,name:dms.selection__res_company__documents_onboarding_directory_state__not_done #: model:ir.model.fields.selection,name:dms.selection__res_company__documents_onboarding_file_state__not_done @@ -1516,7 +1562,7 @@ msgstr "" #. module: dms #: model:ir.model.fields,help:dms.field_dms_directory__message_needaction_counter #: model:ir.model.fields,help:dms.field_dms_file__message_needaction_counter -msgid "Number of messages which requires an action" +msgid "Number of messages requiring action" msgstr "" #. module: dms @@ -1525,18 +1571,13 @@ msgstr "" msgid "Number of messages with delivery error" msgstr "" -#. module: dms -#: model:ir.model.fields,help:dms.field_dms_directory__message_unread_counter -#: model:ir.model.fields,help:dms.field_dms_file__message_unread_counter -msgid "Number of unread messages" -msgstr "" - #. module: dms #: model:dms.access.group,name:dms.access_group_03_demo msgid "Only admin user" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/storage.py:0 #, python-format msgid "Only managers can execute this action." @@ -1598,6 +1639,7 @@ msgid "Parent Record Thread ID" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/access_groups.py:0 #, python-format msgid "Parent group '%(parent)s' is child of '%(current)s'." @@ -1647,6 +1689,13 @@ msgstr "" msgid "Portal Access URL" msgstr "" +#. module: dms +#. odoo-javascript +#: code:addons/dms/static/src/js/views/fields/binary/preview_record.xml:0 +#, python-format +msgid "Preview" +msgstr "" + #. module: dms #: model:dms.tag,name:dms.tag_10_demo msgid "Product" @@ -1693,7 +1742,7 @@ msgid "Responsible User" msgstr "" #. module: dms -#. openerp-web +#. odoo-javascript #: code:addons/dms/static/src/js/views/search_panel.esm.js:0 #, python-format msgid "Root" @@ -1726,6 +1775,15 @@ msgstr "" msgid "Save Type" msgstr "" +#. module: dms +#. odoo-javascript +#: code:addons/dms/static/src/js/views/file_kanban_buttons_template.xml:0 +#: code:addons/dms/static/src/js/views/file_kanban_renderer.xml:0 +#: code:addons/dms/static/src/js/views/file_list_renderer.xml:0 +#, python-format +msgid "Scan" +msgstr "" + #. module: dms #: model:ir.model.fields,field_description:dms.field_dms_directory__access_token #: model:ir.model.fields,field_description:dms.field_dms_file__access_token @@ -1896,24 +1954,28 @@ msgid "The configuration is done!" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "The directory name is invalid." msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/dms_file.py:0 #, python-format msgid "The file has a forbidden file extension." msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/dms_file.py:0 #, python-format msgid "The file name is invalid." msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/dms_file.py:0 #, python-format msgid "The maximum upload size is %s MB)." @@ -1960,6 +2022,7 @@ msgid "" msgstr "" #. module: dms +#. odoo-python #: code:addons/dms/models/directory.py:0 #, python-format msgid "This directory needs to be associated to a record." @@ -2012,15 +2075,13 @@ msgid "Unpack Emails as" msgstr "" #. module: dms -#: model:ir.model.fields,field_description:dms.field_dms_directory__message_unread -#: model:ir.model.fields,field_description:dms.field_dms_file__message_unread -msgid "Unread Messages" -msgstr "" - -#. module: dms -#: model:ir.model.fields,field_description:dms.field_dms_directory__message_unread_counter -#: model:ir.model.fields,field_description:dms.field_dms_file__message_unread_counter -msgid "Unread Messages Counter" +#. odoo-javascript +#: code:addons/dms/static/src/js/views/file_kanban_buttons_template.xml:0 +#: code:addons/dms/static/src/js/views/file_kanban_controller.xml:0 +#: code:addons/dms/static/src/js/views/file_kanban_renderer.xml:0 +#: code:addons/dms/static/src/js/views/file_list_renderer.xml:0 +#, python-format +msgid "Upload" msgstr "" #. module: dms @@ -2049,7 +2110,7 @@ msgid "Vendor Bill" msgstr "" #. module: dms -#. openerp-web +#. odoo-javascript #: code:addons/dms/static/src/xml/views.xml:0 #, python-format msgid "Viewer" @@ -2081,7 +2142,8 @@ msgid "Write Access" msgstr "" #. module: dms -#. openerp-web +#. odoo-javascript +#: code:addons/dms/static/src/js/views/dms_file_upload.js:0 #: code:addons/dms/static/src/js/views/many_drop_target.js:0 #, python-format msgid "You must select a directory first" diff --git a/dms/models/abstract_dms_mixin.py b/dms/models/abstract_dms_mixin.py index 6c04e25e1..009b60253 100644 --- a/dms/models/abstract_dms_mixin.py +++ b/dms/models/abstract_dms_mixin.py @@ -7,7 +7,7 @@ class AbstractDmsMixin(models.AbstractModel): _name = "abstract.dms.mixin" _description = "Abstract Dms Mixin" - name = fields.Char(required=True, index=True) + name = fields.Char(required=True, index="btree") # Only defined to prevent error in other fields that related it storage_id = fields.Many2one( comodel_name="dms.storage", string="Storage", store=True, copy=True @@ -24,7 +24,7 @@ class AbstractDmsMixin(models.AbstractModel): string="Company", readonly=True, store=True, - index=True, + index="btree", ) storage_id_save_type = fields.Selection(related="storage_id.save_type", store=False) color = fields.Integer(default=0) diff --git a/dms/models/access_groups.py b/dms/models/access_groups.py index 1f5f18b0f..371de2f5d 100644 --- a/dms/models/access_groups.py +++ b/dms/models/access_groups.py @@ -13,7 +13,7 @@ class DmsAccessGroups(models.Model): _parent_name = "parent_group_id" name = fields.Char(string="Group Name", required=True, translate=True) - parent_path = fields.Char(index=True) + parent_path = fields.Char(index="btree", unaccent=False) # Permissions written directly on this group perm_create = fields.Boolean(string="Create Access") @@ -64,7 +64,7 @@ class DmsAccessGroups(models.Model): comodel_name="dms.access.group", string="Parent Group", ondelete="cascade", - index=True, + index="btree", ) child_group_ids = fields.One2many( diff --git a/dms/models/category.py b/dms/models/category.py index 2eb391303..fecabe57c 100644 --- a/dms/models/category.py +++ b/dms/models/category.py @@ -37,7 +37,7 @@ class Category(models.Model): comodel_name="dms.category", string="Parent Category", ondelete="cascade", - index=True, + index="btree", ) child_category_ids = fields.One2many( @@ -46,7 +46,7 @@ class Category(models.Model): string="Child Categories", ) - parent_path = fields.Char(index=True) + parent_path = fields.Char(index="btree", unaccent=False) tag_ids = fields.One2many( comodel_name="dms.tag", inverse_name="category_id", string="Tags" ) diff --git a/dms/models/directory.py b/dms/models/directory.py index 4d3b90086..9b96b9695 100644 --- a/dms/models/directory.py +++ b/dms/models/directory.py @@ -41,7 +41,7 @@ class DmsDirectory(models.Model): _parent_name = "parent_id" _directory_field = _parent_name - parent_path = fields.Char(index=True) + parent_path = fields.Char(index="btree", unaccent=False) is_root_directory = fields.Boolean( default=False, help="""Indicates if the directory is a root directory. @@ -68,7 +68,7 @@ class DmsDirectory(models.Model): # Access to a directory doesn't necessarily mean access its parent, so # prefetching this field could lead to misleading access errors prefetch=False, - index=True, + index="btree", store=True, readonly=False, compute="_compute_parent_id", @@ -340,7 +340,7 @@ def toggle_starred(self): with self.env.norecompute(): for vals, ids in updates.items(): self.browse(ids).write(dict(vals)) - self.recompute() + self.flush_recordset() # ---------------------------------------------------------- # SearchPanel @@ -695,7 +695,7 @@ def write(self, vals): domain = [("id", "child_of", self.ids)] records = self.sudo().search(domain) records.modified(["group_ids"]) - records.recompute() + records.flush_recordset() else: res = super().write(vals) return res diff --git a/dms/models/dms_file.py b/dms/models/dms_file.py index 05db26849..76aa02342 100644 --- a/dms/models/dms_file.py +++ b/dms/models/dms_file.py @@ -12,7 +12,7 @@ from PIL import Image from odoo import _, api, fields, models, tools -from odoo.exceptions import ValidationError +from odoo.exceptions import UserError, ValidationError from odoo.osv import expression from odoo.tools import consteq, human_size from odoo.tools.mimetypes import guess_mimetype @@ -55,7 +55,7 @@ class File(models.Model): ondelete="restrict", auto_join=True, required=True, - index=True, + index="btree", ) # Override acording to defined in AbstractDmsMixin storage_id = fields.Many2one( @@ -105,7 +105,7 @@ class File(models.Model): size = fields.Float(readonly=True) - checksum = fields.Char(string="Checksum/SHA1", readonly=True, index=True) + checksum = fields.Char(string="Checksum/SHA1", readonly=True, index="btree") content_binary = fields.Binary(attachment=False, prefetch=False, invisible=True) @@ -601,3 +601,28 @@ def _compute_locked(self): ) else: record.update({"is_locked": False, "is_lock_editor": False}) + + def get_attachment_object(self, attachment): + return { + "name": attachment.name, + "datas": attachment.datas, + "res_model": attachment.res_model, + "mimetype": attachment.mimetype, + } + + def get_dms_files_from_attachments(self, attachment_ids=None): + """Get the dms files from uploaded attachments. + :return: An Array of dms files. + """ + if not attachment_ids: + raise UserError(_("No attachment was provided")) + + attachments = self.env["ir.attachment"].browse(attachment_ids) + + if any( + attachment.res_id or attachment.res_model != "dms.file" + for attachment in attachments + ): + raise UserError(_("Invalid attachments!")) + + return [self.get_attachment_object(attachment) for attachment in attachments] diff --git a/dms/models/dms_security_mixin.py b/dms/models/dms_security_mixin.py index c6433c60e..829a8a786 100644 --- a/dms/models/dms_security_mixin.py +++ b/dms/models/dms_security_mixin.py @@ -18,9 +18,11 @@ class DmsSecurityMixin(models.AbstractModel): # Submodels must define this field that points to the owner dms.directory _directory_field = "directory_id" - res_model = fields.Char(string="Linked attachments model", index=True, store=True) + res_model = fields.Char( + string="Linked attachments model", index="btree", store=True + ) res_id = fields.Integer( - string="Linked attachments record ID", index=True, store=True + string="Linked attachments record ID", index="btree", store=True ) record_ref = fields.Reference( string="Record Referenced", @@ -246,7 +248,7 @@ def create(self, vals_list): res = super(DmsSecurityMixin, self.sudo()).create(vals_list) # Need to flush now, so all groups are stored in DB and the SELECT used # to check access works - res.flush() + res.flush_recordset() # Go back to original sudo state and check we really had creation permission res = res.sudo(self.env.su) res.check_access_rights("create") diff --git a/dms/models/res_company.py b/dms/models/res_company.py index c673e8d43..bf169073b 100644 --- a/dms/models/res_company.py +++ b/dms/models/res_company.py @@ -62,7 +62,7 @@ class ResCompany(models.Model): # ---------------------------------------------------------- def get_and_update_documents_onboarding_state(self): - return self.get_and_update_onbarding_state( + return self._get_and_update_onboarding_state( "documents_onboarding_state", self.get_documents_steps_states_names() ) diff --git a/dms/static/src/js/fields/path_owl.esm.js b/dms/static/src/js/fields/path_owl.esm.js new file mode 100644 index 000000000..7869674e8 --- /dev/null +++ b/dms/static/src/js/fields/path_owl.esm.js @@ -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); diff --git a/dms/static/src/js/fields/path_owl.xml b/dms/static/src/js/fields/path_owl.xml new file mode 100644 index 000000000..02feb45e6 --- /dev/null +++ b/dms/static/src/js/fields/path_owl.xml @@ -0,0 +1,27 @@ + + + + + + + + / + + + + + + / + + + + + + + diff --git a/dms/static/src/js/views/dms_file_upload.esm.js b/dms/static/src/js/views/dms_file_upload.esm.js new file mode 100644 index 000000000..68a35b4ed --- /dev/null +++ b/dms/static/src/js/views/dms_file_upload.esm.js @@ -0,0 +1,169 @@ +/** @odoo-module */ + +import {useBus, useService} from "@web/core/utils/hooks"; +import rpc from "web.rpc"; +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 = this.props.context; + const controllerID = this.actionService.currentController.jsId; + + if (!attachmentIds.length) { + this.notification.add(_t("An error occurred during the upload")); + return; + } + + if (this.props.domain.length === 1) { + ctx.default_directory_id = this.props.domain[0][2]; + } else { + ctx.default_directory_id = this.props.domain[2][2]; + } + + if (ctx.default_directory_id === false) { + 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, + }); + }); + + rpc.query({ + model: "dms.file", + method: "create", + args: [attachments_args], + kwargs: { + context: ctx, + }, + }) + .then(() => { + self.actionService.restore(controllerID); + }) + .catch((error) => { + console.log("##error##: ", error); + window.alert(this.env._t("A file with the same name already exists.")); + self.notification.add( + this.env._t("A file with the same name already exists"), + { + type: "danger", + } + ); + self.actionService.restore(controllerID); + }); + }, +}; diff --git a/dms/static/src/js/views/fields/binary/preview_record.esm.js b/dms/static/src/js/views/fields/binary/preview_record.esm.js new file mode 100644 index 000000000..9954f7056 --- /dev/null +++ b/dms/static/src/js/views/fields/binary/preview_record.esm.js @@ -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); diff --git a/dms/static/src/js/views/fields/binary/preview_record.xml b/dms/static/src/js/views/fields/binary/preview_record.xml new file mode 100644 index 000000000..9a0e1dc13 --- /dev/null +++ b/dms/static/src/js/views/fields/binary/preview_record.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + diff --git a/dms/static/src/js/views/file_kanban_record.esm.js b/dms/static/src/js/views/file_kanban_record.esm.js new file mode 100644 index 000000000..57a89fc10 --- /dev/null +++ b/dms/static/src/js/views/file_kanban_record.esm.js @@ -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); + } +} diff --git a/dms/static/src/js/views/file_kanban_renderer.esm.js b/dms/static/src/js/views/file_kanban_renderer.esm.js new file mode 100644 index 000000000..499d611fb --- /dev/null +++ b/dms/static/src/js/views/file_kanban_renderer.esm.js @@ -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, +}; diff --git a/dms/static/src/js/views/file_kanban_renderer.js b/dms/static/src/js/views/file_kanban_renderer.js deleted file mode 100644 index 52180117b..000000000 --- a/dms/static/src/js/views/file_kanban_renderer.js +++ /dev/null @@ -1,28 +0,0 @@ -/** ******************************************************************************** - Copyright 2020 Creu Blanca - License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). - **********************************************************************************/ - -odoo.define("dms.FileKanbanRenderer", function (require) { - "use strict"; - - var KanbanRenderer = require("web.KanbanRenderer"); - - var FileKanbanRenderer = KanbanRenderer.extend({ - events: _.extend({}, KanbanRenderer.prototype.events || {}, { - "click .o_kanban_dms_file_preview": "_onRecordPreview", - }), - _onRecordPreview: function (ev) { - ev.stopPropagation(); - var id = $(ev.currentTarget).data("id"); - if (id) { - this.trigger_up("preview_file", { - id: id, - target: ev.target, - }); - } - }, - }); - - return FileKanbanRenderer; -}); diff --git a/dms/static/src/js/views/file_kanban_renderer.xml b/dms/static/src/js/views/file_kanban_renderer.xml new file mode 100644 index 000000000..3e4ba2dde --- /dev/null +++ b/dms/static/src/js/views/file_kanban_renderer.xml @@ -0,0 +1,54 @@ + + + + +
+ +
+
+
+ + + + + + + + + + + + + + +
diff --git a/dms/static/src/js/views/file_kanban_view.esm.js b/dms/static/src/js/views/file_kanban_view.esm.js new file mode 100644 index 000000000..e58153f8b --- /dev/null +++ b/dms/static/src/js/views/file_kanban_view.esm.js @@ -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); diff --git a/dms/static/src/js/views/file_kanban_view.js b/dms/static/src/js/views/file_kanban_view.js deleted file mode 100644 index 08f5388a5..000000000 --- a/dms/static/src/js/views/file_kanban_view.js +++ /dev/null @@ -1,28 +0,0 @@ -/** ******************************************************************************** - 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.FileKanbanView", function (require) { - "use strict"; - - var registry = require("web.view_registry"); - - var KanbanView = require("web.KanbanView"); - - var FileKanbanController = require("dms.FileKanbanController"); - - var FileKanbanRenderer = require("dms.FileKanbanRenderer"); - - var FileKanbanView = KanbanView.extend({ - config: _.extend({}, KanbanView.prototype.config, { - Controller: FileKanbanController, - Renderer: FileKanbanRenderer, - }), - }); - - registry.add("file_kanban", FileKanbanView); - - return FileKanbanView; -}); diff --git a/dms/static/src/js/views/file_list_controller.esm.js b/dms/static/src/js/views/file_list_controller.esm.js new file mode 100644 index 000000000..fb79f9648 --- /dev/null +++ b/dms/static/src/js/views/file_list_controller.esm.js @@ -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(); + } +} diff --git a/dms/static/src/js/views/file_list_controller.js b/dms/static/src/js/views/file_list_controller.js deleted file mode 100644 index 7bf768b32..000000000 --- a/dms/static/src/js/views/file_list_controller.js +++ /dev/null @@ -1,16 +0,0 @@ -/** ******************************************************************************** - 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.FileListController", function (require) { - "use strict"; - - var ListController = require("web.ListController"); - var DragDrop = require("dms.DragDrop"); - - var FileListController = ListController.extend(DragDrop); - - return FileListController; -}); diff --git a/dms/static/src/js/views/file_list_renderer.esm.js b/dms/static/src/js/views/file_list_renderer.esm.js new file mode 100644 index 000000000..0d9962310 --- /dev/null +++ b/dms/static/src/js/views/file_list_renderer.esm.js @@ -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, +}; diff --git a/dms/static/src/js/views/file_list_renderer.xml b/dms/static/src/js/views/file_list_renderer.xml new file mode 100644 index 000000000..bbc3fe3a1 --- /dev/null +++ b/dms/static/src/js/views/file_list_renderer.xml @@ -0,0 +1,54 @@ + + + + +
+ +
+
+
+ + + + + + + + + + + + + + +
diff --git a/dms/static/src/js/views/file_list_view.esm.js b/dms/static/src/js/views/file_list_view.esm.js new file mode 100644 index 000000000..ae00d932c --- /dev/null +++ b/dms/static/src/js/views/file_list_view.esm.js @@ -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); diff --git a/dms/static/src/js/views/file_list_view.js b/dms/static/src/js/views/file_list_view.js deleted file mode 100644 index 3e4afc01b..000000000 --- a/dms/static/src/js/views/file_list_view.js +++ /dev/null @@ -1,24 +0,0 @@ -/** ******************************************************************************** - 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.FileListView", function (require) { - "use strict"; - var registry = require("web.view_registry"); - - var ListView = require("web.ListView"); - - var FileListController = require("dms.FileListController"); - - var FileListView = ListView.extend({ - config: _.extend({}, ListView.prototype.config, { - Controller: FileListController, - }), - }); - - registry.add("file_list", FileListView); - - return FileListView; -}); diff --git a/dms/static/src/js/views/search_panel.esm.js b/dms/static/src/js/views/search_panel.esm.js index ea66dc68a..648bc613f 100644 --- a/dms/static/src/js/views/search_panel.esm.js +++ b/dms/static/src/js/views/search_panel.esm.js @@ -2,37 +2,26 @@ /* Copyright 2021-2022 Tecnativa - Víctor Martínez * License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). */ -import SearchPanelModelExtension from "@web/legacy/js/views/search_panel_model_extension"; -import {patch} from "web.utils"; +import {SearchModel} from "@web/search/search_model"; +import {patch} from "@web/core/utils/patch"; -patch(SearchPanelModelExtension.prototype, "dms.SearchPanel", { - _createCategoryTree(sectionId) { - this._super.apply(this, arguments); - if (this.config.modelName === "dms.directory") { - const category = this.state.sections.get(sectionId); - category.values.get(false).display_name = this.env._t("Root"); - } +patch(SearchModel.prototype, "dms.SearchPanel", { + setup() { + this._super(...arguments); }, + _getCategoryDomain(excludedCategoryId) { const domain = this._super.apply(this, arguments); for (const category of this.categories) { - var attrs_item = this.config.archNodes[category.index].attrs; if (category.id === excludedCategoryId) { continue; } - if ("operator" in attrs_item) { - // Modify the domain operator to show only the records in directory. - domain.forEach(function (item, key) { - if ( - item[0] === category.fieldName && - item[1] !== attrs_item.operator - ) { - domain[key][1] = attrs_item.operator; - } - }); - // Apply domain to show only root directories - if (domain.length === 0 && this.config.modelName === "dms.directory") { + if (this.resModel === "dms.directory") { + if (category.activeValueId) { + domain.push([category.fieldName, "=", category.activeValueId]); + } + if (domain.length === 0) { domain.push([category.fieldName, "=", false]); } } diff --git a/dms/static/src/models/attachment.esm.js b/dms/static/src/models/attachment.esm.js new file mode 100644 index 000000000..ba333d18c --- /dev/null +++ b/dms/static/src/models/attachment.esm.js @@ -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`; + }, + }, + }, +}); diff --git a/dms/static/src/models/attachment_image.esm.js b/dms/static/src/models/attachment_image.esm.js new file mode 100644 index 000000000..d90ad09a4 --- /dev/null +++ b/dms/static/src/models/attachment_image.esm.js @@ -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}`; + }, + }, + }, +}); diff --git a/dms/static/src/models/attachment_viewer_viewable.esm.js b/dms/static/src/models/attachment_viewer_viewable.esm.js new file mode 100644 index 000000000..32c0c0cd9 --- /dev/null +++ b/dms/static/src/models/attachment_viewer_viewable.esm.js @@ -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}`; + }, + }, + }, +}); diff --git a/dms/static/src/scss/directory_kanban.scss b/dms/static/src/scss/directory_kanban.scss index fcd6ad4f5..628a3b23f 100644 --- a/dms/static/src/scss/directory_kanban.scss +++ b/dms/static/src/scss/directory_kanban.scss @@ -88,3 +88,11 @@ } } } + +.o_kanban_renderer { + .o_kanban_record { + > div { + padding: 0; + } + } +} diff --git a/dms/static/src/scss/file_kanban.scss b/dms/static/src/scss/file_kanban.scss index 93599a38e..12f117937 100644 --- a/dms/static/src/scss/file_kanban.scss +++ b/dms/static/src/scss/file_kanban.scss @@ -8,6 +8,10 @@ .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 { @@ -60,3 +64,19 @@ } } } + +.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%; + } +} diff --git a/dms/tests/common.py b/dms/tests/common.py index 74075f895..969e1d168 100644 --- a/dms/tests/common.py +++ b/dms/tests/common.py @@ -227,11 +227,14 @@ def create_storage(self, save_type="database"): {"name": "Test Storage", "save_type": save_type} ) - def create_directory(self, storage=False, directory=False, res_model=False): + def create_directory(self, storage=False, directory=False, model_id=False): record = Form(self.directory_model) record.name = uuid.uuid4().hex record.is_root_directory = True - record.res_model = res_model + if model_id and storage.save_type == "attachment": + # set storage_id_save_type to attachment, making model visible + record.storage_id = storage + record.model_id = model_id if directory: record.is_root_directory = False record.parent_id = directory @@ -270,7 +273,8 @@ def setUp(self): "model_ids": [(6, 0, [self.env.ref("base.model_res_partner").id])], } ) - self.create_directory(storage=self.storage, res_model=self.partner_model._name) + self.partner_model_id = self.env.ref("base.model_res_partner") + self.create_directory(storage=self.storage, model_id=self.partner_model_id) self.partner = self.partner_model.create({"name": "test partner"}) self.model_partner = self.env.ref("base.model_res_partner") diff --git a/dms/tests/test_benchmark.py b/dms/tests/test_benchmark.py index 43e415aac..8ef6a9c7b 100644 --- a/dms/tests/test_benchmark.py +++ b/dms/tests/test_benchmark.py @@ -70,6 +70,7 @@ def _benchmark_function(self, func, args_list): args = item[0] if len(item) > 0 else [] kwargs = item[1] if len(item) > 1 else {} tracking = tuple(tfunc(*args, **kwargs)[1][1:]) + # pylint: disable=too-few-format-args benchmark.append("%sq %.3fs %.3fs %.3fs" % tracking) return benchmark diff --git a/dms/tests/test_directory.py b/dms/tests/test_directory.py index 311421499..f1e96a15a 100644 --- a/dms/tests/test_directory.py +++ b/dms/tests/test_directory.py @@ -31,7 +31,7 @@ def test_create_directory(self): @users("dms-manager", "dms-user") def test_copy_root_directory(self): copy_root_directory = self.directory.copy() - copy_root_directory.flush() + copy_root_directory.flush_recordset() self.assertEqual( self.directory.storage_id.id, copy_root_directory.storage_id.id ) diff --git a/dms/tests/test_file_database.py b/dms/tests/test_file_database.py index 65ef29424..fee1c18b1 100644 --- a/dms/tests/test_file_database.py +++ b/dms/tests/test_file_database.py @@ -50,7 +50,7 @@ def test_move_file(self): file = self.create_file(directory=self.directory) path_names = file.path_names file.write({"directory_id": self.directory2.id}) - file.flush() + file.flush_recordset() self.assertNotEqual(path_names, file.path_names) @users("dms-manager", "dms-user") diff --git a/dms/tests/test_portal.py b/dms/tests/test_portal.py index 9d61524ba..077b49687 100644 --- a/dms/tests/test_portal.py +++ b/dms/tests/test_portal.py @@ -47,15 +47,17 @@ def test_permission_flag(self): self.directory_partner.parent_id.child_directory_ids, self.directory_partner ) # Public user can access only the empty res.partner folder - self.directory_partner.with_user(self.public_user).invalidate_cache() + self.directory_partner.with_user(self.public_user).invalidate_recordset() self.assertFalse( self.directory_partner.with_user(self.public_user).permission_read ) - self.directory_partner.parent_id.with_user(self.public_user).invalidate_cache() + self.directory_partner.parent_id.with_user( + self.public_user + ).invalidate_recordset() self.assertTrue( self.directory_partner.parent_id.with_user(self.public_user).permission_read ) - self.file_partner.with_user(self.public_user).invalidate_cache() + self.file_partner.with_user(self.public_user).invalidate_recordset() self.assertFalse(self.file_partner.with_user(self.public_user).permission_read) self.assertFalse( self.directory_partner.parent_id.with_user( diff --git a/dms/tests/test_storage_attachment.py b/dms/tests/test_storage_attachment.py index a079e99d7..576c7dc17 100644 --- a/dms/tests/test_storage_attachment.py +++ b/dms/tests/test_storage_attachment.py @@ -62,7 +62,7 @@ def test_storage_attachment_directory_record_ref_access_dms_manager(self): self.partner.sudo().write({"type": "private"}) self.assertEqual(self.partner.type, "private") self.assertTrue(directory.sudo().permission_read) - directory.invalidate_cache() + directory.invalidate_recordset() self.assertFalse(directory.with_user(self.dms_manager_user).permission_read) @users("dms-user") @@ -74,7 +74,7 @@ def test_storage_attachment_directory_record_ref_access_dms_user(self): self.partner.sudo().write({"type": "private"}) self.assertEqual(self.partner.type, "private") self.assertTrue(directory.sudo().permission_read) - directory.invalidate_cache() + directory.invalidate_recordset() self.assertFalse(directory.with_user(self.dms_user).permission_read) # user can access self.partner self.dms_user.write( @@ -103,7 +103,7 @@ def test_storage_attachment_directory_record_ref_access_basic_user(self): self.partner.sudo().write({"type": "private"}) self.assertEqual(self.partner.type, "private") self.assertTrue(directory.sudo().permission_read) - directory.invalidate_cache() + directory.invalidate_recordset() self.assertFalse(directory.with_user(self.user).permission_read) @users("basic-user") diff --git a/dms/views/directory.xml b/dms/views/directory.xml index 10716cbb6..004911771 100644 --- a/dms/views/directory.xml +++ b/dms/views/directory.xml @@ -88,13 +88,13 @@ kanban,tree,graph,pivot,form [ - ("directory_id", "child_of", active_id), ("is_hidden", "=", False), ] { 'default_directory_id': active_id, + 'searchpanel_default_directory_id': active_id } @@ -445,12 +445,28 @@ - + + + @@ -628,20 +644,6 @@ - - dms_directory.form - dms.directory - - - - - 0 - - - {} - - - Directories dms.directory @@ -685,7 +687,15 @@ - + + +