Sun, 08 Jan 2023 19:32:11 +0100
#15 add sort options
1.1 --- a/src/main/kotlin/de/uapcore/lightpit/servlet/ProjectServlet.kt Sun Jan 08 17:57:05 2023 +0100 1.2 +++ b/src/main/kotlin/de/uapcore/lightpit/servlet/ProjectServlet.kt Sun Jan 08 19:32:11 2023 +0100 1.3 @@ -191,13 +191,7 @@ 1.4 val relationsMap = if (needRelationsMap) dao.getIssueRelationMap(project, filter.includeDone) else emptyMap() 1.5 1.6 val issues = dao.listIssues(project, filter.includeDone, version, component) 1.7 - .sortedWith( 1.8 - IssueSorter( 1.9 - IssueSorter.Criteria(IssueSorter.Field.DONE), 1.10 - IssueSorter.Criteria(IssueSorter.Field.ETA), 1.11 - IssueSorter.Criteria(IssueSorter.Field.UPDATED, false) 1.12 - ) 1.13 - ) 1.14 + .sortedWith(IssueSorter(filter.sortPrimary, filter.sortSecondary, filter.sortTertiary)) 1.15 .filter { 1.16 (!filter.onlyMine || (it.assignee?.username ?: "") == (http.remoteUser ?: "<Anonymous>")) && 1.17 (!filter.onlyBlocker || (relationsMap[it.id]?.any { (_,type) -> type.blocking }?:false)) &&
2.1 --- a/src/main/kotlin/de/uapcore/lightpit/types/IssueCategory.kt Sun Jan 08 17:57:05 2023 +0100 2.2 +++ b/src/main/kotlin/de/uapcore/lightpit/types/IssueCategory.kt Sun Jan 08 19:32:11 2023 +0100 2.3 @@ -26,5 +26,5 @@ 2.4 package de.uapcore.lightpit.types 2.5 2.6 enum class IssueCategory { 2.7 - Feature, Improvement, Bug, Task, Test 2.8 + Bug, Feature, Improvement, Task, Test 2.9 } 2.10 \ No newline at end of file
3.1 --- a/src/main/kotlin/de/uapcore/lightpit/viewmodel/Issues.kt Sun Jan 08 17:57:05 2023 +0100 3.2 +++ b/src/main/kotlin/de/uapcore/lightpit/viewmodel/Issues.kt Sun Jan 08 19:32:11 2023 +0100 3.3 @@ -38,10 +38,20 @@ 3.4 3.5 class IssueSorter(private vararg val criteria: Criteria) : Comparator<Issue> { 3.6 enum class Field { 3.7 - DONE, PHASE, STATUS, CATEGORY, ETA, UPDATED, CREATED 3.8 + DONE, PHASE, STATUS, CATEGORY, ETA, UPDATED, CREATED; 3.9 + 3.10 + val resourceKey: String by lazy { 3.11 + if (this == DONE) "issue.filter.sort.done" 3.12 + else if (this == PHASE) "issue.filter.sort.phase" 3.13 + else "issue.${this.name.lowercase()}" 3.14 + } 3.15 } 3.16 3.17 - data class Criteria(val field: Field, val asc: Boolean = true) 3.18 + data class Criteria(val field: Field, val asc: Boolean = true) { 3.19 + override fun toString(): String { 3.20 + return "$field.$asc" 3.21 + } 3.22 + } 3.23 3.24 override fun compare(left: Issue, right: Issue): Int { 3.25 if (left == right) { 3.26 @@ -170,6 +180,7 @@ 3.27 3.28 val issueStatus = IssueStatus.values() 3.29 val issueCategory = IssueCategory.values() 3.30 + val sortCriteria = IssueSorter.Field.values().flatMap { listOf(IssueSorter.Criteria(it, true), IssueSorter.Criteria(it, false)) } 3.31 val flagIncludeDone = "f.0" 3.32 val flagMine = "f.1" 3.33 val flagBlocker = "f.2" 3.34 @@ -180,6 +191,26 @@ 3.35 val status: List<IssueStatus> = evalEnum(http, "s") 3.36 val category: List<IssueCategory> = evalEnum(http, "c") 3.37 3.38 + val sortPrimary: IssueSorter.Criteria = evalSort(http, "primary", IssueSorter.Criteria(IssueSorter.Field.DONE)) 3.39 + val sortSecondary: IssueSorter.Criteria = evalSort(http, "secondary", IssueSorter.Criteria(IssueSorter.Field.ETA)) 3.40 + val sortTertiary: IssueSorter.Criteria = evalSort(http, "tertiary", IssueSorter.Criteria(IssueSorter.Field.UPDATED, false)) 3.41 + 3.42 + private fun evalSort(http: HttpRequest, prio: String, defaultValue: IssueSorter.Criteria): IssueSorter.Criteria { 3.43 + val param = http.param("sort_$prio") 3.44 + if (param != null) { 3.45 + http.session.removeAttribute("sort_$prio") 3.46 + val p = param.split(".") 3.47 + if (p.size > 1) { 3.48 + try { 3.49 + http.session.setAttribute("sort_$prio", IssueSorter.Criteria(enumValueOf(p[0]), p[1].toBoolean())) 3.50 + } catch (_:IllegalArgumentException) { 3.51 + // ignore malfored values 3.52 + } 3.53 + } 3.54 + } 3.55 + return http.session.getAttribute("sort_$prio") as IssueSorter.Criteria? ?: defaultValue 3.56 + } 3.57 + 3.58 private fun evalFlag(http: HttpRequest, name: String): Boolean { 3.59 val param = http.paramArray("filter") 3.60 if (param.isNotEmpty()) {
4.1 --- a/src/main/resources/localization/strings.properties Sun Jan 08 17:57:05 2023 +0100 4.2 +++ b/src/main/resources/localization/strings.properties Sun Jan 08 19:32:11 2023 +0100 4.3 @@ -86,11 +86,11 @@ 4.4 issue.created=Created 4.5 issue.description=Description 4.6 issue.eta=ETA 4.7 -issue.filter=Filter 4.8 +issue.filter=Filter and Sorting 4.9 issue.filter.blocking=show only blocking 4.10 issue.filter.done=show resolved 4.11 issue.filter.mine=only assigned to me 4.12 -issue.filter.more=more filters 4.13 +issue.filter.more=more filter and sort options 4.14 issue.id=Issue ID 4.15 issue.relations=Relations 4.16 issue.relations.issue=Issue 4.17 @@ -177,4 +177,9 @@ 4.18 version.status=Status 4.19 version=Version 4.20 issue.relations.type.DefectOf=defect of 4.21 -issue.relations.type.DefectOf.rev=defect 4.22 \ No newline at end of file 4.23 +issue.relations.type.DefectOf.rev=defect 4.24 +issue.filter.sort.primary=Primary Order 4.25 +issue.filter.sort.secondary=Secondary Order 4.26 +issue.filter.sort.tertiary=Tertiary Order 4.27 +issue.filter.sort.done=resolved 4.28 +issue.filter.sort.phase=Phase 4.29 \ No newline at end of file
5.1 --- a/src/main/resources/localization/strings_de.properties Sun Jan 08 17:57:05 2023 +0100 5.2 +++ b/src/main/resources/localization/strings_de.properties Sun Jan 08 19:32:11 2023 +0100 5.3 @@ -86,11 +86,11 @@ 5.4 issue.created=Erstellt 5.5 issue.description=Beschreibung 5.6 issue.eta=Zieldatum 5.7 -issue.filter=Filter 5.8 +issue.filter=Filter und Sortierung 5.9 issue.filter.blocking=zeige nur blockierende 5.10 issue.filter.done=zeige erledigte 5.11 issue.filter.mine=nur mir zugewiesene 5.12 -issue.filter.more=mehr Filter 5.13 +issue.filter.more=mehr Filter und Sortieroptionen 5.14 issue.id=Vorgangs-ID 5.15 issue.relations=Beziehungen 5.16 issue.relations.issue=Vorgang 5.17 @@ -178,3 +178,8 @@ 5.18 version=Version 5.19 issue.relations.type.DefectOf.rev=Fehler 5.20 issue.relations.type.DefectOf=Fehler von 5.21 +issue.filter.sort.primary=Prim\u00e4re Sortierung 5.22 +issue.filter.sort.secondary=Sekund\u00e4re Sortierung 5.23 +issue.filter.sort.tertiary=Terti\u00e4re Sortierung 5.24 +issue.filter.sort.done=erledigt 5.25 +issue.filter.sort.phase=Phase
6.1 --- a/src/main/webapp/WEB-INF/changelogs/changelog-de.jspf Sun Jan 08 17:57:05 2023 +0100 6.2 +++ b/src/main/webapp/WEB-INF/changelogs/changelog-de.jspf Sun Jan 08 19:32:11 2023 +0100 6.3 @@ -32,7 +32,7 @@ 6.4 <li>Mehrfachauswahl für Versionen im Vorgang entfernt.</li> 6.5 <li>RSS Feeds für Projekte hinzugefügt.</li> 6.6 <li>Vorgangsansicht vereinfacht.</li> 6.7 - <li>Filteroptionen hinzugefügt.</li> 6.8 + <li>Filter- und Sortieroptionen hinzugefügt.</li> 6.9 <li>Möglichkeit zum Deaktivieren einer Komponente hinzugefügt.</li> 6.10 <li>Datum der Veröffentlichung und des Supportendes zu Versionen hinzugefügt.</li> 6.11 <li>Gesamtanzahl der Kommentare wird nun angezeigt.</li>
7.1 --- a/src/main/webapp/WEB-INF/changelogs/changelog.jspf Sun Jan 08 17:57:05 2023 +0100 7.2 +++ b/src/main/webapp/WEB-INF/changelogs/changelog.jspf Sun Jan 08 19:32:11 2023 +0100 7.3 @@ -32,7 +32,7 @@ 7.4 <li>Remove multi selection of versions within an issue.</li> 7.5 <li>Add RSS feeds for projects.</li> 7.6 <li>Simplify issue view.</li> 7.7 - <li>Add filtering options.</li> 7.8 + <li>Add filtering and sorting options.</li> 7.9 <li>Add possibility to deactivate a component.</li> 7.10 <li>Add release and end of life dates to versions.</li> 7.11 <li>Add the total number of comments to the caption.</li>
8.1 --- a/src/main/webapp/WEB-INF/jspf/issue-filter.jspf Sun Jan 08 17:57:05 2023 +0100 8.2 +++ b/src/main/webapp/WEB-INF/jspf/issue-filter.jspf Sun Jan 08 19:32:11 2023 +0100 8.3 @@ -1,6 +1,3 @@ 8.4 -<%-- 8.5 - 8.6 ---%> 8.7 <form method="GET" id="filter-form"> 8.8 <div> 8.9 <label> 8.10 @@ -53,6 +50,15 @@ 8.11 </c:forEach> 8.12 </select> 8.13 </div> 8.14 + <c:set var="sortPriority" value="primary"/> 8.15 + <c:set var="currentSort" value="${viewmodel.filter.sortPrimary}"/> 8.16 + <%@include file="sort-box.jspf"%> 8.17 + <c:set var="sortPriority" value="secondary"/> 8.18 + <c:set var="currentSort" value="${viewmodel.filter.sortSecondary}"/> 8.19 + <%@include file="sort-box.jspf"%> 8.20 + <c:set var="sortPriority" value="tertiary"/> 8.21 + <c:set var="currentSort" value="${viewmodel.filter.sortTertiary}"/> 8.22 + <%@include file="sort-box.jspf"%> 8.23 </div> 8.24 <div class="medskip"> 8.25 <button name="filter" type="submit"><fmt:message key="button.apply"/></button>
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/src/main/webapp/WEB-INF/jspf/sort-box.jspf Sun Jan 08 19:32:11 2023 +0100 9.3 @@ -0,0 +1,17 @@ 9.4 +<%-- 9.5 +Page attribute: 9.6 + sortPriority: String 9.7 + currentSort: IssueSorter.Criteria 9.8 +--%> 9.9 +<div style="display: inline-block"> 9.10 + <label class="caption" style="display:block;" for="sort_${sortPriority}"><fmt:message key="issue.filter.sort.${sortPriority}"/></label> 9.11 + <select id="sort_${sortPriority}" name="sort_${sortPriority}"> 9.12 + <c:forEach var="criteria" items="${viewmodel.filter.sortCriteria}"> 9.13 + <option value="${criteria}" <c:if test="${currentSort eq criteria}">selected</c:if> > 9.14 + <fmt:message key="${criteria.field.resourceKey}"/> 9.15 + <c:if test="${criteria.asc}">↑</c:if> 9.16 + <c:if test="${not criteria.asc}">↓</c:if> 9.17 + </option> 9.18 + </c:forEach> 9.19 + </select> 9.20 +</div>