forked from tangled.org/core
this repo has no description

appview: add stacking to NewPull form

Changed files
+96 -74
appview
pages
state
+6 -3
appview/pages/templates/repo/pulls/fragments/pullCompareBranches.html
··· 1 1 {{ define "repo/pulls/fragments/pullCompareBranches" }} 2 2 <div id="patch-upload"> 3 - <label for="targetBranch" class="dark:text-white" 4 - >select a branch</label 5 - > 3 + <label for="targetBranch" class="dark:text-white">select a branch</label> 6 4 <div class="flex flex-wrap gap-2 items-center"> 7 5 <select 8 6 name="sourceBranch" ··· 26 24 {{ end }} 27 25 </select> 28 26 </div> 27 + </div> 28 + 29 + <div class="flex items-center gap-2"> 30 + <input type="checkbox" id="isStacked" name="isStacked" value="on"> 31 + <label for="isStacked" class="my-0 py-0 normal-case font-normal">Submit as stacked PRs</label> 29 32 </div> 30 33 31 34 <p class="mt-4">
+7 -1
appview/pages/templates/repo/pulls/fragments/pullCompareForks.html
··· 3 3 <label for="forkSelect" class="dark:text-white" 4 4 >select a fork to compare</label 5 5 > 6 - <div class="flex flex-wrap gap-4 items-center mb-4"> 6 + <div class="flex flex-wrap gap-4 items-center"> 7 7 <div class="flex flex-wrap gap-2 items-center"> 8 8 <select 9 9 id="forkSelect" ··· 39 39 </div> 40 40 </div> 41 41 </div> 42 + 43 + <div class="flex items-center gap-2"> 44 + <input type="checkbox" id="isStacked" name="isStacked" value="on"> 45 + <label for="isStacked" class="my-0 py-0 normal-case font-normal">Submit as stacked PRs</label> 46 + </div> 47 + 42 48 <p class="mt-4"> 43 49 Title and description are optional; if left out, they will be extracted 44 50 from the first commit.
+59 -61
appview/pages/templates/repo/pulls/new.html
··· 3 3 {{ define "repoContent" }} 4 4 <form 5 5 hx-post="/{{ .RepoInfo.FullName }}/pulls/new" 6 - class="mt-6 space-y-6" 7 6 hx-indicator="#create-pull-spinner" 8 7 hx-swap="none" 9 8 > 10 - <div class="flex flex-col gap-4"> 11 - <label>configure your pull request</label> 12 - 13 - <p>First, choose a target branch on {{ .RepoInfo.FullName }}.</p> 14 - <div class="pb-2"> 9 + <div class="flex flex-col gap-6"> 10 + <div class="flex gap-2 items-center"> 11 + <p>First, choose a target branch on {{ .RepoInfo.FullName }}:</p> 12 + <div> 15 13 <select 16 - required 17 - name="targetBranch" 18 - class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600" 19 - > 20 - <option disabled selected>target branch</option> 21 - {{ range .Branches }} 22 - <option value="{{ .Reference.Name }}" class="py-1" {{if .IsDefault}}selected{{end}}> 23 - {{ .Reference.Name }} 24 - </option> 25 - {{ end }} 14 + required 15 + name="targetBranch" 16 + class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600" 17 + > 18 + <option disabled selected>target branch</option> 19 + {{ range .Branches }} 20 + <option value="{{ .Reference.Name }}" class="py-1" {{if .IsDefault}}selected{{end}}> 21 + {{ .Reference.Name }} 22 + </option> 23 + {{ end }} 26 24 </select> 25 + </div> 27 26 </div> 28 27 29 - <p>Next, choose a pull strategy.</p> 30 - <nav class="flex space-x-4 items-end"> 31 - <button 32 - type="button" 33 - class="px-3 py-2 pb-2 btn" 34 - hx-get="/{{ .RepoInfo.FullName }}/pulls/new/patch-upload" 35 - hx-target="#patch-strategy" 36 - hx-swap="innerHTML" 37 - > 38 - paste patch 39 - </button> 40 - 41 - {{ if .RepoInfo.Roles.IsPushAllowed }} 42 - <span class="text-sm text-gray-500 dark:text-gray-400 pb-2"> 43 - or 44 - </span> 45 - <button 46 - type="button" 47 - class="px-3 py-2 pb-2 btn" 48 - hx-get="/{{ .RepoInfo.FullName }}/pulls/new/compare-branches" 49 - hx-target="#patch-strategy" 50 - hx-swap="innerHTML" 51 - > 52 - compare branches 53 - </button> 54 - {{ end }} 55 - 28 + <div class="flex flex-col gap-2"> 29 + <p>Next, choose a pull strategy.</p> 30 + <nav class="flex space-x-4 items-center"> 31 + <button 32 + type="button" 33 + class="btn" 34 + hx-get="/{{ .RepoInfo.FullName }}/pulls/new/patch-upload" 35 + hx-target="#patch-strategy" 36 + hx-swap="innerHTML" 37 + > 38 + paste patch 39 + </button> 56 40 57 - <span class="text-sm text-gray-500 dark:text-gray-400 pb-2"> 58 - or 59 - </span> 60 - <button 61 - type="button" 62 - class="px-3 py-2 pb-2 btn" 63 - hx-get="/{{ .RepoInfo.FullName }}/pulls/new/compare-forks" 64 - hx-target="#patch-strategy" 65 - hx-swap="innerHTML" 66 - > 67 - compare forks 68 - </button> 69 - </nav> 41 + {{ if .RepoInfo.Roles.IsPushAllowed }} 42 + <span class="text-sm text-gray-500 dark:text-gray-400"> 43 + or 44 + </span> 45 + <button 46 + type="button" 47 + class="btn" 48 + hx-get="/{{ .RepoInfo.FullName }}/pulls/new/compare-branches" 49 + hx-target="#patch-strategy" 50 + hx-swap="innerHTML" 51 + > 52 + compare branches 53 + </button> 54 + {{ end }} 70 55 71 - <section id="patch-strategy"> 72 - {{ template "repo/pulls/fragments/pullPatchUpload" . }} 73 - </section> 74 56 75 - <p id="patch-preview"></p> 57 + <span class="text-sm text-gray-500 dark:text-gray-400"> 58 + or 59 + </span> 60 + <button 61 + type="button" 62 + class="btn" 63 + hx-get="/{{ .RepoInfo.FullName }}/pulls/new/compare-forks" 64 + hx-target="#patch-strategy" 65 + hx-swap="innerHTML" 66 + > 67 + compare forks 68 + </button> 69 + </nav> 70 + <section id="patch-strategy" class="flex flex-col gap-2"> 71 + {{ template "repo/pulls/fragments/pullPatchUpload" . }} 72 + </section> 76 73 77 - <div id="patch-error" class="error dark:text-red-300"></div> 74 + <div id="patch-error" class="error dark:text-red-300"></div> 75 + </div> 78 76 79 77 <div> 80 78 <label for="title" class="dark:text-white">write a title</label>
+24 -9
appview/state/pull.go
··· 633 633 isBranchBased := isPushAllowed && sourceBranch != "" && fromFork == "" 634 634 isForkBased := fromFork != "" && sourceBranch != "" 635 635 isPatchBased := patch != "" && !isBranchBased && !isForkBased 636 + isStacked := r.FormValue("isStacked") == "on" 636 637 637 638 if isPatchBased && !patchutil.IsFormatPatch(patch) { 638 639 if title == "" { ··· 678 679 s.pages.Notice(w, "pull", "This knot doesn't support branch-based pull requests. Try another way?") 679 680 return 680 681 } 681 - s.handleBranchBasedPull(w, r, f, user, title, body, targetBranch, sourceBranch) 682 + s.handleBranchBasedPull(w, r, f, user, title, body, targetBranch, sourceBranch, isStacked) 682 683 } else if isForkBased { 683 684 if !caps.PullRequests.ForkSubmissions { 684 685 s.pages.Notice(w, "pull", "This knot doesn't support fork-based pull requests. Try another way?") 685 686 return 686 687 } 687 - s.handleForkBasedPull(w, r, f, user, fromFork, title, body, targetBranch, sourceBranch) 688 + s.handleForkBasedPull(w, r, f, user, fromFork, title, body, targetBranch, sourceBranch, isStacked) 688 689 } else if isPatchBased { 689 690 if !caps.PullRequests.PatchSubmissions { 690 691 s.pages.Notice(w, "pull", "This knot doesn't support patch-based pull requests. Send your patch over email.") 691 692 return 692 693 } 693 - s.handlePatchBasedPull(w, r, f, user, title, body, targetBranch, patch) 694 + s.handlePatchBasedPull(w, r, f, user, title, body, targetBranch, patch, isStacked) 694 695 } 695 696 return 696 697 } 697 698 } 698 699 699 - func (s *State) handleBranchBasedPull(w http.ResponseWriter, r *http.Request, f *FullyResolvedRepo, user *oauth.User, title, body, targetBranch, sourceBranch string) { 700 + func (s *State) handleBranchBasedPull( 701 + w http.ResponseWriter, 702 + r *http.Request, 703 + f *FullyResolvedRepo, 704 + user *oauth.User, 705 + title, 706 + body, 707 + targetBranch, 708 + sourceBranch string, 709 + isStacked bool, 710 + ) { 700 711 pullSource := &db.PullSource{ 701 712 Branch: sourceBranch, 702 713 } ··· 727 738 return 728 739 } 729 740 730 - s.createPullRequest(w, r, f, user, title, body, targetBranch, patch, sourceRev, pullSource, recordPullSource) 741 + s.createPullRequest(w, r, f, user, title, body, targetBranch, patch, sourceRev, pullSource, recordPullSource, isStacked) 731 742 } 732 743 733 - func (s *State) handlePatchBasedPull(w http.ResponseWriter, r *http.Request, f *FullyResolvedRepo, user *oauth.User, title, body, targetBranch, patch string) { 744 + func (s *State) handlePatchBasedPull(w http.ResponseWriter, r *http.Request, f *FullyResolvedRepo, user *oauth.User, title, body, targetBranch, patch string, isStacked bool) { 734 745 if !patchutil.IsPatchValid(patch) { 735 746 s.pages.Notice(w, "pull", "Invalid patch format. Please provide a valid diff.") 736 747 return 737 748 } 738 749 739 - s.createPullRequest(w, r, f, user, title, body, targetBranch, patch, "", nil, nil) 750 + s.createPullRequest(w, r, f, user, title, body, targetBranch, patch, "", nil, nil, isStacked) 740 751 } 741 752 742 - func (s *State) handleForkBasedPull(w http.ResponseWriter, r *http.Request, f *FullyResolvedRepo, user *oauth.User, forkRepo string, title, body, targetBranch, sourceBranch string) { 753 + func (s *State) handleForkBasedPull(w http.ResponseWriter, r *http.Request, f *FullyResolvedRepo, user *oauth.User, forkRepo string, title, body, targetBranch, sourceBranch string, isStacked bool) { 743 754 fork, err := db.GetForkByDid(s.db, user.Did, forkRepo) 744 755 if errors.Is(err, sql.ErrNoRows) { 745 756 s.pages.Notice(w, "pull", "No such fork.") ··· 816 827 s.createPullRequest(w, r, f, user, title, body, targetBranch, patch, sourceRev, &db.PullSource{ 817 828 Branch: sourceBranch, 818 829 RepoAt: &forkAtUri, 819 - }, &tangled.RepoPull_Source{Branch: sourceBranch, Repo: &fork.AtUri}) 830 + }, &tangled.RepoPull_Source{Branch: sourceBranch, Repo: &fork.AtUri}, isStacked) 820 831 } 821 832 822 833 func (s *State) createPullRequest( ··· 829 840 sourceRev string, 830 841 pullSource *db.PullSource, 831 842 recordPullSource *tangled.RepoPull_Source, 843 + isStacked bool, 832 844 ) { 845 + if isStacked { 846 + } 847 + 833 848 tx, err := s.db.BeginTx(r.Context(), nil) 834 849 if err != nil { 835 850 log.Println("failed to start tx")