Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc improvements and additions in details view #119

Merged
merged 7 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions app/controllers/nwbib/Lobid.java
Original file line number Diff line number Diff line change
Expand Up @@ -678,6 +678,24 @@ private static String locationPolygon(String location) {
return location.contains("|") ? location.split("\\|")[1] : location;
}

/**
* @param doc The result JSON doc
* @return A mapping of item IDs (URIs) to item details (JSON strings)
*/
public static Map<String, String> itemDetails(String doc) {
JsonNode items = Json.parse(doc).findValue("hasItem");
Map<String, String> result = new HashMap<>();
if (items != null && (items.isArray() || items.isTextual())) {
Iterator<JsonNode> elements =
items.isArray() ? items.elements() : Arrays.asList(items).iterator();
while (elements.hasNext()) {
JsonNode nextItem = elements.next();
result.put(nextItem.get("id").asText(), nextItem.toString());
}
}
return result;
}

/**
* @param doc The result JSON doc
* @return A mapping of ISILs to item URIs
Expand Down
49 changes: 46 additions & 3 deletions app/views/details.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@
@import play.mvc.Controller.session
@import play.cache.Cache

@idAndLabelLink(e: JsValue) = {
<a href='@((e\"id").asOpt[String].getOrElse("--"))'>@((e\"label").asOpt[String].getOrElse("--"))</a>
}

@pageLink(last: Seq[String], key: String, label: String, tip: String) = {
@defining((last.indexOf(session(key))-1,last.indexOf(session(key))+1)) { case (prev,next) =>
<li class="@if(session(key).isEmpty){disabled}">
Expand Down Expand Up @@ -66,9 +70,9 @@
*@
@tags.search_form(q)
<div class="row" id="search-results">
@defining(Lobid.items(doc.toString)) { items =>
@defining(!(doc\\"containedIn").isEmpty && (doc\"type").toString.contains("Article")){superordination =>
<div class="col-md-12">
@defining((Lobid.items(doc.toString), Lobid.itemDetails(doc.toString))) { case (items, itemDetails) =>
@defining(items.isEmpty && !(doc\\"containedIn").isEmpty && (doc\"type").toString.contains("Article")){superordination =>
<div class="col-md-@if(items.isEmpty && !doc.toString.contains("fulltextOnline") && !superordination){12} else {8}">
<dl>
@defining((doc\"rpbId").asOpt[String].getOrElse(q)){ id =>
<dt>@tags.star_button(id) Titeldetails:
Expand All @@ -80,6 +84,45 @@
}
</dl>
</div>
@if(!items.isEmpty || doc.toString.contains("fulltextOnline") || superordination){
<div class="col-md-4" id="holdings">
<dl>
@if(doc.toString.contains("fulltextOnline")){
<dt>Online-Ressource:</dt>
<dd>
<table class="table table-striped table-condensed">
<tr>
<th style="width: 15%"></th>
<th style="width: 85%"></th>
</tr>
@result_field("Link", "fulltextOnline", doc, TableRow.LINKS)
</table>
</dd>
}
@if(superordination){
<dt>Bestandsangaben:</dt>
<dd>
<table class="table table-striped table-condensed">
<tr>
<th style="width: 40%"></th>
<th style="width: 60%"></th>
</tr>
<tr>
<td>Zum Bestand siehe:</td>
<td>@idAndLabelLink((doc\"containedIn").as[Seq[JsValue]].head)</td>
</tr>
</table>
</dd>
}
@if(!superordination && !items.isEmpty && !doc.toString.contains("fulltextOnline")){
@defining(items.size){num =>
<dt>Bestand in @num Bibliothek@if(num>1){en}:</dt>
}
<dd>@tags.items_map(items, itemDetails)</dd>
}
</dl>
</div>
}
}
}
</div>
Expand Down
134 changes: 134 additions & 0 deletions app/views/tags/items_map.scala.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
@* Copyright 2014-2024 Fabian Steeg, hbz. Licensed under the GPLv2 *@

@(items: Map[String,List[String]], itemDetails: Map[String,String])

@import play.api.libs.ws.WS
@import play.api.libs.json.JsArray
@import play.api.libs.json.Json
@import play.api.libs.json.JsValue
@import scala.concurrent._
@import ExecutionContext.Implicits.global
@import scala.concurrent.duration._
@import play.api.Play.current
@import controllers.nwbib._
@import play.api.cache.Cache

@string(value: JsValue) = { @value.asOpt[String].getOrElse("--") }

<link rel="stylesheet" href="@controllers.routes.Assets.at("stylesheets/leaflet.css")" />
<script src="@controllers.routes.Assets.at("javascripts/leaflet.js")"></script>
@*<script type="text/javascript" src="http://maps.stamen.com/js/tile.stamen.js?v1.2.4"></script>*@
<table class="table table-striped table-condensed">
<tr>
<th style="width: 30%"/>
<th style="width: 70%"/>
</tr>
</table>
<p>
<div class="items-map" id="items-map"></div>
@map_credits()
</p>
<table style="display:none;" id="table" class="table table-striped table-condensed">
</table>
@if(items.size > 1){<a href="#" style="text-decoration-line: underline; text-decoration-style: dotted;" onclick="$('#table').show(); $(this).hide()">Details zum Bestand als Liste anzeigen</a>}
<script>
var layer = L.tileLayer('https://lobid.org/tiles/{z}/{x}/{y}.png');
var rlp = new L.LatLng(49.7, 7.4)
var map = new L.Map("items-map", {
center: rlp,
zoom: 7,
maxZoom: 17,
scrollWheelZoom: true,
attributionControl: false,
zoomControl: false
});
new L.Control.Zoom({ position: 'bottomleft' }).addTo(map);
var markerCount = 0;
var tableDetails = '';
var allTableDetails = '';
var markers = {};
@markers(items)
$('#table').append(allTableDetails);
map.addLayer(layer);
</script>

@markers(items: Map[String,List[String]]) = {
@for((key,i) <- items.keySet.toList.sortWith((k1:String,k2:String)=>Lobid.compareIsil(k1,k2)).zipWithIndex;
owner = Application.CONFIG.getString("orgs.api")+"/"+key;
json = Json.parse(Lobid.cachedJsonCall(owner).toString);
ownerUrl = if((json\\"url").isEmpty) owner else (json\\"url")(0).as[String];
ownerName = if((json\\"name").isEmpty) "" else (json\\"name")(0).as[String]) {
@for((itemId,i) <- items(key).zipWithIndex;
shortItemId = itemId.substring(itemId.lastIndexOf(":") + 1, itemId.lastIndexOf("#"));
itemJson = Json.parse(itemDetails(itemId));
owners = (itemJson\\"heldBy");
if(!owners.isEmpty);
signatures = (itemJson\\"callNumber");
signature = if(signatures.isEmpty) "" else signatures(0).as[String];
urls = (itemJson\\"electronicLocator");
url = if(urls.isEmpty) "" else urls(0).as[String];
seeAlso = (itemJson\\"seeAlso");
opacLink = if(seeAlso.isEmpty) null else seeAlso(0).as[Seq[JsValue]].map(_.as[String])) {
var details = '<tr><td><i>Bibliothek:</i></td><td>'+
'<i>@if(!ownerName.isEmpty){<a href="@ownerUrl">@ownerName</a>}else{&lt;Keine Angabe&gt;}</i></td></tr>'
@if(opacLink!=null){+'<tr><td>Verfügbarkeit:</td>'+'<td><a href="@opacLink">Lokalen Katalog abfragen</a></td></tr>'};
tableDetails = details;
if(allTableDetails=='')
allTableDetails += tableDetails;
else
allTableDetails += '<tr><th style="width: 30%"/><th style="width: 70%"/></tr>' + tableDetails;
var sig = '<tr><td>@if(!signature.isEmpty){Signatur:}@if(!urls.isEmpty){Elektronische Ressource:}</td>'+
'<td>@if(!url.isEmpty){<a href="@url">@shortItemId</a>} else {@if(!signature.isEmpty){@signature}}</td></tr>';
@for(noteSeq <- (itemJson\"note").asOpt[Seq[String]]; note = noteSeq(0)) {sig += '<tr><td>Notiz:</td><td>' + '@note' + '</td></tr>';}
tableDetails += sig;
allTableDetails += sig;
}
@if(
!(json \\ "lon").isEmpty && (json \\ "lon").head.asOpt[String].isDefined &&
!(json \\ "lat").isEmpty && (json \\ "lat").head.asOpt[String].isDefined) {
@defining(i) { id =>
var lat = @string((json \\ "lat").head)
var lon = @string((json \\ "lon").head)
var latlng@(id) = L.latLng(lat, lon);
var icon@(id) = L.icon({
iconUrl: '@controllers.routes.Assets.at("javascripts/images/marker-icon-red.png")',
iconSize: [20, 30],
iconAnchor: [10, 30],
popupAnchor: [0, -30]
});
var marker@(id) = L.marker([lat, lon],{
title: "@ownerName (@key)",
icon: icon@(id)
});
markers[latlng@(id).toString()] = marker@(id);
bindPopup@(id)(tableDetails);
marker@(id).on('click', function(e) {
zoomDetails@(id)();
});
marker@(id).on('popupclose', function(e) {
map.setView(rlp, 7);
});
marker@(id).addTo(map);
markerCount++;
if(@items.size == 1){
bindPopup@(id)(allTableDetails);
zoomDetails@(id)();
}
function zoomDetails@(id)() {
map.setView(latlng@(id), 17);
marker@(id).openPopup();
}
function bindPopup@(id)(content) {
marker@(id).bindPopup(
'<table class="table-striped table-condensed">'+
content+
'</table>',
{
keepInView: true,
maxWidth: 250
});
}
}
}
}
}
12 changes: 5 additions & 7 deletions app/views/tags/map_credits.scala.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
@* Copyright 2015 Fabian Steeg, hbz. Licensed under the GPLv2 *@

<p class="small text-center">
Katalog- und Bestandsdaten von <a href="http://lobid.org">lobid.org</a> unter
<a href="http://creativecommons.org/publicdomain/zero/1.0">CC0</a> |
Kartenbilder von <a href="https://maps.wikimedia.org">Wikimedia</a>,
Kartendaten von <a href="http://openstreetmap.org">OpenStreetMap</a>
unter <a href="http://creativecommons.org/licenses/by-sa/3.0">CC-BY-SA</a>
</p>
<div class="small text-center">
Kartenbilder &amp; -daten von <a href="https://maps.wikimedia.org">Wikimedia</a> &amp;
<a href="http://openstreetmap.org">OpenStreetMap</a>,
<a href="http://creativecommons.org/licenses/by-sa/3.0">CC-BY-SA</a>
</div>
13 changes: 6 additions & 7 deletions app/views/tags/result_doc.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
types = (agents(0) \ "type").asOpt[Seq[String]].getOrElse(Seq())) {
<a title="Nach weiteren Titeln von '@label' suchen"
href='@if(types.contains("CorporateBody")){ @nwbib.routes.Application.search(corporation=id.getOrElse(label)) }else{ @nwbib.routes.Application.search(person=id.getOrElse(label)) }'/>@label</a>
@if(id.isDefined && !id.get.contains("/sw/")){<a title="Linked-Data-Quelle zu '@label' abrufen" href='@id'><span class='glyphicon glyphicon-link'></span></a>}
@if(id.isDefined && id.get.startsWith("http") && !id.get.contains("/sw/")){<a title="Linked-Data-Quelle zu '@label' abrufen" href='@id'><span class='glyphicon glyphicon-link'></span></a>}
@if(c!=cs.last){ | }
}</td>
</tr>
Expand All @@ -146,13 +146,12 @@
@for(subject <- subjects;
components = (subject \ "componentList").asOpt[Seq[JsValue]].getOrElse(Seq(subject));
component <- components;
sourceLabel = (component\"source"\"label").asOpt[String];
if !sourceLabel.getOrElse("").contains("Nordrhein-Westfälischen");
if !sourceLabel.getOrElse("").contains("Rheinland-Pfälzischen");
if !sourceLabel.getOrElse("").contains("Dewey");
label <- (component \ "label").asOpt[String];
id = (component \ "id").asOpt[String].getOrElse("")) {
<span style="white-space: nowrap;"><a title="Nach weiteren Titeln zu '@label' suchen" href='@nwbib.routes.Application.search(subject=if(id.contains("/gnd/")) {id} else {"\""+label+"\""})'/>@label</a></span>
<span style="white-space: nowrap;">
<a title="Nach weiteren Titeln zu '@label' suchen" href='@nwbib.routes.Application.search(subject=if(id.contains("/gnd/")) {id} else {"\""+label+"\""})'/>@label</a>
@if(id.startsWith("http") && !id.contains("/sw/")){<a title="Linked-Data-Quelle zu '@label' abrufen" href='@id'><span class='glyphicon glyphicon-link'></span></a>}
</span>
@if(components.last == component) {
@for(topic <- (subject\"label").asOpt[String]; hits = Lobid.getTotalHits("subject.label.raw", topic.trim, CONFIG.getString("nwbib.filter")).get(Lobid.API_TIMEOUT); if hits > 1){
| <a href='@nwbib.routes.Application.search(q="subject.label.raw:\""+topic.trim+"\"")' title="Alle @hits Titel zum Thema '@topic.trim' anzeigen"><span class='badge progress-bar-success'>@hits</span></a>
Expand Down Expand Up @@ -275,7 +274,7 @@
@raumsystematik("https://rpb.lobid.org/spatial")
@sachsystematik("http://purl.org/lobid/rpb")

@subjects((doc \ "subject").asOpt[Seq[JsValue]].getOrElse(Seq()).filter(v => !(v \ "source").toString.contains("Systematik")))
@subjects((doc \ "subject").asOpt[Seq[JsValue]].getOrElse(Seq()).filter(v => !(v \ "source").toString.matches(".*(Systematik|Notationen|Dewey).*")))

@result_field("Schlagwortfolge", "subjectChain", doc, TableRow.VALUES, valueLabel = Option(Seq()))

Expand Down
Binary file added public/javascripts/images/marker-icon-red.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.