From 2ec80ffbd2157a999c888e74d0a1fd9d61e2597c Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Tue, 7 Oct 2025 10:55:00 +0100 Subject: [PATCH] appview/pulls: show "delete branch" button for merged PRs Change-Id: tqkowplkwznqsssqkpnzzktslwwzoywk Signed-off-by: oppiliappan --- appview/models/pull.go | 5 ++ appview/pages/pages.go | 34 ++++---- .../repo/pulls/fragments/pullActions.html | 11 +++ appview/pages/templates/repo/pulls/pull.html | 11 ++- appview/pulls/pulls.go | 78 +++++++++++++++---- 5 files changed, 107 insertions(+), 32 deletions(-) diff --git a/appview/models/pull.go b/appview/models/pull.go index 39a7dcbb..3902e100 100644 --- a/appview/models/pull.go +++ b/appview/models/pull.go @@ -350,3 +350,8 @@ func (stack Stack) Mergeable() Stack { return mergeable } + +type BranchDeleteStatus struct { + Repo *Repo + Branch string +} diff --git a/appview/pages/pages.go b/appview/pages/pages.go index f78f3856..5fe0f5db 100644 --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -1128,15 +1128,16 @@ func (r ResubmitResult) Unknown() bool { } type RepoSinglePullParams struct { - LoggedInUser *oauth.User - RepoInfo repoinfo.RepoInfo - Active string - Pull *models.Pull - Stack models.Stack - AbandonedPulls []*models.Pull - MergeCheck types.MergeCheckResponse - ResubmitCheck ResubmitResult - Pipelines map[string]models.Pipeline + LoggedInUser *oauth.User + RepoInfo repoinfo.RepoInfo + Active string + Pull *models.Pull + Stack models.Stack + AbandonedPulls []*models.Pull + BranchDeleteStatus *models.BranchDeleteStatus + MergeCheck types.MergeCheckResponse + ResubmitCheck ResubmitResult + Pipelines map[string]models.Pipeline OrderedReactionKinds []models.ReactionKind Reactions map[models.ReactionKind]models.ReactionDisplayData @@ -1232,13 +1233,14 @@ func (p *Pages) PullResubmitFragment(w io.Writer, params PullResubmitParams) err } type PullActionsParams struct { - LoggedInUser *oauth.User - RepoInfo repoinfo.RepoInfo - Pull *models.Pull - RoundNumber int - MergeCheck types.MergeCheckResponse - ResubmitCheck ResubmitResult - Stack models.Stack + LoggedInUser *oauth.User + RepoInfo repoinfo.RepoInfo + Pull *models.Pull + RoundNumber int + MergeCheck types.MergeCheckResponse + ResubmitCheck ResubmitResult + BranchDeleteStatus *models.BranchDeleteStatus + Stack models.Stack } func (p *Pages) PullActionsFragment(w io.Writer, params PullActionsParams) error { diff --git a/appview/pages/templates/repo/pulls/fragments/pullActions.html b/appview/pages/templates/repo/pulls/fragments/pullActions.html index e98b3d83..2963e10a 100644 --- a/appview/pages/templates/repo/pulls/fragments/pullActions.html +++ b/appview/pages/templates/repo/pulls/fragments/pullActions.html @@ -33,6 +33,17 @@ comment {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} + {{ if .BranchDeleteStatus }} + + {{ end }} {{ if and $isPushAllowed $isOpen $isLastRound }} {{ $disabled := "" }} {{ if $isConflicted }} diff --git a/appview/pages/templates/repo/pulls/pull.html b/appview/pages/templates/repo/pulls/pull.html index ac207223..fc149546 100644 --- a/appview/pages/templates/repo/pulls/pull.html +++ b/appview/pages/templates/repo/pulls/pull.html @@ -187,7 +187,16 @@ {{ end }} {{ if $.LoggedInUser }} - {{ template "repo/pulls/fragments/pullActions" (dict "LoggedInUser" $.LoggedInUser "Pull" $.Pull "RepoInfo" $.RepoInfo "RoundNumber" .RoundNumber "MergeCheck" $.MergeCheck "ResubmitCheck" $.ResubmitCheck "Stack" $.Stack) }} + {{ template "repo/pulls/fragments/pullActions" + (dict + "LoggedInUser" $.LoggedInUser + "Pull" $.Pull + "RepoInfo" $.RepoInfo + "RoundNumber" .RoundNumber + "MergeCheck" $.MergeCheck + "ResubmitCheck" $.ResubmitCheck + "BranchDeleteStatus" $.BranchDeleteStatus + "Stack" $.Stack) }} {{ else }}
diff --git a/appview/pulls/pulls.go b/appview/pulls/pulls.go index 126202a7..45a22338 100644 --- a/appview/pulls/pulls.go +++ b/appview/pulls/pulls.go @@ -98,19 +98,21 @@ func (s *Pulls) PullActions(w http.ResponseWriter, r *http.Request) { } mergeCheckResponse := s.mergeCheck(r, f, pull, stack) + branchDeleteStatus := s.branchDeleteStatus(r, f, pull) resubmitResult := pages.Unknown if user.Did == pull.OwnerDid { resubmitResult = s.resubmitCheck(r, f, pull, stack) } s.pages.PullActionsFragment(w, pages.PullActionsParams{ - LoggedInUser: user, - RepoInfo: f.RepoInfo(user), - Pull: pull, - RoundNumber: roundNumber, - MergeCheck: mergeCheckResponse, - ResubmitCheck: resubmitResult, - Stack: stack, + LoggedInUser: user, + RepoInfo: f.RepoInfo(user), + Pull: pull, + RoundNumber: roundNumber, + MergeCheck: mergeCheckResponse, + ResubmitCheck: resubmitResult, + BranchDeleteStatus: branchDeleteStatus, + Stack: stack, }) return } @@ -153,6 +155,7 @@ func (s *Pulls) RepoSinglePull(w http.ResponseWriter, r *http.Request) { } mergeCheckResponse := s.mergeCheck(r, f, pull, stack) + branchDeleteStatus := s.branchDeleteStatus(r, f, pull) resubmitResult := pages.Unknown if user != nil && user.Did == pull.OwnerDid { resubmitResult = s.resubmitCheck(r, f, pull, stack) @@ -217,14 +220,15 @@ func (s *Pulls) RepoSinglePull(w http.ResponseWriter, r *http.Request) { } s.pages.RepoSinglePull(w, pages.RepoSinglePullParams{ - LoggedInUser: user, - RepoInfo: repoInfo, - Pull: pull, - Stack: stack, - AbandonedPulls: abandonedPulls, - MergeCheck: mergeCheckResponse, - ResubmitCheck: resubmitResult, - Pipelines: m, + LoggedInUser: user, + RepoInfo: repoInfo, + Pull: pull, + Stack: stack, + AbandonedPulls: abandonedPulls, + BranchDeleteStatus: branchDeleteStatus, + MergeCheck: mergeCheckResponse, + ResubmitCheck: resubmitResult, + Pipelines: m, OrderedReactionKinds: models.OrderedReactionKinds, Reactions: reactionMap, @@ -301,6 +305,50 @@ func (s *Pulls) mergeCheck(r *http.Request, f *reporesolver.ResolvedRepo, pull * return result } +func (s *Pulls) branchDeleteStatus(r *http.Request, f *reporesolver.ResolvedRepo, pull *models.Pull) *models.BranchDeleteStatus { + if pull.State != models.PullMerged { + return nil + } + + user := s.oauth.GetUser(r) + if user == nil { + return nil + } + + var branch string + var repo *models.Repo + // check if the branch exists + // NOTE: appview could cache branches/tags etc. for every repo by listening for gitRefUpdates + if pull.IsBranchBased() { + branch = pull.PullSource.Branch + repo = &f.Repo + } else if pull.IsForkBased() { + branch = pull.PullSource.Branch + repo = pull.PullSource.Repo + } else { + return nil + } + + scheme := "http" + if !s.config.Core.Dev { + scheme = "https" + } + host := fmt.Sprintf("%s://%s", scheme, repo.Knot) + xrpcc := &indigoxrpc.Client{ + Host: host, + } + + resp, err := tangled.RepoBranch(r.Context(), xrpcc, branch, fmt.Sprintf("%s/%s", repo.Did, repo.Name)) + if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { + return nil + } + + return &models.BranchDeleteStatus{ + Repo: repo, + Branch: resp.Name, + } +} + func (s *Pulls) resubmitCheck(r *http.Request, f *reporesolver.ResolvedRepo, pull *models.Pull, stack models.Stack) pages.ResubmitResult { if pull.State == models.PullMerged || pull.State == models.PullDeleted || pull.PullSource == nil { return pages.Unknown -- 2.43.0