+ {gettext('Drag and drop a file here or click to select a file')} +
+ {errorMessage &&Mit dem Research Data Management Organiser (RDMO) können Institutionen und Forschende das Forschungsdatenmanagement ihre Projekte strukturiert planen und durchführen. Es erlaubt das Erfassen aller relevanten Planungsinformationen in Datenmanagementplänen und die Verwaltung aller Datenmanagementaufgaben über den gesamten Datenlebenszyklus. -
- -- RDMO ist bereit für die Anwendung in kleineren und größeren Projekten. In der zweiten Phase des RDMO-Projekts seit November 2017 erweitern die Projektpartner AIP, FHP und KIT-Bibliothek die bereits veröffentlichte Version des RDMO und arbeiten vertieft mit Anwendern zusammen. Im Fokus der Erweiterung von RDMO stehen u.a. Rollenkonzepte und Anbindungen an die institutionelle Infrastruktur wie Repositorien, Ticket-Systeme und Infrastruktur für Authentifizierung und Autorisierung. Es werden Workshops zur Diskussion der Funktionalitäten durchgeführt, Einführungsmaterialien erstellt und eine Verbreiterung der Entwickler-Community angestrebt. + RDMO wurde im Rahmen einer Kooperation zwischen dem Leibniz-Instituts für Astrophysik Potsdam, der Fachhochschule Potsdam und der Bibliothek des Karlsruher Instituts für Technologie entwickelt und wird heute durch die RDMO Arbeitsgemeinschaft gepflegt, weiterentwickelt und verstetigt.
diff --git a/rdmo/core/templates/core/about_text_en.html b/rdmo/core/templates/core/about_text_en.html index 657676c360..ff252e8139 100644 --- a/rdmo/core/templates/core/about_text_en.html +++ b/rdmo/core/templates/core/about_text_en.html @@ -12,11 +12,8 @@
- The Research Data Management Organiser (RDMO) enables institutions as well as researchers to plan and carry out their management of research data. RDMO can assemble all relevant planning information and data management tasks across the whole life cycle of the research data. -
- -- RDMO is ready for application in smaller or bigger projects. In the next projectphase, which started November 2017, the RDMO tool will be extended and the project partners AIP, FHP, and KIT Library will collaborate with the RDMO users to improve its usage. The tool will be extended by enhancing its implementation of roles and interfaces to institutional infrastructure, e.g. repositories, ticketing systems, and the infrastructure for authentication and authorization. Tutorials, documentation and other material are planned for dissemination, and workshops for users and developers. + The Research Data Management Organiser (RDMO) enables institutions as well as researchers to plan and carry out their management of research data in a structured manner. RDMO can assemble all relevant planning information and data management tasks across the whole life cycle of the research data. + RDMO was developed within a cooperation between the Leibniz Institute for Astrophysics Potsdam, the University of Applied Sciences of Potsdam and the library of the Karlsruhe Institute of Technology and is now maintained, further developed and consolidated by the RDMO working group.
diff --git a/rdmo/core/templates/core/about_text_es.html b/rdmo/core/templates/core/about_text_es.html new file mode 100644 index 0000000000..063c9ec1a0 --- /dev/null +++ b/rdmo/core/templates/core/about_text_es.html @@ -0,0 +1,22 @@ +{% load static %} +{% load core_tags %} +{% load i18n %} + +
+ Con el Organizador de Gestión de Datos de Investigación (RDMO), las instituciones y los investigadores pueden planificar y llevar a cabo la gestión de datos de investigación de sus proyectos de forma estructurada. RDMO permite la integración de toda la información de planificación relevante en los planes de gestión de datos y la administración de las tareas de gestión de datos a lo largo de todo el ciclo de vida de los datos. + RDMO se desarrolló en el marco de una cooperación entre el Instituto Leibniz de Astrofísica de Potsdam, la Universidad de Ciencias Aplicadas de Potsdam y la biblioteca del Instituto de Tecnología de Karlsruhe, y en la actualidad es mantenido, desarrollado y consolidado por el grupo de trabajo RDMO. +
+ ++ Encontrará más información sobre RDMO en rdmorganiser.github.io. +
+- RDMO permet aux institutions ainsi qu'aux chercheurs de planifier et de réaliser leur gestion des données de recherche. RDMO peut rassembler toutes les informations de planification pertinentes et les tâches de gestion des données tout au long du cycle de vie des données de recherche. -
- -- RDMO est prêt à être appliqué dans des projets plus ou moins importants. Dans la prochaine phase du projet, qui a débuté en novembre 2017, l'outil RDMO sera étendu et les partenaires du projet, l'AIP, la FHP et la bibliothèque du KIT, collaboreront avec les utilisateurs de RDMO pour améliorer son utilisation. L'outil sera étendu en améliorant sa mise en œuvre des rôles et des interfaces avec l'infrastructure institutionnelle, par exemple les dépôts, les systèmes de billetterie, et l'infrastructure d'authentification et d'autorisation. Des tutoriels, de la documentation et d'autres matériels sont prévus pour la diffusion, ainsi que des ateliers pour les utilisateurs et les développeurs. + Le Research Data Management Organiser (RDMO) permet aux institutions et aux chercheurs de planifier et de réaliser la gestion des données de recherche de leurs projets de manière structurée. Il permet de saisir toutes les informations de planification pertinentes dans des plans de gestion des données et de gérer toutes les tâches de gestion des données tout au long du cycle de vie des données. + RDMO a été développé dans le cadre d'une coopération entre le Leibniz-Institut für Astrophysik Potsdam, la Fachhochschule Potsdam et la bibliothèque du Karlsruher Institut für Technologie et est aujourd'hui entretenu, développé et pérennisé par le groupe de travail RDMO.
diff --git a/rdmo/core/templates/core/about_text_it.html b/rdmo/core/templates/core/about_text_it.html index 784c25ec38..8830f41606 100644 --- a/rdmo/core/templates/core/about_text_it.html +++ b/rdmo/core/templates/core/about_text_it.html @@ -12,15 +12,8 @@
- RDMO consente alle istituzioni e ai singoli ricercatori la pianificazione della gestione dei dati della ricerca. RDMO assembla tutte le informazioni riguardanti la pianificazione e la gestione - dei dati durante l'intera vita dei dati della ricerca. -
- -- RDMO può essere usata in progetti grossi e piccoli. Nella prossima fase del progetto, iniziata nel Novembre 2017, RDMO sarà esteso e i partner del progetto - AIP, FHP, biblioteca KIT collaboreranno con gli utenti RDMO per migliorarne l'utilizzo. Questo strumento sarà esteso, migliorando l'implementazione dei ruoli e dell'interfacciamento - con le infrastrutture istituzionali, ad es. repositories, sistemi di ticketing, e infrastruttura di autenticazione e autorizzazione. Verranno anche scritti tutorial e documentazione, e - organizzati workshop per utenti e sviluppatori. + Con Research Data Management Organiser (RDMO), istituzioni e ricercatori possono pianificare e implementare la gestione dei dati di ricerca dei loro progetti in modo strutturato. Consente di registrare tutte le informazioni rilevanti per la pianificazione nei piani di gestione dei dati e di gestire tutte le attività di gestione dei dati per l'intero ciclo di vita dei dati. + RDMO è stato sviluppato nell'ambito di una collaborazione tra l'Istituto Leibniz per l'Astrofisica di Potsdam, l'Università di Scienze Applicate di Potsdam e la biblioteca dell'Istituto di Tecnologia di Karlsruhe ed è ora mantenuto, ulteriormente sviluppato e consolidato dal gruppo di lavoro RDMO.
diff --git a/rdmo/core/templates/core/base_head.html b/rdmo/core/templates/core/base_head.html index 23f48f7074..d5e28ea95e 100644 --- a/rdmo/core/templates/core/base_head.html +++ b/rdmo/core/templates/core/base_head.html @@ -1,4 +1,7 @@ {% load static %} +{% load i18n %} +{% get_current_language as LANGUAGE_CODE %} +
- Das Ziel des RDMO Projekts ist es, eine Webapplikation bereitzustellen, die die strukturierte Planung, Umsetzung und Verwaltung der Daten in einem wissenschaftlichen Projekt unterstützt. Zusätzlich sollen die gesammelten Informationen in textueller Form für Anforderungen von Förderern oder für Berichte ausgebbar sein.
+ RDMO ist eine Webapplikation, die die strukturierte Planung, Umsetzung und Verwaltung der Daten in einem wissenschaftlichen Projekt unterstützt.
+ Die gesammelten Informationen können in Forschungsworkflows weiterverwendet werden und zusätzlich in textueller Form ausgegeben werden -
+ als Datenmanagementplan für die Förderer oder als teil eines Forschungsberichts.
- Diese Webseite ist ein Prototyp zur Veranschaulichung der bereits implementierten Funktionen. -
- -- Wenn Sie mehr über das Projekt erfahren wollen, besuchen Sie rdmorganiser.github.io. + Wenn Sie mehr über die Nutzung von RDMO als Endnutzer oder Manager erfahren wollen, besuchen Sie rdmorganiser.github.io.
diff --git a/rdmo/core/templates/core/home_text_en.html b/rdmo/core/templates/core/home_text_en.html index 1eb966979a..de9dcebfc2 100644 --- a/rdmo/core/templates/core/home_text_en.html +++ b/rdmo/core/templates/core/home_text_en.html @@ -1,11 +1,8 @@- The aim of the RDMO project is to deliver a web application to assist structured planning, implementation and administration of the data in a scientific project. Additionally, the gathered information can be cast into textual forms suitable for funding agencies requirements or for reports. -
- -
- This is a prototype of the software, for demonstration purposes.
+ RDMO is a web application that supports the structured planning, realisation and management of data in a scientific project.
+ The information collected can be used in research workflows and can also be output in textual form - as a data management plan for funders or as part of a research report.
diff --git a/rdmo/core/templates/core/home_text_es.html b/rdmo/core/templates/core/home_text_es.html new file mode 100644 index 0000000000..fce115f690 --- /dev/null +++ b/rdmo/core/templates/core/home_text_es.html @@ -0,0 +1,10 @@ +
+ RDMO es una aplicación web que apoya la planificación estructurada, la realización y la gestión de datos en un proyecto científico.
+ La información recopilada puede utilizarse en flujos de trabajo de investigación y también puede ser exportada en forma de texto: como plan de gestión de datos para los financiadores o como parte de un informe de investigación.
+
+ Si desea obtener más información sobre el uso de RDMO como usuario final o gestor, visite rdmorganiser.github.io. +
diff --git a/rdmo/core/templates/core/home_text_fr.html b/rdmo/core/templates/core/home_text_fr.html index 7b806ad812..e4ace4f14b 100644 --- a/rdmo/core/templates/core/home_text_fr.html +++ b/rdmo/core/templates/core/home_text_fr.html @@ -1,11 +1,9 @@- L'objectif du projet RDMO est de fournir une application web pour aider à la planification structurée, à la mise en œuvre et à l'administration des données d'un projet scientifique. En outre, les informations recueillies peuvent être transposées sous forme textuelle pour répondre aux exigences des organismes de financement ou pour les rapports. -
- -
- Il s'agit d'un prototype du logiciel, à des fins de démonstration.
+ RDMO est une application web qui soutient la planification structurée, la mise en œuvre et la gestion des données dans un projet scientifique.
+ Les informations collectées peuvent être réutilisées dans des workflows de recherche et peuvent en outre être éditées sous forme de texte -
+ comme plan de gestion des données pour les bailleurs de fonds ou comme partie d'un rapport de recherche.
diff --git a/rdmo/core/templates/core/home_text_it.html b/rdmo/core/templates/core/home_text_it.html index bf684776ff..b0ca5c4409 100644 --- a/rdmo/core/templates/core/home_text_it.html +++ b/rdmo/core/templates/core/home_text_it.html @@ -1,11 +1,8 @@
- L'obiettivo del progetto RDMO è fornire un'applicazione web per aiutare la pianificazione, l'implementazione e l'amministrazione dei dati in un progetto scientifico. In aggiunta, le informazioni raccolte possono essere stampate in formato testuale per essere inviate ai finanziatori. -
- -
- Questo è un prototipo del software, per soli scopi dimostrativi.
+ RDMO è un'applicazione web che supporta la pianificazione, la realizzazione e la gestione strutturata dei dati in un progetto scientifico.
+ Le informazioni raccolte possono essere utilizzate nei flussi di lavoro della ricerca e possono anche essere prodotte in forma testuale - come piano di gestione dei dati per i finanziatori o come parte di una relazione di ricerca.
diff --git a/rdmo/core/templates/core/projects_page.html b/rdmo/core/templates/core/projects_page.html new file mode 100644 index 0000000000..be3cc66d7f --- /dev/null +++ b/rdmo/core/templates/core/projects_page.html @@ -0,0 +1,13 @@ +{% extends 'core/base.html' %} + +{% block content %} + +
(.*?)
$',r'\1', html) + # convert `[%s"
@@ -129,6 +151,24 @@ msgstr ""
"Dieses Attribut wird der Seite %s
"
"hinzugefügt."
+#: management/assets/js/components/edit/EditAttribute.js:68
+#, javascript-format
+msgid ""
+"This attribute will be added to the question set %s
."
+msgstr ""
+"Dieses Attribut wird dem Fragenset %s
"
+"hinzugefügt."
+
+#: management/assets/js/components/edit/EditAttribute.js:75
+#, javascript-format
+msgid ""
+"This attribute will be added to the question "
+"%s
."
+msgstr ""
+"Dieses Attribut wird der Frage %s
"
+"hinzugefügt."
+
#: management/assets/js/components/edit/EditAttribute.js:82
#, javascript-format
msgid ""
@@ -147,15 +187,13 @@ msgid "Create new section"
msgstr "Neuen Abschnitt erstellen"
#: management/assets/js/components/edit/EditCatalog.js:46
-#: management/assets/js/components/element/Catalog.js:35
+#: management/assets/js/components/element/Catalog.js:37
msgid "This catalog is read only"
msgstr "Dieser Katalog ist schreibgeschützt"
#: management/assets/js/components/edit/EditCatalog.js:53
-#: management/assets/js/components/element/Catalog.js:51
-#: management/assets/js/components/import/ImportCatalog.js:30
+#: management/assets/js/components/element/Catalog.js:56
#: management/assets/js/constants/elements.js:44
-#: management/static/management/js/management.js:2
msgid "Catalog"
msgstr "Katalog"
@@ -170,9 +208,7 @@ msgstr "Diese Bedingung ist schreibgeschützt"
#: management/assets/js/components/edit/EditCondition.js:48
#: management/assets/js/components/element/Condition.js:37
-#: management/assets/js/components/import/ImportCondition.js:28
#: management/assets/js/constants/elements.js:52
-#: management/static/management/js/management.js:2
msgid "Condition"
msgstr "Bedingung"
@@ -236,9 +272,7 @@ msgstr "Die Option ist schreibgeschützt"
#: management/assets/js/components/edit/EditOption.js:45
#: management/assets/js/components/element/Option.js:37
-#: management/assets/js/components/import/ImportOption.js:28
#: management/assets/js/constants/elements.js:51
-#: management/static/management/js/management.js:2
msgid "Option"
msgstr "Option"
@@ -256,15 +290,13 @@ msgstr ""
"hinzugefügt."
#: management/assets/js/components/edit/EditOptionSet.js:45
-#: management/assets/js/components/element/OptionSet.js:31
+#: management/assets/js/components/element/OptionSet.js:35
msgid "This option set is read only"
msgstr "Dieses Optionenset ist schreibgeschützt"
#: management/assets/js/components/edit/EditOptionSet.js:52
-#: management/assets/js/components/element/OptionSet.js:43
-#: management/assets/js/components/import/ImportOptionSet.js:28
+#: management/assets/js/components/element/OptionSet.js:47
#: management/assets/js/constants/elements.js:50
-#: management/static/management/js/management.js:2
msgid "Option set"
msgstr "Optionenset"
@@ -311,31 +343,27 @@ msgstr "Fragenset: %s"
#: management/assets/js/components/edit/EditPage.js:72
#: management/assets/js/components/edit/EditQuestionSet.js:72
-#, fuzzy
-#| msgid "Add existing element"
msgid "Add existing element"
msgstr "Existierendes Element hinzufügen"
#: management/assets/js/components/edit/EditPage.js:73
#: management/assets/js/components/edit/EditQuestionSet.js:73
-msgid "Create new question set"
-msgstr "Neues Fragenset erstellen"
+msgid "Create new question"
+msgstr "Neue Frage erstellen"
#: management/assets/js/components/edit/EditPage.js:74
#: management/assets/js/components/edit/EditQuestionSet.js:74
-msgid "Create new question"
-msgstr "Neue Frage erstellen"
+msgid "Create new question set"
+msgstr "Neues Fragenset erstellen"
#: management/assets/js/components/edit/EditPage.js:80
-#: management/assets/js/components/element/Page.js:42
+#: management/assets/js/components/element/Page.js:45
msgid "This page is read only"
msgstr "Diese Seite ist schreibgeschützt"
#: management/assets/js/components/edit/EditPage.js:87
-#: management/assets/js/components/element/Page.js:57
-#: management/assets/js/components/import/ImportPage.js:28
+#: management/assets/js/components/element/Page.js:60
#: management/assets/js/constants/elements.js:46
-#: management/static/management/js/management.js:2
msgid "Page"
msgstr "Seite"
@@ -352,24 +380,30 @@ msgstr ""
"Diese Seite wird dem Abschnitt %s
"
"hinzugefügt."
-#: management/assets/js/components/edit/EditQuestion.js:47
-#: management/assets/js/components/element/Question.js:33
+#: management/assets/js/components/edit/EditQuestion.js:44
+msgid "Add existing optionset"
+msgstr "Existierendes Optionenset hinzufügen"
+
+#: management/assets/js/components/edit/EditQuestion.js:45
+msgid "Create new optionset"
+msgstr "Neues Optionenset erstellen"
+
+#: management/assets/js/components/edit/EditQuestion.js:51
+#: management/assets/js/components/element/Question.js:37
msgid "This question is read only"
msgstr "Diese Frage ist schreibgschützt"
-#: management/assets/js/components/edit/EditQuestion.js:54
-#: management/assets/js/components/element/Question.js:44
-#: management/assets/js/components/import/ImportQuestion.js:28
+#: management/assets/js/components/edit/EditQuestion.js:58
+#: management/assets/js/components/element/Question.js:48
#: management/assets/js/constants/elements.js:48
-#: management/static/management/js/management.js:2
msgid "Question"
msgstr "Frage"
-#: management/assets/js/components/edit/EditQuestion.js:56
+#: management/assets/js/components/edit/EditQuestion.js:60
msgid "Create question"
msgstr "Neue Frage erstellen"
-#: management/assets/js/components/edit/EditQuestion.js:63
+#: management/assets/js/components/edit/EditQuestion.js:67
#, javascript-format
msgid ""
"This question will be added to the page %s"
@@ -378,7 +412,7 @@ msgstr ""
"Diese Frage wird der Seite %s
"
"hinzugefügt."
-#: management/assets/js/components/edit/EditQuestion.js:70
+#: management/assets/js/components/edit/EditQuestion.js:74
#, javascript-format
msgid ""
"This question will be added to the question set %s values in one project."
@@ -1190,26 +1250,10 @@ msgid_plural "This view is used in %s projects."
msgstr[0] "Diese Ansicht wird in einem Projekt verwendet."
msgstr[1] "Diese Ansicht wird in %s Projekten verwendet."
-#: management/assets/js/components/main/Import.js:26
+#: management/assets/js/components/main/Import.js:35
msgid "Import"
msgstr "Import"
-#: management/assets/js/components/main/Import.js:38
-msgid "created"
-msgstr "erstellt"
-
-#: management/assets/js/components/main/Import.js:39
-msgid "updated"
-msgstr "zuletzt geändert"
-
-#: management/assets/js/components/main/Import.js:42
-msgid "could not be imported"
-msgstr "konnte nicht importiert werden"
-
-#: management/assets/js/components/main/Import.js:46
-msgid "but could not be added to parent element"
-msgstr "konnte aber dem übergeordneten Element nicht hinzugefügt werden"
-
#: management/assets/js/components/modals/DeleteAttributeModal.js:7
msgid "Delete attribute"
msgstr "Attribut entfernen"
@@ -1328,33 +1372,256 @@ msgstr "Element ein/ausblenden:"
msgid "Show elements:"
msgstr "Elemente anzeigen:"
-#: management/assets/js/components/sidebar/ImportSidebar.js:23
+#: management/assets/js/components/sidebar/ElementsSidebar.js:77
+msgid "Export all visible elements."
+msgstr "Exportiert alle sichtbaren Elemente."
+
+#: management/assets/js/components/sidebar/ImportSidebar.js:30
msgid "Import successful"
msgstr "Import erfolgreich"
-#: management/assets/js/components/sidebar/ImportSidebar.js:35
+#: management/assets/js/components/sidebar/ImportSidebar.js:42
msgid "Import elements"
msgstr "Elemente importieren"
-#: management/assets/js/components/sidebar/ImportSidebar.js:39
+#: management/assets/js/components/sidebar/ImportSidebar.js:45
#, javascript-format
msgid "Import one element"
msgid_plural "Import %s elements"
msgstr[0] "Ein Element importieren"
msgstr[1] "%s Elemente importieren"
-#: management/assets/js/components/sidebar/ImportSidebar.js:46
+#: management/assets/js/components/sidebar/ImportSidebar.js:52
msgid "Selection"
msgstr "Auswahl"
-#: management/assets/js/components/sidebar/ImportSidebar.js:51
+#: management/assets/js/components/sidebar/ImportSidebar.js:57
msgid "Select all"
msgstr "Alle auswählen"
-#: management/assets/js/components/sidebar/ImportSidebar.js:56
-msgid "Unselect all"
+#: management/assets/js/components/sidebar/ImportSidebar.js:63
+msgid "Select changed"
+msgstr "Geänderte auswählen"
+
+#: management/assets/js/components/sidebar/ImportSidebar.js:69
+msgid "Deselect all"
msgstr "Alle abwählen"
#: management/assets/js/components/sidebar/ImportSidebar.js:75
+msgid "Deselect changed"
+msgstr "Geänderte abwählen"
+
+#: management/assets/js/components/sidebar/ImportSidebar.js:81
+msgid "Show"
+msgstr "Anzeigen"
+
+#: management/assets/js/components/sidebar/ImportSidebar.js:85
+msgid "Show all"
+msgstr "Alle einblenden"
+
+#: management/assets/js/components/sidebar/ImportSidebar.js:91
+msgid "Show changes"
+msgstr "Änderungen anzeigen"
+
+#: management/assets/js/components/sidebar/ImportSidebar.js:97
+msgid "Hide all"
+msgstr "Alle ausblenden"
+
+#: management/assets/js/components/sidebar/ImportSidebar.js:103
+msgid "Hide changes"
+msgstr "Änderungen ausblenden"
+
+#: management/assets/js/components/sidebar/ImportSidebar.js:123
msgid "Set URI prefix for all elements"
msgstr "URI-Präfix für alle Elemente festlegen"
+
+#: projects/assets/js/components/helper/ProjectImport.js:11
+msgid "Import directly"
+msgstr "Projekt direkt importieren"
+
+#: projects/assets/js/components/helper/ProjectImport.js:27
+#: projects/assets/js/utils/translations.js:8
+msgid "Import from file"
+msgstr "Importieren aus Datei"
+
+#: projects/assets/js/components/helper/Table.js:52
+msgid "Scroll to top"
+msgstr "Zum Seitenanfang"
+
+#: projects/assets/js/components/helper/Table.js:59
+#: projects/assets/js/utils/translations.js:10
+msgid "Load more"
+msgstr "Mehr laden"
+
+#: projects/assets/js/components/helper/Table.js:62
+#: projects/assets/js/utils/translations.js:9
+msgid "Load all"
+msgstr "Alles laden"
+
+#: projects/assets/js/components/main/Projects.js:23
+#: projects/assets/js/utils/translations.js:13
+msgid "Pending invitations"
+msgstr "Ausstehende Einladungen"
+
+#: projects/assets/js/components/main/Projects.js:29
+#: projects/assets/js/utils/translations.js:7
+msgid "Import project"
+msgstr "Projekt importieren"
+
+#: projects/assets/js/components/main/Projects.js:38
+#, javascript-format
+msgid "%s of %s projects are displayed"
+msgstr "%s von %s Projekten werden angezeigt"
+
+#: projects/assets/js/components/main/Projects.js:41
+#, javascript-format
+msgid "%s of %s"
+msgstr "%s von %s"
+
+#: projects/assets/js/components/main/Projects.js:55
+#: projects/assets/js/utils/translations.js:18
+msgid "View all projects"
+msgstr "Alle Projekte ansehen"
+
+#: projects/assets/js/components/main/Projects.js:55
+#: projects/assets/js/utils/translations.js:19
+msgid "View my projects"
+msgstr "Meine Projekte ansehen"
+
+#: projects/assets/js/components/main/Projects.js:56
+#: projects/assets/js/utils/translations.js:11
+msgid "My projects"
+msgstr "Meine Projekte"
+
+#: projects/assets/js/components/main/Projects.js:56
+#: projects/assets/js/utils/translations.js:3
+msgid "All projects"
+msgstr "Alle Projekte"
+
+#: projects/assets/js/utils/constants.js:6
+msgid "Name"
+msgstr "Name"
+
+#: projects/assets/js/utils/constants.js:7
+msgid "Role"
+msgstr "Rolle"
+
+#: projects/assets/js/utils/constants.js:8
+#: projects/assets/js/utils/constants.js:19
+msgid "Owner"
+msgstr "Besitzer"
+
+#: projects/assets/js/utils/constants.js:9
+msgid "Progress"
+msgstr "Fortschritt"
+
+#: projects/assets/js/utils/constants.js:11
+msgid "Last changed"
+msgstr "Letzte Änderung"
+
+#: projects/assets/js/utils/constants.js:16
+msgid "Author"
+msgstr "Autor"
+
+#: projects/assets/js/utils/constants.js:17
+msgid "Guest"
+msgstr "Gast"
+
+#: projects/assets/js/utils/constants.js:18
+msgid "Manager"
+msgstr "Manager"
+
+#: projects/assets/js/utils/translations.js:2
+msgid "Accept"
+msgstr "Akzeptieren"
+
+#: projects/assets/js/utils/translations.js:4
+msgid "Decline"
+msgstr "Ablehnen"
+
+#: projects/assets/js/utils/translations.js:5
+msgid "Filter"
+msgstr "Filter"
+
+#: projects/assets/js/utils/translations.js:6
+msgid "Hide filters"
+msgstr "Filter ausblenden"
+
+#: projects/assets/js/utils/translations.js:12
+msgid "New project"
+msgstr "Neues Projekt"
+
+#: projects/assets/js/utils/translations.js:14
+msgid "Reset all filters"
+msgstr "Alle Filter zurücksetzen"
+
+#: projects/assets/js/utils/translations.js:16
+msgid "Search projects"
+msgstr "Projekte durchsuchen"
+
+#: projects/assets/js/utils/translations.js:17
+msgid "Show filters"
+msgstr "Filter anzeigen"
+
+#~ msgid "Change"
+#~ msgstr "Ändern"
+
+#~ msgid "Import an RDMO XML file."
+#~ msgstr "Eine RDMO-XML Datei importieren."
+
+#, fuzzy
+#~| msgid "Filter"
+#~ msgid "Filter uri"
+#~ msgstr "Filter"
+
+#~ msgid "changed"
+#~ msgstr "geändert"
+
+#~ msgid "created"
+#~ msgstr "erstellt"
+
+#, fuzzy
+#~| msgid "New"
+#~ msgid "new"
+#~ msgstr "Neu"
+
+#~ msgid "catalog"
+#~ msgstr "Katalog"
+
+#~ msgid "task"
+#~ msgstr "Ansicht"
+
+#~ msgid "view"
+#~ msgstr "Ansicht"
+
+#~ msgid "updated"
+#~ msgstr "zuletzt geändert"
+
+#~ msgid "Filter by catalog"
+#~ msgstr "Nach Katalog filtern"
+
+#~ msgid "Filter by created date"
+#~ msgstr "Nach Erstellungsdatum filtern"
+
+#~ msgid "Select start date"
+#~ msgstr "Startdatum wählen"
+
+#~ msgid "Select end date"
+#~ msgstr "Enddatum wählen"
+
+#~ msgid "Filter by last changed date"
+#~ msgstr "Nach Änderungsdatum filtern"
+
+#, fuzzy
+#~| msgid "Load More"
+#~ msgid "Load More"
+#~ msgstr "Mehr laden"
+
+#, fuzzy
+#~| msgid "Load All"
+#~ msgid "Load All"
+#~ msgstr "Alles laden"
+
+#, fuzzy
+#~ msgid "Direct import"
+#~ msgstr "Projekt direkt importieren"
diff --git a/rdmo/locale/es/LC_MESSAGES/djangojs.mo b/rdmo/locale/es/LC_MESSAGES/djangojs.mo
index b14080add3..73fa5e5c1a 100644
Binary files a/rdmo/locale/es/LC_MESSAGES/djangojs.mo and b/rdmo/locale/es/LC_MESSAGES/djangojs.mo differ
diff --git a/rdmo/locale/es/LC_MESSAGES/djangojs.po b/rdmo/locale/es/LC_MESSAGES/djangojs.po
index 2428e8d185..95b12bfb2f 100644
--- a/rdmo/locale/es/LC_MESSAGES/djangojs.po
+++ b/rdmo/locale/es/LC_MESSAGES/djangojs.po
@@ -7,8 +7,8 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-12-09 10:45+0100\n"
-"PO-Revision-Date: 2023-12-09 10:49+0100\n"
+"POT-Creation-Date: 2024-04-26 16:24+0200\n"
+"PO-Revision-Date: 2024-09-04 10:06+0200\n"
"Last-Translator: DAVID MARTINEZ \n"
"Language-Team: \n"
"Language: es\n"
@@ -16,7 +16,31 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.4.2\n"
+"X-Generator: Poedit 3.4.2\n"
+
+#: core/assets/js/components/Modal.js:16
+#: management/assets/js/components/common/Modals.js:16
+msgid "Close"
+msgstr "Cerrar"
+
+#: core/assets/js/components/Modal.js:20
+#: management/assets/js/components/common/Buttons.js:19
+msgid "Save"
+msgstr "Guardar"
+
+#: core/assets/js/components/SearchAndFilter.js:42
+#: projects/assets/js/utils/translations.js:15
+msgid "Search"
+msgstr "Búsqueda"
+
+#: core/assets/js/components/UploadDropZone.js:18
+#, javascript-format
+msgid "%s has unsupported file type"
+msgstr "%s has unsupported file type"
+
+#: core/assets/js/components/UploadDropZone.js:26
+msgid "Drag and drop a file here or click to select a file"
+msgstr "Arrastre y suelte un archivo aquí o haga clic para seleccionarlo"
#: management/assets/js/components/common/Buttons.js:6
#: management/assets/js/components/sidebar/ImportSidebar.js:27
@@ -40,10 +64,6 @@ msgstr "Copiar"
msgid "Copy and continue editing"
msgstr "Copiar y seguir editando"
-#: management/assets/js/components/common/Buttons.js:19
-msgid "Save"
-msgstr "Guardar"
-
#: management/assets/js/components/common/Buttons.js:19
msgid "Save and continue editing"
msgstr "Guardar y seguir editando"
@@ -93,10 +113,6 @@ msgstr "XML"
msgid "XML (full)"
msgstr "XML (completo)"
-#: management/assets/js/components/common/Modals.js:16
-msgid "Close"
-msgstr "Cerrar"
-
#: management/assets/js/components/edit/EditAttribute.js:37
#: management/assets/js/components/element/Attribute.js:31
msgid "This attribute is read only"
@@ -117,8 +133,8 @@ msgstr "Crear atributo"
#: management/assets/js/components/edit/EditAttribute.js:53
#, javascript-format
msgid ""
-"This attribute will be added to the attribute "
-"%s
."
+"This attribute will be added to the attribute %s
."
msgstr ""
"Este atributo se añadirá al atributo %s
."
@@ -136,8 +152,8 @@ msgstr ""
#: management/assets/js/components/edit/EditAttribute.js:82
#, javascript-format
msgid ""
-"This attribute will be added to the condition %s
."
+"This attribute will be added to the condition %s
."
msgstr ""
"Este atributo se añadirá a la condición %s"
"code>."
@@ -187,11 +203,11 @@ msgstr "Crear condición"
#: management/assets/js/components/edit/EditCondition.js:57
#, javascript-format
msgid ""
-"This condition will be added to the option set "
-"%s
."
+"This condition will be added to the option set %s
."
msgstr ""
-"Esta condición se añadirá al conjunto de opciones %s
."
+"Esta condición se añadirá al conjunto de opciones %s
."
#: management/assets/js/components/edit/EditCondition.js:64
#, javascript-format
@@ -205,8 +221,8 @@ msgstr ""
#: management/assets/js/components/edit/EditCondition.js:71
#, javascript-format
msgid ""
-"This condition will be added to the question set %s
."
+"This condition will be added to the question set %s
."
msgstr ""
"Esta condición se añadirá al conjunto de preguntas %s
."
@@ -214,8 +230,8 @@ msgstr ""
#: management/assets/js/components/edit/EditCondition.js:78
#, javascript-format
msgid ""
-"This condition will be added to the question "
-"%s
."
+"This condition will be added to the question %s
."
msgstr ""
"Esta condición se añadirá a la pregunta %s"
"code>."
@@ -255,8 +271,8 @@ msgid ""
"This option will be added to the option set %s"
"code>."
msgstr ""
-"Esta opción se añadirá al conjunto de opciones "
-"%s
."
+"Esta opción se añadirá al conjunto de opciones %s
."
#: management/assets/js/components/edit/EditOptionSet.js:45
#: management/assets/js/components/element/OptionSet.js:31
@@ -278,8 +294,8 @@ msgstr "Crear conjunto de opciones"
#: management/assets/js/components/edit/EditOptionSet.js:61
#, javascript-format
msgid ""
-"This option set will be added to the question "
-"%s
."
+"This option set will be added to the question %s
."
msgstr ""
"Este conjunto de opciones se añadirá a la pregunta %s
."
@@ -381,8 +397,8 @@ msgstr ""
#: management/assets/js/components/edit/EditQuestion.js:70
#, javascript-format
msgid ""
-"This question will be added to the question set %s
."
+"This question will be added to the question set %s
."
msgstr ""
"Esta pregunta se añadirá al conjunto de preguntas %s
."
@@ -407,8 +423,8 @@ msgstr "Crear conjunto de preguntas"
#: management/assets/js/components/edit/EditQuestionSet.js:96
#, javascript-format
msgid ""
-"This question set will be added to the page "
-"%s
."
+"This question set will be added to the page %s
."
msgstr ""
"Este conjunto de preguntas se añadirá a la página %s
."
@@ -419,8 +435,8 @@ msgid ""
"This question set will be added to the question set %s
."
msgstr ""
-"Este conjunto de preguntas se añadirá al conjunto de preguntas %s
."
+"Este conjunto de preguntas se añadirá al conjunto de preguntas %s
."
#: management/assets/js/components/edit/EditSection.js:38
msgid "Add existing page"
diff --git a/rdmo/locale/fr/LC_MESSAGES/djangojs.mo b/rdmo/locale/fr/LC_MESSAGES/djangojs.mo
index cdfd59d386..800a6160c7 100644
Binary files a/rdmo/locale/fr/LC_MESSAGES/djangojs.mo and b/rdmo/locale/fr/LC_MESSAGES/djangojs.mo differ
diff --git a/rdmo/locale/fr/LC_MESSAGES/djangojs.po b/rdmo/locale/fr/LC_MESSAGES/djangojs.po
index 9b319d6724..f56cf7ca9a 100644
--- a/rdmo/locale/fr/LC_MESSAGES/djangojs.po
+++ b/rdmo/locale/fr/LC_MESSAGES/djangojs.po
@@ -3,7 +3,7 @@ msgstr ""
"Project-Id-Version: RDMO\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-08-05 12:56+0200\n"
-"PO-Revision-Date: 2024-02-15 12:41+0100\n"
+"PO-Revision-Date: 2024-09-04 10:07+0200\n"
"Last-Translator: Yonny CARDENAS, Gautier DEBAECKER, Nadia LAJILI, Gino "
"MARCHETTI \n"
"Language-Team: RDMO \n"
@@ -12,7 +12,26 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 3.1\n"
+"X-Generator: Poedit 3.4.2\n"
+
+#: core/assets/js/components/Modal.js:16
+#: management/assets/js/components/common/Modals.js:16
+msgid "Close"
+msgstr "Fermer"
+
+#: core/assets/js/components/SearchAndFilter.js:42
+#: projects/assets/js/utils/translations.js:15
+msgid "Search"
+msgstr "Recherche"
+
+#: core/assets/js/components/UploadDropZone.js:18
+#, javascript-format
+msgid "%s has unsupported file type"
+msgstr "%s a un type de fichier non supporté"
+
+#: core/assets/js/components/UploadDropZone.js:26
+msgid "Drag and drop a file here or click to select a file"
+msgstr "Glisser-déposer un fichier ici ou cliquer pour sélectionner un fichier"
#: management/assets/js/components/common/Buttons.js:6
#: management/assets/js/components/sidebar/ImportSidebar.js:27
@@ -89,10 +108,6 @@ msgstr "XML"
msgid "XML (full)"
msgstr "XML (complet)"
-#: management/assets/js/components/common/Modals.js:16
-msgid "Close"
-msgstr "Fermer"
-
#: management/assets/js/components/edit/EditAttribute.js:37
#: management/assets/js/components/element/Attribute.js:31
msgid "This attribute is read only"
@@ -112,8 +127,8 @@ msgstr "Créer un attribut"
#: management/assets/js/components/edit/EditAttribute.js:53
#, javascript-format
msgid ""
-"This attribute will be added to the attribute "
-"%s
."
+"This attribute will be added to the attribute %s
."
msgstr ""
"Cet attribut sera ajouté à l'attribut %s
."
@@ -130,8 +145,8 @@ msgstr ""
#: management/assets/js/components/edit/EditAttribute.js:82
#, javascript-format
msgid ""
-"This attribute will be added to the condition %s
."
+"This attribute will be added to the condition %s
."
msgstr ""
"Cet attribut sera ajouté à la condition %s"
"code>."
@@ -171,11 +186,11 @@ msgstr "Créer une condition"
#: management/assets/js/components/edit/EditCondition.js:57
#, javascript-format
msgid ""
-"This condition will be added to the option set "
-"%s
."
+"This condition will be added to the option set %s
."
msgstr ""
-"Cette condition sera ajoutée au jeu d'options "
-"%s
."
+"Cette condition sera ajoutée au jeu d'options %s
."
#: management/assets/js/components/edit/EditCondition.js:64
#, javascript-format
@@ -189,8 +204,8 @@ msgstr ""
#: management/assets/js/components/edit/EditCondition.js:71
#, javascript-format
msgid ""
-"This condition will be added to the question set %s
."
+"This condition will be added to the question set %s
."
msgstr ""
"Cette condition sera ajoutée à l'ensemble de questions %s
."
@@ -198,11 +213,11 @@ msgstr ""
#: management/assets/js/components/edit/EditCondition.js:78
#, javascript-format
msgid ""
-"This condition will be added to the question "
-"%s
."
+"This condition will be added to the question %s
."
msgstr ""
-"Cette condition sera ajoutée à la question "
-"%s
."
+"Cette condition sera ajoutée à la question %s
."
#: management/assets/js/components/edit/EditCondition.js:85
#, javascript-format
@@ -260,11 +275,11 @@ msgstr "Créer un jeu d'options"
#: management/assets/js/components/edit/EditOptionSet.js:61
#, javascript-format
msgid ""
-"This option set will be added to the question "
-"%s
."
+"This option set will be added to the question %s
."
msgstr ""
-"Ce jeu d'options sera ajouté à la question "
-"%s
."
+"Ce jeu d'options sera ajouté à la question %s
."
#: management/assets/js/components/edit/EditPage.js:32
#: management/assets/js/components/edit/EditQuestionSet.js:32
@@ -331,8 +346,8 @@ msgstr ""
#: management/assets/js/components/edit/EditQuestion.js:70
#, javascript-format
msgid ""
-"This question will be added to the question set %s
."
+"This question will be added to the question set %s
."
msgstr ""
"Cette question sera ajoutée à l'ensemble de questions %s
."
@@ -356,11 +371,11 @@ msgstr "Créer un ensemble de questions"
#: management/assets/js/components/edit/EditQuestionSet.js:91
#, javascript-format
msgid ""
-"This question set will be added to the page "
-"%s
."
+"This question set will be added to the page %s
."
msgstr ""
-"Cet ensemble de questions sera ajouté à la page %s
."
+"Cet ensemble de questions sera ajouté à la page %s
."
#: management/assets/js/components/edit/EditQuestionSet.js:98
#, javascript-format
@@ -368,8 +383,8 @@ msgid ""
"This question set will be added to the question set %s
."
msgstr ""
-"Cet ensemble de questions sera ajouté à l'ensemble de questions %s
."
+"Cet ensemble de questions sera ajouté à l'ensemble de questions %s
."
#: management/assets/js/components/edit/EditSection.js:41
#: management/assets/js/components/element/Section.js:39
diff --git a/rdmo/locale/it/LC_MESSAGES/djangojs.mo b/rdmo/locale/it/LC_MESSAGES/djangojs.mo
index 4acfb7a444..2b7bbd51b8 100644
Binary files a/rdmo/locale/it/LC_MESSAGES/djangojs.mo and b/rdmo/locale/it/LC_MESSAGES/djangojs.mo differ
diff --git a/rdmo/locale/it/LC_MESSAGES/djangojs.po b/rdmo/locale/it/LC_MESSAGES/djangojs.po
index 66166f7f8b..9731e48322 100644
--- a/rdmo/locale/it/LC_MESSAGES/djangojs.po
+++ b/rdmo/locale/it/LC_MESSAGES/djangojs.po
@@ -2,7 +2,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2023-12-09 10:33+0100\n"
+"POT-Creation-Date: 2024-04-26 16:24+0200\n"
"PO-Revision-Date: \n"
"Last-Translator: Dario Pilori \n"
"Language-Team: \n"
@@ -11,7 +11,31 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.4.2\n"
+"X-Generator: Poedit 3.4.2\n"
+
+#: core/assets/js/components/Modal.js:16
+#: management/assets/js/components/common/Modals.js:16
+msgid "Close"
+msgstr "Chiudi"
+
+#: core/assets/js/components/Modal.js:20
+#: management/assets/js/components/common/Buttons.js:19
+msgid "Save"
+msgstr "Salva"
+
+#: core/assets/js/components/SearchAndFilter.js:42
+#: projects/assets/js/utils/translations.js:15
+msgid "Search"
+msgstr "Ricerca"
+
+#: core/assets/js/components/UploadDropZone.js:18
+#, javascript-format
+msgid "%s has unsupported file type"
+msgstr "%s ha un tipo di file non supportato"
+
+#: core/assets/js/components/UploadDropZone.js:26
+msgid "Drag and drop a file here or click to select a file"
+msgstr "Trascinare e rilasciare un file qui o fare clic per selezionarlo"
#: management/assets/js/components/common/Buttons.js:6
#: management/assets/js/components/sidebar/ImportSidebar.js:27
@@ -35,10 +59,6 @@ msgstr "Copia"
msgid "Copy and continue editing"
msgstr "Copiare e continuare a modificare"
-#: management/assets/js/components/common/Buttons.js:19
-msgid "Save"
-msgstr "Salva"
-
#: management/assets/js/components/common/Buttons.js:19
msgid "Save and continue editing"
msgstr "Salvare e continuare a modificare"
@@ -88,10 +108,6 @@ msgstr "XML"
msgid "XML (full)"
msgstr "XML (completo)"
-#: management/assets/js/components/common/Modals.js:16
-msgid "Close"
-msgstr "Chiudi"
-
#: management/assets/js/components/edit/EditAttribute.js:37
#: management/assets/js/components/element/Attribute.js:31
msgid "This attribute is read only"
@@ -112,11 +128,11 @@ msgstr "Crea attributo"
#: management/assets/js/components/edit/EditAttribute.js:53
#, javascript-format
msgid ""
-"This attribute will be added to the attribute "
-"%s
."
+"This attribute will be added to the attribute %s
."
msgstr ""
-"Questo attributo verrà aggiunto all'attributo "
-"%s
."
+"Questo attributo verrà aggiunto all'attributo %s
."
#: management/assets/js/components/edit/EditAttribute.js:61
#: management/assets/js/components/edit/EditAttribute.js:68
@@ -126,17 +142,17 @@ msgid ""
"This attribute will be added to the page %s"
"code>."
msgstr ""
-"Questo attributo verrà aggiunto alla pagina "
-"%s
."
+"Questo attributo verrà aggiunto alla pagina %s
."
#: management/assets/js/components/edit/EditAttribute.js:82
#, javascript-format
msgid ""
-"This attribute will be added to the condition %s
."
+"This attribute will be added to the condition %s
."
msgstr ""
-"Questo attributo verrà aggiunto alla condizione %s
."
+"Questo attributo verrà aggiunto alla condizione %s
."
#: management/assets/js/components/edit/EditCatalog.js:39
msgid "Add existing section"
@@ -183,8 +199,8 @@ msgstr "Crea condizione"
#: management/assets/js/components/edit/EditCondition.js:57
#, javascript-format
msgid ""
-"This condition will be added to the option set "
-"%s
."
+"This condition will be added to the option set %s
."
msgstr ""
"Questa condizione verrà aggiunta all'insieme di opzioni %s
."
@@ -195,14 +211,14 @@ msgid ""
"This condition will be added to the page %s"
"code>."
msgstr ""
-"Questa condizione verrà aggiunta alla pagina "
-"%s
."
+"Questa condizione verrà aggiunta alla pagina %s
."
#: management/assets/js/components/edit/EditCondition.js:71
#, javascript-format
msgid ""
-"This condition will be added to the question set %s
."
+"This condition will be added to the question set %s
."
msgstr ""
"Questa condizione sarà aggiunta all'insieme di domande %s
."
@@ -210,11 +226,11 @@ msgstr ""
#: management/assets/js/components/edit/EditCondition.js:78
#, javascript-format
msgid ""
-"This condition will be added to the question "
-"%s
."
+"This condition will be added to the question %s
."
msgstr ""
-"Questa condizione sarà aggiunta alla domanda "
-"%s
."
+"Questa condizione sarà aggiunta alla domanda %s
."
#: management/assets/js/components/edit/EditCondition.js:85
#, javascript-format
@@ -275,11 +291,11 @@ msgstr "Crea raccolta di opzioni"
#: management/assets/js/components/edit/EditOptionSet.js:61
#, javascript-format
msgid ""
-"This option set will be added to the question "
-"%s
."
+"This option set will be added to the question %s
."
msgstr ""
-"Questo set di opzioni sarà aggiunto alla domanda %s
."
+"Questo set di opzioni sarà aggiunto alla domanda %s
."
#: management/assets/js/components/edit/EditOptionSet.js:99
msgid "Add existing option"
@@ -379,8 +395,8 @@ msgstr ""
#: management/assets/js/components/edit/EditQuestion.js:70
#, javascript-format
msgid ""
-"This question will be added to the question set %s
."
+"This question will be added to the question set %s
."
msgstr ""
"Questa domanda sarà aggiunta all'insieme di domande %s
."
@@ -405,8 +421,8 @@ msgstr "Creare un set di domande"
#: management/assets/js/components/edit/EditQuestionSet.js:96
#, javascript-format
msgid ""
-"This question set will be added to the page "
-"%s
."
+"This question set will be added to the page %s
."
msgstr ""
"Questo insieme di domande sarà aggiunto alla pagina %s
."
@@ -417,8 +433,8 @@ msgid ""
"This question set will be added to the question set %s
."
msgstr ""
-"Questo insieme di domande sarà aggiunto all'insieme di domande %s
."
+"Questo insieme di domande sarà aggiunto all'insieme di domande %s
."
#: management/assets/js/components/edit/EditSection.js:38
msgid "Add existing page"
diff --git a/rdmo/management/assets/js/actions/configActions.js b/rdmo/management/assets/js/actions/configActions.js
index baf9203e5f..ec2a21fb75 100644
--- a/rdmo/management/assets/js/actions/configActions.js
+++ b/rdmo/management/assets/js/actions/configActions.js
@@ -47,7 +47,7 @@ export function toggleElements(element) {
}
}
-export function toggleDescandants(element, elementType) {
+export function toggleDescendants(element, elementType) {
return (dispatch) => {
findDescendants(element, elementType).forEach(e => dispatch(toggleElements(e)))
}
diff --git a/rdmo/management/assets/js/actions/elementActions.js b/rdmo/management/assets/js/actions/elementActions.js
index e16db608db..a91633d940 100644
--- a/rdmo/management/assets/js/actions/elementActions.js
+++ b/rdmo/management/assets/js/actions/elementActions.js
@@ -235,9 +235,19 @@ export function fetchElement(elementType, elementId, elementAction=null) {
QuestionsApi.fetchQuestions('index'),
TasksApi.fetchTasks('index'),
]).then(([element, attributes, conditions, pages, questionsets,
- questions, tasks]) => ({
+ questions, tasks]) => {
+ if (elementAction == 'copy') {
+ delete element.conditions
+ delete element.pages
+ delete element.questionsets
+ delete element.questions
+ delete element.tasks
+ }
+
+ return {
element, attributes, conditions, pages, questionsets, questions, tasks
- }))
+ }
+ })
}
break
@@ -251,9 +261,14 @@ export function fetchElement(elementType, elementId, elementAction=null) {
ConditionsApi.fetchConditions('index'),
OptionsApi.fetchOptions('index'),
QuestionsApi.fetchQuestions('index')
- ]).then(([element, conditions, options, questions]) => ({
- element, conditions, options, questions
- }))
+ ]).then(([element, conditions, options, questions]) => {
+ if (elementAction == 'copy') {
+ delete element.questions
+ }
+ return {
+ element, conditions, options, questions
+ }
+ })
}
break
@@ -265,6 +280,7 @@ export function fetchElement(elementType, elementId, elementAction=null) {
]).then(([element, optionsets, conditions]) => {
if (elementAction == 'copy') {
delete element.optionsets
+ delete element.conditions
}
return {
element, optionsets, conditions
@@ -283,9 +299,18 @@ export function fetchElement(elementType, elementId, elementAction=null) {
QuestionsApi.fetchQuestions('index'),
TasksApi.fetchTasks('index'),
]).then(([element, attributes, optionsets, options,
- pages, questionsets, questions, tasks]) => ({
- element, attributes, optionsets, options, pages, questionsets, questions, tasks
- }))
+ pages, questionsets, questions, tasks]) => {
+ if (elementAction == 'copy') {
+ delete element.optionsets
+ delete element.pages
+ delete element.questionsets
+ delete element.questions
+ delete element.tasks
+ }
+ return {
+ element, attributes, optionsets, options, pages, questionsets, questions, tasks
+ }
+ })
break
case 'tasks':
@@ -342,14 +367,15 @@ export function fetchElementError(error) {
// store element
-export function storeElement(elementType, element, back) {
+export function storeElement(elementType, element, elementAction = null, back = false) {
return function(dispatch, getState) {
+
dispatch(storeElementInit(element))
let action
switch (elementType) {
case 'catalogs':
- action = () => QuestionsApi.storeCatalog(element)
+ action = () => QuestionsApi.storeCatalog(element, elementAction)
break
case 'sections':
@@ -385,11 +411,11 @@ export function storeElement(elementType, element, back) {
break
case 'tasks':
- action = () => TasksApi.storeTask(element)
+ action = () => TasksApi.storeTask(element, elementAction)
break
case 'views':
- action = () => ViewsApi.storeView(element)
+ action = () => ViewsApi.storeView(element, elementAction)
break
}
@@ -398,7 +424,7 @@ export function storeElement(elementType, element, back) {
dispatch(storeElementSuccess(element))
if (back) {
history.back()
- } else if (getState().elements.elementAction == 'create') {
+ } else if (['create', 'copy'].includes(getState().elements.elementAction)) {
dispatch(fetchElement(getState().elements.elementType, element.id))
}
})
@@ -574,7 +600,6 @@ export function deleteElement(elementType, element) {
case 'catalogs':
action = () => QuestionsApi.deleteCatalog(element)
break
-
case 'sections':
action = () => QuestionsApi.deleteSection(element)
break
@@ -653,9 +678,9 @@ export function dropElement(dragElement, dropElement, mode) {
const element = {...getState().elements.element}
const { dragParent, dropParent } = moveElement(element, dragElement, dropElement, mode)
- dispatch(storeElement(elementTypes[dragParent.model], dragParent))
- if (!isNil(dropParent)) {
- dispatch(storeElement(elementTypes[dropParent.model], dropParent))
+ dispatch(storeElement(elementTypes[dragParent.model], dragParent))
+ if (!isNil(dropParent)) {
+ dispatch(storeElement(elementTypes[dropParent.model], dropParent))
}
}
}
diff --git a/rdmo/management/assets/js/actions/importActions.js b/rdmo/management/assets/js/actions/importActions.js
index fa88c51870..b65dc32cbd 100644
--- a/rdmo/management/assets/js/actions/importActions.js
+++ b/rdmo/management/assets/js/actions/importActions.js
@@ -8,7 +8,7 @@ import { fetchElements, fetchElement } from './elementActions'
export function uploadFile(file) {
return function(dispatch) {
- dispatch(uploadFileInit())
+ dispatch(uploadFileInit(file))
return ManagementApi.uploadFile(file)
.then(elements => dispatch(uploadFileSuccess(elements)))
@@ -18,8 +18,8 @@ export function uploadFile(file) {
}
}
-export function uploadFileInit() {
- return {type: 'import/uploadFileInit'}
+export function uploadFileInit(file) {
+ return {type: 'import/uploadFileInit', file: file}
}
export function uploadFileSuccess(elements) {
@@ -65,6 +65,16 @@ export function updateElement(element, values) {
export function selectElements(value) {
return {type: 'import/selectElements', value}
}
+export function selectChangedElements(value) {
+ return {type: 'import/selectChangedElements', value}
+}
+
+export function showElements(value) {
+ return {type: 'import/showElements', value}
+}
+export function showChangedElements(value) {
+ return {type: 'import/showChangedElements', value}
+}
export function updateUriPrefix(uriPrefix) {
return {type: 'import/updateUriPrefix', uriPrefix}
diff --git a/rdmo/management/assets/js/api/QuestionsApi.js b/rdmo/management/assets/js/api/QuestionsApi.js
index 2a3b6f99c9..ca8895b96b 100644
--- a/rdmo/management/assets/js/api/QuestionsApi.js
+++ b/rdmo/management/assets/js/api/QuestionsApi.js
@@ -17,11 +17,12 @@ class QuestionsApi extends BaseApi {
return this.get(url)
}
- static storeCatalog(catalog) {
+ static storeCatalog(catalog, action) {
if (isNil(catalog.id)) {
return this.post('/api/v1/questions/catalogs/', catalog)
} else {
- return this.put(`/api/v1/questions/catalogs/${catalog.id}/`, catalog)
+ const actionPath = isNil(action) ? '' : `${action}/`
+ return this.put(`/api/v1/questions/catalogs/${catalog.id}/${actionPath}`, catalog)
}
}
diff --git a/rdmo/management/assets/js/api/TasksApi.js b/rdmo/management/assets/js/api/TasksApi.js
index b6a1d0f949..513d42de8b 100644
--- a/rdmo/management/assets/js/api/TasksApi.js
+++ b/rdmo/management/assets/js/api/TasksApi.js
@@ -14,11 +14,12 @@ class TasksApi extends BaseApi {
return this.get(`/api/v1/tasks/tasks/${id}/`)
}
- static storeTask(task) {
+ static storeTask(task, action) {
if (isNil(task.id)) {
return this.post('/api/v1/tasks/tasks/', task)
} else {
- return this.put(`/api/v1/tasks/tasks/${task.id}/`, task)
+ const actionPath = isNil(action) ? '' : `${action}/`
+ return this.put(`/api/v1/tasks/tasks/${task.id}/${actionPath}`, task)
}
}
diff --git a/rdmo/management/assets/js/api/ViewsApi.js b/rdmo/management/assets/js/api/ViewsApi.js
index 02a11b7da3..f9174cafb0 100644
--- a/rdmo/management/assets/js/api/ViewsApi.js
+++ b/rdmo/management/assets/js/api/ViewsApi.js
@@ -14,11 +14,12 @@ class ViewsApi extends BaseApi {
return this.get(`/api/v1/views/views/${id}/`)
}
- static storeView(view) {
+ static storeView(view, action) {
if (isNil(view.id)) {
return this.post('/api/v1/views/views/', view)
} else {
- return this.put(`/api/v1/views/views/${view.id}/`, view)
+ const actionPath = isNil(action) ? '' : `${action}/`
+ return this.put(`/api/v1/views/views/${view.id}/${actionPath}`, view)
}
}
diff --git a/rdmo/management/assets/js/components/common/Icons.js b/rdmo/management/assets/js/components/common/Icons.js
index 6456be6de4..afb21d8460 100644
--- a/rdmo/management/assets/js/components/common/Icons.js
+++ b/rdmo/management/assets/js/components/common/Icons.js
@@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
const ReadOnlyIcon = ({ title, show }) => {
return show && (
-
+
)
}
diff --git a/rdmo/management/assets/js/components/common/Labels.js b/rdmo/management/assets/js/components/common/Labels.js
new file mode 100644
index 0000000000..f0d3e3729e
--- /dev/null
+++ b/rdmo/management/assets/js/components/common/Labels.js
@@ -0,0 +1,21 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+
+const Label = ({ text, type, onClick, show = true, className = '' }) => {
+ const labelClass = `label label-${type} ${className}`
+ return show && (
+
+ {text}
+
+ )
+}
+
+Label.propTypes = {
+ text: PropTypes.string.isRequired,
+ type: PropTypes.string.isRequired,
+ onClick: PropTypes.func,
+ show: PropTypes.bool,
+ className: PropTypes.string,
+}
+
+export default Label
diff --git a/rdmo/management/assets/js/components/common/Links.js b/rdmo/management/assets/js/components/common/Links.js
index 8f816dd64a..51898ad635 100644
--- a/rdmo/management/assets/js/components/common/Links.js
+++ b/rdmo/management/assets/js/components/common/Links.js
@@ -1,7 +1,6 @@
import React from 'react'
import PropTypes from 'prop-types'
import classNames from 'classnames'
-import isEmpty from 'lodash/isEmpty'
import isNil from 'lodash/isNil'
import isUndefined from 'lodash/isUndefined'
@@ -19,14 +18,15 @@ NestedLink.propTypes = {
show: PropTypes.bool
}
-const EditLink = ({ href, title, onClick }) => {
- return
+const EditLink = ({ href, title, onClick, disabled= false }) => {
+ return
}
EditLink.propTypes = {
href: PropTypes.string.isRequired,
title: PropTypes.string.isRequired,
- onClick: PropTypes.func.isRequired
+ onClick: PropTypes.func.isRequired,
+ disabled: PropTypes.bool
}
const CopyLink = ({ href, title, onClick }) => {
@@ -103,6 +103,24 @@ LockedLink.propTypes = {
disabled: PropTypes.bool
}
+const ToggleCurrentSiteLink = ({ hasCurrentSite, onClick, show }) => {
+ const className = classNames({
+ 'element-btn-link fa': true,
+ 'fa-plus-square': !hasCurrentSite,
+ 'fa-minus-square': hasCurrentSite,
+ })
+ const title = hasCurrentSite ? gettext('Remove your site'): gettext('Add your site')
+
+ return show &&
+}
+
+ToggleCurrentSiteLink.propTypes = {
+ hasCurrentSite: PropTypes.bool.isRequired,
+ onClick: PropTypes.func.isRequired,
+ show: PropTypes.bool
+}
+
+
const ShowElementsLink = ({ showElements, show, onClick }) => {
const className = classNames({
'element-btn-link fa': true,
@@ -180,10 +198,10 @@ ExtendLink.propTypes = {
onClick: PropTypes.func.isRequired
}
-const CodeLink = ({ className, uri, onClick, order }) => {
+const CodeLink = ({ className, uri, href, onClick, order }) => {
return (
<>
-
+
{uri}
{!isNil(order) ? (
@@ -196,51 +214,42 @@ const CodeLink = ({ className, uri, onClick, order }) => {
CodeLink.propTypes = {
className: PropTypes.string.isRequired,
uri: PropTypes.string.isRequired,
+ href: PropTypes.string,
onClick: PropTypes.func.isRequired,
order: PropTypes.number
}
-const ErrorLink = ({ element, onClick }) => {
- return (
- !isEmpty(element.errors) &&
-
- )
+const ErrorLink = ({ onClick }) => {
+ return
}
ErrorLink.propTypes = {
- element: PropTypes.object.isRequired,
onClick: PropTypes.func.isRequired
}
-
-const WarningLink = ({ element, onClick }) => {
- return (
- !isEmpty(element.warnings) &&
-
- )
+const WarningLink = ({ onClick }) => {
+ return
}
WarningLink.propTypes = {
- element: PropTypes.object.isRequired,
onClick: PropTypes.func.isRequired
}
-
-const ShowLink = ({ element, onClick }) => {
- const title = element.show ? gettext('Hide') : gettext('Show')
+const ShowLink = ({ show = false, onClick }) => {
+ const title = show ? gettext('Hide') : gettext('Show')
const className = classNames({
'element-link fa': true,
- 'fa-eye-slash': element.show,
- 'fa-eye': !element.show
+ 'fa-chevron-down': !show,
+ 'fa-chevron-up': show
})
return
}
ShowLink.propTypes = {
- element: PropTypes.object.isRequired,
+ show: PropTypes.bool,
onClick: PropTypes.func.isRequired
}
-export { EditLink, CopyLink, AddLink, AvailableLink, LockedLink, ShowElementsLink,
+export { EditLink, CopyLink, AddLink, AvailableLink, ToggleCurrentSiteLink, LockedLink, ShowElementsLink,
NestedLink, ExportLink, ExtendLink, CodeLink, ErrorLink, WarningLink, ShowLink }
diff --git a/rdmo/management/assets/js/components/edit/EditAttribute.js b/rdmo/management/assets/js/components/edit/EditAttribute.js
index 8355caf91c..1d49213573 100644
--- a/rdmo/management/assets/js/components/edit/EditAttribute.js
+++ b/rdmo/management/assets/js/components/edit/EditAttribute.js
@@ -23,7 +23,7 @@ const EditAttribute = ({ config, attribute, elements, elementActions }) => {
const editAttribute = (attribute) => elementActions.fetchElement('attributes', attribute)
const updateAttribute = (key, value) => elementActions.updateElement(attribute, {[key]: value})
- const storeAttribute = (back) => elementActions.storeElement('attributes', attribute, back)
+ const storeAttribute = (back) => elementActions.storeElement('attributes', attribute, elementAction, back)
const deleteAttribute = () => elementActions.deleteElement('attributes', attribute)
const [showDeleteModal, openDeleteModal, closeDeleteModal] = useDeleteModal()
@@ -65,14 +65,14 @@ const EditAttribute = ({ config, attribute, elements, elementActions }) => {
{
parent && parent.questionset &&
%s.'), [parent.questionset.uri])
+ __html:interpolate(gettext('This attribute will be added to the question set %s
.'), [parent.questionset.uri])
}} />
}
{
parent && parent.question &&
%s.'), [parent.question.uri])
+ __html:interpolate(gettext('This attribute will be added to the question %s
.'), [parent.question.uri])
}} />
}
diff --git a/rdmo/management/assets/js/components/edit/EditCatalog.js b/rdmo/management/assets/js/components/edit/EditCatalog.js
index 9d688694ac..883f431c60 100644
--- a/rdmo/management/assets/js/components/edit/EditCatalog.js
+++ b/rdmo/management/assets/js/components/edit/EditCatalog.js
@@ -25,7 +25,7 @@ const EditCatalog = ({ config, catalog, elements, elementActions }) => {
const { elementAction, sections } = elements
const updateCatalog = (key, value) => elementActions.updateElement(catalog, {[key]: value})
- const storeCatalog = (back) => elementActions.storeElement('catalogs', catalog, back)
+ const storeCatalog = (back) => elementActions.storeElement('catalogs', catalog, elementAction, back)
const deleteCatalog = () => elementActions.deleteElement('catalogs', catalog)
const editSection = (value) => elementActions.fetchElement('sections', value.section)
diff --git a/rdmo/management/assets/js/components/edit/EditCondition.js b/rdmo/management/assets/js/components/edit/EditCondition.js
index 8cffeb4b13..6f990441fa 100644
--- a/rdmo/management/assets/js/components/edit/EditCondition.js
+++ b/rdmo/management/assets/js/components/edit/EditCondition.js
@@ -22,7 +22,7 @@ const EditCondition = ({ config, condition, elements, elementActions }) => {
const { elementAction, parent, attributes, options } = elements
const updateCondition = (key, value) => elementActions.updateElement(condition, {[key]: value})
- const storeCondition = (back) => elementActions.storeElement('conditions', condition, back)
+ const storeCondition = (back) => elementActions.storeElement('conditions', condition, elementAction, back)
const deleteCondition = () => elementActions.deleteElement('conditions', condition)
const editAttribute = (attribute) => elementActions.fetchElement('attributes', attribute)
diff --git a/rdmo/management/assets/js/components/edit/EditOption.js b/rdmo/management/assets/js/components/edit/EditOption.js
index 08c865deca..23776667a0 100644
--- a/rdmo/management/assets/js/components/edit/EditOption.js
+++ b/rdmo/management/assets/js/components/edit/EditOption.js
@@ -24,7 +24,7 @@ const EditOption = ({ config, option, elements, elementActions }) => {
const { elementAction, parent } = elements
const updateOption = (key, value) => elementActions.updateElement(option, {[key]: value})
- const storeOption = (back) => elementActions.storeElement('options', option, back)
+ const storeOption = (back) => elementActions.storeElement('options', option, elementAction, back)
const deleteOption = () => elementActions.deleteElement('options', option)
const [showDeleteModal, openDeleteModal, closeDeleteModal] = useDeleteModal()
diff --git a/rdmo/management/assets/js/components/edit/EditOptionSet.js b/rdmo/management/assets/js/components/edit/EditOptionSet.js
index 1ac9da2128..f8d3e09265 100644
--- a/rdmo/management/assets/js/components/edit/EditOptionSet.js
+++ b/rdmo/management/assets/js/components/edit/EditOptionSet.js
@@ -25,7 +25,7 @@ const EditOptionSet = ({ config, optionset, elements, elementActions }) => {
const { elementAction, parent, conditions, options } = elements
const updateOptionSet = (key, value) => elementActions.updateElement(optionset, {[key]: value})
- const storeOptionSet = (back) => elementActions.storeElement('optionsets', optionset, back)
+ const storeOptionSet = (back) => elementActions.storeElement('optionsets', optionset, elementAction, back)
const deleteOptionSet = () => elementActions.deleteElement('optionsets', optionset)
const editOption = (value) => elementActions.fetchElement('options', value.option)
diff --git a/rdmo/management/assets/js/components/edit/EditPage.js b/rdmo/management/assets/js/components/edit/EditPage.js
index 707a82a2d4..6c25ab0d7f 100644
--- a/rdmo/management/assets/js/components/edit/EditPage.js
+++ b/rdmo/management/assets/js/components/edit/EditPage.js
@@ -45,7 +45,7 @@ const EditPage = ({ config, page, elements, elementActions }) => {
elementActions.updateElement(page, { [key]: value })
}
}
- const storePage = (back) => elementActions.storeElement('pages', page, back)
+ const storePage = (back) => elementActions.storeElement('pages', page, elementAction, back)
const deletePage = () => elementActions.deleteElement('pages', page)
const editElement = (value) => {
@@ -70,8 +70,8 @@ const EditPage = ({ config, page, elements, elementActions }) => {
// for reasons unknown, the strings are not picked up by makemessages from the props
const addElementText = gettext('Add existing element')
- const createQuestionText = gettext('Create new question set')
- const createQuestionSetText = gettext('Create new question')
+ const createQuestionText = gettext('Create new question')
+ const createQuestionSetText = gettext('Create new question set')
return (
@@ -136,6 +136,8 @@ const EditPage = ({ config, page, elements, elementActions }) => {
+
{
const { elementAction, parent, attributes, optionsets, options, conditions } = elements
const updateQuestion = (key, value) => elementActions.updateElement(question, {[key]: value})
- const storeQuestion = (back) => elementActions.storeElement('questions', question, back)
+ const storeQuestion = (back) => elementActions.storeElement('questions', question, elementAction, back)
const deleteQuestion = () => elementActions.deleteElement('questions', question)
const editOptionSet = (optionset) => elementActions.fetchElement('optionsets', optionset)
@@ -40,6 +40,10 @@ const EditQuestion = ({ config, question, elements, elementActions}) => {
const info =
+ // for reasons unknown, the strings are not picked up by makemessages from the props
+ const addOptionText = gettext('Add existing optionset')
+ const createOptionText = gettext('Create new optionset')
+
return (
@@ -153,7 +157,7 @@ const EditQuestion = ({ config, question, elements, elementActions}) => {
diff --git a/rdmo/management/assets/js/components/edit/EditQuestionSet.js b/rdmo/management/assets/js/components/edit/EditQuestionSet.js
index e23c4fa146..8736156615 100644
--- a/rdmo/management/assets/js/components/edit/EditQuestionSet.js
+++ b/rdmo/management/assets/js/components/edit/EditQuestionSet.js
@@ -45,7 +45,7 @@ const EditQuestionSet = ({ config, questionset, elements, elementActions }) => {
elementActions.updateElement(questionset, { [key]: value })
}
}
- const storeQuestionSet = (back) => elementActions.storeElement('questionsets', questionset, back)
+ const storeQuestionSet = (back) => elementActions.storeElement('questionsets', questionset, elementAction, back)
const deleteQuestionSet = () => elementActions.deleteElement('questionsets', questionset)
const editElement = (value) => {
@@ -70,8 +70,8 @@ const EditQuestionSet = ({ config, questionset, elements, elementActions }) => {
// for reasons unknown, the strings are not picked up by makemessages from the props
const addElementText = gettext('Add existing element')
- const createQuestionText = gettext('Create new question set')
- const createQuestionSetText = gettext('Create new question')
+ const createQuestionText = gettext('Create new question')
+ const createQuestionSetText = gettext('Create new question set')
return (
diff --git a/rdmo/management/assets/js/components/edit/EditSection.js b/rdmo/management/assets/js/components/edit/EditSection.js
index 4c55d368c0..da22871f1a 100644
--- a/rdmo/management/assets/js/components/edit/EditSection.js
+++ b/rdmo/management/assets/js/components/edit/EditSection.js
@@ -24,7 +24,7 @@ const EditSection = ({ config, section, elements, elementActions }) => {
const { elementAction, parent, pages } = elements
const updateSection = (key, value) => elementActions.updateElement(section, {[key]: value})
- const storeSection = (back) => elementActions.storeElement('sections', section, back)
+ const storeSection = (back) => elementActions.storeElement('sections', section, elementAction, back)
const deleteSection = () => elementActions.deleteElement('sections', section)
const editPage = (value) => elementActions.fetchElement('pages', value.page)
@@ -93,6 +93,8 @@ const EditSection = ({ config, section, elements, elementActions }) => {
+
))
}
diff --git a/rdmo/management/assets/js/components/edit/EditTask.js b/rdmo/management/assets/js/components/edit/EditTask.js
index 551e039cc6..ba66dfe603 100644
--- a/rdmo/management/assets/js/components/edit/EditTask.js
+++ b/rdmo/management/assets/js/components/edit/EditTask.js
@@ -25,7 +25,7 @@ const EditTask = ({ config, task, elements, elementActions}) => {
const { elementAction, attributes, catalogs, conditions } = elements
const updateTask = (key, value) => elementActions.updateElement(task, {[key]: value})
- const storeTask = (back) => elementActions.storeElement('tasks', task, back)
+ const storeTask = (back) => elementActions.storeElement('tasks', task, elementAction, back)
const deleteTask = () => elementActions.deleteElement('tasks', task)
const editCondition = (condition) => elementActions.fetchElement('conditions', condition)
diff --git a/rdmo/management/assets/js/components/edit/EditView.js b/rdmo/management/assets/js/components/edit/EditView.js
index ae5bfb2986..416d450263 100644
--- a/rdmo/management/assets/js/components/edit/EditView.js
+++ b/rdmo/management/assets/js/components/edit/EditView.js
@@ -25,7 +25,7 @@ const EditView = ({ config, view, elements, elementActions }) => {
const { elementAction, catalogs } = elements
const updateView = (key, value) => elementActions.updateElement(view, {[key]: value})
- const storeView = (back) => elementActions.storeElement('views', view, back)
+ const storeView = (back) => elementActions.storeElement('views', view, elementAction, back)
const deleteView = () => elementActions.deleteElement('views', view)
const [showDeleteModal, openDeleteModal, closeDeleteModal] = useDeleteModal()
diff --git a/rdmo/management/assets/js/components/element/Attribute.js b/rdmo/management/assets/js/components/element/Attribute.js
index 7c8d161d7f..8d4915a36a 100644
--- a/rdmo/management/assets/js/components/element/Attribute.js
+++ b/rdmo/management/assets/js/components/element/Attribute.js
@@ -16,7 +16,7 @@ const Attribute = ({ config, attribute, elementActions, display='list', indent=0
const editUrl = buildPath(config.baseUrl, 'attributes', attribute.id)
const copyUrl = buildPath(config.baseUrl, 'attributes', attribute.id, 'copy')
const nestedUrl = buildPath(config.baseUrl, 'attributes', attribute.id, 'nested')
- const exportUrl = buildPath('/api/v1/', 'domain', 'attributes', attribute.id, 'export')
+ const exportUrl = buildPath(config.apiUrl, 'domain', 'attributes', attribute.id, 'export')
const fetchEdit = () => elementActions.fetchElement('attributes', attribute.id)
const fetchCopy = () => elementActions.fetchElement('attributes', attribute.id, 'copy')
@@ -42,7 +42,7 @@ const Attribute = ({ config, attribute, elementActions, display='list', indent=0
{gettext('Attribute')}{': '}
- fetchEdit()} />
+ fetchEdit()} />
diff --git a/rdmo/management/assets/js/components/element/Catalog.js b/rdmo/management/assets/js/components/element/Catalog.js
index fd934ae585..13001a614b 100644
--- a/rdmo/management/assets/js/components/element/Catalog.js
+++ b/rdmo/management/assets/js/components/element/Catalog.js
@@ -6,7 +6,7 @@ import { filterElement } from '../../utils/filter'
import { buildPath } from '../../utils/location'
import { ElementErrors } from '../common/Errors'
-import { EditLink, CopyLink, AddLink, AvailableLink, LockedLink, NestedLink,
+import { EditLink, CopyLink, AddLink, AvailableLink, ToggleCurrentSiteLink, LockedLink, NestedLink,
ExportLink, CodeLink } from '../common/Links'
import { ReadOnlyIcon } from '../common/Icons'
@@ -18,7 +18,7 @@ const Catalog = ({ config, catalog, elementActions, display='list',
const editUrl = buildPath(config.baseUrl, 'catalogs', catalog.id)
const copyUrl = buildPath(config.baseUrl, 'catalogs', catalog.id, 'copy')
const nestedUrl = buildPath(config.baseUrl, 'catalogs', catalog.id, 'nested')
- const exportUrl = buildPath('/api/v1/', 'questions', 'catalogs', catalog.id, 'export')
+ const exportUrl = buildPath(config.apiUrl, 'questions', 'catalogs', catalog.id, 'export')
const fetchEdit = () => elementActions.fetchElement('catalogs', catalog.id)
const fetchCopy = () => elementActions.fetchElement('catalogs', catalog.id, 'copy')
@@ -27,6 +27,8 @@ const Catalog = ({ config, catalog, elementActions, display='list',
const toggleAvailable = () => elementActions.storeElement('catalogs', {...catalog, available: !catalog.available })
const toggleLocked = () => elementActions.storeElement('catalogs', {...catalog, locked: !catalog.locked })
+ const toggleCurrentSite = () => elementActions.storeElement('catalogs', catalog, 'toggle-site')
+
const createSection = () => elementActions.createElement('sections', { catalog })
const elementNode = (
@@ -41,6 +43,9 @@ const Catalog = ({ config, catalog, elementActions, display='list',
: gettext('Make catalog available')}
available={catalog.available} locked={catalog.locked} onClick={toggleAvailable}
disabled={catalog.read_only} />
+
- {gettext('Catalog')}{': '} {catalog.title}
+ {gettext('Catalog')}{': '}
+
{
get(config, 'display.uri.catalogs', true) &&
- fetchEdit()} />
+ fetchEdit()} />
}
diff --git a/rdmo/management/assets/js/components/element/Condition.js b/rdmo/management/assets/js/components/element/Condition.js
index 816f77c65d..37c1d1c82b 100644
--- a/rdmo/management/assets/js/components/element/Condition.js
+++ b/rdmo/management/assets/js/components/element/Condition.js
@@ -14,7 +14,7 @@ const Condition = ({ config, condition, elementActions, filter=false, filterEdit
const editUrl = buildPath(config.baseUrl, 'conditions', condition.id)
const copyUrl = buildPath(config.baseUrl, 'conditions', condition.id, 'copy')
- const exportUrl = buildPath('/api/v1/', 'conditions', 'conditions', condition.id, 'export')
+ const exportUrl = buildPath(config.apiUrl, 'conditions', 'conditions', condition.id, 'export')
const fetchEdit = () => elementActions.fetchElement('conditions', condition.id)
const fetchCopy = () => elementActions.fetchElement('conditions', condition.id, 'copy')
@@ -35,7 +35,7 @@ const Condition = ({ config, condition, elementActions, filter=false, filterEdit
{gettext('Condition')}{': '}
- fetchEdit()} />
+ fetchEdit()} />
diff --git a/rdmo/management/assets/js/components/element/Option.js b/rdmo/management/assets/js/components/element/Option.js
index 64aac49362..a3528c6739 100644
--- a/rdmo/management/assets/js/components/element/Option.js
+++ b/rdmo/management/assets/js/components/element/Option.js
@@ -15,7 +15,7 @@ const Option = ({ config, option, elementActions, display='list', indent=0, filt
const editUrl = buildPath(config.baseUrl, 'options', option.id)
const copyUrl = buildPath(config.baseUrl, 'options', option.id, 'copy')
- const exportUrl = buildPath('/api/v1/', 'options', 'options', option.id, 'export')
+ const exportUrl = buildPath(config.apiUrl, 'options', 'options', option.id, 'export')
const fetchEdit = () => elementActions.fetchElement('options', option.id)
const fetchCopy = () => elementActions.fetchElement('options', option.id, 'copy')
@@ -34,11 +34,12 @@ const Option = ({ config, option, elementActions, display='list', indent=0, filt
- {gettext('Option')}{': '} {option.text}
+ {gettext('Option')}{': '}
+
{
get(config, 'display.uri.options', true) &&
- fetchEdit()} />
+ fetchEdit()} />
}
diff --git a/rdmo/management/assets/js/components/element/OptionSet.js b/rdmo/management/assets/js/components/element/OptionSet.js
index 3628d8efa1..cbc6cfba2e 100644
--- a/rdmo/management/assets/js/components/element/OptionSet.js
+++ b/rdmo/management/assets/js/components/element/OptionSet.js
@@ -1,5 +1,6 @@
import React from 'react'
import PropTypes from 'prop-types'
+import get from 'lodash/get'
import { filterElement } from '../../utils/filter'
import { buildPath } from '../../utils/location'
@@ -16,7 +17,9 @@ const OptionSet = ({ config, optionset, elementActions, display='list', filter=f
const editUrl = buildPath(config.baseUrl, 'optionsets', optionset.id)
const copyUrl = buildPath(config.baseUrl, 'optionsets', optionset.id, 'copy')
const nestedUrl = buildPath(config.baseUrl, 'optionsets', optionset.id, 'nested')
- const exportUrl = buildPath('/api/v1/', 'options', 'optionsets', optionset.id, 'export')
+ const exportUrl = buildPath(config.apiUrl, 'options', 'optionsets', optionset.id, 'export')
+
+ const getConditionUrl = (index) => buildPath(config.apiUrl, 'conditions', 'conditions', optionset.conditions[index])
const fetchEdit = () => elementActions.fetchElement('optionsets', optionset.id)
const fetchCopy = () => elementActions.fetchElement('optionsets', optionset.id, 'copy')
@@ -24,6 +27,7 @@ const OptionSet = ({ config, optionset, elementActions, display='list', filter=f
const toggleLocked = () => elementActions.storeElement('optionsets', {...optionset, locked: !optionset.locked })
const createOption = () => elementActions.createElement('options', { optionset })
+ const fetchCondition = (index) => elementActions.fetchElement('conditions', optionset.conditions[index])
const elementNode = (
@@ -41,8 +45,20 @@ const OptionSet = ({ config, optionset, elementActions, display='list', filter=f
{gettext('Option set')}{': '}
- fetchEdit()} />
+ fetchEdit()} />
+ {
+ get(config, 'display.uri.conditions', true) && optionset.condition_uris.map((uri, index) => (
+
+ fetchCondition(index)}
+ />
+
+ ))
+ }
diff --git a/rdmo/management/assets/js/components/element/Page.js b/rdmo/management/assets/js/components/element/Page.js
index 0a7e086296..e54fc2b99d 100644
--- a/rdmo/management/assets/js/components/element/Page.js
+++ b/rdmo/management/assets/js/components/element/Page.js
@@ -22,7 +22,10 @@ const Page = ({ config, page, configActions, elementActions, display='list', ind
const editUrl = buildPath(config.baseUrl, 'pages', page.id)
const copyUrl = buildPath(config.baseUrl, 'pages', page.id, 'copy')
const nestedUrl = buildPath(config.baseUrl, 'pages', page.id, 'nested')
- const exportUrl = buildPath('/api/v1/', 'questions', 'pages', page.id, 'export')
+ const exportUrl = buildPath(config.apiUrl, 'questions', 'pages', page.id, 'export')
+ const attributeUrl = buildPath(config.apiUrl, 'domain', 'attributes', page.attribute)
+
+ const getConditionUrl = (index) => buildPath(config.apiUrl, 'conditions', 'conditions', page.conditions[index])
const fetchEdit = () => elementActions.fetchElement('pages', page.id)
const fetchCopy = () => elementActions.fetchElement('pages', page.id, 'copy')
@@ -54,22 +57,39 @@ const Page = ({ config, page, configActions, elementActions, display='list', ind
- {gettext('Page')}{': '} {page.title}
+ {gettext('Page')}{': '}
+
{
get(config, 'display.uri.pages', true) &&
- fetchEdit()} order={order} />
+ fetchEdit()}
+ order={order}
+ />
}
{
get(config, 'display.uri.attributes', true) && page.attribute_uri &&
- fetchAttribute()} />
+ fetchAttribute()}
+ />
}
{
get(config, 'display.uri.conditions', true) && page.condition_uris.map((uri, index) => (
- fetchCondition(index)} />
+ fetchCondition(index)}
+ />
))
}
diff --git a/rdmo/management/assets/js/components/element/Question.js b/rdmo/management/assets/js/components/element/Question.js
index e9864d8cd2..8feeaab205 100644
--- a/rdmo/management/assets/js/components/element/Question.js
+++ b/rdmo/management/assets/js/components/element/Question.js
@@ -17,7 +17,11 @@ const Question = ({ config, question, elementActions, display='list', indent=0,
const editUrl = buildPath(config.baseUrl, 'questions', question.id)
const copyUrl = buildPath(config.baseUrl, 'questions', question.id, 'copy')
- const exportUrl = buildPath('/api/v1/', 'questions', 'questions', question.id, 'export')
+ const exportUrl = buildPath(config.apiUrl, 'questions', 'questions', question.id, 'export')
+ const attributeUrl = buildPath(config.apiUrl, 'domain', 'attributes', question.attribute)
+
+ const getConditionUrl = (index) => buildPath(config.apiUrl, 'conditions', 'conditions', question.conditions[index])
+ const getOptionSetUrl = (index) => buildPath(config.apiUrl, 'options', 'optionsets', question.optionsets[index])
const fetchEdit = () => elementActions.fetchElement('questions', question.id)
const fetchCopy = () => elementActions.fetchElement('questions', question.id, 'copy')
@@ -42,29 +46,46 @@ const Question = ({ config, question, elementActions, display='list', indent=0,
{gettext('Question')}{': '}
- {question.text}
+
{
get(config, 'display.uri.questions', true) &&
- fetchEdit()} order={order} />
+ fetchEdit()}
+ order={order} />
}
{
get(config, 'display.uri.attributes', true) && question.attribute_uri &&
- fetchAttribute()} />
+ fetchAttribute()} />
}
{
get(config, 'display.uri.conditions', true) && question.condition_uris.map((uri, index) => (
- fetchCondition(index)} />
+ fetchCondition(index)} />
))
}
{
get(config, 'display.uri.optionsets', true) && question.optionset_uris.map((uri, index) => (
- fetchOptionSet(index)} />
+ fetchOptionSet(index)} />
))
}
diff --git a/rdmo/management/assets/js/components/element/QuestionSet.js b/rdmo/management/assets/js/components/element/QuestionSet.js
index 56d3bdd701..c72759b1d1 100644
--- a/rdmo/management/assets/js/components/element/QuestionSet.js
+++ b/rdmo/management/assets/js/components/element/QuestionSet.js
@@ -21,7 +21,10 @@ const QuestionSet = ({ config, questionset, configActions, elementActions, displ
const editUrl = buildPath(config.baseUrl, 'questionsets', questionset.id)
const copyUrl = buildPath(config.baseUrl, 'questionsets', questionset.id, 'copy')
const nestedUrl = buildPath(config.baseUrl, 'questionsets', questionset.id, 'nested')
- const exportUrl = buildPath('/api/v1/', 'questions', 'questionsets', questionset.id, 'export')
+ const exportUrl = buildPath(config.apiUrl, 'questions', 'questionsets', questionset.id, 'export')
+ const attributeUrl = buildPath(config.apiUrl, 'domain', 'attributes', questionset.attribute)
+
+ const getConditionUrl = (index) => buildPath(config.apiUrl, 'conditions', 'conditions', questionset.conditions[index])
const fetchEdit = () => elementActions.fetchElement('questionsets', questionset.id)
const fetchCopy = () => elementActions.fetchElement('questionsets', questionset.id, 'copy')
@@ -53,22 +56,39 @@ const QuestionSet = ({ config, questionset, configActions, elementActions, displ
- {gettext('Question set')}{': '} {questionset.title}
+ {gettext('Question set')}{': '}
+
{
get(config, 'display.uri.questionsets', true) &&
- fetchEdit()} order={order} />
+ fetchEdit()}
+ order={order}
+ />
}
{
get(config, 'display.uri.attributes', true) && questionset.attribute_uri &&
- fetchAttribute()} />
+ fetchAttribute()}
+ />
}
{
get(config, 'display.uri.conditions', true) && questionset.condition_uris.map((uri, index) => (
- fetchCondition(index)} />
+ fetchCondition(index)}
+ />
))
}
diff --git a/rdmo/management/assets/js/components/element/Section.js b/rdmo/management/assets/js/components/element/Section.js
index 92e0150ad7..6983c35d2c 100644
--- a/rdmo/management/assets/js/components/element/Section.js
+++ b/rdmo/management/assets/js/components/element/Section.js
@@ -23,7 +23,7 @@ const Section = ({ config, section, configActions, elementActions, display='list
const editUrl = buildPath(config.baseUrl, 'sections', section.id)
const copyUrl = buildPath(config.baseUrl, 'sections', section.id, 'copy')
const nestedUrl = buildPath(config.baseUrl, 'sections', section.id, 'nested')
- const exportUrl = buildPath('/api/v1/', 'questions', 'sections', section.id, 'export')
+ const exportUrl = buildPath(config.apiUrl, 'questions', 'sections', section.id, 'export')
const fetchEdit = () => elementActions.fetchElement('sections', section.id)
const fetchCopy = () => elementActions.fetchElement('sections', section.id, 'copy')
@@ -51,11 +51,12 @@ const Section = ({ config, section, configActions, elementActions, display='list
- {gettext('Section')}{': '} {section.title}
+ {gettext('Section')}{': '}
+
{
get(config, 'display.uri.sections', true) &&
- fetchEdit()} order={order} />
+ fetchEdit()} order={order} />
}
diff --git a/rdmo/management/assets/js/components/element/Task.js b/rdmo/management/assets/js/components/element/Task.js
index 12676cc89f..1e0eee4f6f 100644
--- a/rdmo/management/assets/js/components/element/Task.js
+++ b/rdmo/management/assets/js/components/element/Task.js
@@ -6,7 +6,7 @@ import { filterElement } from '../../utils/filter'
import { buildPath } from '../../utils/location'
import { ElementErrors } from '../common/Errors'
-import { EditLink, CopyLink, AvailableLink, LockedLink, ExportLink, CodeLink } from '../common/Links'
+import { EditLink, CopyLink, AvailableLink, LockedLink, ExportLink, CodeLink, ToggleCurrentSiteLink } from '../common/Links'
import { ReadOnlyIcon } from '../common/Icons'
const Task = ({ config, task, elementActions, filter=false, filterSites=false, filterEditors=false }) => {
@@ -15,12 +15,15 @@ const Task = ({ config, task, elementActions, filter=false, filterSites=false, f
const editUrl = buildPath(config.baseUrl, 'tasks', task.id)
const copyUrl = buildPath(config.baseUrl, 'tasks', task.id, 'copy')
- const exportUrl = buildPath('/api/v1/', 'tasks', 'tasks', task.id, 'export')
+ const exportUrl = buildPath(config.apiUrl, 'tasks', 'tasks', task.id, 'export')
+
+ const getConditionUrl = (index) => buildPath(config.apiUrl, 'conditions', 'conditions', task.conditions[index])
const fetchEdit = () => elementActions.fetchElement('tasks', task.id)
const fetchCopy = () => elementActions.fetchElement('tasks', task.id, 'copy')
const toggleAvailable = () => elementActions.storeElement('tasks', {...task, available: !task.available })
const toggleLocked = () => elementActions.storeElement('tasks', {...task, locked: !task.locked })
+ const toggleCurrentSite = () => elementActions.storeElement('tasks', task, 'toggle-site')
const fetchCondition = (index) => elementActions.fetchElement('conditions', task.conditions[index])
@@ -35,6 +38,9 @@ const Task = ({ config, task, elementActions, filter=false, filterSites=false, f
: gettext('Make task available')}
available={task.available} locked={task.locked} onClick={toggleAvailable}
disabled={task.read_only} />
+
{gettext('Task')}{': '}
- {task.title}
+
{
get(config, 'display.uri.tasks', true) &&
- fetchEdit()} />
+ fetchEdit()} />
}
{
get(config, 'display.uri.conditions', true) && task.condition_uris.map((uri, index) => (
- fetchCondition(index)} />
+ fetchCondition(index)}
+ />
))
}
diff --git a/rdmo/management/assets/js/components/element/View.js b/rdmo/management/assets/js/components/element/View.js
index 3c1655ae81..60d51dc72b 100644
--- a/rdmo/management/assets/js/components/element/View.js
+++ b/rdmo/management/assets/js/components/element/View.js
@@ -5,7 +5,7 @@ import { filterElement } from '../../utils/filter'
import { buildPath } from '../../utils/location'
import { ElementErrors } from '../common/Errors'
-import { EditLink, CopyLink, AvailableLink, LockedLink, ExportLink, CodeLink } from '../common/Links'
+import { EditLink, CopyLink, AvailableLink, LockedLink, ExportLink, CodeLink, ToggleCurrentSiteLink } from '../common/Links'
import { ReadOnlyIcon } from '../common/Icons'
const View = ({ config, view, elementActions, filter=false, filterSites=false, filterEditors=false }) => {
@@ -14,12 +14,13 @@ const View = ({ config, view, elementActions, filter=false, filterSites=false, f
const editUrl = buildPath(config.baseUrl, 'views', view.id)
const copyUrl = buildPath(config.baseUrl, 'views', view.id, 'copy')
- const exportUrl = buildPath('/api/v1/', 'views', 'views', view.id, 'export')
+ const exportUrl = buildPath(config.apiUrl, 'views', 'views', view.id, 'export')
const fetchEdit = () => elementActions.fetchElement('views', view.id)
const fetchCopy = () => elementActions.fetchElement('views', view.id, 'copy')
const toggleAvailable = () => elementActions.storeElement('views', {...view, available: !view.available })
const toggleLocked = () => elementActions.storeElement('views', {...view, locked: !view.locked })
+ const toggleCurrentSite = () => elementActions.storeElement('views', view, 'toggle-site')
return showElement && (
@@ -32,6 +33,9 @@ const View = ({ config, view, elementActions, filter=false, filterSites=false, f
: gettext('Make view available')}
available={view.available} locked={view.locked} onClick={toggleAvailable}
disabled={view.read_only} />
+
{gettext('View')}{': '}
- fetchEdit()} />
+
+
+
+ fetchEdit()} />
diff --git a/rdmo/management/assets/js/components/elements/Attributes.js b/rdmo/management/assets/js/components/elements/Attributes.js
index ffb83c62d9..e89b5b8d7b 100644
--- a/rdmo/management/assets/js/components/elements/Attributes.js
+++ b/rdmo/management/assets/js/components/elements/Attributes.js
@@ -33,7 +33,7 @@ const Attributes = ({ config, attributes, configActions, elementActions }) => {
placeholder={gettext('Filter attributes')} />
-
{
diff --git a/rdmo/management/assets/js/components/import/ImportAggregatedErrorsPanel.js b/rdmo/management/assets/js/components/import/ImportAggregatedErrorsPanel.js
new file mode 100644
index 0000000000..8f7fd000e6
--- /dev/null
+++ b/rdmo/management/assets/js/components/import/ImportAggregatedErrorsPanel.js
@@ -0,0 +1,56 @@
+// ImportAggregatedErrorsPanel.js
+import React from 'react'
+import PropTypes from 'prop-types'
+import { ShowLink } from '../common/Links'
+import { generateErrorMessageListItems } from './common/ErrorsListGroup'
+import get from 'lodash/get'
+
+// Function to aggregate unique errors from elements
+const aggregateUniqueErrors = (elements) => {
+ const allErrors = elements.reduce((acc, element) => {
+ return acc.concat(element.errors)
+ }, [])
+
+ // Filter out duplicate errors
+ const uniqueErrors = [...new Set(allErrors)]
+
+ return uniqueErrors
+}
+
+const ImportAggregatedErrorsPanel = ({ config, elements, configActions }) => {
+ const updateShowErrors = () => {
+ const currentVal = get(config, 'filter.import.errors.show', false)
+ configActions.updateConfig('filter.import.errors.show', !currentVal)
+ }
+
+ const showErrors = get(config, 'filter.import.errors.show', false)
+
+ // Aggregate all unique errors into a single flat array
+ const uniqueErrors = aggregateUniqueErrors(elements)
+
+ const errorsHeadingText = {gettext('Errors')} ({elements.length}) :
+
+ return ( uniqueErrors.length > 0 &&
+
+
+ {errorsHeadingText}
+
+ {}}/>
+
+
+ {showErrors && (
+
+ {generateErrorMessageListItems(uniqueErrors)}
+
+ )}
+
+ )
+}
+
+ImportAggregatedErrorsPanel.propTypes = {
+ config: PropTypes.object.isRequired,
+ elements: PropTypes.array.isRequired,
+ configActions: PropTypes.object.isRequired
+}
+
+export default ImportAggregatedErrorsPanel
diff --git a/rdmo/management/assets/js/components/import/ImportAggregatedWarningsPanel.js b/rdmo/management/assets/js/components/import/ImportAggregatedWarningsPanel.js
new file mode 100644
index 0000000000..12d7dc6b58
--- /dev/null
+++ b/rdmo/management/assets/js/components/import/ImportAggregatedWarningsPanel.js
@@ -0,0 +1,56 @@
+// ImportAggregatedWarningsPanel.js
+import React from 'react'
+import PropTypes from 'prop-types'
+import { ShowLink } from '../common/Links'
+import { generateWarningListItems } from './common/WarningsListGroup'
+import get from 'lodash/get'
+
+// Function to aggregate warnings from elements
+const aggregateWarnings = (elements) => {
+ return elements.reduce((acc, element) => {
+ Object.entries(element.warnings).forEach(([uri, messages]) => {
+ acc.push({ elementWarnings: { [uri]: messages }, elementModel: element.model })
+ })
+ return acc
+ }, [])
+}
+
+const ImportAggregatedWarningsPanel = ({ config, elements, configActions }) => {
+ const updateShowWarnings = () => {
+ const currentVal = get(config, 'filter.import.warnings.show', false)
+ configActions.updateConfig('filter.import.warnings.show', !currentVal)
+ }
+
+ const showWarnings = get(config, 'filter.import.warnings.show', false)
+
+ // Aggregate all warnings into a single list
+ const aggregatedWarnings = aggregateWarnings(elements)
+
+ const warningsHeadingText = {gettext('Warnings')} ({elements.length}):
+
+ return ( aggregatedWarnings.length > 0 &&
+
+
+ {warningsHeadingText}
+
+ {}}/>
+
+
+ {showWarnings && (
+
+ {aggregatedWarnings.map(({ elementWarnings, elementModel }) =>
+ generateWarningListItems(elementWarnings, elementModel)
+ )}
+
+ )}
+
+ )
+}
+
+ImportAggregatedWarningsPanel.propTypes = {
+ config: PropTypes.object.isRequired,
+ elements: PropTypes.array.isRequired,
+ configActions: PropTypes.object.isRequired
+}
+
+export default ImportAggregatedWarningsPanel
diff --git a/rdmo/management/assets/js/components/import/ImportAttribute.js b/rdmo/management/assets/js/components/import/ImportAttribute.js
deleted file mode 100644
index a360f9c14f..0000000000
--- a/rdmo/management/assets/js/components/import/ImportAttribute.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-
-import { CodeLink, WarningLink, ErrorLink, ShowLink } from '../common/Links'
-
-import Errors from './common/Errors'
-import Fields from './common/Fields'
-import Form from './common/Form'
-import Warnings from './common/Warnings'
-
-import { codeClass } from '../../constants/elements'
-
-const ImportAttribute = ({ config, attribute, importActions }) => {
- const showFields = () => importActions.updateElement(attribute, {show: !attribute.show})
- const toggleImport = () => importActions.updateElement(attribute, {import: !attribute.import})
- const updateAttribute = (key, value) => importActions.updateElement(attribute, {[key]: value})
-
- return (
-
-
-
-
-
-
-
-
-
-
- {
- attribute.show && <>
-
-
-
-
- >
- }
-
- )
-}
-
-ImportAttribute.propTypes = {
- config: PropTypes.object.isRequired,
- attribute: PropTypes.object.isRequired,
- importActions: PropTypes.object.isRequired
-}
-
-export default ImportAttribute
diff --git a/rdmo/management/assets/js/components/import/ImportCatalog.js b/rdmo/management/assets/js/components/import/ImportCatalog.js
deleted file mode 100644
index 2e564e3b69..0000000000
--- a/rdmo/management/assets/js/components/import/ImportCatalog.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-
-import { AvailableLink, CodeLink, WarningLink, ErrorLink, ShowLink } from '../common/Links'
-
-import Errors from './common/Errors'
-import Fields from './common/Fields'
-import Form from './common/Form'
-import Warnings from './common/Warnings'
-
-import { codeClass } from '../../constants/elements'
-
-const ImportCatalog = ({ config, catalog, importActions }) => {
- const showFields = () => importActions.updateElement(catalog, {show: !catalog.show})
- const toggleImport = () => importActions.updateElement(catalog, {import: !catalog.import})
- const toggleAvailable = () => importActions.updateElement(catalog, {available: !catalog.available})
- const updateCatalog = (key, value) => importActions.updateElement(catalog, {[key]: value})
-
- return (
-
-
-
-
-
-
-
-
-
-
-
- {
- catalog.show && <>
-
-
-
-
- >
- }
-
- )
-}
-
-ImportCatalog.propTypes = {
- config: PropTypes.object.isRequired,
- catalog: PropTypes.object.isRequired,
- importActions: PropTypes.object.isRequired
-}
-
-export default ImportCatalog
diff --git a/rdmo/management/assets/js/components/import/ImportCondition.js b/rdmo/management/assets/js/components/import/ImportCondition.js
deleted file mode 100644
index 58598f2429..0000000000
--- a/rdmo/management/assets/js/components/import/ImportCondition.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-
-import { CodeLink, WarningLink, ErrorLink, ShowLink } from '../common/Links'
-
-import Errors from './common/Errors'
-import Fields from './common/Fields'
-import Form from './common/Form'
-import Warnings from './common/Warnings'
-
-import { codeClass } from '../../constants/elements'
-
-const ImportCondition = ({ config, condition, importActions }) => {
- const showFields = () => importActions.updateElement(condition, {show: !condition.show})
- const toggleImport = () => importActions.updateElement(condition, {import: !condition.import})
- const updateCondition = (key, value) => importActions.updateElement(condition, {[key]: value})
-
- return (
-
-
-
-
-
-
-
-
-
-
- {
- condition.show && <>
-
-
-
-
- >
- }
-
- )
-}
-
-ImportCondition.propTypes = {
- config: PropTypes.object.isRequired,
- condition: PropTypes.object.isRequired,
- importActions: PropTypes.object.isRequired
-}
-
-export default ImportCondition
diff --git a/rdmo/management/assets/js/components/import/ImportElement.js b/rdmo/management/assets/js/components/import/ImportElement.js
new file mode 100644
index 0000000000..64b7887d58
--- /dev/null
+++ b/rdmo/management/assets/js/components/import/ImportElement.js
@@ -0,0 +1,75 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+
+import {isEmpty} from 'lodash'
+
+import {
+ WarningLink,
+ ErrorLink,
+ ShowLink,
+ AvailableLink,
+ LockedLink,
+} from '../common/Links'
+import ImportSelectCheckbox from './common/ImportSelectCheckbox'
+import Errors from './common/Errors'
+
+import Warnings from './common/Warnings'
+import Fields from './common/Fields'
+import Form from './common/Form'
+
+
+const ImportElement = ({ config, element, importActions }) => {
+ const updateShowField = () => importActions.updateElement(element, {show: !element.show})
+ const toggleImport = () => importActions.updateElement(element, {import: !element.import})
+ const updateElement = (key, value) => importActions.updateElement(element, {[key]: value})
+ const toggleAvailable = () => importActions.updateElement(element, {available: !element.available})
+
+ return (
+
+
+
+ {
+ (isEmpty(element.errors) && ('available' in element)) &&
+
+ }
+ {
+ !isEmpty(element.warnings) &&
+
+ }
+ {
+ !isEmpty(element.errors) &&
+
+ }
+ {
+ (element.updated && element.locked) &&
+
+
+ }
+
+
+
+
+
+ {
+ element.show && <>
+
+
+
+
+ >
+ }
+
+ )
+}
+
+ImportElement.propTypes = {
+ config: PropTypes.object.isRequired,
+ element: PropTypes.object.isRequired,
+ importActions: PropTypes.object.isRequired
+}
+
+export default ImportElement
diff --git a/rdmo/management/assets/js/components/import/ImportOption.js b/rdmo/management/assets/js/components/import/ImportOption.js
deleted file mode 100644
index af8f0166ac..0000000000
--- a/rdmo/management/assets/js/components/import/ImportOption.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-
-import { CodeLink, WarningLink, ErrorLink, ShowLink } from '../common/Links'
-
-import Errors from './common/Errors'
-import Fields from './common/Fields'
-import Form from './common/Form'
-import Warnings from './common/Warnings'
-
-import { codeClass } from '../../constants/elements'
-
-const ImportOption = ({ config, option, importActions }) => {
- const showFields = () => importActions.updateElement(option, {show: !option.show})
- const toggleImport = () => importActions.updateElement(option, {import: !option.import})
- const updateOption = (key, value) => importActions.updateElement(option, {[key]: value})
-
- return (
-
-
-
-
-
-
-
-
-
-
- {
- option.show && <>
-
-
-
-
- >
- }
-
- )
-}
-
-ImportOption.propTypes = {
- config: PropTypes.object.isRequired,
- option: PropTypes.object.isRequired,
- importActions: PropTypes.object.isRequired
-}
-
-export default ImportOption
diff --git a/rdmo/management/assets/js/components/import/ImportOptionSet.js b/rdmo/management/assets/js/components/import/ImportOptionSet.js
deleted file mode 100644
index e7798c051d..0000000000
--- a/rdmo/management/assets/js/components/import/ImportOptionSet.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-
-import { CodeLink, WarningLink, ErrorLink, ShowLink } from '../common/Links'
-
-import Errors from './common/Errors'
-import Fields from './common/Fields'
-import Form from './common/Form'
-import Warnings from './common/Warnings'
-
-import { codeClass } from '../../constants/elements'
-
-const ImportOptionSet = ({ config, optionset, importActions }) => {
- const showFields = () => importActions.updateElement(optionset, {show: !optionset.show})
- const toggleImport = () => importActions.updateElement(optionset, {import: !optionset.import})
- const updateOptionSet = (key, value) => importActions.updateElement(optionset, {[key]: value})
-
- return (
-
-
-
-
-
-
-
-
-
-
- {
- optionset.show && <>
-
-
-
-
- >
- }
-
- )
-}
-
-ImportOptionSet.propTypes = {
- config: PropTypes.object.isRequired,
- optionset: PropTypes.object.isRequired,
- importActions: PropTypes.object.isRequired
-}
-
-export default ImportOptionSet
diff --git a/rdmo/management/assets/js/components/import/ImportPage.js b/rdmo/management/assets/js/components/import/ImportPage.js
deleted file mode 100644
index 2fb438f904..0000000000
--- a/rdmo/management/assets/js/components/import/ImportPage.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-
-import { CodeLink, WarningLink, ErrorLink, ShowLink } from '../common/Links'
-
-import Errors from './common/Errors'
-import Fields from './common/Fields'
-import Form from './common/Form'
-import Warnings from './common/Warnings'
-
-import { codeClass } from '../../constants/elements'
-
-const ImportPage = ({ config, page, importActions }) => {
- const showFields = () => importActions.updateElement(page, {show: !page.show})
- const toggleImport = () => importActions.updateElement(page, {import: !page.import})
- const updatePage = (key, value) => importActions.updateElement(page, {[key]: value})
-
- return (
-
-
-
-
-
-
-
-
-
-
- {
- page.show && <>
-
-
-
-
- >
- }
-
- )
-}
-
-ImportPage.propTypes = {
- config: PropTypes.object.isRequired,
- page: PropTypes.object.isRequired,
- importActions: PropTypes.object.isRequired
-}
-
-export default ImportPage
diff --git a/rdmo/management/assets/js/components/import/ImportQuestion.js b/rdmo/management/assets/js/components/import/ImportQuestion.js
deleted file mode 100644
index 12c757ee28..0000000000
--- a/rdmo/management/assets/js/components/import/ImportQuestion.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-
-import { CodeLink, WarningLink, ErrorLink, ShowLink } from '../common/Links'
-
-import Errors from './common/Errors'
-import Fields from './common/Fields'
-import Form from './common/Form'
-import Warnings from './common/Warnings'
-
-import { codeClass } from '../../constants/elements'
-
-const ImportQuestion = ({ config, question, importActions }) => {
- const showFields = () => importActions.updateElement(question, {show: !question.show})
- const toggleImport = () => importActions.updateElement(question, {import: !question.import})
- const updateQuestion = (key, value) => importActions.updateElement(question, {[key]: value})
-
- return (
-
-
-
-
-
-
-
-
-
-
- {
- question.show && <>
-
-
-
-
- >
- }
-
- )
-}
-
-ImportQuestion.propTypes = {
- config: PropTypes.object.isRequired,
- question: PropTypes.object.isRequired,
- importActions: PropTypes.object.isRequired
-}
-
-export default ImportQuestion
diff --git a/rdmo/management/assets/js/components/import/ImportQuestionSet.js b/rdmo/management/assets/js/components/import/ImportQuestionSet.js
deleted file mode 100644
index 8163015cbe..0000000000
--- a/rdmo/management/assets/js/components/import/ImportQuestionSet.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-
-import { CodeLink, WarningLink, ErrorLink, ShowLink } from '../common/Links'
-
-import Errors from './common/Errors'
-import Fields from './common/Fields'
-import Form from './common/Form'
-import Warnings from './common/Warnings'
-
-import { codeClass } from '../../constants/elements'
-
-const ImportQuestionSet = ({ config, questionset, importActions }) => {
- const showFields = () => importActions.updateElement(questionset, {show: !questionset.show})
- const toggleImport = () => importActions.updateElement(questionset, {import: !questionset.import})
- const updateQuestionSet = (key, value) => importActions.updateElement(questionset, {[key]: value})
-
- return (
-
-
-
-
-
-
-
-
-
-
- {
- questionset.show && <>
-
-
-
-
- >
- }
-
- )
-}
-
-ImportQuestionSet.propTypes = {
- config: PropTypes.object.isRequired,
- questionset: PropTypes.object.isRequired,
- importActions: PropTypes.object.isRequired
-}
-
-export default ImportQuestionSet
diff --git a/rdmo/management/assets/js/components/import/ImportSection.js b/rdmo/management/assets/js/components/import/ImportSection.js
deleted file mode 100644
index 92203a8771..0000000000
--- a/rdmo/management/assets/js/components/import/ImportSection.js
+++ /dev/null
@@ -1,50 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-
-import { CodeLink, WarningLink, ErrorLink, ShowLink } from '../common/Links'
-
-import Errors from './common/Errors'
-import Fields from './common/Fields'
-import Form from './common/Form'
-import Warnings from './common/Warnings'
-
-import { codeClass } from '../../constants/elements'
-
-const ImportSection = ({ config, section, importActions }) => {
- const showFields = () => importActions.updateElement(section, {show: !section.show})
- const toggleImport = () => importActions.updateElement(section, {import: !section.import})
- const updateSection = (key, value) => importActions.updateElement(section, {[key]: value})
-
- return (
-
-
-
-
-
-
-
-
-
-
- {
- section.show && <>
-
-
-
-
- >
- }
-
- )
-}
-
-ImportSection.propTypes = {
- config: PropTypes.object.isRequired,
- section: PropTypes.object.isRequired,
- importActions: PropTypes.object.isRequired
-}
-
-export default ImportSection
diff --git a/rdmo/management/assets/js/components/import/ImportSuccessElement.js b/rdmo/management/assets/js/components/import/ImportSuccessElement.js
new file mode 100644
index 0000000000..892f78f80c
--- /dev/null
+++ b/rdmo/management/assets/js/components/import/ImportSuccessElement.js
@@ -0,0 +1,50 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import { isEmpty } from 'lodash'
+
+import { codeClass, verboseNames } from '../../constants/elements'
+import Warnings from './common/Warnings'
+import Errors from './common/Errors'
+import {ChangedLabel, CreatedLabel} from './common/ImportLabels'
+
+
+
+const ImportSuccessElement = ({ element, importActions }) => {
+
+ const updateShowField = () => importActions.updateElement(element, { show: !element.show })
+ const changedLabelText = gettext('Changed')
+ const createdLabelText = gettext('Created')
+
+ return (
+
+
+ {verboseNames[element.model]}{' '}
+ {element.uri}
+
+
+
+
+
+ {
+ !isEmpty(element.errors) && (
+
+ {' '}{gettext('could not be imported')}
+ {(element.created || element.updated) && `, ${gettext('but could not be added to parent element')}`}
+ {'.'}
+
+ )
+ }
+
+
+
+
+
+ )
+}
+
+ImportSuccessElement.propTypes = {
+ element: PropTypes.object.isRequired,
+ importActions: PropTypes.object.isRequired
+}
+
+export default ImportSuccessElement
diff --git a/rdmo/management/assets/js/components/import/ImportTask.js b/rdmo/management/assets/js/components/import/ImportTask.js
deleted file mode 100644
index 72b2b73158..0000000000
--- a/rdmo/management/assets/js/components/import/ImportTask.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-
-import { AvailableLink, CodeLink, WarningLink, ErrorLink, ShowLink } from '../common/Links'
-
-import Errors from './common/Errors'
-import Fields from './common/Fields'
-import Form from './common/Form'
-import Warnings from './common/Warnings'
-
-import { codeClass } from '../../constants/elements'
-
-const ImportTask = ({ config, task, importActions }) => {
- const showFields = () => importActions.updateElement(task, {show: !task.show})
- const toggleImport = () => importActions.updateElement(task, {import: !task.import})
- const toggleAvailable = () => importActions.updateElement(task, {available: !task.available})
- const updateTask = (key, value) => importActions.updateElement(task, {[key]: value})
-
- return (
-
-
-
-
-
-
-
-
-
-
-
- {
- task.show && <>
-
-
-
-
- >
- }
-
- )
-}
-
-ImportTask.propTypes = {
- config: PropTypes.object.isRequired,
- task: PropTypes.object.isRequired,
- importActions: PropTypes.object.isRequired
-}
-
-export default ImportTask
diff --git a/rdmo/management/assets/js/components/import/ImportView.js b/rdmo/management/assets/js/components/import/ImportView.js
deleted file mode 100644
index e48196efb5..0000000000
--- a/rdmo/management/assets/js/components/import/ImportView.js
+++ /dev/null
@@ -1,52 +0,0 @@
-import React from 'react'
-import PropTypes from 'prop-types'
-
-import { AvailableLink, CodeLink, WarningLink, ErrorLink, ShowLink } from '../common/Links'
-
-import Errors from './common/Errors'
-import Fields from './common/Fields'
-import Form from './common/Form'
-import Warnings from './common/Warnings'
-
-import { codeClass } from '../../constants/elements'
-
-const ImportView = ({ config, view, importActions }) => {
- const showFields = () => importActions.updateElement(view, {show: !view.show})
- const toggleImport = () => importActions.updateElement(view, {import: !view.import})
- const toggleAvailable = () => importActions.updateElement(view, {available: !view.available})
- const updateView = (key, value) => importActions.updateElement(view, {[key]: value})
-
- return (
-
-
-
-
-
-
-
-
-
-
-
- {
- view.show && <>
-
-
-
-
- >
- }
-
- )
-}
-
-ImportView.propTypes = {
- config: PropTypes.object.isRequired,
- view: PropTypes.object.isRequired,
- importActions: PropTypes.object.isRequired
-}
-
-export default ImportView
diff --git a/rdmo/management/assets/js/components/import/common/Errors.js b/rdmo/management/assets/js/components/import/common/Errors.js
index 47fcd60d50..35af668236 100644
--- a/rdmo/management/assets/js/components/import/common/Errors.js
+++ b/rdmo/management/assets/js/components/import/common/Errors.js
@@ -1,25 +1,23 @@
+// Errors.js
import React from 'react'
import PropTypes from 'prop-types'
-import isEmpty from 'lodash/isEmpty'
-import uniqueId from 'lodash/uniqueId'
+import ErrorsListGroup from './ErrorsListGroup'
+import isUndefined from 'lodash/isUndefined'
-const Errors = ({ element }) => {
- return !isEmpty(element.errors) &&
-
- {gettext('Errors')}
-
-
-
- {
- element.errors.map(message => - {message}
)
- }
-
+const Errors = ({ elementErrors }) => {
+ const show = !isUndefined(elementErrors) && elementErrors.length > 0
+ const errorsHeadingText = {gettext('Errors')}
+
+ return show && (
+
+ {errorsHeadingText}
+
-
+ )
}
Errors.propTypes = {
- element: PropTypes.object.isRequired
+ elementErrors: PropTypes.array.isRequired,
}
export default Errors
diff --git a/rdmo/management/assets/js/components/import/common/ErrorsListGroup.js b/rdmo/management/assets/js/components/import/common/ErrorsListGroup.js
new file mode 100644
index 0000000000..c6f209938b
--- /dev/null
+++ b/rdmo/management/assets/js/components/import/common/ErrorsListGroup.js
@@ -0,0 +1,31 @@
+// ErrorsListGroup.js
+import React from 'react'
+import PropTypes from 'prop-types'
+import uniqueId from 'lodash/uniqueId'
+
+// Helper function to generate error messages
+export const generateErrorMessageListItems = (messages) =>
+ messages.map(message => (
+
+
+ {message}
+
+
+ ))
+
+const ErrorsListGroup = ({ elementErrors }) => {
+ // Filter out duplicate elementErrors
+ const uniqueErrors = [...new Set(elementErrors)]
+
+ return (
+
+ {generateErrorMessageListItems(uniqueErrors)}
+
+ )
+}
+
+ErrorsListGroup.propTypes = {
+ elementErrors: PropTypes.array.isRequired
+}
+
+export default ErrorsListGroup
diff --git a/rdmo/management/assets/js/components/import/common/FieldRow.js b/rdmo/management/assets/js/components/import/common/FieldRow.js
new file mode 100644
index 0000000000..33a9229763
--- /dev/null
+++ b/rdmo/management/assets/js/components/import/common/FieldRow.js
@@ -0,0 +1,32 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import uniqueId from 'lodash/uniqueId'
+import FieldRowValue from './FieldRowValue'
+import FieldRowDiffs from './FieldRowDiffs'
+
+const FieldRow = ({ element, keyName, value }) => {
+
+ return (
+
+
+
+ {keyName}
+
+
+
+
+ {element.updated && element.changed && keyName in element.updated_and_changed && (
+
+ )}
+
+
+ )
+}
+
+FieldRow.propTypes = {
+ element: PropTypes.object.isRequired,
+ keyName: PropTypes.string.isRequired,
+ value: PropTypes.any.isRequired,
+}
+
+export default FieldRow
diff --git a/rdmo/management/assets/js/components/import/common/FieldRowDiffs.js b/rdmo/management/assets/js/components/import/common/FieldRowDiffs.js
new file mode 100644
index 0000000000..86d2e97230
--- /dev/null
+++ b/rdmo/management/assets/js/components/import/common/FieldRowDiffs.js
@@ -0,0 +1,66 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import isEmpty from 'lodash/isEmpty'
+import ReactDiffViewer from 'react-diff-viewer-continued'
+
+import Warnings from './Warnings'
+import Errors from './Errors'
+
+const FieldRowDiffs = ({ element, field }) => {
+ if (isEmpty(element.updated_and_changed[field])) {
+ return null
+ }
+ const fieldDiffData = element.updated_and_changed[field]
+ const newVal = fieldDiffData.newValue.toString() ?? ''
+ const oldVal = fieldDiffData.oldValue.toString() ?? ''
+ const changed = fieldDiffData.changed ?? false
+ const splitView = false
+ const hideLineNumbers = true
+ const warnings = fieldDiffData.warnings ?? {}
+ const errors = fieldDiffData.errors ?? []
+
+ const newStyles = {
+ variables: {
+ light: {
+ diffViewerBackground: '#fff',
+ changedBackground: '#fff',
+ gutterBackground: '#fff',
+ },
+ },
+ contentText: {
+ backgroundColor: '#fff !important',
+ },
+ }
+
+ return (changed &&
+
+
+
+ {
+ !isEmpty(warnings) && <>
+
+ >
+ }
+ {
+ !isEmpty(errors) && <>
+
+ >
+ }
+
+ )
+}
+
+FieldRowDiffs.propTypes = {
+ element: PropTypes.object.isRequired,
+ field: PropTypes.string.isRequired,
+}
+
+export default FieldRowDiffs
diff --git a/rdmo/management/assets/js/components/import/common/FieldRowValue.js b/rdmo/management/assets/js/components/import/common/FieldRowValue.js
new file mode 100644
index 0000000000..7d633fd153
--- /dev/null
+++ b/rdmo/management/assets/js/components/import/common/FieldRowValue.js
@@ -0,0 +1,41 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import uniqueId from 'lodash/uniqueId'
+import isString from 'lodash/isString'
+import isPlainObject from 'lodash/isPlainObject'
+import isUndefined from 'lodash/isUndefined'
+import truncate from 'lodash/truncate'
+import {codeClass} from '../../../constants/elements'
+
+
+const FieldRowValue = ({ value }) => {
+ return (
+
+ {
+ Array.isArray(value) && (
+
+ {value.map((el) => (
+ -
+
{el.uri}
+
+ ))}
+
+ )
+ }
+ {
+ isPlainObject(value) && !isUndefined(value.uri) &&
+ {value.uri}
+ }
+ {
+ isString(value) &&
+ {truncate(value, { length: 512 })}
+ }
+
+ )
+}
+
+FieldRowValue.propTypes = {
+ value: PropTypes.any.isRequired,
+}
+
+export default FieldRowValue
diff --git a/rdmo/management/assets/js/components/import/common/Fields.js b/rdmo/management/assets/js/components/import/common/Fields.js
index da483eb9cb..f49217bebd 100644
--- a/rdmo/management/assets/js/components/import/common/Fields.js
+++ b/rdmo/management/assets/js/components/import/common/Fields.js
@@ -1,66 +1,61 @@
import React from 'react'
import PropTypes from 'prop-types'
-import isNil from 'lodash/isNil'
-import isString from 'lodash/isString'
-import isUndefined from 'lodash/isUndefined'
-import truncate from 'lodash/truncate'
import uniqueId from 'lodash/uniqueId'
-
-import { codeClass } from '../../../constants/elements'
+import FieldRow from './FieldRow'
+import isString from 'lodash/isString'
const excludeKeys = [
- 'created',
- 'errors',
'import',
'key',
'model',
'show',
'type',
- 'updated',
'uri',
'uri_path',
'uri_prefix',
'valid',
- 'warnings'
+ 'created',
+ 'updated',
+ 'errors',
+ 'warnings',
+ 'updated_and_changed',
+ 'changed',
+ 'changedFields',
+ 'locked'
]
+
+export const serializeValue = (value) => {
+ if (value === null) return ''
+ if (value === true) return 'true'
+ if (value === false) return 'false'
+ if (Array.isArray(value)) return value
+ if (isString(value)) return value
+ if (typeof value === 'number') return value.toString()
+ return value
+}
+
const Fields = ({ element }) => {
+
return (
- {
- Object.entries(element).sort().map(([key, value]) => {
- if (!isNil(value) && !excludeKeys.includes(key)) {
- return (
-
-
- {key}
-
-
- {
- Array.isArray(value) &&
- { value.map(el => -
-
{el.uri}
- ) }
-
- }
- {
- !isUndefined(value.uri) && {value.uri}
- }
- {
- isString(value) && {truncate(value, {length: 512})}
- }
-
-
- )
+ {Object.entries(element)
+ .sort()
+ .map(([key, value]) => {
+ if (!excludeKeys.includes(key)) {
+ const serializedValue = serializeValue(value)
+ if (serializedValue !== '' || (element.changedFields?.includes(key))) {
+ return
+ }
}
- })
- }
+ return null
+ })}
)
}
Fields.propTypes = {
- element: PropTypes.object.isRequired
+ element: PropTypes.object.isRequired,
}
export default Fields
diff --git a/rdmo/management/assets/js/components/import/common/Form.js b/rdmo/management/assets/js/components/import/common/Form.js
index a34892cc14..fa872b4efa 100644
--- a/rdmo/management/assets/js/components/import/common/Form.js
+++ b/rdmo/management/assets/js/components/import/common/Form.js
@@ -7,7 +7,6 @@ import UriPath from './UriPath'
import UriPrefix from './UriPrefix'
const Form = ({ config, element, updateElement }) => {
-
return (
diff --git a/rdmo/management/assets/js/components/import/common/ImportFilters.js b/rdmo/management/assets/js/components/import/common/ImportFilters.js
new file mode 100644
index 0000000000..8f5cc1b140
--- /dev/null
+++ b/rdmo/management/assets/js/components/import/common/ImportFilters.js
@@ -0,0 +1,57 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import {FilterString, FilterUriPrefix} from '../../common/Filter'
+import get from 'lodash/get'
+import {getUriPrefixes} from '../../../utils/filter'
+import {Checkbox} from '../../common/Checkboxes'
+
+const ImportFilters = ({ config, elements, changedElements, filteredElements, configActions, success= false}) => {
+ const updateFilterString = (value) => configActions.updateConfig('filter.import.elements.search', value)
+ const getValueFilterString = () => get(config, 'filter.import.elements.search', '')
+ const updateFilterUriPrefix = (value) => configActions.updateConfig('filter.import.elements.uri_prefix', value)
+ const getValueFilterUriPrefix = () => get(config, 'filter.import.elements.uri_prefix', '')
+ const updateFilterChanged = (value) => configActions.updateConfig('filter.import.elements.changed', value)
+ const getValueFilterChanged = () => get(config, 'filter.import.elements.changed', false)
+
+ const filterCheckBoxText = interpolate(
+ success ? gettext('Show only created and changed elements (%s)')
+ : gettext('Show only new and changed elements (%s)'),
+ [changedElements.length]
+ )
+
+ return ( elements.length > 0 &&
+
+
+
+
+
+
+
+
+ {elements.length > 0 && (
+
+
+
+
+
+ {gettext('Shown')}: {filteredElements.length} / {elements.length}
+
+
+ )}
+ )
+}
+
+ImportFilters.propTypes = {
+ config: PropTypes.object.isRequired,
+ elements: PropTypes.array.isRequired,
+ changedElements: PropTypes.array.isRequired,
+ filteredElements: PropTypes.array.isRequired,
+ configActions: PropTypes.object.isRequired,
+ success: PropTypes.bool
+}
+
+export default ImportFilters
diff --git a/rdmo/management/assets/js/components/import/common/ImportInfo.js b/rdmo/management/assets/js/components/import/common/ImportInfo.js
new file mode 100644
index 0000000000..d1fbf9722b
--- /dev/null
+++ b/rdmo/management/assets/js/components/import/common/ImportInfo.js
@@ -0,0 +1,44 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import {isUndefined} from 'lodash'
+
+const renderElementLengthInfo = (label, length) => (
+ length > 0 && (
+ {gettext(label)}: {length}
+ )
+)
+
+const ImportInfo = ({
+ elementsLength,
+ updatedLength,
+ createdLength,
+ changedLength,
+ warningsLength,
+ errorsLength
+ }) => {
+ if (isUndefined(elementsLength) || elementsLength === 0) {
+ return null
+ }
+
+ return (
+
+ {renderElementLengthInfo('Total', elementsLength)}
+ {renderElementLengthInfo('Updated', updatedLength)}
+ {renderElementLengthInfo('Changed', changedLength)}
+ {renderElementLengthInfo('Created', createdLength)}
+ {renderElementLengthInfo('Warnings', warningsLength)}
+ {renderElementLengthInfo('Errors', errorsLength)}
+
+ )
+}
+
+ImportInfo.propTypes = {
+ elementsLength: PropTypes.number,
+ updatedLength: PropTypes.number,
+ createdLength: PropTypes.number,
+ changedLength: PropTypes.number,
+ warningsLength: PropTypes.number,
+ errorsLength: PropTypes.number,
+}
+
+export default ImportInfo
diff --git a/rdmo/management/assets/js/components/import/common/ImportLabels.js b/rdmo/management/assets/js/components/import/common/ImportLabels.js
new file mode 100644
index 0000000000..b44fb7b3f1
--- /dev/null
+++ b/rdmo/management/assets/js/components/import/common/ImportLabels.js
@@ -0,0 +1,33 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import Label from 'rdmo/management/assets/js/components/common/Labels'
+
+const ChangedLabel = ({ text, onClick, show }) => {
+ return
+}
+
+ChangedLabel.propTypes = {
+ text: PropTypes.string.isRequired,
+ onClick: PropTypes.func,
+ show: PropTypes.bool,
+}
+
+const CreatedLabel = ({ text, onClick, show }) => {
+ return
+}
+
+CreatedLabel.propTypes = {
+ text: PropTypes.string.isRequired,
+ onClick: PropTypes.func,
+ show: PropTypes.bool,
+}
+
+export { ChangedLabel, CreatedLabel }
diff --git a/rdmo/management/assets/js/components/import/common/ImportSelectCheckbox.js b/rdmo/management/assets/js/components/import/common/ImportSelectCheckbox.js
new file mode 100644
index 0000000000..53f4189301
--- /dev/null
+++ b/rdmo/management/assets/js/components/import/common/ImportSelectCheckbox.js
@@ -0,0 +1,30 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import { CodeLink } from '../../common/Links'
+import { codeClass, verboseNames } from '../../../constants/elements'
+import {ChangedLabel, CreatedLabel} from './ImportLabels'
+
+const ImportSelectCheckbox = ({ element, toggleImport, updateShowField }) => {
+ const changedLabelText = gettext('Changed')
+ const createdLabelText = gettext('New')
+ return (
+
+
+
+
+
+
+
+
+)}
+
+ImportSelectCheckbox.propTypes = {
+ element: PropTypes.object.isRequired,
+ toggleImport: PropTypes.func.isRequired,
+ updateShowField: PropTypes.func.isRequired
+}
+
+export default ImportSelectCheckbox
diff --git a/rdmo/management/assets/js/components/import/common/Key.js b/rdmo/management/assets/js/components/import/common/Key.js
index e6396b0098..fe63bac327 100644
--- a/rdmo/management/assets/js/components/import/common/Key.js
+++ b/rdmo/management/assets/js/components/import/common/Key.js
@@ -4,7 +4,7 @@ import uniqueId from 'lodash/uniqueId'
const Key = ({ element, onChange }) => {
const id = uniqueId('key-'),
- value = element.key
+ value = element.key ?? ''
return (
diff --git a/rdmo/management/assets/js/components/import/common/UriPath.js b/rdmo/management/assets/js/components/import/common/UriPath.js
index 70ebe4ccaf..62e9d99be1 100644
--- a/rdmo/management/assets/js/components/import/common/UriPath.js
+++ b/rdmo/management/assets/js/components/import/common/UriPath.js
@@ -2,9 +2,9 @@ import React from 'react'
import PropTypes from 'prop-types'
import uniqueId from 'lodash/uniqueId'
-const UriPrefix = ({ element, onChange }) => {
- const id = uniqueId('uriPrefix-'),
- value = element.uri_path
+const UriPath = ({ element, onChange }) => {
+ const id = uniqueId('uriPath-'),
+ value = element.uri_path ?? ''
return (
@@ -18,9 +18,9 @@ const UriPrefix = ({ element, onChange }) => {
)
}
-UriPrefix.propTypes = {
+UriPath.propTypes = {
element: PropTypes.object.isRequired,
onChange: PropTypes.func.isRequired
}
-export default UriPrefix
+export default UriPath
diff --git a/rdmo/management/assets/js/components/import/common/Warnings.js b/rdmo/management/assets/js/components/import/common/Warnings.js
index c4c91bdb83..2ecfc75ab1 100644
--- a/rdmo/management/assets/js/components/import/common/Warnings.js
+++ b/rdmo/management/assets/js/components/import/common/Warnings.js
@@ -1,25 +1,28 @@
import React from 'react'
import PropTypes from 'prop-types'
-import isEmpty from 'lodash/isEmpty'
-import uniqueId from 'lodash/uniqueId'
+import WarningsListGroup from './WarningsListGroup'
+import isUndefined from 'lodash/isUndefined'
-const Warnings = ({ element }) => {
- return !isEmpty(element.warnings) &&
-
- {gettext('Warnings')}
-
-
-
- {
- element.warnings.map(message => - {message}
)
- }
-
+const Warnings = ({elementWarnings, elementModel, shouldShowURI = true}) => {
+ const show = !isUndefined(elementWarnings) && Object.keys(elementWarnings).length > 0
+ const warningsHeadingText = {gettext('Warnings')}
+
+ return show && (
+
+ {warningsHeadingText}
+
-
+ )
}
Warnings.propTypes = {
- element: PropTypes.object.isRequired
+ elementWarnings: PropTypes.object.isRequired,
+ elementModel: PropTypes.string.isRequired,
+ shouldShowURI: PropTypes.bool
}
export default Warnings
diff --git a/rdmo/management/assets/js/components/import/common/WarningsListGroup.js b/rdmo/management/assets/js/components/import/common/WarningsListGroup.js
new file mode 100644
index 0000000000..efcfb665f5
--- /dev/null
+++ b/rdmo/management/assets/js/components/import/common/WarningsListGroup.js
@@ -0,0 +1,40 @@
+// WarningsListGroup.js
+import React from 'react'
+import PropTypes from 'prop-types'
+import uniqueId from 'lodash/uniqueId'
+import { codeClass, verboseNames } from '../../../constants/elements'
+
+// Helper function to generate warning messages
+export const generateWarningListItems = (elementWarnings, elementModel, shouldShowURI = true) =>
+ Object.entries(elementWarnings).flatMap(([uri, messages]) =>
+ messages.map(message => (
+
+ {shouldShowURI && (
+ <>
+ {verboseNames[elementModel]}{' '}
+ {uri}
+
+ >
+ )}
+
+ {message}
+
+
+ ))
+ )
+
+const WarningsListGroup = ({ elementWarnings, elementModel, shouldShowURI }) => {
+ return (
+
+ {generateWarningListItems(elementWarnings, elementModel, shouldShowURI)}
+
+ )
+}
+
+WarningsListGroup.propTypes = {
+ elementWarnings: PropTypes.object.isRequired,
+ elementModel: PropTypes.string.isRequired,
+ shouldShowURI: PropTypes.bool
+}
+
+export default WarningsListGroup
diff --git a/rdmo/management/assets/js/components/main/Import.js b/rdmo/management/assets/js/components/main/Import.js
index 6f93e80fdc..8f27c8d35d 100644
--- a/rdmo/management/assets/js/components/main/Import.js
+++ b/rdmo/management/assets/js/components/main/Import.js
@@ -1,94 +1,83 @@
import React from 'react'
import PropTypes from 'prop-types'
-import uniqueId from 'lodash/uniqueId'
-import isEmpty from 'lodash/isEmpty'
+import get from 'lodash/get'
-import ImportAttribute from '../import/ImportAttribute'
-import ImportCatalog from '../import/ImportCatalog'
-import ImportCondition from '../import/ImportCondition'
-import ImportOption from '../import/ImportOption'
-import ImportOptionSet from '../import/ImportOptionSet'
-import ImportPage from '../import/ImportPage'
-import ImportQuestion from '../import/ImportQuestion'
-import ImportQuestionSet from '../import/ImportQuestionSet'
-import ImportSection from '../import/ImportSection'
-import ImportTask from '../import/ImportTask'
-import ImportView from '../import/ImportView'
+import ImportElement from '../import/ImportElement'
+import ImportSuccessElement from '../import/ImportSuccessElement'
+import ImportAggregatedWarningsPanel from '../import/ImportAggregatedWarningsPanel'
+import ImportAggregatedErrorsPanel from '../import/ImportAggregatedErrorsPanel'
+import ImportInfo from '../import/common/ImportInfo'
+import ImportFilters from '../import/common/ImportFilters'
+import useFilteredElements from '../../utils/importFilters'
+import {useImportElements} from '../../hooks/useImportElements'
-import { codeClass, verboseNames } from '../../constants/elements'
-const Import = ({ config, imports, importActions }) => {
- const { elements, success } = imports
+const Import = ({ config, imports, configActions, importActions }) => {
+ const { file, elements, success } = imports
+ // the elements are already processed by processElementDiffs in the importsReducer
+ const {
+ createdElements,
+ updatedElements,
+ changedElements,
+ importWarnings,
+ importErrors
+ } = useImportElements(elements)
+
+ const searchString = get(config, 'filter.import.elements.search', '')
+ const selectedUriPrefix = get(config, 'filter.import.elements.uri_prefix', '')
+ const selectFilterChanged = get(config, 'filter.import.elements.changed', false)
+
+ const filteredElements = useFilteredElements(elements, selectFilterChanged, selectedUriPrefix, searchString)
return (
-
-
- {gettext('Import')}
-
+
+
+ {gettext('Import')} from: {file.name}
+
-
- {
- elements.map((element, index) => {
- if (success) {
- return (
- -
-
- {verboseNames[element.model]}{' '}
- {element.uri}
- {element.created && {' '}{gettext('created')}}
- {element.updated && {' '}{gettext('updated')}}
- {
- !isEmpty(element.errors) && !(element.created || element.updated) &&
- {' '}{gettext('could not be imported')}
- }
- {
- !isEmpty(element.errors) && (element.created || element.updated) &&
- <>{', '}{gettext('but could not be added to parent element')}>
- }
- {'.'}
-
- {element.warnings.map(message => {message}
)}
- {element.errors.map(message => {message}
)}
-
- )
- } else {
- switch (element.model) {
- case 'questions.catalog':
- return
- case 'questions.section':
- return
- case 'questions.page':
- return
- case 'questions.questionset':
- return
- case 'questions.question':
- return
- case 'domain.attribute':
- return
- case 'options.optionset':
- return
- case 'options.option':
- return
- case 'conditions.condition':
- return
- case 'tasks.task':
- return
- case 'views.view':
- return
- default:
- return null
- }
+
+
+ {
+
+ }
+ {
+
+ }
+ {
+
+ }
+
+
+ {
+ filteredElements.map((element, index) => {
+ if (success) {
+ return
+ } else {
+ return
+ }
+ })
}
- })
- }
-
-
+
+
)
}
Import.propTypes = {
config: PropTypes.object.isRequired,
imports: PropTypes.object.isRequired,
+ configActions: PropTypes.object.isRequired,
importActions: PropTypes.object.isRequired
}
diff --git a/rdmo/management/assets/js/components/nested/NestedCatalog.js b/rdmo/management/assets/js/components/nested/NestedCatalog.js
index b57840b9c6..3a82efef8b 100644
--- a/rdmo/management/assets/js/components/nested/NestedCatalog.js
+++ b/rdmo/management/assets/js/components/nested/NestedCatalog.js
@@ -19,9 +19,9 @@ const NestedCatalog = ({ config, catalog, configActions, elementActions }) => {
const updateFilterString = (value) => configActions.updateConfig('filter.catalog.search', value)
const updateFilterUriPrefix = (value) => configActions.updateConfig('filter.catalog.uri_prefix', value)
- const toggleSections = () => configActions.toggleDescandants(catalog, 'sections')
- const togglePages = () => configActions.toggleDescandants(catalog, 'pages')
- const toggleQuestionSets = () => configActions.toggleDescandants(catalog, 'questionsets')
+ const toggleSections = () => configActions.toggleDescendants(catalog, 'sections')
+ const togglePages = () => configActions.toggleDescendants(catalog, 'pages')
+ const toggleQuestionSets = () => configActions.toggleDescendants(catalog, 'questionsets')
const updateDisplayCatalogURI = (value) => configActions.updateConfig('display.uri.catalogs', value)
const updateDisplaySectionsURI = (value) => configActions.updateConfig('display.uri.sections', value)
diff --git a/rdmo/management/assets/js/components/nested/NestedPage.js b/rdmo/management/assets/js/components/nested/NestedPage.js
index 801ddc4640..08751f25a2 100644
--- a/rdmo/management/assets/js/components/nested/NestedPage.js
+++ b/rdmo/management/assets/js/components/nested/NestedPage.js
@@ -21,7 +21,7 @@ const NestedPage = ({ config, page, configActions, elementActions }) => {
const updateFilterString = (uri) => configActions.updateConfig('filter.page.search', uri)
const updateFilterUriPrefix = (uriPrefix) => configActions.updateConfig('filter.page.uri_prefix', uriPrefix)
- const toggleQuestionSets = () => configActions.toggleDescandants(page, 'questionsets')
+ const toggleQuestionSets = () => configActions.toggleDescendants(page, 'questionsets')
const updateDisplayPagesURI = (value) => configActions.updateConfig('display.uri.pages', value)
const updateDisplayQuestionSetsURI = (value) => configActions.updateConfig('display.uri.questionsets', value)
diff --git a/rdmo/management/assets/js/components/nested/NestedQuestionSet.js b/rdmo/management/assets/js/components/nested/NestedQuestionSet.js
index 70db94a5e0..debed7a6c6 100644
--- a/rdmo/management/assets/js/components/nested/NestedQuestionSet.js
+++ b/rdmo/management/assets/js/components/nested/NestedQuestionSet.js
@@ -20,7 +20,7 @@ const NestedQuestionSet = ({ config, questionset, configActions, elementActions
const updateFilterString = (uri) => configActions.updateConfig('filter.questionset.search', uri)
const updateFilterUriPrefix = (uriPrefix) => configActions.updateConfig('filter.questionset.uri_prefix', uriPrefix)
- const toggleQuestionSets = () => configActions.toggleDescandants(questionset, 'questionsets')
+ const toggleQuestionSets = () => configActions.toggleDescendants(questionset, 'questionsets')
const updateDisplayQuestionSetsURI = (value) => configActions.updateConfig('display.uri.questionsets', value)
const updateDisplayQuestionsURI = (value) => configActions.updateConfig('display.uri.questions', value)
diff --git a/rdmo/management/assets/js/components/nested/NestedSection.js b/rdmo/management/assets/js/components/nested/NestedSection.js
index 1552ddd0bc..9fa29b6559 100644
--- a/rdmo/management/assets/js/components/nested/NestedSection.js
+++ b/rdmo/management/assets/js/components/nested/NestedSection.js
@@ -20,8 +20,8 @@ const NestedCatalog = ({ config, section, configActions, elementActions }) => {
const updateFilterString = (uri) => configActions.updateConfig('filter.section.search', uri)
const updateFilterUriPrefix = (uriPrefix) => configActions.updateConfig('filter.section.uri_prefix', uriPrefix)
- const togglePages = () => configActions.toggleDescandants(section, 'pages')
- const toggleQuestionSets = () => configActions.toggleDescandants(section, 'questionsets')
+ const togglePages = () => configActions.toggleDescendants(section, 'pages')
+ const toggleQuestionSets = () => configActions.toggleDescendants(section, 'questionsets')
const updateDisplaySectionURI = (value) => configActions.updateConfig('display.uri.sections', value)
const updateDisplayPagesURI = (value) => configActions.updateConfig('display.uri.pages', value)
diff --git a/rdmo/management/assets/js/components/sidebar/ElementsSidebar.js b/rdmo/management/assets/js/components/sidebar/ElementsSidebar.js
index 65420eab49..88e92cd84b 100644
--- a/rdmo/management/assets/js/components/sidebar/ElementsSidebar.js
+++ b/rdmo/management/assets/js/components/sidebar/ElementsSidebar.js
@@ -3,8 +3,6 @@ import PropTypes from 'prop-types'
import isNil from 'lodash/isNil'
import invert from 'lodash/invert'
-import baseUrl from 'rdmo/core/assets/js/utils/baseUrl'
-
import { elementTypes, elementModules } from '../../constants/elements'
import { buildPath } from '../../utils/location'
@@ -18,8 +16,8 @@ const ElementsSidebar = ({ config, elements, elementActions, importActions }) =>
const { elementType, elementId } = elements
const model = invert(elementTypes)[elementType]
- const exportUrl = isNil(elementId) ? `${baseUrl}/api/v1/${elementModules[model]}/${elementType}/export/`
- : `${baseUrl}/api/v1/${elementModules[model]}/${elementType}/${elementId}/export/`
+ const exportUrl = isNil(elementId) ? buildPath(config.apiUrl, elementModules[model], elementType, 'export')
+ : buildPath(config.apiUrl, elementModules[model], elementType, elementId, 'export')
const exportParams = getExportParams(config.filter[elementType])
return (
@@ -75,10 +73,33 @@ const ElementsSidebar = ({ config, elements, elementActions, importActions }) =>
Export
+
+ {gettext('Export all visible elements.')}
+
+
-
{gettext('XML')}
+ {
+ [
+ 'catalogs',
+ 'sections',
+ 'pages',
+ 'questionsets',
+ 'questions',
+ 'optionsets',
+ 'conditions',
+ 'tasks'
+ ].includes(elementType) && (
+ -
+ {gettext('XML (full)')}
+
+ )
+ }
+
+
+
{
elementType == 'attributes' && <>
-
@@ -105,6 +126,10 @@ const ElementsSidebar = ({ config, elements, elementActions, importActions }) =>
Import
+
+ {gettext('Import an RDMO XML file.')}
+
+
importActions.uploadFile(file)} />
)
diff --git a/rdmo/management/assets/js/components/sidebar/ImportSidebar.js b/rdmo/management/assets/js/components/sidebar/ImportSidebar.js
index 9d27019d28..176ccb0413 100644
--- a/rdmo/management/assets/js/components/sidebar/ImportSidebar.js
+++ b/rdmo/management/assets/js/components/sidebar/ImportSidebar.js
@@ -4,9 +4,16 @@ import isEmpty from 'lodash/isEmpty'
import isNil from 'lodash/isNil'
import Link from 'rdmo/core/assets/js/components/Link'
+import {useImportElements} from '../../hooks/useImportElements'
+
const ImportSidebar = ({ config, imports, importActions }) => {
const { elements, success } = imports
+
+ const {
+ changedElements,
+ } = useImportElements(elements)
+
const count = elements.filter(e => e.import).length
const [uriPrefix, setUriPrefix] = useState('')
const disabled = isNil(uriPrefix) || isEmpty(uriPrefix)
@@ -33,7 +40,6 @@ const ImportSidebar = ({ config, imports, importActions }) => {
return (
{gettext('Import elements')}
-