Commit db918752 authored by Henrik tom Wörden's avatar Henrik tom Wörden
Browse files

Merge branch 'dev' into f-footer

parents f96ac1c1 44c249b2
......@@ -4,6 +4,7 @@
#
# Copyright (C) 2018 Research Group Biomedical Physics,
# Max-Planck-Institute for Dynamics and Self-Organization Göttingen
# Copyright (C) 2019 Henrik tom Wörden
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
......@@ -20,44 +21,64 @@
#
# ** end header
#
stages:
- setup
- linting
- test
#######
# setup
#######
variables:
CI_REGISTRY_IMAGE: $CI_REGISTRY/caosdb-webui-testenv
# With dind the docker deamon is available on the network
DOCKER_HOST: tcp://docker:2375/
# When using dind, it's wise to use the overlayfs driver for
# improved performance.
DOCKER_DRIVER: overlay2
services:
- docker:dind
# install pylint
setup:install-pylint:
stage: setup
tags: [ py36 ]
script:
- pip3 install pylint --user
image: $CI_REGISTRY_IMAGE:latest
#########
# linting
#########
# pylint everything
linting:pylint:python3:
stage: linting
tags: [ py36 ]
script:
- make pylint
stages:
- setup
- linting
- test
- deploy
######
# test
######
# run qunit tests and pylint
test:
tags: [ docker ]
stage: test
artifacts:
paths:
- public/qunit.log
- screenlog.*
script:
- make pylint
- make run-qunit
# Trigger building of server image and integration tests
trigger_build:
tags: [ docker ]
stage: deploy
script:
- echo $TOKEN
- /usr/bin/curl -X POST
-F token=$TOKEN
-F "variables[WEBUI]=$CI_COMMIT_REF_NAME"
-F "variables[TriggerdBy]=WEBUI"
-F "variables[TriggerdByHash]=$CI_COMMIT_SHORT_SHA"
-F ref=master https://gitlab.indiscale.com/api/v4/projects/14/trigger/pipeline
# run qunit tests
test:qunit:
stage: test
tags: [ py36 ]
artifacts:
paths:
- public/qunit.log
- screenlog.*
script:
- make run-qunit
# Build a docker image in which tests for this repository can run
build-testenv:
tags: [ docker ]
image: docker:latest
stage: setup
script:
- cd test/docker
- docker login -u testuser -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
# use here general latest or specific branch latest...
- docker pull $CI_REGISTRY_IMAGE:latest || true
- docker build
--pull
--cache-from $CI_REGISTRY_IMAGE:latest
-t $CI_REGISTRY_IMAGE:latest .
- docker push $CI_REGISTRY_IMAGE:latest
......@@ -173,11 +173,11 @@ unzip:
for f in $(LIBS_ZIP); do unzip -o -d libs $$f; done
PYLINT = pylint -d all -e E,F
PYLINT = pylint3 -d all -e E,F
PYTHON_FILES = $(subst $(ROOT_DIR)/,,$(shell find $(ROOT_DIR)/ -iname "*.py"))
pylint: $(PYTHON_FILES)
for f in $(PYTHON_FILES); do $(PYLINT) $$f || exit 1; done
PYLINT_LOCAL = /usr/bin/pylint -d all -e E,F
PYLINT_LOCAL = /usr/bin/pylint3 -d all -e E,F
pylint-local: $(PYTHON_FILES)
for f in $(PYTHON_FILES); do $(PYLINT_LOCAL) $$f || exit 1; done
......@@ -433,6 +433,7 @@ h5 {
.caosdb-property-row {
animation: appear 0.5s 1;
padding: 0.3ex 1em;
}
@keyframes appear {
......
......@@ -74,8 +74,8 @@ var edit_mode = new function() {
this.parent_drop_listener = function(e) {
e.preventDefault();
var entity = $(this).parent();
app.startEdit(entity);
edit_mode.add_dropped_parent(e, app.entity);
edit_mode.app.startEdit(entity);
edit_mode.add_dropped_parent(e, edit_mode.app.entity);
}
this.add_new_property = function(entity, new_prop) {
......
......@@ -3,9 +3,48 @@
* Alexander Schlemmer, 11/2018
*/
/*!
* Check if an element is out of the viewport
* (c) 2018 Chris Ferdinandi, MIT License, https://gomakethings.com
* @param {Node} elem The element to check
* @return {Object} A set of booleans for each side of the element
*/
// Source address: https://gomakethings.com/how-to-check-if-any-part-of-an-element-is-out-of-the-viewport-with-vanilla-js/
var isOutOfViewport = function (elem) {
// Get element's bounding
var bounding = elem.getBoundingClientRect();
// Check if it's out of the viewport on each side
var out = {};
out.top = bounding.top < 0;
out.left = bounding.left < 0;
out.bottom = bounding.bottom > (window.innerHeight || document.documentElement.clientHeight);
out.right = bounding.right > (window.innerWidth || document.documentElement.clientWidth);
out.any = out.top || out.left || out.bottom || out.right;
out.all = out.top && out.left && out.bottom && out.right;
return out;
};
// Variation that checks whether an element is inside of the viewport.
var isInViewport = function (elem) {
var bounding = elem.getBoundingClientRect();
var out = {};
out.top = bounding.bottom < 0;
out.left = bounding.left < 0;
out.bottom = bounding.top > (window.innerHeight || document.documentElement.clientHeight);
out.right = bounding.left > (window.innerWidth || document.documentElement.clientWidth);
return !(out.top || out.bottom);
// return !(out.top || out.left || out.bottom || out.right);
}
var resolve_references = new function() {
this.init = function() {
this.references();
// this.references();
this.update_visible_references();
}
this.get_person_str = function(el) {
......@@ -13,10 +52,17 @@ var resolve_references = new function() {
if (valpr == undefined) {
return;
}
return valpr.filter(valprel => valprel.name == "firstName")[0].value +
" " + valpr.filter(valprel => valprel.name == "lastName")[0].value;
return valpr.filter(valprel => valprel.name.toLowerCase() == "firstname")[0].value +
" " + valpr.filter(valprel => valprel.name.toLowerCase() == "lastname")[0].value;
}
/*
* Function that retrieves meaningful information for a single element.
*
* This function needs to be customized for specific implementations.
*
* rs: Element having the class caosdb-resolvable-reference and including a caosdb-resolve-reference target.
*/
this.update_single_resolvable_reference = async function(rs) {
var rseditable = rs.getElementsByClassName("caosdb-resolve-reference-target")[0];
var el = await retrieve(getIDfromHREF(rs));
......@@ -26,6 +72,8 @@ var resolve_references = new function() {
rseditable.textContent = pths[pths.length - 1];
} else if (pr[0].name == "Person") {
rseditable.textContent = this.get_person_str(el[0]);
} else if (pr[0].name == "ExperimentSeries") {
rseditable.textContent = getEntityName(el[0]);
} else if (pr[0].name == "BoxType") {
rseditable.textContent = getEntityName(el[0]);
} else if (pr[0].name == "Loan") {
......@@ -43,6 +91,20 @@ var resolve_references = new function() {
}
}
/*
* This function updates all references that are inside of the current viewport.
*
*/
this.update_visible_references = async function() {
var rs = document.getElementsByClassName("caosdb-resolvable-reference");
for (var i = 0; i < rs.length; i++) {
if (isInViewport(rs[i])) {
this.update_single_resolvable_reference(rs[i]);
}
}
}
this.references = async function() {
var rs = document.getElementsByClassName("caosdb-resolvable-reference");
......@@ -55,4 +117,13 @@ var resolve_references = new function() {
$(document).ready(function() {
resolve_references.init();
var scrollTimeout = undefined;
$(window).scroll(()=> {
if (scrollTimeout) {
clearTimeout(scrollTimeout);
}
scrollTimeout = setTimeout(function() {
resolve_references.update_visible_references();
}, 500);
});
});
// ** header v3.0
// This file is a part of the CaosDB Project.
// Copyright (C) 2019 IndiScale GmbH
// Max-Planck-Institute for Dynamics and Self-Organization Göttingen
// 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
// Templates Extension for CaosDB WebUI
// A. Schlemmer, 11/2018
// (c) 2019 D. Hornung <d.hornung@indiscale.com>
/**
* Loads, generates and expands templates.
*
* Templates are stored in conf/ext/templates.json, the format is as follows:
*
* [
* {
* "help": "Find all geological data sets with temperature above {temp} K.",
* "query": "FIND Record Geodata with temperature > \"$1\""
* }, {
* ...
* }
* ]
*/
var templates_ext = new function() {
this.init = function() {
......@@ -41,7 +76,9 @@ var templates_ext = new function() {
shortcuts_container.append(
this.generate_template(tempel.help, tempel.query));
}
}, globalError);
}, e => {
alert("Error in ext/templates.json!");
});
}
......
......@@ -98,7 +98,7 @@ this.connection = new function() {
this.runScript = async function _runScript(scriptname, params) {
var pstring = "call=" + scriptname;
for (var key in params) {
pstring += "&O" + key + "=" + params[key];
pstring += "&-O" + key + "=" + params[key];
}
try {
return await $.ajax({
......
......@@ -76,7 +76,9 @@
</xsl:if>
<xsl:apply-templates mode="query-results" select="./ParseTree"/>
</div>
<xsl:apply-templates mode="select-table" select="./Selection"/>
<xsl:if test="@results!=0">
<xsl:apply-templates mode="select-table" select="./Selection"/>
</xsl:if>
</xsl:template>
<xsl:template match="Selection" mode="select-table">
<div class="panel panel-default caosdb-select-table">
......
......@@ -55,6 +55,67 @@ QUnit.test("basic properties of select-table feature", function(assert) {
assert.equal(html.firstElementChild.className, "panel panel-default caosdb-select-table", "first child has class caosdb-select-table.");
});
/* Test table of empty result sets of queries */
QUnit.test("empty results in SELECT create no table", function(assert) {
var testresult = '\
<?xml version="1.0" encoding="UTF-8"?>\
<Response count="0">\
<Query string="select test from bla" results="0">\
<ParseTree>(cq select (prop_sel (prop_subsel (selector_txt t e s t ))) from (entity bla) &lt;EOF&gt;)</ParseTree>\
<Role />\
<Entity>bla</Entity>\
<Selection>\
<Selector name="test" />\
</Selection>\
</Query>\
</Response>\
';
var xml = str2xml(testresult);
var html = applyTemplates(xml, this.queryXSL, "query-results");
assert.equal(html.children.length, 1);
// For select queries actually containing results, this would be 2.
});
// This uses results from the demo server.
QUnit.test("one result in SELECT create table", function(assert) {
var testresult = '\
<?xml version="1.0" encoding="UTF-8"?>\
<Response count="12">\
<Query string="SELECT Width, Result, Success FROM MySimulation" results="1">\
<ParseTree>(cq SELECT (prop_sel (prop_subsel (selector_txt W i d t h)) , (prop_subsel (selector_txt R e s u l t)) , (prop_subsel (selector_txt S u c c e s s ))) FROM (entity MySimulation) &lt;EOF&gt;)</ParseTree>\
<Role />\
<Entity>MySimulation</Entity>\
<Selection>\
<Selector name="Width" />\
<Selector name="Result" />\
<Selector name="Success" />\
</Selection>\
</Query>\
<Record id="243">\
<Permissions />\
<Property id="235" name="Width" datatype="INTEGER" importance="FIX" unit="px">\
200\
<Permissions />\
</Property>\
<Property id="237" name="Result" datatype="DOUBLE" importance="FIX">\
1.25\
<Permissions />\
</Property>\
<Property id="238" name="Success" datatype="BOOLEAN" importance="FIX">\
TRUE\
<Permissions />\
</Property>\
</Record>\
</Response>';
var xml = str2xml(testresult);
var html = applyTemplates(xml, this.queryXSL, "query-results");
assert.equal(html.children.length, 2);
});
/* -- -- */
QUnit.test("Query tag is transformed via xslt", function(assert) {
assert.equal(this.queryXSL.getElementsByClassName("caosdb-query-response")[0].tagName, "div", "xsl sheet defines a caosdb-query response div");
......
FROM debian:latest
RUN apt-get update && \
apt-get install firefox-esr pylint3 python3-pip python3-httpbin git \
curl -y
RUN git clone -b dev https://gitlab.gwdg.de/bmp-caosdb/caosdb-pylib.git && \
cd caosdb-pylib && pip3 install .
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment