Commit 0ad33c2f authored by mrodzis's avatar mrodzis 🦊

Merge branch 'develop' into feature/#104-navigation-docs

parents e32abeb3 c36670ab
......@@ -110,6 +110,32 @@ After implementing (or declining) the desired suggestions, the MR is reassigned
If a merge conflict occurs the person who has proposed the MR is responsible for solving all conflicts.
### Release
New features and bugfixes will be added to new releases. [Here](https://gitlab.gwdg.de/SADE/SADE/-/releases)
you can find an overview of all releases.
#### How to set up a new release
Following the *git flow* new releases will be prepared with the CLI tool [gitflow-avh](https://github.com/petervanderdoes/gitflow-avh)).
+ the currently active [milestone](https://gitlab.gwdg.de/groups/SADE/-/milestones) names the version number of SADE/SADE only! For SADE/assets, SADE/build and all others please look at the version with `grep --max-count=1 project.version < build.properties`
* is there a sufficient number of issues closed?
* move open issues to next milestone
+ remove the [branch protection](https://gitlab.gwdg.de/SADE/SADE/-/settings/repository#js-protected-branches-settings) to enable push requests to develop and master (otherwise all merges have to be done at GitLab and not locally)
+ `git flow release start '[VERSION]'` to create the release branch.
+ set the version number according to the milestone
+ `git flow release finish '[VERSION]'` to merge the release branch into master and develop.
+ add Release Notes: The first commit message (`.git/MERGE_MSG`) the command above will ask for will become the release description.
* write in markdown and escape `#` with `\#`
* insert a headline and write a short paragraph about this release
* insert sections for features and bugfixes and list all of them using the issue reference `#[ISSUENUMBER]`
+ it is possible to use the same text for the following tag and commit message
+ after successfully finishing the release process, the version for develop should be increased by a PATCH ([SemVer](https://semver.org/#backusnaur-form-grammar-for-valid-semver-versions)). please commit this change.
+ send all of this to the remote `git push --all && git push --tags`
+ reset the [branch protection](https://gitlab.gwdg.de/SADE/SADE/-/settings/repository#js-protected-branches-settings)
#### GitLab Releases
GitLab can maintain releases via API only. Therefore a CI job is used parsing the
merge message, preserving the build artifact and preparing the release.
### Meetings
Once in a month all team members will meet at an informal (and usually internal)
meeting to discuss issues and proceedings. If external participants are interested
......
......@@ -39,12 +39,14 @@
<!-- this path may be and is subject to change! -->
<get src="https://bintray.com/existdb/releases/download_file?file_path=exist-distribution-${project.processorversion}-unix.tar.bz2" dest="${build.dir}/eXist-db-${project.processorversion}.tar.bz2" skipexisting="true" />
<untar src="${build.dir}/eXist-db-${project.processorversion}.tar.bz2" dest="${test.dir}" compression="bzip2" />
<!-- directory name changed: exist-distribution-5.0.0-->
<move todir="${test.dir}/eXist-db-${project.processorversion}">
<fileset dir="${test.dir}/exist-distribution-${project.processorversion}" />
</move>
<!-- task setpermissions requries at least ant 1.10.0 -->
<setpermissions mode="755">
<setpermissions permissions="OWNER_READ,OWNER_WRITE,OWNER_EXECUTE,OTHERS_READ,OTHERS_EXECUTE,GROUP_READ,GROUP_EXECUTE">
<file file="${test.dir}/eXist-db-${project.processorversion}/bin/startup.sh"/>
</setpermissions>
......
......@@ -14,7 +14,7 @@ xquery version "3.1";
:
: @author Ubbo Veentjer
: @author Mathias Göbel
: @version 1.0
: @version 2.0
: :)
module namespace fsearch="https://sade.textgrid.de/ns/faceted-search";
......@@ -48,8 +48,8 @@ as xs:string? {
$q
};
declare function fsearch:results($node as node(), $model as map(*)) as map()* {
let $page := xs:integer(request:get-parameter("page", "1"))
declare function fsearch:results($node as node(), $model as map(*), $page as xs:string) as map()* {
let $page := (if($page) then $page else 1) cast as xs:integer
let $target := $config:app-root || "/" || config:get("project-id") || "/data"
let $hits := local:get-hits($model, $target)
......@@ -75,8 +75,7 @@ declare function fsearch:results($node as node(), $model as map(*)) as map()* {
"hits" : subsequence($hitsordered,$start,$num),
"totalhits" : count($hits),
"start" : $start,
"page" : $page,
"pages" : $pages
"pagination" : local:pagination(xs:integer($page), xs:integer($pages))
}
};
......@@ -108,42 +107,6 @@ function fsearch:hitend($node as node(), $model as map(*)) {
else $res
};
(:~ Helper for pagination, used from template, returns actal page number.
: This method injects in its HTML node (%templates-wrap).
:
: Usage:
: <span id="page" class="hidden" data-template="fsearch:page"/>
:
: Output:
: <span id="page" class="hidden" data-template="fsearch:page">1</span>
:
: @param $node
: @param $model
:)
declare
%templates:wrap
function fsearch:page($node as node(), $model as map(*)) {
$model("page")
};
(:~ Helper for pagination, used from template, return number of all pages.
: This method injects in its HTML node (%templates-wrap).
:
: Usage:
: <span id="pages" class="hidden" data-template="fsearch:pages"/>
:
: Output:
: <span id="pages" class="hidden" data-template="fsearch:pages">4</span>
:
: @param $node
: @param $model
:)
declare
%templates:wrap
function fsearch:pages($node as node(), $model as map(*)) {
$model("pages")
};
declare function fsearch:result-title($node as node(), $model as map(*)) {
let $viewdoc := config:get('viewer-html', 'faceted-search')
......@@ -292,13 +255,13 @@ declare function local:facet($model as map(*), $hits as node()*, $key as xs:stri
let $facetRemoveQuery := replace($facetReq, $key || ":" || xmldb:encode($facet) || "," , "")
return
<li class="facetSelected">
<a class="facet-minus" href="{ $search-html }?q={ $query }&amp;facet={ $facetRemoveQuery }&amp;order={ $order }&amp;order-by={ $order-by }"><i class="fas fa-minus"></i> </a>
<a class="facet-minus" href="{ $search-html }?q={ $query }&amp;facet={ $facetRemoveQuery }&amp;order={ $order }&amp;order-by={ $order-by }&amp;page=1"><i class="fas fa-minus"></i> </a>
{ $facet } ({ $freq })
</li>
else
<li>
<a class="facet-minus" href="{ $search-html }?q={ $query }&amp;facet={ $key }:!{ xmldb:encode($facet) },{ $facetReq }&amp;order={ $order }&amp;order-by={ $order-by }"><i class="fas fa-minus" title="exclude"></i></a>
<a title="exclude all others" href="{ $search-html }?q={ $query }&amp;facet={ $key }:{ xmldb:encode($facet) },{ $facetReq }&amp;order={ $order }&amp;order-by={ $order-by }">{ $facet } </a> ({ $freq })
<a class="facet-minus" href="{ $search-html }?q={ $query }&amp;facet={ $key }:!{ xmldb:encode($facet) },{ $facetReq }&amp;order={ $order }&amp;order-by={ $order-by }&amp;page=1"><i class="fas fa-minus" title="exclude"></i></a>
<a title="exclude all others" href="{ $search-html }?q={ $query }&amp;facet={ $key }:{ xmldb:encode($facet) },{ $facetReq }&amp;order={ $order }&amp;order-by={ $order-by }&amp;page=1">{ $facet } </a> ({ $freq })
</li>
};
......@@ -322,7 +285,7 @@ declare function local:deselected-for-key($model, $key as xs:string) {
let $facetRemoveQuery := replace($facetReq, $key || ":" || $parts[2] || "," , "")
return
<li class="facet-deselected">
<a class="facet-plus" href="{$search-html}?q={$query}&amp;facet={$facetRemoveQuery}&amp;order={$order}&amp;order-by={$order-by}">
<a class="facet-plus" href="{$search-html}?q={$query}&amp;facet={$facetRemoveQuery}&amp;order={$order}&amp;order-by={$order-by}&amp;page=1">
<i class="fa fa-plus"></i>
</a>
{" " || xmldb:decode(substring-after($parts[2], "!"))}
......@@ -396,7 +359,8 @@ declare function local:facet-query-from-request() {
};
declare function local:facetSelected($key as xs:string, $value as xs:string) as xs:boolean {
declare function local:facetSelected($key as xs:string, $value as xs:string)
as xs:boolean {
let $r := for $token in tokenize(local:facet-query-from-request(), ",")
let $parts := tokenize($token, ":")
......@@ -407,3 +371,59 @@ declare function local:facetSelected($key as xs:string, $value as xs:string) as
return boolean($r)
};
(:~
: Create the pagination list in xhtml, made for bootstrap 3. As local function
: to be added to the $model, so can be added to the page several times.
: @since 2.0
: @author Mathias Göbel
:)
declare function local:pagination($page as xs:integer, $pages as xs:integer)
as element(ul) {
let $disableFirst := if($page = 1)
then attribute class {"disabled"}
else ()
let $disableLast := if($page = $pages)
then attribute class {"disabled"}
else ()
let $pagesListItems :=
for $i in 1 to $pages
let $title :=
if($page = $i)
then "Current page is " || $i
else "Go to page " || $i
let $disableCurrent :=
if($page = $i)
then attribute class {"disabled"}
else ()
let $queryString := request:get-query-string() => replace("page=\d+", "page=" || $i)
let $prefixEllipsis := if(($page - $i eq 2) and $pages ne $i and $i ne 1) then "…" else ()
let $suffixEllipsis := if(($page - $i eq -2) and $pages ne $i and $i ne 1) then "…" else ()
where $page - $i lt 3
where $page - $i gt -3
return
<li>
{$disableCurrent}
<a href="?{ $queryString }" title="{$title}">
{ $prefixEllipsis }{ $i }{ $suffixEllipsis }
</a>
</li>
return
<ul class="pagination">
<li>{$disableFirst}<a href="?{ request:get-query-string() => replace("page=\d+", "page=1") }" title="Go to first page">&lt;&lt;</a></li>
<li>{$disableFirst}<a href="?{ request:get-query-string() => replace("page=\d+", "page=" || ($page - 1)) }" title="Go to previous page">&lt;</a></li>
{ $pagesListItems }
<li>{$disableLast}<a href="?{ request:get-query-string() => replace("page=\d+", "page=" || ($page + 1)) }" title="Go to next page">&gt;</a></li>
<li>{$disableLast}<a href="?{ request:get-query-string() => replace("page=\d+", "page=" || $pages) }" title="Go to last page">&gt;&gt;</a></li>
</ul>
};
(:~
: Templating function for pagination.
: @see local:pagination
: @since 2.0
: @author Mathias Göbel
:)
declare function fsearch:pagination($node as node(), $model as map(*)) {
$model("pagination")
};
......@@ -71,15 +71,11 @@ declare function tgclient:getData($id as xs:string, $tgcrud-url as xs:string, $s
<http:request method="get">
<http:header name="Connection" value="close" />
</http:request>
let $getBody := http:send-request($reqGet, $reqUrl)[2]
let $request := http:send-request($reqGet, $reqUrl)
let $getBody := $request[2]
return
switch ($getBody/@mimetype)
case "text/plain" return
if ($getBody/@encoding = "URLEncoded") then
process:execute(('/usr/bin/curl',$reqUrl, "-s"), ())//line => string-join("&#13;")
else string($getBody)
default return document { $getBody/node() }
document { $getBody }
};
(:~ Returns a list of TextGrid items within a given aggregation, but only the
......@@ -224,7 +220,7 @@ map:merge(
map:entry($key, $value))
};
declare function local:soapHeader($requestName as xs:string) as node()
declare function local:soapHeader($requestName as xs:string) as node()
{
<http:header
name = "SOAP-Action"
......
......@@ -24,7 +24,7 @@ declare namespace xhtml="http://www.w3.org/1999/xhtml";
: @param $uri – a textgrid uri
: @param $sid – a valid sessionId for TextGrid
: :)
declare function tgconnect:publish( $uri as xs:string, $sid as xs:string )
declare function tgconnect:publish( $uri as xs:string, $sid as xs:string )
{
tgconnect:publish
(
......@@ -120,7 +120,7 @@ declare function tgconnect:publish( $uri as xs:string,
let $data :=
try { tgclient:getData($pubUri, $tgcrudUrl, $sid) }
catch * { error( QName("https://sade.textgrid.de/ns/error", "PUBLISH03"),
"getData failed with " || $err:code || ": " || $err:description
"getData failed for " || $pubUri || " with " || $err:code || ": " || $err:description
|| "Is your file conform to XML standard?") }
let $name := (: JING requires :)
if($data/*/namespace-uri() = "http://relaxng.org/ns/structure/1.0")
......@@ -129,7 +129,7 @@ declare function tgconnect:publish( $uri as xs:string,
let $store :=
try { xmldb:store($targetPath||"/data", $name, $data, "text/xml") }
catch * { error( QName("https://sade.textgrid.de/ns/error", "PUBLISH04"),
"storing the data failed with " || $err:code || ": " || $err:description
"storing the data for "|| $name ||" failed with " || $err:code || ": " || $err:description
|| "Is your file conform to XML standard? Typical mistakes are empty xml:id attributes.") }
let $render := (: this is where you can start with prerendering.
......@@ -166,12 +166,12 @@ declare function tgconnect:publish( $uri as xs:string,
let $data :=
try { tgclient:getData($pubUri, $tgcrudUrl, $sid) }
catch * { error( QName("https://sade.textgrid.de/ns/error", "PUBLISH05"),
"get data failed with " || $err:code || ": " || $err:description
"get data failed " || $pubUri || " with " || $err:code || ": " || $err:description
)}
let $store :=
try { xmldb:store($targetPath || '/tile', $targetUri, $data) }
catch * { error( QName("https://sade.textgrid.de/ns/error", "PUBLISH06"),
"get data failed with " || $err:code || ": " || $err:description
"get data for " || $pubUri || " failed with " || $err:code || ": " || $err:description
) }
return $targetUri
......@@ -216,10 +216,7 @@ declare function tgconnect:publish( $uri as xs:string,
xmldb:store($targetPath || "/data", $name, $text, "text/plain")
return $name
default return
error(
QName("https://sade.textgrid.de/ns/error", "PUBLISH08"),
"The publisher does not know how to handle " || string($meta//tgmd:format) || "."
)
"The publisher does not know how to handle " || string($meta//tgmd:format) || "."
else
error(
......
......@@ -18,9 +18,11 @@
<ul xmlns="http://www.w3.org/1999/xhtml">
<li class="feat">Features
<ul>
<li>Add a documentation on release procedure</li>
<li>Add documentation on how to use faceted search</li>
<li>Add documentation on how to customize the top navigation</li>
<li>Pretty print test results on command line</li>
<li>Server side pagination for search.html</li>
</ul>
</li>
<li class="bugs">Bugfixes
......
......@@ -59,6 +59,7 @@
<i class="fas fa-search fa-lg" style="color:white"/>
</span>
<input id="searchInput" type="text" class="form-control" data-template="lang:translate" data-template-content="Search" name="q"/>
<input class="hidden" name="page" value="1"/>
<button type="submit" class="btn btn-default"/>
</form>
</div>
......
......@@ -6,8 +6,6 @@
</ul>
<div class="col-md-9">
<div>
<span id="page" class="hidden" data-template="fsearch:page"/>
<span id="pages" class="hidden" data-template="fsearch:pages"/>
<div>
<div>Sie haben nach <strong>
<span id="prevQuery">
......@@ -28,7 +26,9 @@
</div>
</div>
<div>
<ul class="paginator pull-right"/> Zeige Treffer <span id="hitstart" data-template="fsearch:hitstart"/> - <span id="hitend" data-template="fsearch:hitend"/> von <span id="hitcount" data-template="fsearch:hitcount"/> Treffern </div>
Zeige Treffer <span id="hitstart" data-template="fsearch:hitstart"/> - <span id="hitend" data-template="fsearch:hitend"/> von <span id="hitcount" data-template="fsearch:hitcount"/> Treffern
</div>
<div data-template="fsearch:pagination"></div>
<form class="form-horizontal" role="form">
<div class="form-group">
<label class="col-sm-3 control-label">Sortierung nach</label>
......@@ -60,48 +60,15 @@
</div>
</div>
<div>
<ul class="paginator pull-right"/> Zeige Treffer <span id="hitstart" data-template="fsearch:hitstart"/> - <span id="hitend" data-template="fsearch:hitend"/> von <span id="hitcount" data-template="fsearch:hitcount"/> Treffern </div>
Zeige Treffer <span id="hitstart" data-template="fsearch:hitstart"/> - <span id="hitend" data-template="fsearch:hitend"/> von <span id="hitcount" data-template="fsearch:hitcount"/> Treffern
</div>
<div data-template="fsearch:pagination"></div>
</div>
</div>
</div>
</div>
<script>
document.addEventListener("DOMContentLoaded", function(event) {
// http://www.samaxes.com/2011/09/change-url-parameters-with-jquery/
/*
* queryParameters: handles the query string parameters
* queryString: the query string without the fist '?' character
* re: the regular expression
* m: holds the string matching the regular expression
*/
var queryParameters = {};
var queryString = location.search.substring(1);
var re = /([^&amp;=]+)=([^&amp;]*)/g, m;
// Creates a map with the query string parameters
while (m = re.exec(queryString)) {
queryParameters[m[1]] = m[2];
}
$('.paginator').bootstrapPaginator({
bootstrapMajorVersion: 3,
currentPage: $('#page').text(),
totalPages: $('#pages').text(),
pageUrl: function(type, page, current){
queryParameters['page'] = page;
var querystring = "";
$.each(queryParameters, function(key, val) {
querystring += key + "=" + val + "&amp;";
})
querystring = querystring.substring(0, querystring.length-1)
return window.location.pathname + '?' + querystring;
}
})
$('.facet-minus').each(function() {
$(this).html($('&lt;span class="glyphicon glyphicon-minus-sign" /&gt;'));
});
......
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