#15 add sort options

Sun, 08 Jan 2023 19:32:11 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 08 Jan 2023 19:32:11 +0100
changeset 271
f8f5e82944fa
parent 270
8c088c628a20
child 272
edb6f12b334b

#15 add sort options

src/main/kotlin/de/uapcore/lightpit/servlet/ProjectServlet.kt file | annotate | diff | comparison | revisions
src/main/kotlin/de/uapcore/lightpit/types/IssueCategory.kt file | annotate | diff | comparison | revisions
src/main/kotlin/de/uapcore/lightpit/viewmodel/Issues.kt file | annotate | diff | comparison | revisions
src/main/resources/localization/strings.properties file | annotate | diff | comparison | revisions
src/main/resources/localization/strings_de.properties file | annotate | diff | comparison | revisions
src/main/webapp/WEB-INF/changelogs/changelog-de.jspf file | annotate | diff | comparison | revisions
src/main/webapp/WEB-INF/changelogs/changelog.jspf file | annotate | diff | comparison | revisions
src/main/webapp/WEB-INF/jspf/issue-filter.jspf file | annotate | diff | comparison | revisions
src/main/webapp/WEB-INF/jspf/sort-box.jspf file | annotate | diff | comparison | revisions
     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}">&uarr;</c:if>
    9.16 +                <c:if test="${not criteria.asc}">&darr;</c:if>
    9.17 +            </option>
    9.18 +        </c:forEach>
    9.19 +    </select>
    9.20 +</div>

mercurial