Commit 6bddaef0 authored by Aleksandr Sharaban's avatar Aleksandr Sharaban Committed by Matija Obreza

Genesys UX 2016: filtering

parent e923f380
......@@ -23,6 +23,7 @@ import org.apache.commons.collections4.list.UnmodifiableList;
public class I18nListFilter<T> extends BasicFilter {
private List<ValueName<T>> options = new ArrayList<ValueName<T>>();
private List<Integer> counts = new ArrayList<Integer>();
public I18nListFilter(String name, DataType dataType) {
super(name, dataType, FilterType.I18NLIST);
......@@ -40,4 +41,12 @@ public class I18nListFilter<T> extends BasicFilter {
public List<ValueName<T>> getOptions() {
return options;
}
public List<Integer> getCounts() {
return counts;
}
public void setCounts(List<Integer> counts) {
this.counts = counts;
}
}
\ No newline at end of file
......@@ -18,14 +18,7 @@ package org.genesys2.server.service.impl;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.Predicate;
......@@ -122,6 +115,15 @@ public class FilterHandler {
return Collections.unmodifiableList(this.availableFilters);
}
public Map<String, GenesysFilter> mapAvailableFilters() {
Map<String, GenesysFilter> filters = new HashMap<>();
for (GenesysFilter filter: availableFilters) {
filters.put(filter.getKey(), filter);
}
return filters;
}
public GenesysFilter getFilter(String key) {
if (key.startsWith("gm:")) {
return getMethodFilter(key);
......
......@@ -35,13 +35,7 @@ import org.genesys2.server.model.impl.Crop;
import org.genesys2.server.model.impl.FaoInstitute;
import org.genesys2.server.persistence.domain.AccessionRepository;
import org.genesys2.server.persistence.domain.MethodRepository;
import org.genesys2.server.service.CropService;
import org.genesys2.server.service.FilterConstants;
import org.genesys2.server.service.GenesysFilterService;
import org.genesys2.server.service.GenesysService;
import org.genesys2.server.service.GeoService;
import org.genesys2.server.service.InstituteService;
import org.genesys2.server.service.TaxonomyService;
import org.genesys2.server.service.*;
import org.genesys2.server.service.impl.DirectMysqlQuery.MethodResolver;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilter;
import org.genesys2.server.service.impl.FilterHandler.AppliedFilters;
......@@ -52,6 +46,8 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.facet.result.Term;
import org.springframework.data.elasticsearch.core.facet.result.TermResult;
import org.springframework.jdbc.core.ArgumentPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementCreator;
......@@ -92,6 +88,9 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
@Autowired
private CropService cropService;
@Autowired
private ElasticService elasticService;
@Autowired
public void setDataSource(final DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
......@@ -192,18 +191,66 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
final List<LabelValue<String>> completed = new ArrayList<LabelValue<String>>();
if (FilterConstants.INSTCODE.equalsIgnoreCase(filter)) {
final List<FaoInstitute> faoInst = instituteService.autocomplete(ac);
for (final FaoInstitute inst : faoInst) {
completed.add(new LabelValue<String>(inst.getCode(), inst.getCode() + ", " + inst.getFullName()));
TermResult termResult = null;
try {
termResult = elasticService.termStatisticsAuto(filters, FilterConstants.INSTCODE, 20000);
} catch (SearchException e) {
LOG.error("Error occurred during search", e);
}
if (termResult != null) {
for (final FaoInstitute inst : faoInst) {
String label = inst.getCode() + ", " + inst.getFullName();
for (Term term: termResult.getTerms()) {
if (term.getTerm().equals(inst.getCode()) && term.getCount() > 0) {
label = label.concat(" (" + term.getCount() + ")");
completed.add(new LabelValue<String>(inst.getCode(), label));
break;
}
}
}
}
} else if (FilterConstants.ORGCTY_ISO3.equalsIgnoreCase(filter)) {
final List<Country> countries = geoService.autocomplete(ac);
for (final Country c : countries) {
completed.add(new LabelValue<String>(c.getCode3(), c.getCode3() + ", " + c.getName()));
TermResult termResult = null;
try {
termResult = elasticService.termStatisticsAuto(filters, FilterConstants.ORGCTY_ISO3, 20000);
} catch (SearchException e) {
LOG.error("Error occurred during search", e);
}
if (termResult != null) {
for (final Country c : countries) {
String label = c.getCode3() + ", " + c.getName();
for (Term term: termResult.getTerms()) {
if (term.getTerm().equals(c.getCode3()) && term.getCount() > 0) {
label = label.concat(" (" + term.getCount() + ")");
completed.add(new LabelValue<String>(c.getCode3(), label));
break;
}
}
}
}
} else if (FilterConstants.TAXONOMY_GENUS.equalsIgnoreCase(filter)) {
final List<String> genera = taxonomyService.autocompleteGenus(ac, crop);
for (final String value : genera) {
completed.add(new LabelValue<String>(value, value));
TermResult termResult = null;
try {
termResult = elasticService.termStatisticsAuto(filters, FilterConstants.TAXONOMY_GENUS, 20000);
} catch (SearchException e) {
LOG.error("Error occurred during search", e);
}
if (termResult != null) {
for (final String value : genera) {
String label = value;
for (Term term: termResult.getTerms()) {
if (term.getTerm().equals(value) && term.getCount() > 0) {
label = label.concat(" (" + term.getCount() + ")");
completed.add(new LabelValue<String>(value, label));
break;
}
}
}
}
} else if (FilterConstants.TAXONOMY_SPECIES.equalsIgnoreCase(filter)) {
List<String> genus = new ArrayList<>();
......@@ -216,8 +263,24 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
}
final List<String> species = taxonomyService.autocompleteSpecies(ac, crop, genus);
for (final String value : species) {
completed.add(new LabelValue<String>(value, value));
TermResult termResult = null;
try {
termResult = elasticService.termStatisticsAuto(filters, FilterConstants.TAXONOMY_SPECIES, 20000);
} catch (SearchException e) {
LOG.error("Error occurred during search", e);
}
if (termResult != null) {
for (final String value : species) {
String label = value;
for (Term term: termResult.getTerms()) {
if (term.getTerm().equals(value) && term.getCount() > 0) {
label = label.concat(" (" + term.getCount() + ")");
completed.add(new LabelValue<String>(value, label));
break;
}
}
}
}
} else if (FilterConstants.TAXONOMY_SUBTAXA.equalsIgnoreCase(filter)) {
List<String> genus = new ArrayList<>();
......@@ -237,13 +300,45 @@ public class GenesysFilterServiceImpl implements GenesysFilterService {
}
final List<String> subtaxa = taxonomyService.autocompleteSubtaxa(ac, crop, genus, species);
for (final String value : subtaxa) {
completed.add(new LabelValue<String>(value, value));
TermResult termResult = null;
try {
termResult = elasticService.termStatisticsAuto(filters, FilterConstants.TAXONOMY_SUBTAXA, 20000);
} catch (SearchException e) {
LOG.error("Error occurred during search", e);
}
if (termResult != null) {
for (final String value : subtaxa) {
String label = value;
for (Term term: termResult.getTerms()) {
if (term.getTerm().equals(value) && term.getCount() > 0) {
label = label.concat(" (" + term.getCount() + ")");
completed.add(new LabelValue<String>(value, label));
break;
}
}
}
}
} else if (FilterConstants.TAXONOMY_SCINAME.equalsIgnoreCase(filter)) {
final List<String> taxa = taxonomyService.autocompleteTaxonomy(ac);
for (final String taxonomy : taxa) {
completed.add(new LabelValue<String>(taxonomy, taxonomy));
TermResult termResult = null;
try {
termResult = elasticService.termStatisticsAuto(filters, FilterConstants.TAXONOMY_SCINAME, 20000);
} catch (SearchException e) {
LOG.error("Error occurred during search", e);
}
if (termResult != null) {
for (final String taxonomy : taxa) {
String label = taxonomy;
for (Term term: termResult.getTerms()) {
if (term.getTerm().equals(taxonomy) && term.getCount() > 0) {
label = label.concat(" (" + term.getCount() + ")");
completed.add(new LabelValue<String>(taxonomy, label));
break;
}
}
}
}
} else {
throw new RuntimeException("No autocompleter for " + filter);
......
......@@ -206,6 +206,8 @@ faoInstitute.wiewsLink={0} details on FAO WIEWS website
view.accessions=Browse accessions
view.datasets=View datasets
paged.pageOfPages=Page {0} of {1}
paged.ofPages=of {0} pages
paged.resultsPerPage=Show results / page:
paged.totalElements={0} entries
accessions.number={0} accessions
......@@ -445,6 +447,7 @@ filter.internal.message.and={0} and {0}
filter.internal.message.more=More than {0}
filter.internal.message.less=Less than {0}
filter.lists=Listed on accession list
filter.more-filters=More filters
columns.add=Change displayed columns
columns.apply=Apply
......
......@@ -204,6 +204,8 @@ faoInstitute.wiewsLink={0} подробностей на веб-сайте FAO W
view.accessions=Просмотр образцов
view.datasets=Просмотр наборов данных
paged.pageOfPages=Страница {0} из {1}
paged.ofPages=из {0} страниц
paged.resultsPerPage=Показать результаты / странице:
paged.totalElements={0} записей
accessions.number={0} образцов
......@@ -443,6 +445,7 @@ filter.internal.message.and={0} и {0}
filter.internal.message.more=Больше чем {0}
filter.internal.message.less=Меньше чем {0}
filter.lists=Уже есть в списке выбранного
filter.more-filters=Больше фильтров
columns.add=Измените отображаемые столбцы
columns.apply=Применить
......
......@@ -285,7 +285,12 @@ var GenesysFilterUtil = {
}
var div = '<div class="filtval complex" x-key="' + normKey + jsonValue + '" i-key="' + key + '">' + value + '</div>';
$(element).parents('.filter-block').find('.filter-values').append(div);
//$(element).parents('.filter-block').find('.filter-values').append(div);
if (key === 'geo.latitude' || key === 'geo.longitude' || key === 'geo.elevation') {
$(element).parent().parent().parent().after(div);
} else {
$(element).parent().parent().parent().find('button.applyBtn').before(div);
}
},
// remove value from json array
removeValue : function(value, key, jsonData) {
......@@ -331,6 +336,7 @@ var GenesysFilterUtil = {
$.ajax('/' + document.documentElement.lang + '/1/additional-filter', {
type : 'GET',
data : 'filter=' + filter,
async: false,
success : function(data) {
jsonData[filter] = [];
......@@ -500,7 +506,7 @@ var GenesysFilter = {
var key = $(element).attr('i-key');
delete jsonData[key];
// Clear previous crop selection
element.parent().parent().parent().parent().find('.complex').remove();
element.parent().find('.complex').remove();
if (value !== null) {
GenesysFilterUtil.appendHtml(key, value, value, element);
......@@ -516,7 +522,7 @@ var GenesysFilter = {
var normKey = GenesysFilter.normKey(key);
var inputId = '#' + normKey + '_input';
var value = $(element).parent().find(inputId).val();
var value = $(element).parent().parent().find(inputId).val();
if (value === '') {
return;
}
......
This diff is collapsed.
<c:set var="string" value="${value}"/>
<c:if test="${fn:contains(value, 'range')}">
<c:set var="string" value="${fn:replace(value,'{range=[',between)}"/>
<c:set var="string" value="${fn:replace(string,',',varEnd)}"/>
<c:set var="string" value="${fn:replace(string,']}','')}"/>
<c:set var="value" value="${fn:replace(value,'{','{\"')}"/>
<c:set var="value" value="${fn:replace(value,'=','\":')}"/>
</c:if>
<c:if test="${fn:contains(value, 'min')}">
<c:set var="string" value="${fn:replace(value,'{min=',moreThan)}"/>
<c:set var="string" value="${fn:replace(string,'}','')}"/>
<c:set var="value" value="${fn:replace(value,'{','{\"')}"/>
<c:set var="value" value="${fn:replace(value,'=','\":')}"/>
</c:if>
<c:if test="${fn:contains(value, 'max')}">
<c:set var="string" value="${fn:replace(value,'{max=',lessThan)}"/>
<c:set var="string" value="${fn:replace(string,'}','')}"/>
<c:set var="value" value="${fn:replace(value,'{','{\"')}"/>
<c:set var="value" value="${fn:replace(value,'=','\":')}"/>
</c:if>
<c:if test="${fn:contains(value, 'like')}">
<c:set var="string" value="${fn:replace(value,'{like=', like)}"/>
<c:set var="string" value="${fn:replace(string,'}','')}"/>
<c:set var="value" value="${fn:replace(value,'{','{\"')}"/>
<c:set var="value" value="${fn:replace(value,'=','\":\"')}"/>
<c:set var="value" value="${fn:replace(value,'}','\"}')}"/>
</c:if>
<c:if test="${fn:contains(value, 'true')}">
<c:set var="string" value="${fn:replace(value,'true', varTrue)}"/>
</c:if>
<c:if test="${fn:contains(value, 'false')}">
<c:set var="string" value="${fn:replace(value,'false', varFalse)}"/>
</c:if>
<c:if test="${string==null}">
<c:set var="string" value="${varNull}"/>
<c:set var="value" value="null"/>
</c:if>
<c:if test="${appliedFilter.key=='storage'}">
<spring:message code='accession.storage.${value}' var="string"/>
</c:if>
<c:if test="${appliedFilter.key=='sampStat'}">
<spring:message code='accession.sampleStatus.${value}' var="string"/>
</c:if>
<div class="filtval complex" x-key="<c:out value="${normalizedKey}" /><c:out value="${value}"/>"
i-key="<c:out value="${filter.key}" />"><c:out value="${string}"/></div>
<c:remove var="string"/>
\ No newline at end of file
<%@page contentType="text/javascript" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
var messages = new Array();
<c:forEach var="key" items="${keys}">
messages["<spring:message text='${key}' javaScriptEscape='true'/>"] = "<spring:message code='${key}' javaScriptEscape='true' />";
</c:forEach>
<c:forEach var="country" items="${countries}">
messages["geo.iso3166-3.<spring:message text='${country.getCode3()}' javaScriptEscape='true'/>"] = "<c:out value='${country.getName(locale)}'/>";
</c:forEach>
\ No newline at end of file
......@@ -7,3 +7,4 @@
<%@ taglib prefix="local" tagdir="/WEB-INF/tags" %>
<%@ taglib prefix="cms" tagdir="/WEB-INF/tags/cms" %>
<%@ taglib prefix="gui" tagdir="/WEB-INF/tags/gui" %>
<%@ taglib prefix="filters" tagdir="/WEB-INF/tags/filters"%>
<%@ tag description="Display filter" pageEncoding="UTF-8" %>
<%@ tag body-content="empty" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ attribute name="filter" required="true" type="org.genesys2.server.model.filters.GenesysFilter" %>
<%@ attribute name="filterMap" required="true" type="java.util.Map" %>
<%@ attribute name="appliedFilters" required="true" type="org.genesys2.server.service.impl.FilterHandler.AppliedFilters" %>
<%@ attribute name="wrap" required="true" type="java.lang.Boolean" %>
<spring:message code='filter.internal.message.between' var="between" arguments=" "/>
<spring:message code='filter.internal.message.and' var="varEnd" arguments=" "/>
<spring:message code='filter.internal.message.more' var="moreThan" arguments=" "/>
<spring:message code='filter.internal.message.less' var="lessThan" arguments=" "/>
<spring:message code='filter.internal.message.like' var="like" arguments=" "/>
<spring:message code='boolean.true' var="varTrue"/>
<spring:message code='boolean.false' var="varFalse"/>
<spring:message code='boolean.null' var="varNull"/>
<c:if test="${wrap}">
<div class="input-group">
</c:if>
<c:set var="normalizedKey" value="${filter.key.replace('.', '-').replace(':', '_')}"/>
<c:set var="appliedFilter" value="${appliedFilters.get(filter.key)}"/>
<div class="input-group">
<input id="<c:out value="${normalizedKey}" />_input_1" class="span5 form-control"
type="text"/>
<input id="<c:out value="${normalizedKey}" />_input_2" class="span5 form-control"
type="text"/>
<span class="input-group-btn">
<button class="btn notimportant filter-range"
norm-key="<c:out value="${normalizedKey}" />"
i-key="<c:out value="${filter.key}" />">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>
</button>
</span>
</div>
<c:if test="${wrap}">
</div>
</c:if>
<c:forEach items="${filterMap[appliedFilter.key]}" var="value">
<%@include file="/WEB-INF/jsp/accession/filtval.jspf" %>
</c:forEach>
\ No newline at end of file
This diff is collapsed.
<%@ tag description="Display filter group" pageEncoding="UTF-8" %>
<%@ tag body-content="scriptless" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<div class="col-lg-3 col-md-3 col-sm-3 col-xs-12 filters">
<div class="panel-group" id="accordion">
<div class="panel panel-default" id="panelFilters">
<div class="panel-heading">
<h4 class="panel-title"><a data-toggle="collapse" href="#collapseFilters">
<spring:message code="filters.toggle-filters" />
</a></h4>
</div>
<div id="collapseFilters" class="panel-collapse collapse in">
<div class="panel-body">
<div class="panel-group">
<jsp:doBody/>
</div>
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
<%@ tag description="Display pagination" pageEncoding="UTF-8" %>
<%@ tag body-content="empty" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags" %>
<%@ attribute name="pagedData" required="true" type="org.springframework.data.domain.Page" %>
<%@ attribute name="jsonFilter" required="true" type="java.lang.String" %>
<nav class="text-center pull-left">
<form method="get" action="">
<ul class="pagination pagination-lg">
<li>
<span class="results">
<spring:message code="accessions.number" arguments="${pagedData.totalElements}"/>
</span>
</li>
<li>
<span aria-label="< Previous" class="firstPage">
<span aria-hidden="true">
<a href="<spring:url value=""><spring:param name="page" value="1" /><spring:param name="filter" value="${jsonFilter}" /></spring:url>">
&laquo;
</a>
</span>
</span>
</li>
<li>
<span aria-label="< Previous" class="previousPage">
<span aria-hidden="true">
<a href="<spring:url value=""><spring:param name="page" value="${pagedData.number eq 0 ? 1 : pagedData.number}" /><spring:param name="filter" value="${jsonFilter}" /></spring:url>">
&lsaquo;
</a>
</span>
</span>
</li>
<li>
<span class="pagination-input">
<input class="form-control" style="display: inline; max-width: 5em; text-align: center"
type="text" name="page" value="${pagedData.number + 1}"/>
</span>
</li>
<li>
<span aria-label="Next >" class="nextPage">
<span aria-hidden="true">
<a href="<spring:url value=""><spring:param name="page" value="${pagedData.number + 2}" /><spring:param name="filter" value="${jsonFilter}" /></spring:url>">
&rsaquo;
</a>
</span>
</span>
</li>
<li>
<span aria-label="Next >" class="lastPage">
<span aria-hidden="true">
<a href="<spring:url value=""><spring:param name="page" value="${pagedData.totalPages}" /><spring:param name="filter" value="${jsonFilter}" /></spring:url>">
&raquo;
</a>
</span>
</span>
</li>
<li>
<span class="totalPages">
<spring:message code="paged.ofPages" arguments="${pagedData.totalPages}"/>
</span>
</li>
</ul>
<input type="hidden" name="filter" value="<c:out value="${jsonFilter}" />"/>
</form>
</nav>
\ No newline at end of file
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