# HG changeset patch # User Mike Becker # Date 1759679251 -7200 # Node ID 288cb8d22584b55d9d296d0537863c04b1ca33ef # Parent c3ef1c328b3635de4884ad5d0daf05df5c994d43 add convenience button to progress an issue and change behavior of the resolve button when a variant is opened - resolves #735 diff -r c3ef1c328b36 -r 288cb8d22584 src/main/kotlin/de/uapcore/lightpit/entities/Issue.kt --- a/src/main/kotlin/de/uapcore/lightpit/entities/Issue.kt Sat Oct 04 16:59:07 2025 +0200 +++ b/src/main/kotlin/de/uapcore/lightpit/entities/Issue.kt Sun Oct 05 17:47:31 2025 +0200 @@ -62,6 +62,11 @@ return variantStatus[variant] } + /** + * The minimum status phase across all variants or the issue status phase if there are no variants. + */ + val minimumStatusPhaseAcrossAllVariants get() = variantStatus.values.minOfOrNull { it.phase } ?: status.phase + fun updateStatusFromVariants() { if (!isTrackingVariantStatus) return diff -r c3ef1c328b36 -r 288cb8d22584 src/main/kotlin/de/uapcore/lightpit/logic/IssueLogic.kt --- a/src/main/kotlin/de/uapcore/lightpit/logic/IssueLogic.kt Sat Oct 04 16:59:07 2025 +0200 +++ b/src/main/kotlin/de/uapcore/lightpit/logic/IssueLogic.kt Sun Oct 05 17:47:31 2025 +0200 @@ -136,16 +136,34 @@ return true } -fun issueQuickResolve(http: HttpRequest, dao: DataAccessObject, issue: Issue) { - if (issue.status.phase == IssueStatusPhase.Done) return +fun issueQuickProgress(http: HttpRequest, dao: DataAccessObject, issue: Issue, variant: Variant? = null) { + if (issue.minimumStatusPhaseAcrossAllVariants != IssueStatusPhase.Open) return if (issue.isTrackingVariantStatus) { - issue.variantStatus.filter { it.value.phase != IssueStatusPhase.Done }.keys.forEach { + issue.variantStatus.filter { + it.value.phase == IssueStatusPhase.Open && (variant == null || it.key == variant) + }.keys.forEach { + issue.variantStatus[it] = IssueStatus.InProgress + } + issue.updateStatusFromVariants() + } else { + issue.status = IssueStatus.InProgress + } + dao.updateIssue(issue) + dao.insertHistoryEvent(http.user, issue) +} + +fun issueQuickResolve(http: HttpRequest, dao: DataAccessObject, issue: Issue, variant: Variant? = null) { + if (issue.minimumStatusPhaseAcrossAllVariants == IssueStatusPhase.Done) return + if (issue.isTrackingVariantStatus) { + issue.variantStatus.filter { + it.value.phase != IssueStatusPhase.Done && (variant == null || it.key == variant) + }.keys.forEach { issue.variantStatus[it] = IssueStatus.Done } + issue.updateStatusFromVariants() } else { issue.status = IssueStatus.Done } - issue.updateStatusFromVariants() dao.updateIssue(issue) dao.insertHistoryEvent(http.user, issue) } diff -r c3ef1c328b36 -r 288cb8d22584 src/main/kotlin/de/uapcore/lightpit/servlet/IssuesServlet.kt --- a/src/main/kotlin/de/uapcore/lightpit/servlet/IssuesServlet.kt Sat Oct 04 16:59:07 2025 +0200 +++ b/src/main/kotlin/de/uapcore/lightpit/servlet/IssuesServlet.kt Sun Oct 05 17:47:31 2025 +0200 @@ -19,6 +19,7 @@ get("/search", this::issueSearch) get("/%issue", this::issue) get("/%issue/edit", this::issueForm) + get("/%issue/progress", this::issueProgress) get("/%issue/resolve", this::issueResolve) post("/%issue/comment", this::issueComment) post("/%issue/relation", this::issueRelation) @@ -55,6 +56,16 @@ renderIssueView(http, dao, issue, pathInfos) } + private fun issueProgress(http: HttpRequest, dao: DataAccessObject) { + val issue = http.pathParams["issue"]?.toIntOrNull()?.let(dao::findIssue) + if (issue == null) { + http.response.sendError(404) + return + } + issueQuickProgress(http, dao, issue) + http.renderCommit("${pathInfos.issuesHref}${issue.id}") + } + private fun issueResolve(http: HttpRequest, dao: DataAccessObject) { val issue = http.pathParams["issue"]?.toIntOrNull()?.let(dao::findIssue) if (issue == null) { diff -r c3ef1c328b36 -r 288cb8d22584 src/main/kotlin/de/uapcore/lightpit/servlet/ProjectServlet.kt --- a/src/main/kotlin/de/uapcore/lightpit/servlet/ProjectServlet.kt Sat Oct 04 16:59:07 2025 +0200 +++ b/src/main/kotlin/de/uapcore/lightpit/servlet/ProjectServlet.kt Sun Oct 05 17:47:31 2025 +0200 @@ -63,6 +63,7 @@ get("/%project/issues/%version/%component/%variant/%issue", this::issue) get("/%project/issues/%version/%component/%variant/%issue/edit", this::issueForm) + get("/%project/issues/%version/%component/%variant/%issue/progress", this::issueProgress) get("/%project/issues/%version/%component/%variant/%issue/resolve", this::issueResolve) post("/%project/issues/%version/%component/%variant/%issue/comment", this::issueComment) post("/%project/issues/%version/%component/%variant/%issue/relation", this::issueRelation) @@ -392,14 +393,26 @@ } } + private fun issueProgress(http: HttpRequest, dao: DataAccessObject) { + val issue = http.pathParams["issue"]?.toIntOrNull()?.let(dao::findIssue) + if (issue == null) { + http.response.sendError(404) + return + } + withPathInfo(http, dao)?.let { path -> + issueQuickProgress(http, dao, issue, (path.variantInfo as? OptionalPathInfo.Specific)?.elem) + http.renderCommit("${path.issuesHref}${issue.id}") + } + } + private fun issueResolve(http: HttpRequest, dao: DataAccessObject) { val issue = http.pathParams["issue"]?.toIntOrNull()?.let(dao::findIssue) if (issue == null) { http.response.sendError(404) return } - issueQuickResolve(http, dao, issue) withPathInfo(http, dao)?.let { path -> + issueQuickResolve(http, dao, issue, (path.variantInfo as? OptionalPathInfo.Specific)?.elem) http.renderCommit("${path.issuesHref}${issue.id}") } } diff -r c3ef1c328b36 -r 288cb8d22584 src/main/kotlin/de/uapcore/lightpit/viewmodel/Issues.kt --- a/src/main/kotlin/de/uapcore/lightpit/viewmodel/Issues.kt Sat Oct 04 16:59:07 2025 +0200 +++ b/src/main/kotlin/de/uapcore/lightpit/viewmodel/Issues.kt Sun Oct 05 17:47:31 2025 +0200 @@ -32,6 +32,7 @@ import com.vladsch.flexmark.util.data.MutableDataSet import com.vladsch.flexmark.util.data.SharedDataKeys import de.uapcore.lightpit.HttpRequest +import de.uapcore.lightpit.OptionalPathInfo import de.uapcore.lightpit.dao.DataAccessObject import de.uapcore.lightpit.entities.* import de.uapcore.lightpit.logic.compareEtaTo @@ -129,6 +130,7 @@ ) : View() { val relationTypes = RelationType.entries val commitLinks: List + val openedVariant: Variant? = ((pathInfos as? PathInfosFull)?.variantInfo as? OptionalPathInfo.Specific)?.elem private val parser: Parser private val renderer: HtmlRenderer diff -r c3ef1c328b36 -r 288cb8d22584 src/main/resources/localization/strings.properties --- a/src/main/resources/localization/strings.properties Sat Oct 04 16:59:07 2025 +0200 +++ b/src/main/resources/localization/strings.properties Sun Oct 05 17:47:31 2025 +0200 @@ -38,6 +38,7 @@ button.issue.create=New Issue button.issue.edit=Edit button.issue.open-in-project=Open in Project +button.issue.progress=Progress button.issue.resolve=Resolve button.okay=OK button.project.create=New Project diff -r c3ef1c328b36 -r 288cb8d22584 src/main/resources/localization/strings_de.properties --- a/src/main/resources/localization/strings_de.properties Sat Oct 04 16:59:07 2025 +0200 +++ b/src/main/resources/localization/strings_de.properties Sun Oct 05 17:47:31 2025 +0200 @@ -38,6 +38,7 @@ button.issue.create=Neuer Vorgang button.issue.edit=Bearbeiten button.issue.open-in-project=In Projekt \u00d6ffnen +button.issue.progress=In Arbeit button.issue.resolve=Erledigt button.okay=OK button.project.create=Neues Projekt diff -r c3ef1c328b36 -r 288cb8d22584 src/main/webapp/WEB-INF/changelogs/changelog-de.jspf --- a/src/main/webapp/WEB-INF/changelogs/changelog-de.jspf Sat Oct 04 16:59:07 2025 +0200 +++ b/src/main/webapp/WEB-INF/changelogs/changelog-de.jspf Sun Oct 05 17:47:31 2025 +0200 @@ -28,7 +28,7 @@