From 9a4f65174556c7e9b4cdb489ba750123dc2279b4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Henrik=20tom=20W=C3=B6rden?= <h.tomwoerden@indiscale.com>
Date: Tue, 8 Apr 2025 12:37:25 +0200
Subject: [PATCH] FEAT: allow to export entities as xlsx via a button in gui

---
 build.properties.d/00_default.properties |   5 +-
 src/core/js/ext_export_to_xlsx.js        | 122 +++++++++++++++++++++++
 2 files changed, 126 insertions(+), 1 deletion(-)
 create mode 100644 src/core/js/ext_export_to_xlsx.js

diff --git a/build.properties.d/00_default.properties b/build.properties.d/00_default.properties
index 6b15cbf2..b09fc6d5 100644
--- a/build.properties.d/00_default.properties
+++ b/build.properties.d/00_default.properties
@@ -69,6 +69,8 @@ BUILD_EXT_REFERENCES_CUSTOM_RESOLVER=caosdb_default_person_reference
 BUILD_MODULE_EXT_EDITMODE_WYSIWYG_TEXT=DISABLED
 BUILD_MODULE_EXT_PROPERTY_DISPLAY=DISABLED
 
+BUILD_MODULE_EXT_EXPORT_TO_XLSX=ENABLED
+
 ### Put long text property values into a details tag. "DISABLED" means disabled.
 BUILD_LONG_TEXT_PROPERTY_THRESHOLD_LIST=40
 BUILD_LONG_TEXT_PROPERTY_THRESHOLD_SINGLE=140
@@ -173,7 +175,7 @@ JS_DIST_BUNDLE=TRUE
 ##############################################################################
 # TRUE means that all javascript sources which are no mentioned in the
 # MODULE_DEPENDENCIES array will be added in no particular order into the
-# build. If you need to guarantee a specific order (in which the are loaded or
+# build. If you need to guarantee a specific order (in which they are loaded or
 # appear in the dit file) you need to add them to the MODULE_DEPENDENCIES.
 ##############################################################################
 AUTO_DISCOVER_MODULES=TRUE
@@ -182,6 +184,7 @@ AUTO_DISCOVER_MODULES=TRUE
 # Module dependencies
 # Override or extend to specify the order of js files in the resulting
 # bundled js file
+# Extend it with `MODULE_DEPENDENCIES+=("a.js", "b.js");`
 ##############################################################################
 MODULE_DEPENDENCIES=(
     jquery.js
diff --git a/src/core/js/ext_export_to_xlsx.js b/src/core/js/ext_export_to_xlsx.js
new file mode 100644
index 00000000..2ac2f341
--- /dev/null
+++ b/src/core/js/ext_export_to_xlsx.js
@@ -0,0 +1,122 @@
+/*
+ * This file is a part of the LinkAhead Project.
+ *
+ * Copyright (C) 2020,2021 IndiScale GmbH <info@indiscale.com>
+ * Copyright (C) 2020 Timm Fitschen <t.fitschen@indiscale.com>
+ * Copyright (C) 2021 Florian Spreckelsen <f.spreckelsen@indiscale.com>
+ *
+ * This program is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU Affero General Public License as published by the Free
+ * Software Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ * FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ *
+ */
+
+'use strict';
+
+
+/**
+ * Export all entites that are in the result set of a query to an xlsx file
+ * 
+ * @module ext_export_to_xlsx
+ * @version 0.1
+ *
+ */
+var ext_export_to_xlsx = function ($, logger) {
+    /**
+     * Add a button to add all query results to bookmarks.
+     */
+    const add_add_query_results_button = function () {
+        const row_id = "caosdb-f-add-query-to-bookmarks-row"
+        console.log("add_add_query_results_button");
+
+        // do nothing if already existing
+        if ($("#" + row_id).length > 0) {
+            return;
+        }
+
+        // do nothing if no results
+        if ($(".caosdb-query-response-results").text().trim() == "0") {
+            return;
+        }
+
+        const button_html = $(`<div class="text-end" id=${row_id}>
+        <button class="btn btn-link" onclick="ext_export_to_xlsx.export_query_results();">Export entities</button>
+</div>`)[0];
+        const waiting_notification = $(`<p style="display:none">Exporting query results. Please wait and do not reload the page.</p>`)[0];
+
+        // Add to query results box
+        $(".caosdb-query-response-heading").append(button_html);
+        $("#" + row_id).append(waiting_notification);
+    }
+
+    /**
+     * Return the SELECT query created from the contents of the query response field
+     */
+    const get_query_from_response = function () {
+        const orig_query = $(".caosdb-f-query-response-string")[0].innerText;
+        return orig_query.trim();
+    }
+
+    /**
+     * Execute select query and add all new ids to bookmarks.
+     */
+    const export_query_results = async function () {
+        const query_string = get_query_from_response();
+        const bookmarks_row = $("#caosdb-f-add-query-to-bookmarks-row");
+        bookmarks_row.find("button").hide();
+        bookmarks_row.find("p").show();
+        //const resp = await query(query_string);
+
+        const xls_result = await connection.runScript("xlsx.py",
+            {"-p0": { "bluu": "selected.tsv", }});
+
+        const code = xls_result.getElementsByTagName("script")[0].getAttribute("code");
+        if (parseInt(code) > 0) {
+            throw ("An error occurred during execution of the server-side script:\n"
+                   + xls_result.getElementsByTagName("script")[0].outerHTML);
+        }
+        const filename = xls_result.getElementsByTagName("stdout")[0].textContent;
+        if (filename.length == 0) {
+            throw("Server-side script produced no file or did not return the file name: \n"
+                  + xls_result.getElementsByTagName("script")[0].outerHTML);
+        }
+
+        window.location.href = connection.getBasePath() + "Shared/" + filename;
+
+
+        bookmarks_row.find("button").prop("disabled", true).show();
+        bookmarks_row.find("p").hide();
+    }
+
+    /**
+     * Initialize this module.
+     */
+    const init = async function (scope) {
+        logger.info("init ext_export_to_xlsx");
+        console.log("init ext_export_to_xlsx");
+        add_add_query_results_button();
+    }
+
+    return {
+        init: init,
+        export_query_results: export_query_results,
+    }
+}($, log.getLogger("ext_export_to_xlsx"));
+
+$(document).ready(function () {
+    if ("ENABLED" == "ENABLED") {
+    //if ("${BUILD_MODULE_EXT_EXPORT_TO_XLSX}" == "ENABLED") {
+        // The following is the configuration for the LinkAhead WebUI.
+        const get_context_root = (() => connection.getBasePath() + "Entity/");
+        caosdb_modules.register(ext_export_to_xlsx);
+    }
+});
-- 
GitLab