Skip to content
Snippets Groups Projects
Verified Commit f59f972f authored by Timm Fitschen's avatar Timm Fitschen
Browse files

Merge branch 'f-doc-link-footer' into f-linkify-edit-mode

parents 89ab9e71 d1783fb4
No related branches found
No related tags found
2 merge requests!59REL: release 0.4.1,!55F linkify edit mode
Pipeline #16520 failed
......@@ -35,6 +35,31 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Documentation (for notable additions or changes of the documentation)
## [0.4.1] - 2021-11-04
### Added (for new features, dependecies etc.)
* `form_panel` module for conveniently creating a panel for web forms.
### Changed (for changes in existing functionality)
* Default footer elements contain invalid links for imprint, contact, and data-policy now
### Deprecated (for soon-to-be removed features)
### Removed (for now removed features)
* Build property `BUILD_CUSTOM_IMPRINT`. Please use BUILD_FOOTER_IMPRINT_HREF
and link a document instead. You can always put a html page to
`src/ext/html/` and link to that.
### Fixed (for any bug fixes)
### Security (in case of vulnerabilities)
### Documentation (for notable additions or changes of the documentation)
## [0.4.0] - 2021-10-28
### Added (for new features, dependecies etc.)
......
......@@ -176,6 +176,9 @@ cp-ext:
for f in $(wildcard $(SRC_EXT_DIR)/xsl/*) ; do \
echo "y" | $(CMD_COPY_EXT_FILES) "$$(realpath "$$f")" $(PUBLIC_DIR)/xsl/ ; \
done
for f in $(wildcard $(SRC_EXT_DIR)/include/*) ; do \
echo "y" | $(CMD_COPY_EXT_FILES) "$$(realpath "$$f")" "$(PUBLIC_DIR)/$$(basename "$$f")" ; \
done
cp-ext-test:
for f in $(wildcard $(TEST_EXT_DIR)/js/*) ; do \
......
......@@ -172,4 +172,5 @@ MODULE_DEPENDENCIES=(
ext_cosmetics.js
qrcode.js
ext_qrcode.js
form_panel.js
)
......@@ -100,14 +100,41 @@ var form_elements = new function () {
this.version = "0.1";
this.dependencies = ["log", "caosdb_utils", "markdown", "bootstrap"];
this.logger = log.getLogger("form_elements");
/**
* Event. On form cancel.
*/
this.cancel_form_event = new Event("caosdb.form.cancel");
/**
* Event. On form submit.
*/
this.submit_form_event = new Event("caosdb.form.submit");
/**
* Event. On field change.
*/
this.field_changed_event = new Event("caosdb.field.changed");
/**
* Event. On field enabled.
*/
this.field_enabled_event = new Event("caosdb.field.enabled");
/**
* Event. On field disabled.
*/
this.field_disabled_event = new Event("caosdb.field.disabled");
/**
* Event. On field ready (e.g. for reference drop downs)
*/
this.field_ready_event = new Event("caosdb.field.ready");
/**
* Event. On field error (e.g. for reference drop downs)
*/
this.field_error_event = new Event("caosdb.field.error");
/**
* Event. Form submitted successfully.
*/
this.form_success_event = new Event("caosdb.form.success");
/**
* Event. Error after form was submitted.
*/
this.form_error_event = new Event("caosdb.form.error");
......@@ -1266,7 +1293,10 @@ var form_elements = new function () {
}, config.to);
const from_input = this.make_form_field(from_config);
$(from_input).toggleClass("form-control", false);
const to_input = this.make_form_field(to_config);
$(to_input).toggleClass("form-control", false);
const ret = $(this._make_field_wrapper(config.name));
if (config.label) {
......@@ -1277,12 +1307,8 @@ var form_elements = new function () {
ret.append(to_input);
// styling
$(from_input).toggleClass("form-control", false);
$(from_input).find(".col-sm-3").toggleClass("col-sm-3", false).toggleClass("col-sm-1");
$(from_input).find(".col-sm-9").toggleClass("col-sm-9", false).toggleClass("col-sm-3");
$(to_input).toggleClass("form-control", false);
$(to_input).find(".col-sm-3").toggleClass("col-sm-3", false).toggleClass("col-sm-1").toggleClass("col-sm-offset-1");
$(to_input).find(".col-sm-9").toggleClass("col-sm-9", false).toggleClass("col-sm-3");
$(from_input).toggleClass("col-sm-4", true);
$(to_input).toggleClass("col-sm-4", true);
return ret[0];
}
......
/*
* ** header v3.0
* This file is a part of the CaosDB Project.
*
* Copyright (C) 2021 IndiScale GmbH <info@indiscale.com>
* Copyright (C) 2021 Timm Fitschen <t.fitschen@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
*/
'use strict';
/**
* form_panel module for creating a panel below the navbar where forms can be
* placed.
*/
var form_panel = new function () {
const logger = log.getLogger("form_panel");
this.version = "0.1";
this.dependencies = ["log", "caosdb_utils", "markdown", "bootstrap"];
/**
* Return a the panel which shall contain the form.
*
* Side-effects:
* 1. Creates the form panel if it does not exist.
* 2. Removes the welcome panel if present.
*/
this.get_form_panel = function (panel_id, title) {
// remove welcome
$(".caosdb-f-welcome-panel").remove();
$(".caosdb-v-welcome-panel").remove();
var existing = $("#" + panel_id);
if (existing.length > 0) {
return existing[0];
}
const panel = $('<div id="' + panel_id + '" class="caosdb-f-form-panel bg-light container mb-1"/>');
const header = $('<h2 class="text-center">' + title + '</h2>');
panel.append(header);
// add to main panel
$('nav').after(panel);
return panel[0];
};
/**
* Remove the form panel from the DOM tree.
*/
this.destroy_form_panel = function (panel) {
$(panel).remove();
};
/**
* Creates a callback function that toggles the form panel which
*/
this.create_show_form_callback = function (panel_id, title, form_config) {
return (e) => {
logger.trace("enter show_form_panel", e);
const panel = $(form_panel.get_form_panel(panel_id, title));
if (panel.find("form").length === 0) {
const form = form_elements.make_form(form_config);
panel.append(form);
$(form).find(".selectpicker").selectpicker();
form.addEventListener("caosdb.form.cancel",
(e) => form_panel.destroy_form_panel(panel),
true
);
}
}
};
this.init = function () {
}
}
$(document).ready(function () {
caosdb_modules.register(form_panel);
});
......@@ -45,6 +45,36 @@ On submission, the function ``my_special_submit_handler`` is being called with t
As the generated form is a plain HTML form, the javascript form API can be used. However, there are special methods in the ``form_elements`` module e.g. :doc:`get_fields <../api/module-form_elements>` which are especially designed to interact with the forms generated by the ``make_form`` factory.
Placing the form in a panel below the navbar
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
There are functions in the `form_panel` module to make it easy to place forms at the typical location:
below the navbar. The following shows how the config (see above) is passed to
`init_show_form_panel_button` a direct call to `make_form` is no longer necessary.
.. code-block:: javascript
const title = "Upload CSV File"; // title of the form and text in the toolbox
const panel_id = "csv_upload_form_panel";
/**
* Add a button to the navbar, saying "Upload CSV File" which opens a
* form for file upload.
*/
const init_show_form_panel_button = function () {
navbar.add_tool(title, tool_box, {
callback: form_panel.create_show_form_callback(
panel_id,
title,
csv_form_config)
});
};
const init = function () {
init_show_form_panel_button();
}
Calling a server-side script
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
......
......@@ -4,7 +4,14 @@ The CaosDB WebUI is organized in modules which can easily be added and on a modu
There are a few steps necessary to create a new module.
## Create the module file
Create a new file in `src/core/js` starting with `ext_`. E.g. `ext_flight_preview.js`. This file should define one function that wraps every thing and which is enabled at the bottom of the file:
Create a new file for each new module. We have the convention, that extensions
which are optional and should stay that way and also custom extensions for
special purposes to name the file starting with `ext_`. E.g.
`ext_flight_preview.js`.
This file should define one function that wraps every thing and which is
enabled at the bottom of the file:
```js
/*
......@@ -23,16 +30,14 @@ Create a new file in `src/core/js` starting with `ext_`. E.g. `ext_flight_previe
* @requires somelibrary
* (pass the dependencies as arguments)
*/
var ext_flight_preview = function (somelibrary) {
const ext_flight_preview = function (libA, libB) {
var init = function (toolbox) {
const init = function () {
/* initialization of the module */
}
/**
* doc string
*/
var some_function = function (arg1, arg2) {
/* doc string */
const some_function = function (arg1, arg2) {
}
/* the main function must return the initialization of the module */
......@@ -40,7 +45,7 @@ var ext_flight_preview = function (somelibrary) {
init: init,
};
//pass the dependencies as arguments here as well
}(somelibrary);
}(libA, libB);
// this will be replaced by require.js in the future.
$(document).ready(function() {
......@@ -52,21 +57,36 @@ $(document).ready(function() {
}
});
```
## Update xml
Add a section to `src/core/xsl/main.xsl` to include your new file.
```xsl
<xsl:element name="script">
<xsl:attribute name="src">
<xsl:value-of select="concat($basepath,'webinterface/${BUILD_NUMBER}/js/ext_sss_markdown.js')"/>
</xsl:attribute>
</xsl:element>
```
## Add to index.html in test
If you have unittests (and you should), you need to add a line in :
`test/core/index.html`.
## Install the module
The new new file should be placed in `src/core/js` if it is intended to be merged into the main repository eventually. For development purposes and for custom extensions which are not to be published you may place it in `src/ext/js`.
Everything inside `src/core/js` and `src/ext/js` will eventually being loaded.
So, if there are no other modules which depend on this particular new module,
you are done.
Otherwise, when we need to configure the order in which the
module is being loaded.
### Dependency order
#### For Upstream Code
For modules which are about to be merged into the main or dev branch of this
repository, add the module's file to `build.properties.d/00_default.properties`
at the right location in the list of module files (Array
`MODULE_DEPENDENCIES`). The list defines the order in which module files are
being loaded.
#### For Custom Extensions
For modules which will not be published and merged with the main repository you
may append all your module files in the desired order to the
`MODULE_DEPENDENCIES` array in a new `*.properties` file (e.g.
`build.properties.d/99_local_stuff`):
## Update the changelog
MODULE_DEPENDENCIES+=(libA.js libB.js ext_flight_preview.js)
## Create a merge request
\ No newline at end of file
In this example, `libA.js`, `libB.js` and `ext_flight_preview.js` are custom modules developed for this particular CaosDB webui instance.
/*
* ** header v3.0
* This file is a part of the CaosDB Project.
*
* Copyright (C) 2021 IndiScale GmbH
*
* 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
*/
'use strict';
QUnit.module("form_panel.js", {
before: function (assert) {
},
after: function (assert) {
}
});
QUnit.test("availability", function (assert) {
assert.ok(form_panel.init, "init available");
assert.ok(form_panel.create_show_form_callback , "version available");
});
QUnit.test("create_show_form_callback ", function (assert) {
const title = "Upload CSV File"; // title of the form and text in the toolbox
const panel_id = "csv_upload_form_panel";
const server_side_script = "csv_script.py";
const tool_box = "Tools"; // Name of the drop-down menu where the button is added in the navbar
const help_text = "something";
const accepted_files_formats = [ ".csv", "text/tsv", ] // Mime types and file endings.
const csv_form_config = {
script: server_side_script,
fields: [{
type: "file",
name: "csv_file",
label: "CSV File", // label of the file selector in the form
required: true,
cached: false,
accept: accepted_files_formats.join(","),
help: help_text,
}, ],
};
cb = form_panel.create_show_form_callback( panel_id, title, csv_form_config);
assert.equal(typeof cb, "function", "function created");
cb()
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment