From a4b7b5276c4e0b6a7da7172d9dd602f7a8552b43 Mon Sep 17 00:00:00 2001 From: Jonathan Miller Date: Sat, 6 Jun 2026 14:12:27 -0500 Subject: [PATCH] feat(issues): status dropdown replaces close button for issues Move the status dropdown from sidebar to the comment form footer, replacing the close/reopen button. Status selections that have closes_issue=true auto-close, non-closing statuses auto-reopen. Falls back to standard close/reopen button for PRs and repos without org statuses. --- routers/web/repo/issue_comment.go | 39 ++++++++++++++ templates/repo/issue/view_content.tmpl | 52 +++++++++++++------ .../repo/issue/view_content/sidebar.tmpl | 2 - 3 files changed, 75 insertions(+), 18 deletions(-) diff --git a/routers/web/repo/issue_comment.go b/routers/web/repo/issue_comment.go index d2d14fa305..45bdfac975 100644 --- a/routers/web/repo/issue_comment.go +++ b/routers/web/repo/issue_comment.go @@ -184,6 +184,45 @@ func NewComment(ctx *context.Context) { } } // end if: handle close or reopen + // Handle custom status from the status dropdown (replaces close button for issues with org statuses). + if statusIDStr := ctx.Req.FormValue("status_id"); statusIDStr != "" && statusIDStr != "" { + if statusIDStr == "reopen" { + // Reopen via dropdown + if issue.IsClosed { + if err := issue_service.ReopenIssue(ctx, issue, ctx.Doer, ""); err != nil { + log.Error("ReopenIssue via status dropdown: %v", err) + } + if err := issues_model.SetIssueStatusID(ctx, issue.ID, 0); err != nil { + log.Error("SetIssueStatusID: %v", err) + } + } + } else if statusIDStr == "close" { + // Plain close via dropdown + if !issue.IsClosed { + if err := issue_service.CloseIssue(ctx, issue, ctx.Doer, ""); err != nil { + log.Error("CloseIssue via status dropdown: %v", err) + } + } + } else if statusID, err := strconv.ParseInt(statusIDStr, 10, 64); err == nil && statusID > 0 { + // Custom status selected + statusDef, err := issues_model.GetIssueStatusDefByID(ctx, statusID) + if err == nil && statusDef.OrgID == ctx.Repo.Repository.OwnerID { + if err := issues_model.SetIssueStatusID(ctx, issue.ID, statusID); err != nil { + log.Error("SetIssueStatusID: %v", err) + } + if statusDef.ClosesIssue && !issue.IsClosed { + if err := issue_service.CloseIssue(ctx, issue, ctx.Doer, ""); err != nil { + log.Error("CloseIssue via custom status: %v", err) + } + } else if !statusDef.ClosesIssue && issue.IsClosed { + if err := issue_service.ReopenIssue(ctx, issue, ctx.Doer, ""); err != nil { + log.Error("ReopenIssue via custom status: %v", err) + } + } + } + } + } + ctx.JSONRedirect(redirect) } diff --git a/templates/repo/issue/view_content.tmpl b/templates/repo/issue/view_content.tmpl index d1b327434b..4b7342ae39 100644 --- a/templates/repo/issue/view_content.tmpl +++ b/templates/repo/issue/view_content.tmpl @@ -85,24 +85,44 @@