diff --git a/build.properties.d/00_default.properties b/build.properties.d/00_default.properties index cd57b632e2ea2b9ab005c7185a309a9594f123ff..0304440ef627ee453f646bc8eec4809dc1553024 100644 --- a/build.properties.d/00_default.properties +++ b/build.properties.d/00_default.properties @@ -75,6 +75,27 @@ BUILD_NAVBAR_BRAND_NAME=CaosDB BUILD_TITLE_BRAND_NAME=CaosDB BUILD_FAVICON=pics/caosdb_logo_42.png +############################################################################## +# queryForm properties +############################################################################## + +# Initialize the free search to generate search queries which search only +# within one of several options of roles or entity names. +# +# E.g. when `options` is "Person, Experiment, Sample" the user can select +# one of these options before submitting the query. When the user types in +# something that doesn't looks like a CQL-query, a query is generated +# instead which goes like: FIND Persion WHICH HAS A PROPERTY LIKE +# "*something*". +# +# Note: This feature is disabled by default. Enable it by specifying the +# build variable BUILD_FREE_SEARCH_ROLE_NAME_FACET_OPTIONS as a +# comma-separated list of **properly quoted** expressions, e.g. +# "FILE 'numpy array', 'Plant Experiemnt', 'quotes_not_necessary'". +# Otherwise, the server will throw a syntax error. +BUILD_FREE_SEARCH_ROLE_NAME_FACET_OPTIONS= + + ############################################################################## # Footer properties ############################################################################## @@ -121,6 +142,7 @@ BUILD_MODULE_EXT_TRIGGER_CRAWLER_FORM_TOOLBOX="Tools" # MODULE_DEPENDENCIES array. ############################################################################## 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 @@ -128,6 +150,7 @@ JS_DIST_BUNDLE=TRUE # appear in the dit file) you need to add them to the MODULE_DEPENDENCIES. ############################################################################## AUTO_DISCOVER_MODULES=TRUE + ############################################################################## # Module dependencies # Override or extend to specify the order of js files in the resulting @@ -146,6 +169,7 @@ MODULE_DEPENDENCIES=( webcaosdb.js pako.js utif.js + ext_version_history.js caosdb.js form_elements.js ext_autocomplete.js diff --git a/src/core/js/ext_version_history.js b/src/core/js/ext_version_history.js new file mode 100644 index 0000000000000000000000000000000000000000..ea65481589c2f95405833f7b4a929f450ea6da96 --- /dev/null +++ b/src/core/js/ext_version_history.js @@ -0,0 +1,238 @@ +/* + * ** header v3.0 + * This file is a part of the CaosDB Project. + * + * Copyright (C) 2019-2022 IndiScale GmbH <info@indiscale.com> + * Copyright (C) 2019-2022 Timm Fitschen <t.fitschen@indiscale.com> + * Copyright (C) 2022 Florian Spreckelsen <f.spreckelsen@indiscale.com> + * Copyright (C) 2022 Daniel Hornung <d.hornung@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/>. + * + * ** end header + */ + + +/** + * This module provides the functionality to load the full version history (for + * privileged users) and export it to tsv. + * + * @module version_history + */ +var version_history = new function () { + + const logger = log.getLogger("version_history"); + this.logger = logger; + + this._has_version_fragment = function () { + const fragment = window.location.hash.substr(1); + return fragment === 'version_history'; + } + + this._get = connection.get; + /** + * Retrieve the version history of an entity and return a table with the + * history. + * + * @function retrieve_history + * @param {string} entity - the entity id with or without version id. + * @return {HTMLElement} A table with the version history. + */ + this.retrieve_history = async function (entity) { + const xml = this._get(transaction + .generateEntitiesUri([entity]) + "?H"); + const html = (await transformation.transformEntities(xml))[0]; + const history_table = $(html).find(".caosdb-f-entity-version-history"); + return history_table[0]; + } + + /** + * Initalize the buttons for loading the version history. + * + * The buttons are visible when the entity has only the normal version info + * attached and the current user has the permissions to retrieve the + * version history. + * + * The buttons trigger the retrieval of the version history and append the + * version history to the version info modal. + * + * @function init_load_history_buttons + */ + this.init_load_history_buttons = function () { + for (let entity of $(".caosdb-entity-panel")) { + const is_permitted = hasEntityPermission(entity, "RETRIEVE:HISTORY"); + if (!is_permitted) { + continue; + } + const entity_id_version = getEntityIdVersion(entity); + const version_info = $(entity) + .find(".caosdb-f-entity-version-info"); + const button = $(version_info) + .find(".caosdb-f-entity-version-load-history-btn"); + button.show(); + button + .click(async () => { + button.prop("disabled", true); + const wait = createWaitingNotification("Retrieving full history. Please wait."); + const sparse = $(version_info) + .find(".caosdb-f-entity-version-history"); + sparse.find(".modal-body *").replaceWith(wait); + + const history_table = await version_history + .retrieve_history(entity_id_version); + sparse.replaceWith(history_table); + version_history.init_export_history_buttons(entity); + version_history.init_restore_version_buttons(entity); + }); + } + } + + /** + * Transform the HTML table with the version history to tsv. + * + * @function get_history_tsv + * @param {HTMLElement} history_table - the HTML representation of the + * version history. + * @return {string} the version history as downloadable tsv string, + * suitable for the href attribute of a link or window.location. + */ + this.get_history_tsv = function (history_table) { + const rows = []; + for (let row of $(history_table).find("tr")) { + const cells = $(row).find(".export-data").toArray().map(x => x.textContent); + rows.push(cells); + } + return caosdb_utils.create_tsv_table(rows); + } + + /** + * Initialize the export buttons of `entity`. + * + * The buttons are only visible when the version history is visible and + * trigger a download of a tsv file which contains the version history. + * + * The buttons trigger the download of a tsv file with the version history. + * + * @function init_export_history_buttons + * @param {HTMLElement} [entity] - if undefined, the export buttons of all + * page entities are initialized. + */ + this.init_export_history_buttons = function (entity) { + entity = entity || $(".caosdb-entity-panel"); + for (let version_info of $(entity) + .find(".caosdb-f-entity-version-info")) { + $(version_info).find(".caosdb-f-entity-version-export-history-btn") + .click(() => { + const html_table = $(version_info).find("table")[0]; + const history_tsv = this.get_history_tsv(html_table); + version_history._download_tsv(history_tsv); + }); + } + } + + /** + * Initialize the restore old version buttons of `entity`. + * + * The buttons are only visible when the user is allowed to update the + * entity. + * + * The causes a retrieve of the specified version of the entity and then an + * update that restores that version. + * + * @function init_restore_version_buttons + * @param {HTMLElement} [entity] - if undefined, the export buttons of all + * page entities are initialized. + */ + this.init_restore_version_buttons = function (entity) { + var entities = [entity] || $(".caosdb-entity-panel"); + + for (let _entity of entities) { + // initialize buttons only if the user is allowed to update the entity + if (hasEntityPermission(_entity, "UPDATE:*") || hasEntityPermission(_entity, "UPDATE:DESCRIPTION")) { + for (let version_info of + $(_entity).find(".caosdb-f-entity-version-info")) { + // find the restore button + $(version_info).find(".caosdb-f-entity-version-restore-btn") + .toggleClass("d-none", false) // show button + .click(async (eve) => { + // the version id is stored in the restore button's + // data-version-id attribute + const versionid = eve.delegateTarget.getAttribute("data-version-id") + const reload = () => { + window.location.reload(); + } + const _alert = form_elements.make_alert({ + title: "Warning", + message: "You are going to restore this version of the entity.", + proceed_callback: async () => { + try { + await restore_old_version(versionid); + $(_alert).remove(); + // reload after sucessful update + $(version_info).find(".modal-body").prepend( + $(`<div class="alert alert-success" role="alert">Restore successful! <p>You are being forwarded to the latest version of this entity or you can click <a href="#" onclick="window.location.reload()">here</a>.</p></div>`)); + setTimeout(reload, 5000); + } catch (e) { + logger.error(e); + // print errors in an alert div + $(version_info).find(".modal-body").prepend( + $(`<div class="alert alert-danger alert-dismissible " role="alert"> <button class="btn-close" data-bs-dismiss="alert" aria-label="close"></button> Restore failed! <p>${e.message}</p></div>`)); + + } + }, + cancel_callback: () => { + // do nothing + $(_alert).remove(); + $(version_info).find("table").show(); + }, + proceed_text: "Yes, restore!", + remember_my_decision_id: "restore_entity", + }); + + $(version_info).find("table").after(_alert).hide(); + $(_alert).addClass("text-end"); + }); + } + } + } + } + + this._download_tsv = function (tsv_link) { + window.location.href = tsv_link; + } + + + /** + * @function init + */ + this.init = function () { + this.init_load_history_buttons(); + this.init_export_history_buttons(); + this.init_restore_version_buttons(); + + // check for the version_history fragment and open the modal if present. + if (this._has_version_fragment()) { + const first_entity = $(".caosdb-entity-panel")[0]; + if (first_entity && hasEntityPermission(first_entity, "RETRIEVE:HISTORY")) { + logger.debug("Showing full version modal for first entity"); + const version_button = $(first_entity).find(".caosdb-f-entity-version-button"); + version_button.click(); + const full_version_history_button = $(first_entity).find(".caosdb-f-entity-version-load-history-btn"); + full_version_history_button.click(); + } + } + } +} + +caosdb_modules.register(version_history); diff --git a/src/core/js/webcaosdb.js b/src/core/js/webcaosdb.js index 3f26cd7b4aa127b7c3d2065f0eece10194332618..bfe0eb35c8e72e6493ad273ae0ed5a727019c628 100644 --- a/src/core/js/webcaosdb.js +++ b/src/core/js/webcaosdb.js @@ -26,6 +26,13 @@ */ 'use strict'; +/** + * Core functionality of the CaosDB web interface. + * + * @module webcaosdb + * @global + */ + window.addEventListener('error', (e) => globalError(e.error)); var globalError = function (error) { @@ -61,6 +68,9 @@ var globalClassNames = new function () { /** * navbar module contains convenience functions for the navbar. + * + * @module navbar + * @global */ this.navbar = new function () { @@ -299,6 +309,10 @@ this.navbar = new function () { } +/** + * @module caosdb_utils + * @global + */ this.caosdb_utils = new function () { this.assert_string = function (obj, name, optional = false) { if (typeof obj === "undefined" && optional) { @@ -370,6 +384,9 @@ this.caosdb_utils = new function () { /** * connection module contains all ajax calls. + * + * @module connection + * @global */ this.connection = new function () { const logger = log.getLogger("connection"); @@ -544,6 +561,9 @@ this.connection = new function () { /** * transformation module contains all code for tranforming xml into html via * xslt. + * + * @module transformation + * @global */ this.transformation = new function () { /** @@ -656,6 +676,9 @@ this.transformation = new function () { /** * transaction module contains all code for insertion, update and deletion of * entities. Currently, only updates are implemented. + * + * @module transaction + * @global */ this.transaction = new function () { this.classNameUpdateForm = "caosdb-update-entity-form"; @@ -995,205 +1018,9 @@ this.transaction = new function () { } /** - * This module provides the functionality to load the full version history (for - * privileged users) and export it to tsv. + * @module paging + * @global */ -var version_history = new function () { - - const logger = log.getLogger("version_history"); - this.logger = logger; - - this._has_version_fragment = function () { - const fragment = window.location.hash.substr(1); - return fragment === 'version_history'; - } - - this._get = connection.get; - /** - * Retrieve the version history of an entity and return a table with the - * history. - * - * @param {string} entity - the entity id with or without version id. - * @return {HTMLElement} A table with the version history. - */ - this.retrieve_history = async function (entity) { - const xml = this._get(transaction - .generateEntitiesUri([entity]) + "?H"); - const html = (await transformation.transformEntities(xml))[0]; - const history_table = $(html).find(".caosdb-f-entity-version-history"); - return history_table[0]; - } - - /** - * Initalize the buttons for loading the version history. - * - * The buttons are visible when the entity has only the normal version info - * attached and the current user has the permissions to retrieve the - * version history. - * - * The buttons trigger the retrieval of the version history and append the - * version history to the version info modal. - */ - this.init_load_history_buttons = function () { - for (let entity of $(".caosdb-entity-panel")) { - const is_permitted = hasEntityPermission(entity, "RETRIEVE:HISTORY"); - if (!is_permitted) { - continue; - } - const entity_id_version = getEntityIdVersion(entity); - const version_info = $(entity) - .find(".caosdb-f-entity-version-info"); - const button = $(version_info) - .find(".caosdb-f-entity-version-load-history-btn"); - button.show(); - button - .click(async () => { - button.prop("disabled", true); - const wait = createWaitingNotification("Retrieving full history. Please wait."); - const sparse = $(version_info) - .find(".caosdb-f-entity-version-history"); - sparse.find(".modal-body *").replaceWith(wait); - - const history_table = await version_history - .retrieve_history(entity_id_version); - sparse.replaceWith(history_table); - version_history.init_export_history_buttons(entity); - version_history.init_restore_version_buttons(entity); - }); - } - } - - /** - * Transform the HTML table with the version history to tsv. - * - * @param {HTMLElement} history_table - the HTML representation of the - * version history. - * @return {string} the version history as downloadable tsv string, - * suitable for the href attribute of a link or window.location. - */ - this.get_history_tsv = function (history_table) { - const rows = []; - for (let row of $(history_table).find("tr")) { - const cells = $(row).find(".export-data").toArray().map(x => x.textContent); - rows.push(cells); - } - return caosdb_utils.create_tsv_table(rows); - } - - /** - * Initialize the export buttons of `entity`. - * - * The buttons are only visible when the version history is visible and - * trigger a download of a tsv file which contains the version history. - * - * The buttons trigger the download of a tsv file with the version history. - * - * @param {HTMLElement} [entity] - if undefined, the export buttons of all - * page entities are initialized. - */ - this.init_export_history_buttons = function (entity) { - entity = entity || $(".caosdb-entity-panel"); - for (let version_info of $(entity) - .find(".caosdb-f-entity-version-info")) { - $(version_info).find(".caosdb-f-entity-version-export-history-btn") - .click(() => { - const html_table = $(version_info).find("table")[0]; - const history_tsv = this.get_history_tsv(html_table); - version_history._download_tsv(history_tsv); - }); - } - } - - /** - * Initialize the restore old version buttons of `entity`. - * - * The buttons are only visible when the user is allowed to update the - * entity. - * - * The causes a retrieve of the specified version of the entity and then an - * update that restores that version. - * - * @param {HTMLElement} [entity] - if undefined, the export buttons of all - * page entities are initialized. - */ - this.init_restore_version_buttons = function (entity) { - var entities = [entity] || $(".caosdb-entity-panel"); - - for (let _entity of entities) { - // initialize buttons only if the user is allowed to update the entity - if (hasEntityPermission(_entity, "UPDATE:*") || hasEntityPermission(_entity, "UPDATE:DESCRIPTION")) { - for (let version_info of - $(_entity).find(".caosdb-f-entity-version-info")) { - // find the restore button - $(version_info).find(".caosdb-f-entity-version-restore-btn") - .toggleClass("d-none", false) // show button - .click(async (eve) => { - // the version id is stored in the restore button's - // data-version-id attribute - const versionid = eve.delegateTarget.getAttribute("data-version-id") - const reload = () => { - window.location.reload(); - } - const _alert = form_elements.make_alert({ - title: "Warning", - message: "You are going to restore this version of the entity.", - proceed_callback: async () => { - try { - await restore_old_version(versionid); - $(_alert).remove(); - // reload after sucessful update - $(version_info).find(".modal-body").prepend( - $(`<div class="alert alert-success" role="alert">Restore successful! <p>You are being forwarded to the latest version of this entity or you can click <a href="#" onclick="window.location.reload()">here</a>.</p></div>`)); - setTimeout(reload, 5000); - } catch (e) { - logger.error(e); - // print errors in an alert div - $(version_info).find(".modal-body").prepend( - $(`<div class="alert alert-danger alert-dismissible " role="alert"> <button class="btn-close" data-bs-dismiss="alert" aria-label="close"></button> Restore failed! <p>${e.message}</p></div>`)); - - } - }, - cancel_callback: () => { - // do nothing - $(_alert).remove(); - $(version_info).find("table").show(); - }, - proceed_text: "Yes, restore!", - remember_my_decision_id: "restore_entity", - }); - - $(version_info).find("table").after(_alert).hide(); - $(_alert).addClass("text-end"); - }); - } - } - } - } - - this._download_tsv = function (tsv_link) { - window.location.href = tsv_link; - } - - - this.init = function () { - this.init_load_history_buttons(); - this.init_export_history_buttons(); - this.init_restore_version_buttons(); - - // check for the version_history fragment and open the modal if present. - if (this._has_version_fragment()) { - const first_entity = $(".caosdb-entity-panel")[0]; - if (first_entity && hasEntityPermission(first_entity, "RETRIEVE:HISTORY")) { - logger.debug("Showing full version modal for first entity"); - const version_button = $(first_entity).find(".caosdb-f-entity-version-button"); - version_button.click(); - const full_version_history_button = $(first_entity).find(".caosdb-f-entity-version-load-history-btn"); - full_version_history_button.click(); - } - } - } -} - var paging = new function () { this.defaultPageLen = 10; @@ -1373,20 +1200,30 @@ var paging = new function () { } }; -var queryForm = new function () { - var logger = log.getLogger("queryForm"); - this.logger = logger; +/** + * Extend the functionality of the pure html query panel. + * + * @module queryForm + * @global + */ +var queryForm = function () { - this.init = function (form) { - this.restoreLastQuery(form, () => window.sessionStorage.lastQuery); - this.bindOnClick(form, (set) => { + const init = function (form) { + queryForm.restoreLastQuery(form, () => window.sessionStorage.lastQuery); + queryForm.bindOnClick(form, (set) => { window.sessionStorage.lastQuery = set; }); - const BUILD_FREE_SEARCH_ROLE_NAME_FACET_OPTIONS = "PathObject, MapObject"; - this.initFreeSearch(form, `${BUILD_FREE_SEARCH_ROLE_NAME_FACET_OPTIONS}`); + const BUILD_FREE_SEARCH_ROLE_NAME_FACET_OPTIONS = ""; + queryForm.initFreeSearch(form, `${BUILD_FREE_SEARCH_ROLE_NAME_FACET_OPTIONS}`); }; - this.role_name_facet_select = undefined; + const logger = log.getLogger("queryForm"); + var role_name_facet_select = undefined; + + const _isCql = function (query) { + query = query.toUpperCase().trim(); + return (query.startsWith("FIND") || query.startsWith("COUNT") || query.startsWith("SELECT")); + } /** * Initialize the free search to generate search queries which search only @@ -1404,13 +1241,14 @@ var queryForm = new function () { * "FILE 'numpy array', 'Plant Experiemnt', 'quotes_not_necessary'". * Otherwise, the server will throw a syntax error. * + * @function initFreeSearch * @param {HTMLElement} form - the form which will be initialized for the * free search. * @param {string} options - comma-separated list of options. * @return {boolean} - true if the initialization was successful, false * otherwise. */ - this.initFreeSearch = function (form, options) { + const initFreeSearch = function (form, options) { const textArea = $(form).find(".caosdb-f-query-textarea"); logger.trace("initFreeSearch", form, textArea, options); if (textArea.length > 0 && options && options != "") { @@ -1422,13 +1260,13 @@ var queryForm = new function () { const selected = window.localStorage["role_name_facet_option"]; const select = $(`<select class="btn btn-secondary"/>`); for (let option of options.split(",")) { - select.append(`<option ${selected === option ? "selected" : ""}>${option}</option>`); + select.append(`<option ${selected === option.trim() ? "selected" : ""}>${option}</option>`); } $(form).find(".input-group").prepend(select); - this.role_name_facet_select = select[0]; + role_name_facet_select = select[0]; const switchFreeSearch = (text_area) => { - if(this._isCql(text_area.value)) { + if(_isCql(text_area.value)) { select.hide(); $(text_area).css({"border-top-left-radius": "0.375rem", "border-bottom-left-radius": "0.375rem"}); } else { @@ -1444,11 +1282,14 @@ var queryForm = new function () { }); return true; } - this.role_name_facet_select = undefined; + role_name_facet_select = undefined; return false; } - this.restoreLastQuery = function (form, getter) { + /** + * @function restoreLastQuery + */ + const restoreLastQuery = function (form, getter) { if (form == null) { throw new Error("form was null"); } @@ -1458,10 +1299,11 @@ var queryForm = new function () { }; /** - * @value {string} query - the query string. + * @function redirect + * @param {string} query - the query string. * @param {string} paging - the paging string, e.g. 0L10. */ - this.redirect = function (query, paging) { + const redirect = function (query, paging) { var pagingparam = "" if (paging && paging.length > 0) { pagingparam = "P=" + paging + "&"; @@ -1472,10 +1314,11 @@ var queryForm = new function () { /** * Read out the selector for the role/name facet of the query. Return * "RECORD" if the selector is disabled. + * @function getRoleNameFacet */ - this.getRoleNameFacet = function () { - if (this.role_name_facet_select) { - const result = this.role_name_facet_select.value; + const getRoleNameFacet = function () { + if (role_name_facet_select) { + const result = role_name_facet_select.value; window.localStorage["role_name_facet_option"] = result; return result; } @@ -1492,20 +1335,30 @@ var queryForm = new function () { * enclosing quotation marks are being stripped. Currently no support for * escape sequences for quotation marks. * + * @function splitSearchTerms * @param {string} query - complete query string. * @return {string[]} array of the search terms. */ - this.splitSearchTerms = function (query) { + const splitSearchTerms = function (query) { // add empty space at the end, so every matching group ends with it -> easier regex. Also, undefined is filtered out return Array.from((query + " ").matchAll(_splitSearchTermsPattern), (m) => m[1] || m[2] || m[3]).filter((word) => word); } - this._isCql = function (query) { - query = query.toUpperCase().trim(); - return (query.startsWith("FIND") || query.startsWith("COUNT") || query.startsWith("SELECT")); + /** + * Is the query a SELECT field,... FROM entity query? + * + * @function isSelectQuery + * @param {HTMLElement} query, the query to be tested. + * @return {Boolean} + */ + const isSelectQuery = function (query) { + return query.toUpperCase().startsWith("SELECT"); } - this.bindOnClick = function (form, setter) { + /** + * @function bindOnClick + */ + const bindOnClick = function (form, setter) { if (setter == null || typeof (setter) !== 'function' || setter.length !== 1) { throw new Error("setter must be a function with one param"); } @@ -1522,13 +1375,13 @@ var queryForm = new function () { if (typeof value == "undefined" || value.length == 0) { return; } - if (!queryForm._isCql(value)) { + if (!_isCql(value)) { // split words in query field at space and create query fragments - var words = queryForm.splitSearchTerms(queryField.value).map(word => `A PROPERTY LIKE '*${word.replaceAll("'", `\\'`)}*'`); + var words = splitSearchTerms(queryField.value).map(word => `A PROPERTY LIKE '*${word.replaceAll("'", `\\'`)}*'`); if (!words.length) { return false; } - const e = queryForm.getRoleNameFacet(); + const e = getRoleNameFacet(); const query_string = `FIND ${e} WHICH HAS ` + words.join(" AND "); queryField.value = query_string; @@ -1538,7 +1391,7 @@ var queryForm = new function () { setter(queryField.value); var paging = ""; - if (form.P && !queryForm.isSelectQuery(queryField.value)) { + if (form.P && !isSelectQuery(queryField.value)) { paging = form.P.value } @@ -1567,31 +1420,28 @@ var queryForm = new function () { }; /** - * Is the query a SELECT field,... FROM entity query? - * - * @param {HTMLElement} query, the query to be tested. - * @return {Boolean} + * @function getRoleNameFacetSelect */ - this.isSelectQuery = function (query) { - return query.toUpperCase().startsWith("SELECT"); - } - /** - * Remove the (hidden) paging input from the query form. - * The form is changed in-place without copying it. - * - * @param {HTMLElement} form, the query form. - * @return {HTMLElement} the form without the paging input. - */ - this.removePagingField = function (form) { - $(form.P).remove(); - return form; + return { + init: init, + initFreeSearch: initFreeSearch, + isSelectQuery: isSelectQuery, + restoreLastQuery: restoreLastQuery, + redirect: redirect, + bindOnClick: bindOnClick, + splitSearchTerms: splitSearchTerms, + getRoleNameFacet: getRoleNameFacet, + getRoleNameFacetSelect: () => role_name_facet_select, } -}; +}(); -/** +/* * Small module containing only a converter from markdown to html. + * + * @module markdown + * @global */ this.markdown = new function () { this.dependencies = ["showdown", "caosdb_utils"]; @@ -1625,6 +1475,10 @@ this.markdown = new function () { }); } +/** + * @module hintMessages + * @global + */ var hintMessages = new function () { this.init = function () { for (var entity of $('.caosdb-entity-panel')) { @@ -2079,7 +1933,6 @@ function initOnDocumentReady() { } caosdb_modules.init(); navbar.init(); - version_history.init(); if ("${BUILD_MODULE_USER_MANAGEMENT}" == "ENABLED") { caosdb_modules.register(user_management); @@ -2102,6 +1955,7 @@ function initOnDocumentReady() { * * Singleton which is globally available under caosdb_modules. * + * @class _CaosDBModules * @property {boolean} auto_init - if modules are initialized automatically * after beeing registered, or when `this.init_all()` is being called. */ diff --git a/test/core/js/modules/webcaosdb.js.js b/test/core/js/modules/webcaosdb.js.js index cfb86e459acf6f38e5672918df81a42b0eb1ea2a..f838e35f5a8e70e0e1032a89e09885444c3fb250 100644 --- a/test/core/js/modules/webcaosdb.js.js +++ b/test/core/js/modules/webcaosdb.js.js @@ -1115,16 +1115,6 @@ QUnit.module("webcaosdb.js - queryForm", { } }); -QUnit.test("removePagingField", function (assert) { - assert.ok(queryForm.removePagingField, "function available."); - assert.throws(() => queryForm.removePagingField(), "null param throws."); - let form = $('<form><input name="P"></form>')[0]; - assert.ok(form.P, "before: paging available."); - queryForm.removePagingField(form); - assert.notOk(form.P, "after: paging removed."); - -}); - QUnit.test("isSelectQuery", function (assert) { assert.ok(queryForm.isSelectQuery, "function available."); assert.throws(() => queryForm.isSelectQuery(), "null param throws."); @@ -1263,19 +1253,21 @@ QUnit.test("initFreeSearch", function (assert) { // without initialization assert.ok(queryForm.initFreeSearch, "available"); - assert.notOk(queryForm.role_name_facet_select, "role_name_facet_select is undefined 1"); + assert.notOk(queryForm.getRoleNameFacetSelect(), "role_name_facet_select is undefined 1"); assert.notOk(queryForm.initFreeSearch(), "not initialized"); - assert.notOk(queryForm.role_name_facet_select, "role_name_facet_select is undefined 2"); + assert.notOk(queryForm.getRoleNameFacetSelect(), "role_name_facet_select is undefined 2"); assert.equal(form.find("select").length, 0, "no select present"); assert.equal(queryForm.getRoleNameFacet(), "RECORD"); - // after initialization + window.localStorage["role_name_facet_select"] = "Sample"; assert.ok(queryForm.initFreeSearch(form, "Person, Experiment, Sample"), "initialized"); - assert.ok(queryForm.role_name_facet_select, "role_name_facet_select is defined"); - assert.equal(queryForm.role_name_facet_select.tagName, "SELECT", "role_name_facet_select is SELECT"); + + // after initialization + assert.ok(queryForm.getRoleNameFacetSelect(), "role_name_facet_select is defined"); + assert.equal(queryForm.getRoleNameFacetSelect().tagName, "SELECT", "role_name_facet_select is SELECT"); assert.equal(form.find("select").length, 1, "select is present"); assert.equal(queryForm.getRoleNameFacet(), "Person");