Mon, 05 Aug 2024 19:17:36 +0200
add more filter options and cross-links
relates to issue #397
--- a/src/main/kotlin/de/uapcore/lightpit/types/IssueStatus.kt Mon Aug 05 18:40:47 2024 +0200 +++ b/src/main/kotlin/de/uapcore/lightpit/types/IssueStatus.kt Mon Aug 05 19:17:36 2024 +0200 @@ -36,4 +36,6 @@ Rejected(IssueStatusPhase.Done), Withdrawn(IssueStatusPhase.Done), Duplicate(IssueStatusPhase.Done); -} \ No newline at end of file +} + +fun issueStatusOf(phase: IssueStatusPhase) = IssueStatus.entries.filter { it.phase == phase } \ No newline at end of file
--- a/src/main/kotlin/de/uapcore/lightpit/viewmodel/Issues.kt Mon Aug 05 18:40:47 2024 +0200 +++ b/src/main/kotlin/de/uapcore/lightpit/viewmodel/Issues.kt Mon Aug 05 19:17:36 2024 +0200 @@ -220,7 +220,7 @@ val includeDone: Boolean = evalFlag(http, flagIncludeDone) val onlyMine: Boolean = evalFlag(http, flagMine) val onlyBlocker: Boolean = evalFlag(http, flagBlocker) - val status: List<IssueStatus> = evalEnum(http, "s") + val status: List<IssueStatus> = evalEnum(http, "s") { issueStatusOf(IssueStatusPhase(it)) } val category: List<IssueCategory> = evalEnum(http, "c") val assignee: List<Int> = evalInts(http, "u") @@ -258,18 +258,29 @@ return http.session.getAttribute(name) != null } - private inline fun <reified T : Enum<T>> evalEnum(http: HttpRequest, prefix: String): List<T> { + private inline fun <reified T : Enum<T>> evalEnum( + http: HttpRequest, + prefix: String, + categorizer: ((Int) -> List<T>) = { emptyList() } + ): List<T> { val sattr = "f.${prefix}" val param = http.paramArray("filter") if (param.isNotEmpty()) { val list = param.filter { it.startsWith("${prefix}.") } .map { it.substring(prefix.length + 1) } - .map { - try { - // quick and very dirty validation - enumValueOf<T>(it) - } catch (_: IllegalArgumentException) { - // skip + .flatMap { + // try resolving as category + val cat = it.toIntOrNull() + if (cat != null) { + categorizer(cat) + } else { + try { + // quick and very dirty validation + listOf(enumValueOf<T>(it)) + } catch (_: IllegalArgumentException) { + // simply skip bogus enums + emptyList() + } } } if (list.isEmpty()) {
--- a/src/main/webapp/WEB-INF/changelogs/changelog-de.jspf Mon Aug 05 18:40:47 2024 +0200 +++ b/src/main/webapp/WEB-INF/changelogs/changelog-de.jspf Mon Aug 05 19:17:36 2024 +0200 @@ -29,6 +29,7 @@ <ul> <li>Neue globale Vorgangsseite hinzugefügt.</li> <li>Filter für Bearbeiter hinzugefügt.</li> + <li>Filter für Vorgangsphasen hinzugefügt.</li> <li>Automatische Zuweisung von Vorgängen bezieht neben der Leitung für eine Komponente nun auch die Leitung des Projektes ein.</li> <li>Der "OK" Button im Vorgangseditor führt nun zurück zur Vorgangsübersicht.</li> <li>Ein neuer "Speichern" Button im Vorgangseditor führt, wie zuvor, zurück zur Vorgangsansicht.</li>
--- a/src/main/webapp/WEB-INF/changelogs/changelog.jspf Mon Aug 05 18:40:47 2024 +0200 +++ b/src/main/webapp/WEB-INF/changelogs/changelog.jspf Mon Aug 05 19:17:36 2024 +0200 @@ -29,6 +29,7 @@ <ul> <li>Add new Issues page to globally list all issues across all projects.</li> <li>Add filter for assignee.</li> + <li>Add filter for issue phases.</li> <li>Automatic assignment of issue now uses the project lead as fallback when no component lead is available.</li> <li>The "OK" button in the issue editor now leads to the issue overview.</li> <li>A new "Save" button in the issue editor retains the old behavior and returns to the issue viewer.</li>
--- a/src/main/webapp/WEB-INF/jsp/users.jsp Mon Aug 05 18:40:47 2024 +0200 +++ b/src/main/webapp/WEB-INF/jsp/users.jsp Mon Aug 05 19:17:36 2024 +0200 @@ -69,9 +69,9 @@ <tr> <td><a href="./users/${userdata.user.id}/edit">✎</a></td> <td><c:out value="${userdata.user.displayname}"/></td> - <td class="hright">${userdata.issueSummary.open}</td> - <td class="hright">${userdata.issueSummary.active}</td> - <td class="hright">${userdata.issueSummary.done}</td> + <td class="hright"><a href="./issues/?filter=u.${userdata.user.id}&filter=s.0">${userdata.issueSummary.open}</a></td> + <td class="hright"><a href="./issues/?filter=u.${userdata.user.id}&filter=s.1">${userdata.issueSummary.active}</a></td> + <td class="hright"><a href="./issues/?filter=u.${userdata.user.id}&filter=s.2&filter=f.0">${userdata.issueSummary.done}</a></td> </tr> </c:forEach> </tbody>
--- a/src/main/webapp/WEB-INF/jspf/issue-summary.jspf Mon Aug 05 18:40:47 2024 +0200 +++ b/src/main/webapp/WEB-INF/jspf/issue-summary.jspf Mon Aug 05 19:17:36 2024 +0200 @@ -6,12 +6,24 @@ <div class="table issue-summary"> <div class="row"> <div class="caption"><fmt:message key="issues.open"/>:</div> - <div><c:out value="${summary.open}"/></div> + <div> + <a href="${issuesHref}?filter=s.0"> + <c:out value="${summary.open}"/> + </a> + </div> <div class="caption"><fmt:message key="issues.active"/>:</div> - <div><c:out value="${summary.active}"/></div> + <div> + <a href="${issuesHref}?filter=s.1"> + <c:out value="${summary.active}"/> + </a> + </div> <c:if test="${summary.done gt 0}"> <div class="caption"><fmt:message key="issues.done"/>:</div> - <div><c:out value="${summary.done}"/></div> + <div> + <a href="${issuesHref}?filter=s.2&filter=f.0"> + <c:out value="${summary.done}"/> + </a> + </div> </c:if> </div> </div> \ No newline at end of file