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

appview: pulls: make target branch picking generic

anirudh.fi 6379061a c2e3b7a7

verified
Changed files
+99 -96
appview
-1
appview/pages/pages.go
···
type RepoNewPullParams struct {
LoggedInUser *auth.User
RepoInfo RepoInfo
-
Forks []db.Repo
Branches []types.Branch
Active string
}
+17 -32
appview/pages/templates/fragments/pullCompareBranches.html
···
{{ define "fragments/pullCompareBranches" }}
-
-
<div id="patch-upload">
-
<label for="targetBranch" class="dark:text-white">configure branches</label>
-
<div class="flex flex-wrap gap-2 items-center">
-
<select
-
required
-
name="targetBranch"
-
class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600"
+
<div id="patch-upload">
+
<label for="targetBranch" class="dark:text-white"
+
>select a branch</label
>
-
<option disabled selected>target branch</option>
-
{{ range .Branches }}
-
<option value="{{ .Reference.Name }}" class="py-1">
-
{{ .Reference.Name }}
-
</option>
-
{{ end }}
-
</select>
-
-
{{ i "move-left" "w-5 h-5" }}
-
-
<select
-
name="sourceBranch"
-
class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600"
-
>
-
<option disabled selected>source branch</option>
-
{{ range .Branches }}
-
<option value="{{ .Reference.Name }}" class="py-1">
-
{{ .Reference.Name }}
-
</option>
-
{{ end }}
-
</select>
-
</div>
-
-
</div>
+
<div class="flex flex-wrap gap-2 items-center">
+
<select
+
name="sourceBranch"
+
class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600"
+
>
+
<option disabled selected>source branch</option>
+
{{ range .Branches }}
+
<option value="{{ .Reference.Name }}" class="py-1">
+
{{ .Reference.Name }}
+
</option>
+
{{ end }}
+
</select>
+
</div>
+
</div>
{{ end }}
+32 -25
appview/pages/templates/fragments/pullCompareForks.html
···
<label for="forkSelect" class="dark:text-white"
>select a fork to compare</label
>
-
<div class="flex flex-wrap gap-2 items-center mb-4">
-
<select
-
id="forkSelect"
-
name="fork"
-
required
-
class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600"
-
hx-get="/{{ $.RepoInfo.FullName }}/pulls/new/fork-branches"
-
hx-target="#branch-selection"
-
hx-vals='{"fork": this.value}'
-
hx-swap="innerHTML"
-
onchange="document.getElementById('hiddenForkInput').value = this.value;"
-
>
-
<option disabled selected>select a fork</option>
-
{{ range .Forks }}
-
<option value="{{ .Name }}" class="py-1">
-
{{ .Name }}
-
</option>
-
{{ end }}
-
</select>
-
-
<input type="hidden" id="hiddenForkInput" name="fork" value="">
-
</div>
+
<div class="flex flex-wrap gap-4 items-center mb-4">
+
<div class="flex flex-wrap gap-2 items-center">
+
<select
+
id="forkSelect"
+
name="fork"
+
required
+
class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600"
+
hx-get="/{{ $.RepoInfo.FullName }}/pulls/new/fork-branches"
+
hx-target="#branch-selection"
+
hx-vals='{"fork": this.value}'
+
hx-swap="innerHTML"
+
onchange="document.getElementById('hiddenForkInput').value = this.value;"
+
>
+
<option disabled selected>select a fork</option>
+
{{ range .Forks }}
+
<option value="{{ .Name }}" class="py-1">
+
{{ .Name }}
+
</option>
+
{{ end }}
+
</select>
+
+
<input
+
type="hidden"
+
id="hiddenForkInput"
+
name="fork"
+
value=""
+
/>
+
</div>
-
<div id="branch-selection" class="mt-2">
-
<div class="text-sm text-gray-500 dark:text-gray-400">
-
Select a fork first to view available branches
+
<div id="branch-selection">
+
<div class="text-sm text-gray-500 dark:text-gray-400">
+
Select a fork first to view available branches
+
</div>
</div>
</div>
</div>
-16
appview/pages/templates/fragments/pullCompareForksBranches.html
···
{{ define "fragments/pullCompareForksBranches" }}
<div class="flex flex-wrap gap-2 items-center">
<select
-
required
-
name="targetBranch"
-
class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600"
-
>
-
<option disabled selected>target branch</option>
-
{{ range .TargetBranches }}
-
<option value="{{ .Reference.Name }}" class="py-1">
-
{{ .Reference.Name }}
-
</option>
-
{{ end }}
-
</select>
-
-
{{ i "move-left" "w-5 h-5" }}
-
-
-
<select
name="sourceBranch"
class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600"
>
+30 -5
appview/pages/templates/repo/pulls/new.html
···
</div>
-
<label>choose your pull strategy</label>
-
<nav class="flex space-x-4">
+
<label>configure your pull request</label>
+
+
<p>First, choose a target branch on {{ .RepoInfo.FullName }}.</p>
+
<div class="pb-2">
+
<select
+
required
+
name="targetBranch"
+
class="p-1 border border-gray-200 bg-white dark:bg-gray-700 dark:text-white dark:border-gray-600"
+
>
+
<option disabled selected>target branch</option>
+
{{ range .Branches }}
+
<option value="{{ .Reference.Name }}" class="py-1">
+
{{ .Reference.Name }}
+
</option>
+
{{ end }}
+
</select>
+
</div>
+
+
<p>Then, choose a pull strategy.</p>
+
<nav class="flex space-x-4 items-end">
<button
type="button"
class="px-3 py-2 pb-2 btn"
···
</button>
{{ if .RepoInfo.Roles.IsPushAllowed }}
+
<span class="text-sm text-gray-500 dark:text-gray-400 pb-2">
+
or
+
</span>
<button
type="button"
class="px-3 py-2 pb-2 btn"
···
compare branches
</button>
{{ end }}
+
+
<span class="text-sm text-gray-500 dark:text-gray-400 pb-2">
+
or
+
</span>
<button
type="button"
class="px-3 py-2 pb-2 btn"
···
</button>
</nav>
-
<section id="patch-strategy">
+
<section id="patch-strategy">
{{ template "fragments/pullPatchUpload" . }}
</section>
-
<div class="flex justify-start items-center gap-2">
+
<div class="flex justify-start items-center gap-2 mt-4">
<button type="submit" class="btn flex items-center gap-2">
{{ i "git-pull-request-create" "w-4 h-4" }}
create pull
</button>
-
</div>
+
</div>
</div>
<div id="pull" class="error dark:text-red-300"></div>
+6 -1
appview/pages/templates/repo/pulls/pull.html
···
{{ if not .Pull.IsSameRepoBranch }}
<a href="/{{ $owner }}/{{ .PullSourceRepo.Name }}" class="no-underline hover:underline">{{ $owner }}/{{ .PullSourceRepo.Name }}</a>
{{ end }}
+
+
{{ $fullRepo := .RepoInfo.FullName }}
+
{{ if not .Pull.IsSameRepoBranch }}
+
{{ $fullRepo = printf "%s/%s" $owner .PullSourceRepo.Name }}
+
{{ end }}
<span class="text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 mx-1/2 inline-flex items-center">
-
<a href="/{{ $owner }}/{{ .PullSourceRepo.Name }}/tree/{{ .Pull.PullSource.Branch }}" class="no-underline hover:underline">{{ .Pull.PullSource.Branch }}</a>
+
<a href="/{{ $fullRepo }}/tree/{{ .Pull.PullSource.Branch }}" class="no-underline hover:underline">{{ .Pull.PullSource.Branch }}</a>
</span>
</span>
{{ end }}
+14 -16
appview/state/pull.go
···
return
}
-
forks, err := db.GetForksByDid(s.db, user.Did)
-
if err != nil {
-
log.Println("failed to get forks", err)
-
return
-
}
-
switch r.Method {
case http.MethodGet:
us, err := NewUnsignedClient(f.Knot, s.config.Dev)
···
s.pages.RepoNewPull(w, pages.RepoNewPullParams{
LoggedInUser: user,
RepoInfo: f.RepoInfo(s, user),
-
Forks: forks,
Branches: result.Branches,
})
case http.MethodPost:
···
sourceBranch := r.FormValue("sourceBranch")
patch := r.FormValue("patch")
+
// Validate required fields for all PR types
+
if title == "" || body == "" || targetBranch == "" {
+
s.pages.Notice(w, "pull", "Title, body and target branch are required.")
+
return
+
}
+
+
// Determine PR type based on input parameters
isPushAllowed := f.RepoInfo(s, user).Roles.IsPushAllowed()
isBranchBased := isPushAllowed && sourceBranch != "" && fromFork == ""
-
isPatchBased := patch != ""
isForkBased := fromFork != "" && sourceBranch != ""
+
isPatchBased := patch != "" && !isBranchBased && !isForkBased
+
// Validate we have at least one valid PR creation method
if !isBranchBased && !isPatchBased && !isForkBased {
s.pages.Notice(w, "pull", "Neither source branch nor patch supplied.")
return
}
-
if isBranchBased && isPatchBased {
+
// Can't mix branch-based and patch-based approaches
+
if isBranchBased && patch != "" {
s.pages.Notice(w, "pull", "Cannot select both patch and source branch.")
return
}
-
if title == "" || body == "" || targetBranch == "" {
-
s.pages.Notice(w, "pull", "Title, body and target branch are required.")
-
return
-
}
-
+
// Handle the PR creation based on the type
if isBranchBased {
s.handleBranchBasedPull(w, r, f, user, title, body, targetBranch, sourceBranch)
+
} else if isForkBased {
+
s.handleForkBasedPull(w, r, f, user, fromFork, title, body, targetBranch, sourceBranch)
} else if isPatchBased {
s.handlePatchBasedPull(w, r, f, user, title, body, targetBranch, patch)
-
} else if isForkBased {
-
s.handleForkBasedPull(w, r, f, user, fromFork, title, body, targetBranch, sourceBranch)
}
return
}