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

merged
opened by oppi.li targeting master from push-rvtqynpmozzy
Changed files
+107 -32
appview
models
pages
templates
repo
pulls
pulls
+5
appview/models/pull.go
··· 350 351 return mergeable 352 }
··· 350 351 return mergeable 352 } 353 + 354 + type BranchDeleteStatus struct { 355 + Repo *Repo 356 + Branch string 357 + }
+18 -16
appview/pages/pages.go
··· 1128 } 1129 1130 type RepoSinglePullParams struct { 1131 - LoggedInUser *oauth.User 1132 - RepoInfo repoinfo.RepoInfo 1133 - Active string 1134 - Pull *models.Pull 1135 - Stack models.Stack 1136 - AbandonedPulls []*models.Pull 1137 - MergeCheck types.MergeCheckResponse 1138 - ResubmitCheck ResubmitResult 1139 - Pipelines map[string]models.Pipeline 1140 1141 OrderedReactionKinds []models.ReactionKind 1142 Reactions map[models.ReactionKind]models.ReactionDisplayData ··· 1232 } 1233 1234 type PullActionsParams struct { 1235 - LoggedInUser *oauth.User 1236 - RepoInfo repoinfo.RepoInfo 1237 - Pull *models.Pull 1238 - RoundNumber int 1239 - MergeCheck types.MergeCheckResponse 1240 - ResubmitCheck ResubmitResult 1241 - Stack models.Stack 1242 } 1243 1244 func (p *Pages) PullActionsFragment(w io.Writer, params PullActionsParams) error {
··· 1128 } 1129 1130 type RepoSinglePullParams struct { 1131 + LoggedInUser *oauth.User 1132 + RepoInfo repoinfo.RepoInfo 1133 + Active string 1134 + Pull *models.Pull 1135 + Stack models.Stack 1136 + AbandonedPulls []*models.Pull 1137 + BranchDeleteStatus *models.BranchDeleteStatus 1138 + MergeCheck types.MergeCheckResponse 1139 + ResubmitCheck ResubmitResult 1140 + Pipelines map[string]models.Pipeline 1141 1142 OrderedReactionKinds []models.ReactionKind 1143 Reactions map[models.ReactionKind]models.ReactionDisplayData ··· 1233 } 1234 1235 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 + BranchDeleteStatus *models.BranchDeleteStatus 1243 + Stack models.Stack 1244 } 1245 1246 func (p *Pages) PullActionsFragment(w io.Writer, params PullActionsParams) error {
+11
appview/pages/templates/repo/pulls/fragments/pullActions.html
··· 33 <span>comment</span> 34 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 35 </button> 36 {{ if and $isPushAllowed $isOpen $isLastRound }} 37 {{ $disabled := "" }} 38 {{ if $isConflicted }}
··· 33 <span>comment</span> 34 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }} 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 }} 47 {{ if and $isPushAllowed $isOpen $isLastRound }} 48 {{ $disabled := "" }} 49 {{ if $isConflicted }}
+10 -1
appview/pages/templates/repo/pulls/pull.html
··· 187 {{ end }} 188 189 {{ if $.LoggedInUser }} 190 - {{ template "repo/pulls/fragments/pullActions" (dict "LoggedInUser" $.LoggedInUser "Pull" $.Pull "RepoInfo" $.RepoInfo "RoundNumber" .RoundNumber "MergeCheck" $.MergeCheck "ResubmitCheck" $.ResubmitCheck "Stack" $.Stack) }} 191 {{ else }} 192 <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 <a href="/signup" class="btn-create py-0 hover:no-underline hover:text-white flex items-center gap-2">
··· 187 {{ end }} 188 189 {{ if $.LoggedInUser }} 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) }} 200 {{ else }} 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"> 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 } 99 100 mergeCheckResponse := s.mergeCheck(r, f, pull, stack) 101 resubmitResult := pages.Unknown 102 if user.Did == pull.OwnerDid { 103 resubmitResult = s.resubmitCheck(r, f, pull, stack) 104 } 105 106 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, 114 }) 115 return 116 } ··· 153 } 154 155 mergeCheckResponse := s.mergeCheck(r, f, pull, stack) 156 resubmitResult := pages.Unknown 157 if user != nil && user.Did == pull.OwnerDid { 158 resubmitResult = s.resubmitCheck(r, f, pull, stack) ··· 217 } 218 219 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, 228 229 OrderedReactionKinds: models.OrderedReactionKinds, 230 Reactions: reactionMap, ··· 301 return result 302 } 303 304 func (s *Pulls) resubmitCheck(r *http.Request, f *reporesolver.ResolvedRepo, pull *models.Pull, stack models.Stack) pages.ResubmitResult { 305 if pull.State == models.PullMerged || pull.State == models.PullDeleted || pull.PullSource == nil { 306 return pages.Unknown
··· 98 } 99 100 mergeCheckResponse := s.mergeCheck(r, f, pull, stack) 101 + branchDeleteStatus := s.branchDeleteStatus(r, f, pull) 102 resubmitResult := pages.Unknown 103 if user.Did == pull.OwnerDid { 104 resubmitResult = s.resubmitCheck(r, f, pull, stack) 105 } 106 107 s.pages.PullActionsFragment(w, pages.PullActionsParams{ 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, 116 }) 117 return 118 } ··· 155 } 156 157 mergeCheckResponse := s.mergeCheck(r, f, pull, stack) 158 + branchDeleteStatus := s.branchDeleteStatus(r, f, pull) 159 resubmitResult := pages.Unknown 160 if user != nil && user.Did == pull.OwnerDid { 161 resubmitResult = s.resubmitCheck(r, f, pull, stack) ··· 220 } 221 222 s.pages.RepoSinglePull(w, pages.RepoSinglePullParams{ 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, 232 233 OrderedReactionKinds: models.OrderedReactionKinds, 234 Reactions: reactionMap, ··· 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 + } 350 + } 351 + 352 func (s *Pulls) resubmitCheck(r *http.Request, f *reporesolver.ResolvedRepo, pull *models.Pull, stack models.Stack) pages.ResubmitResult { 353 if pull.State == models.PullMerged || pull.State == models.PullDeleted || pull.PullSource == nil { 354 return pages.Unknown