fix: restore owner name in PR target branch selector (#39262)

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Zettat123
2026-09-08 09:34:49 -06:00
committed by GitHub
parent 45a78bbc8e
commit c9193adb68
7 changed files with 44 additions and 53 deletions

View File

@@ -202,15 +202,10 @@ func (pr *PullRequest) String() string {
return s.String() return s.String()
} }
// MustHeadUserName returns the HeadRepo's username if failed return blank // OptionalHeadUserName returns the HeadRepo's username if failed return blank
func (pr *PullRequest) MustHeadUserName(ctx context.Context) string { func (pr *PullRequest) OptionalHeadUserName(ctx context.Context) string {
if err := pr.LoadHeadRepo(ctx); err != nil { if err := pr.LoadHeadRepo(ctx); err != nil && !errors.Is(err, util.ErrNotExist) {
if !repo_model.IsErrRepoNotExist(err) { log.Error("LoadHeadRepo: %v", err)
log.Error("LoadHeadRepo: %v", err)
} else {
log.Warn("LoadHeadRepo %d but repository does not exist: %v", pr.HeadRepoID, err)
}
return ""
} }
if pr.HeadRepo == nil { if pr.HeadRepo == nil {
return "" return ""

View File

@@ -207,10 +207,12 @@ func (cpi *comparePageInfoType) parseCompareInfo(ctx *context.Context, comparePa
return err return err
} }
// for the dropdown links ("{base} ... {head}") in the compare page "compare.tmpl"
ctx.Data["BaseName"] = baseRepo.OwnerName ctx.Data["BaseName"] = baseRepo.OwnerName
ctx.Data["BaseBranch"] = baseRef.ShortName() // for legacy templates
ctx.Data["HeadUser"] = headOwner ctx.Data["HeadUser"] = headOwner
ctx.Data["HeadBranch"] = headRef.ShortName() // for legacy templates ctx.Data["BaseBranch"] = baseRef.ShortName() // also for "commits_table.tmpl"'s "no_commits" message
ctx.Data["HeadBranch"] = headRef.ShortName()
ctx.Data["IsPull"] = true ctx.Data["IsPull"] = true
context.InitRepoPullRequestCtx(ctx, baseRepo, headRepo) context.InitRepoPullRequestCtx(ctx, baseRepo, headRepo)

View File

@@ -161,12 +161,12 @@ func getPullInfo(ctx *context.Context) (issue *issues_model.Issue, ok bool) {
func (prInfo *pullRequestViewInfo) setTemplateDataMergeTarget(ctx *context.Context) { func (prInfo *pullRequestViewInfo) setTemplateDataMergeTarget(ctx *context.Context) {
pull := prInfo.issue.PullRequest pull := prInfo.issue.PullRequest
if ctx.Repo.Owner.Name == pull.MustHeadUserName(ctx) { if ctx.Repo.Owner.Name == pull.OptionalHeadUserName(ctx) {
prInfo.headTarget = pull.HeadBranch prInfo.headTarget = pull.HeadBranch
} else if pull.HeadRepo == nil { } else if pull.HeadRepo == nil {
prInfo.headTarget = ctx.Locale.TrString("repo.pull.deleted_branch", pull.HeadBranch) prInfo.headTarget = ctx.Locale.TrString("repo.pull.deleted_branch", pull.HeadBranch)
} else { } else {
prInfo.headTarget = pull.MustHeadUserName(ctx) + "/" + pull.HeadRepo.Name + ":" + pull.HeadBranch prInfo.headTarget = pull.OptionalHeadUserName(ctx) + "/" + pull.HeadRepo.Name + ":" + pull.HeadBranch
} }
ctx.Data["HeadTarget"] = prInfo.headTarget ctx.Data["HeadTarget"] = prInfo.headTarget
ctx.Data["BaseTarget"] = pull.BaseBranch ctx.Data["BaseTarget"] = pull.BaseBranch
@@ -351,11 +351,6 @@ func (prInfo *pullRequestViewInfo) prepareViewInfo(ctx *context.Context, issue *
return return
} }
// for the PR target branch selector
ctx.Data["BaseBranch"] = issue.PullRequest.BaseBranch
ctx.Data["HeadBranch"] = issue.PullRequest.HeadBranch
ctx.Data["HeadUserName"] = issue.PullRequest.MustHeadUserName(ctx)
if issue.PullRequest.HasMerged { if issue.PullRequest.HasMerged {
prInfo.prepareViewMergedPullInfo(ctx) prInfo.prepareViewMergedPullInfo(ctx)
} else { } else {

View File

@@ -38,7 +38,7 @@
</div> </div>
</form> </form>
{{end}} {{end}}
<div class="issue-title-meta"> <div class="issue-title-meta flex-text-block">
{{if .HasMerged}} {{if .HasMerged}}
<div class="ui purple label issue-state-label">{{svg "octicon-git-merge" 16 "tw-mr-1"}} {{if eq .Issue.PullRequest.Status 3}}{{ctx.Locale.Tr "repo.pulls.manually_merged"}}{{else}}{{ctx.Locale.Tr "repo.pulls.merged"}}{{end}}</div> <div class="ui purple label issue-state-label">{{svg "octicon-git-merge" 16 "tw-mr-1"}} {{if eq .Issue.PullRequest.Status 3}}{{ctx.Locale.Tr "repo.pulls.manually_merged"}}{{else}}{{ctx.Locale.Tr "repo.pulls.merged"}}{{end}}</div>
{{else if .Issue.IsClosed}} {{else if .Issue.IsClosed}}
@@ -52,7 +52,7 @@
{{else}} {{else}}
<div class="ui green label issue-state-label">{{svg "octicon-issue-opened"}} {{ctx.Locale.Tr "repo.issues.open_title"}}</div> <div class="ui green label issue-state-label">{{svg "octicon-issue-opened"}} {{ctx.Locale.Tr "repo.issues.open_title"}}</div>
{{end}} {{end}}
<div class="tw-ml-2 tw-flex-1 tw-break-anywhere"> <div class="flex-text-block">
{{if .Issue.IsPull}} {{if .Issue.IsPull}}
{{$headHref := .HeadTarget}} {{$headHref := .HeadTarget}}
{{if .HeadBranchLink}} {{if .HeadBranchLink}}
@@ -90,16 +90,22 @@
{{ctx.Locale.Tr "repo.pulls.title_desc" .NumCommits $headHref $baseHref}} {{ctx.Locale.Tr "repo.pulls.title_desc" .NumCommits $headHref $baseHref}}
</span> </span>
{{end}} {{end}}
<span id="pull-desc-editor" class="tw-hidden flex-text-block" data-target-update-url="{{$.RepoLink}}/pull/{{.Issue.Index}}/target_branch"> {{if .Issue.PullRequest}}
<div class="ui floating filter dropdown"> <div id="pull-desc-editor" class="tw-hidden flex-text-block tw-flex-wrap" data-target-update-url="{{$.RepoLink}}/pull/{{.Issue.Index}}/target_branch">
<div class="ui basic small button tw-mr-0"> {{$pr := .Issue.PullRequest}}
<span class="text">{{ctx.Locale.Tr "repo.pulls.compare_compare"}}: {{$.HeadTarget}}</span> {{$baseBranch := $pr.BaseBranch}}
</div> {{$headBranch := $pr.HeadBranch}}
{{$baseUserName := $pr.BaseRepo.OwnerName}}
{{$headUserName := $pr.OptionalHeadUserName ctx}}
<div class="ui basic small button tw-pointer-events-none">
<span class="gt-ellipsis">{{ctx.Locale.Tr "repo.pulls.compare_compare"}}: {{$.HeadTarget}}</span>
</div> </div>
{{svg "octicon-arrow-right"}} {{svg "octicon-arrow-right"}}
<div class="ui floating filter dropdown" data-no-results="{{ctx.Locale.Tr "no_results_found"}}"> <div class="ui floating dropdown" data-no-results="{{ctx.Locale.Tr "no_results_found"}}">
<div class="ui basic small button"> <div class="ui basic small button">
<span class="text" id="pull-target-branch" data-basename="{{$.BaseName}}" data-branch="{{$.BaseBranch}}">{{ctx.Locale.Tr "repo.pulls.compare_base"}}: {{$.BaseName}}:{{$.BaseBranch}}</span> <span id="pull-target-branch" class="gt-ellipsis" data-base-user-name="{{$baseUserName}}" data-text-compare-base="{{ctx.Locale.Tr "repo.pulls.compare_base"}}">
{{ctx.Locale.Tr "repo.pulls.compare_base"}}: {{$baseUserName}}:{{$baseBranch}}
</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}} {{svg "octicon-triangle-down" 14 "dropdown icon"}}
</div> </div>
<div class="menu"> <div class="menu">
@@ -108,17 +114,18 @@
<input name="search" placeholder="{{ctx.Locale.Tr "repo.pulls.filter_branch"}}..."> <input name="search" placeholder="{{ctx.Locale.Tr "repo.pulls.filter_branch"}}...">
</div> </div>
<div class="scrolling menu" id="branch-select"> <div class="scrolling menu" id="branch-select">
{{range .Branches}} {{$differentOwner := ne $baseUserName $headUserName}}
{{$sameBase := ne $.BaseName $.HeadUserName}} {{range $branch := $.Branches}}
{{$differentBranch := ne . $.HeadBranch}} {{$differentBranch := ne $branch $headBranch}}
{{if or $sameBase $differentBranch}} {{if or $differentOwner $differentBranch}}
<div class="item {{if eq $.BaseBranch .}}selected{{end}}" data-branch="{{.}}">{{$.BaseName}}:{{.}}</div> <div class="item {{if eq $baseBranch $branch}}selected{{end}}" data-branch="{{$branch}}">{{$baseUserName}}:{{$branch}}</div>
{{end}} {{end}}
{{end}} {{end}}
</div> </div>
</div> </div>
</div> </div>
</span> </div>
{{end}}
{{end}} {{end}}
{{else}} {{else}}
{{$createdStr:= DateUtils.TimeSince .Issue.CreatedUnix}} {{$createdStr:= DateUtils.TimeSince .Issue.CreatedUnix}}

View File

@@ -302,11 +302,6 @@
margin-bottom: 1rem; margin-bottom: 1rem;
} }
.issue-title-meta {
display: flex;
align-items: center;
}
.repository.view.issue .issue-title-buttons { .repository.view.issue .issue-title-buttons {
display: flex; display: flex;
gap: 0.5em; gap: 0.5em;

View File

@@ -399,6 +399,17 @@ export function initRepoIssueTitleEdit() {
const pullDescEditor = document.querySelector('#pull-desc-editor'); // it may not exist for a merged PR const pullDescEditor = document.querySelector('#pull-desc-editor'); // it may not exist for a merged PR
const prTargetUpdateUrl = pullDescEditor?.getAttribute('data-target-update-url'); const prTargetUpdateUrl = pullDescEditor?.getAttribute('data-target-update-url');
pullDescEditor?.querySelector('#branch-select')?.addEventListener('click', (e: Event) => {
const el = (e.target as HTMLElement).closest('.item[data-branch]');
if (!el) return;
const pullTargetBranch = pullDescEditor.querySelector('#pull-target-branch')!;
const textCompareBase = pullTargetBranch.getAttribute('data-text-compare-base')!;
const baseUserName = pullTargetBranch.getAttribute('data-base-user-name')!;
const branchNameNew = el.getAttribute('data-branch')!;
pullTargetBranch.textContent = `${textCompareBase}: ${baseUserName}:${branchNameNew}`;
pullTargetBranch.setAttribute('data-branch', branchNameNew);
});
const editSaveButton = issueTitleEditor.querySelector('.ui.primary.button')!; const editSaveButton = issueTitleEditor.querySelector('.ui.primary.button')!;
issueTitleEditor.addEventListener('submit', async (e) => { issueTitleEditor.addEventListener('submit', async (e) => {
e.preventDefault(); e.preventDefault();
@@ -429,19 +440,6 @@ export function initRepoIssueTitleEdit() {
}); });
} }
export function initRepoIssueBranchSelect() {
document.querySelector<HTMLElement>('#branch-select')?.addEventListener('click', (e: Event) => {
const el = (e.target as HTMLElement).closest('.item[data-branch]');
if (!el) return;
const pullTargetBranch = document.querySelector('#pull-target-branch')!;
const baseName = pullTargetBranch.getAttribute('data-basename');
const branchNameNew = el.getAttribute('data-branch')!;
const branchNameOld = pullTargetBranch.getAttribute('data-branch');
pullTargetBranch.textContent = pullTargetBranch.textContent.replace(`${baseName}:${branchNameOld}`, `${baseName}:${branchNameNew}`);
pullTargetBranch.setAttribute('data-branch', branchNameNew);
});
}
async function initSingleCommentEditor(commentForm: HTMLFormElement) { async function initSingleCommentEditor(commentForm: HTMLFormElement) {
// pages: // pages:
// * normal new issue/pr page: no status-button, no comment-button (there is only a normal submit button which can submit empty content) // * normal new issue/pr page: no status-button, no comment-button (there is only a normal submit button which can submit empty content)

View File

@@ -1,7 +1,7 @@
import {registerGlobalInitFunc} from '../modules/observer.ts'; import {registerGlobalInitFunc} from '../modules/observer.ts';
import { import {
initRepoCommentFormAndSidebar, initRepoCommentFormAndSidebar,
initRepoIssueBranchSelect, initRepoIssueCodeCommentCancel, initRepoIssueCommentDelete, initRepoIssueCodeCommentCancel, initRepoIssueCommentDelete,
initRepoIssueComments, initRepoIssueReferenceIssue, initRepoIssueComments, initRepoIssueReferenceIssue,
initRepoIssueTitleEdit, initRepoIssueWipNewTitle, initRepoIssueWipToggle, initRepoIssueTitleEdit, initRepoIssueWipNewTitle, initRepoIssueWipToggle,
} from './repo-issue.ts'; } from './repo-issue.ts';
@@ -61,7 +61,6 @@ export function initRepository() {
if (pageContent.matches('.page-content.repository.view.issue')) { if (pageContent.matches('.page-content.repository.view.issue')) {
initRepoIssueCommentEdit(); initRepoIssueCommentEdit();
initRepoIssueBranchSelect();
initRepoIssueTitleEdit(); initRepoIssueTitleEdit();
initRepoIssueWipToggle(); initRepoIssueWipToggle();
initRepoIssueComments(); initRepoIssueComments();