forked from tangled.org/core
Monorepo for Tangled

appview/pulls: show "delete branch" button for merged PRs

Signed-off-by: oppiliappan <me@oppi.li>

authored by oppi.li and committed by Tangled 32a172c3 980e07be

Changed files
+107 -32
appview
models
pages
templates
repo
pulls
pulls
+5
appview/models/pull.go
··· 350 350 351 351 return mergeable 352 352 } 353 + 354 + type BranchDeleteStatus struct { 355 + Repo *Repo 356 + Branch string 357 + }
+18 -16
appview/pages/pages.go
··· 1129 1129 } 1130 1130 1131 1131 type RepoSinglePullParams struct { 1132 - LoggedInUser *oauth.User 1133 - RepoInfo repoinfo.RepoInfo 1134 - Active string 1135 - Pull *models.Pull 1136 - Stack models.Stack 1137 - AbandonedPulls []*models.Pull 1138 - MergeCheck types.MergeCheckResponse 1139 - ResubmitCheck ResubmitResult 1140 - Pipelines map[string]models.Pipeline 1132 + LoggedInUser *oauth.User 1133 + RepoInfo repoinfo.RepoInfo 1134 + Active string 1135 + Pull *models.Pull 1136 + Stack models.Stack 1137 + AbandonedPulls []*models.Pull 1138 + BranchDeleteStatus *models.BranchDeleteStatus 1139 + MergeCheck types.MergeCheckResponse 1140 + ResubmitCheck ResubmitResult 1141 + Pipelines map[string]models.Pipeline 1141 1142 1142 1143 OrderedReactionKinds []models.ReactionKind 1143 1144 Reactions map[models.ReactionKind]models.ReactionDisplayData ··· 1233 1234 } 1234 1235 1235 1236 type PullActionsParams struct { 1236 - LoggedInUser *oauth.User 1237 - RepoInfo repoinfo.RepoInfo 1238 - Pull *models.Pull 1239 - RoundNumber int 1240 - MergeCheck types.MergeCheckResponse 1241 - ResubmitCheck ResubmitResult 1242 - Stack models.Stack 1237 + LoggedInUser *oauth.User 1238 + RepoInfo repoinfo.RepoInfo 1239 + Pull *models.Pull 1240 + RoundNumber int 1241 + MergeCheck types.MergeCheckResponse 1242 + ResubmitCheck ResubmitResult 1243 + BranchDeleteStatus *models.BranchDeleteStatus 1244 + Stack models.Stack 1243 1245 } 1244 1246 1245 1247 func (p *Pages) PullActionsFragment(w io.Writer, params PullActionsParams) error {
+11
appview/pages/templates/repo/pulls/fragments/pullActions.html
··· 33 33 <span>comment</span> 34 34 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 35 35 </button> 36 + {{ if .BranchDeleteStatus }} 37 + <button 38 + hx-delete="/{{ .BranchDeleteStatus.Repo.Did }}/{{ .BranchDeleteStatus.Repo.Name }}/branches" 39 + hx-vals='{"branch": "{{ .BranchDeleteStatus.Branch }}" }' 40 + hx-swap="none" 41 + class="btn p-2 flex items-center gap-2 no-underline hover:no-underline group text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"> 42 + {{ i "git-branch" "w-4 h-4" }} 43 + <span>delete branch</span> 44 + {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 45 + </button> 46 + {{ end }} 36 47 {{ if and $isPushAllowed $isOpen $isLastRound }} 37 48 {{ $disabled := "" }} 38 49 {{ if $isConflicted }}
+10 -1
appview/pages/templates/repo/pulls/pull.html
··· 187 187 {{ end }} 188 188 189 189 {{ if $.LoggedInUser }} 190 - {{ template "repo/pulls/fragments/pullActions" (dict "LoggedInUser" $.LoggedInUser "Pull" $.Pull "RepoInfo" $.RepoInfo "RoundNumber" .RoundNumber "MergeCheck" $.MergeCheck "ResubmitCheck" $.ResubmitCheck "Stack" $.Stack) }} 190 + {{ template "repo/pulls/fragments/pullActions" 191 + (dict 192 + "LoggedInUser" $.LoggedInUser 193 + "Pull" $.Pull 194 + "RepoInfo" $.RepoInfo 195 + "RoundNumber" .RoundNumber 196 + "MergeCheck" $.MergeCheck 197 + "ResubmitCheck" $.ResubmitCheck 198 + "BranchDeleteStatus" $.BranchDeleteStatus 199 + "Stack" $.Stack) }} 191 200 {{ else }} 192 201 <div class="bg-amber-50 dark:bg-amber-900 border border-amber-500 rounded drop-shadow-sm p-2 relative flex gap-2 items-center w-fit"> 193 202 <a href="/signup" class="btn-create py-0 hover:no-underline hover:text-white flex items-center gap-2">
+63 -15
appview/pulls/pulls.go
··· 98 98 } 99 99 100 100 mergeCheckResponse := s.mergeCheck(r, f, pull, stack) 101 + branchDeleteStatus := s.branchDeleteStatus(r, f, pull) 101 102 resubmitResult := pages.Unknown 102 103 if user.Did == pull.OwnerDid { 103 104 resubmitResult = s.resubmitCheck(r, f, pull, stack) 104 105 } 105 106 106 107 s.pages.PullActionsFragment(w, pages.PullActionsParams{ 107 - LoggedInUser: user, 108 - RepoInfo: f.RepoInfo(user), 109 - Pull: pull, 110 - RoundNumber: roundNumber, 111 - MergeCheck: mergeCheckResponse, 112 - ResubmitCheck: resubmitResult, 113 - Stack: stack, 108 + LoggedInUser: user, 109 + RepoInfo: f.RepoInfo(user), 110 + Pull: pull, 111 + RoundNumber: roundNumber, 112 + MergeCheck: mergeCheckResponse, 113 + ResubmitCheck: resubmitResult, 114 + BranchDeleteStatus: branchDeleteStatus, 115 + Stack: stack, 114 116 }) 115 117 return 116 118 } ··· 153 155 } 154 156 155 157 mergeCheckResponse := s.mergeCheck(r, f, pull, stack) 158 + branchDeleteStatus := s.branchDeleteStatus(r, f, pull) 156 159 resubmitResult := pages.Unknown 157 160 if user != nil && user.Did == pull.OwnerDid { 158 161 resubmitResult = s.resubmitCheck(r, f, pull, stack) ··· 217 220 } 218 221 219 222 s.pages.RepoSinglePull(w, pages.RepoSinglePullParams{ 220 - LoggedInUser: user, 221 - RepoInfo: repoInfo, 222 - Pull: pull, 223 - Stack: stack, 224 - AbandonedPulls: abandonedPulls, 225 - MergeCheck: mergeCheckResponse, 226 - ResubmitCheck: resubmitResult, 227 - Pipelines: m, 223 + LoggedInUser: user, 224 + RepoInfo: repoInfo, 225 + Pull: pull, 226 + Stack: stack, 227 + AbandonedPulls: abandonedPulls, 228 + BranchDeleteStatus: branchDeleteStatus, 229 + MergeCheck: mergeCheckResponse, 230 + ResubmitCheck: resubmitResult, 231 + Pipelines: m, 228 232 229 233 OrderedReactionKinds: models.OrderedReactionKinds, 230 234 Reactions: reactionMap, ··· 299 303 } 300 304 301 305 return result 306 + } 307 + 308 + func (s *Pulls) branchDeleteStatus(r *http.Request, f *reporesolver.ResolvedRepo, pull *models.Pull) *models.BranchDeleteStatus { 309 + if pull.State != models.PullMerged { 310 + return nil 311 + } 312 + 313 + user := s.oauth.GetUser(r) 314 + if user == nil { 315 + return nil 316 + } 317 + 318 + var branch string 319 + var repo *models.Repo 320 + // check if the branch exists 321 + // NOTE: appview could cache branches/tags etc. for every repo by listening for gitRefUpdates 322 + if pull.IsBranchBased() { 323 + branch = pull.PullSource.Branch 324 + repo = &f.Repo 325 + } else if pull.IsForkBased() { 326 + branch = pull.PullSource.Branch 327 + repo = pull.PullSource.Repo 328 + } else { 329 + return nil 330 + } 331 + 332 + scheme := "http" 333 + if !s.config.Core.Dev { 334 + scheme = "https" 335 + } 336 + host := fmt.Sprintf("%s://%s", scheme, repo.Knot) 337 + xrpcc := &indigoxrpc.Client{ 338 + Host: host, 339 + } 340 + 341 + resp, err := tangled.RepoBranch(r.Context(), xrpcc, branch, fmt.Sprintf("%s/%s", repo.Did, repo.Name)) 342 + if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 343 + return nil 344 + } 345 + 346 + return &models.BranchDeleteStatus{ 347 + Repo: repo, 348 + Branch: resp.Name, 349 + } 302 350 } 303 351 304 352 func (s *Pulls) resubmitCheck(r *http.Request, f *reporesolver.ResolvedRepo, pull *models.Pull, stack models.Stack) pages.ResubmitResult {