Commit 21d252ae authored by Jean-Baptiste Nizet's avatar Jean-Baptiste Nizet
Browse files

feat: start working on site card

xrefs missing, latitude/longitude TODO
parent 9675514a
package fr.inra.urgi.faidare.web.site;
import fr.inra.urgi.faidare.api.NotFoundException;
import fr.inra.urgi.faidare.config.FaidareProperties;
import fr.inra.urgi.faidare.domain.brapi.v1.data.BrapiAdditionalInfo;
import fr.inra.urgi.faidare.domain.data.LocationVO;
import fr.inra.urgi.faidare.repository.es.LocationRepository;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;
/**
* Controller used to display a site card based on its ID.
* @author JB Nizet
*/
@Controller
@RequestMapping("/sites")
public class SiteController {
private final LocationRepository locationRepository;
private final FaidareProperties faidareProperties;
public SiteController(LocationRepository locationRepository,
FaidareProperties faidareProperties) {
this.locationRepository = locationRepository;
this.faidareProperties = faidareProperties;
}
@GetMapping("/{siteId}")
public ModelAndView site(@PathVariable("siteId") String siteId) {
// LocationVO site = locationRepository.getById(siteId);
LocationVO site = createSite();
if (site == null) {
throw new NotFoundException("Site with ID " + siteId + " not found");
}
return new ModelAndView("site",
"model",
new SiteModel(site, faidareProperties.getByUri(site.getSourceUri())));
}
private LocationVO createSite() {
LocationVO site = new LocationVO();
site.setLocationName("France");
site.setSourceUri("https://urgi.versailles.inrae.fr/gnpis");
site.setUri("Test URI");
site.setUrl("https://google.com");
site.setLatitude(45.65);
site.setLongitude(1.34);
BrapiAdditionalInfo additionalInfo = new BrapiAdditionalInfo();
additionalInfo.addProperty("Slope", 4.32);
additionalInfo.addProperty("Distance to city", "3 km");
additionalInfo.addProperty("foo", "bar");
additionalInfo.addProperty("baz", "zing");
additionalInfo.addProperty("blob", null);
site.setAdditionalInfo(additionalInfo);
return site;
}
}
package fr.inra.urgi.faidare.web.site;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import fr.inra.urgi.faidare.domain.data.LocationVO;
import fr.inra.urgi.faidare.domain.datadiscovery.data.DataSource;
/**
* TODO add javadoc
*
* @author JB Nizet
*/
public final class SiteModel {
private static final Set<String> IGNORED_PROPERTIES =
new HashSet<>(Arrays.asList("Site status",
"Coordinates precision",
"Slope",
"Exposure",
"Geographical location",
"Distance to city",
"Direction from city",
"Environment type",
"Topography",
"Comment"));
private final LocationVO site;
private final DataSource source;
private final Map<String, Object> additionalInfo;
private final List<Map.Entry<String, Object>> additionalInfoProperties;
public SiteModel(LocationVO site, DataSource source) {
this.site = site;
this.source = source;
this.additionalInfo = site.getAdditionalInfo() == null ? Collections.emptyMap() : site.getAdditionalInfo().getProperties();
this.additionalInfoProperties =
this.additionalInfo
.entrySet()
.stream()
.filter(entry -> !IGNORED_PROPERTIES.contains(entry.getKey()))
.filter(entry -> entry.getValue() != null && !entry.getValue().toString().isEmpty())
.sorted(Map.Entry.comparingByKey())
.collect(Collectors.toList());
}
public LocationVO getSite() {
return site;
}
public DataSource getSource() {
return source;
}
public Map<String, Object> getAdditionalInfo() {
return this.additionalInfo;
}
public Object getSiteStatus() {
return this.additionalInfo.get("Site status");
}
public Object getCoordinatesPrecision() {
return this.additionalInfo.get("Coordinates precision");
}
public Object getGeographicalLocation() {
return this.additionalInfo.get("Geographical location");
}
public Object getSlope() {
return this.additionalInfo.get("Slope");
}
public Object getExposure() {
return this.additionalInfo.get("Exposure");
}
public Object getTopography() {
return this.additionalInfo.get("Topography");
}
public Object getEnvironmentType() {
return this.additionalInfo.get("Environment type");
}
public Object getDistanceToCity() {
return this.additionalInfo.get("Distance to city");
}
public Object getDirectionFromCity() {
return this.additionalInfo.get("Direction from city");
}
public Object getComment() {
return this.additionalInfo.get("Comment");
}
public List<Map.Entry<String, Object>> getAdditionalInfoProperties() {
return additionalInfoProperties;
}
}
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>
<div th:fragment="row(label, content)" class="row py-2">
<div class="col-md-4 label pb-1 pb-md-0" th:text="${label}"></div>
<div class="col">
<th:block th:replace="${content}" />
</div>
</div>
<div th:fragment="text-row(label, text)" th:if="${!#strings.isEmpty(text)}" class="row py-2">
<div class="col-md-4 label pb-1 pb-md-0" th:text="${label}"></div>
<div class="col" th:text="${text}"></div>
</div>
</body>
</html>
......@@ -7,6 +7,7 @@
<meta content="width=device-width, initial-scale=1" name="viewport" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-KyZXEAg3QhqLMpG8r+8fhAXLRk2vvoC2f3B09zVXn8CA5QIVfZOJ3BCsw2P0p/We" crossorigin="anonymous">
<link th:href="@{/assets/style.css}" rel="stylesheet">
<link rel="shortcut icon" th:href="@{/static/assets/images/favicon.ico}" type="image/x-icon" />
</head>
......
<!DOCTYPE html>
<html
xmlns:th="http://www.thymeleaf.org"
xmlns:biom="http://www.thymeleaf.org"
th:replace="~{layout/main :: layout(title=~{::title}, content=~{::main})}"
>
<head>
<title>Site <th:block th:text="${model.site.locationName}" /></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<main>
<h1>Site <th:block th:text="${model.site.locationName}" /></h1>
<div th:if="${model.site.uri && !model.site.uri.startsWith('urn:')}"
th:replace="fragments/row::text-row(label='Permanent unique identifier', text=${model.site.uri})">
</div>
<div th:if="${model.source}"
th:replace="fragments/row::row(label='Source', content=~{::#source}, text='')">
<a id="source" target="_blank" th:href="${model.source.url}">
<img style="max-height: 60px;" th:src="${model.source.image}" th:alt="${model.source.name} + ' logo'" />
</a>
</div>
<div th:if="${model.site.url && model.source}"
th:replace="fragments/row::row(label='Data link', content=~{::#url}, text='')">
<a id="url" target="_blank" th:href="${model.site.url}">
Link to this site on <th:block th:text="${model.source.name}" />
</a>
</div>
<div th:replace="fragments/row::text-row(label='Abbreviation', text=${model.site.abbreviation})"></div>
<div th:replace="fragments/row::text-row(label='Type', text=${model.site.locationType})"></div>
<div th:replace="fragments/row::text-row(label='Status', text=${model.siteStatus})"></div>
<div th:replace="fragments/row::text-row(label='Institution/Landowner', text=${model.site.instituteName})"></div>
<div th:replace="fragments/row::text-row(label='Institution address', text=${model.site.instituteAddress})"></div>
<div th:replace="fragments/row::text-row(label='Coordinates precision', text=${model.coordinatesPrecision})"></div>
<div th:if="${model.site.latitude}"
th:replace="fragments/row::text-row(label='Latitude', text=${model.site.latitude + ' - TODO in degrees'})"></div>
<div th:if="${model.site.longitude}"
th:replace="fragments/row::text-row(label='Longitude', text=${model.site.longitude + ' - TODO in degrees'})"></div>
<div th:replace="fragments/row::text-row(label='Geographical location', text=${model.geographicalLocation})"></div>
<div th:if="${model.site.countryName && !model.geographicalLocation}"
th:replace="fragments/row::text-row(label='Country name', text=${model.site.countryName})"></div>
<div th:if="${model.site.countryCode && !model.geographicalLocation}"
th:replace="fragments/row::text-row(label='Country code', text=${model.site.countryName})"></div>
<div th:replace="fragments/row::text-row(label='Altitude', text=${model.site.altitude})"></div>
<div th:replace="fragments/row::text-row(label='Slope', text=${model.slope})"></div>
<div th:replace="fragments/row::text-row(label='Exposure', text=${model.exposure})"></div>
<div th:replace="fragments/row::text-row(label='Topography', text=${model.topography})"></div>
<div th:replace="fragments/row::text-row(label='Environment type', text=${model.environmentType})"></div>
<div th:replace="fragments/row::text-row(label='Distance to city', text=${model.distanceToCity})"></div>
<div th:replace="fragments/row::text-row(label='Direction from city', text=${model.directionFromCity})"></div>
<div th:replace="fragments/row::text-row(label='Comment', text=${model.comment})"></div>
<h2>Additional info</h2>
<th:block th:each="prop : ${model.additionalInfoProperties}">
<div th:replace="fragments/row::text-row(label=${prop.key}, text=${prop.value})"></div>
</th:block>
</main>
</body>
</html>
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