From f442189a09af55d41384be05adfa6e998fe30087 Mon Sep 17 00:00:00 2001 From: whereareiam Date: Thu, 22 Oct 2026 22:36:03 +0200 Subject: [PATCH] fix(issues): GitHub's Development section for an issue's branch Forgejo's branch or tag selector sat in the issue sidebar as a loose "No Branch/Tag specified" button, and at the top of the new issue sidebar. It is now GitHub's Development section: a muted heading with the gear, like Assignees or Milestone, over the linked branch or tag. The new issue and pull request sidebar follows the issue page's GitHub order (assignees, labels, projects, milestone, then Development). Forgejo's menu and its scripts are unchanged. Co-Authored-By: Claude Opus 5.5 --- src/build-output.test.ts | 19 +++ styles/components/issues/issue.ts | 23 ++- templates/repo/issue/new_form.tmpl | 161 ++++++++++++++++++ .../repo/issue/view_content/sidebar.tmpl | 6 +- .../sidebar/branch_selector_field.tmpl | 57 +++++++ 5 files changed, 263 insertions(+), 3 deletions(-) create mode 100644 templates/repo/issue/new_form.tmpl create mode 100644 templates/repo/issue/view_content/sidebar/branch_selector_field.tmpl diff --git a/src/build-output.test.ts b/src/build-output.test.ts index 4e37f4f7..3157b27b 100644 --- a/src/build-output.test.ts +++ b/src/build-output.test.ts @@ -624,6 +624,25 @@ describe("Forgejo 15 native integration", () => { expect(read("styles", "components", "newrepo.ts")).toContain(".page-content.repository.new.repo {"); }); + it("shows the issue's branch as GitHub's Development section, last in both issue sidebars", () => { + const read = (...parts: string[]) => + fs.readFileSync(path.join(ROOT_DIR, "templates", "repo", "issue", ...parts), "utf-8"); + const field = read("view_content", "sidebar", "branch_selector_field.tmpl"); + expect(field).toContain("Development"); + expect(field).toContain(''); + expect(field).not.toContain('
'); + const form = read("new_form.tmpl"); + const order = [ + "sidebar/assignees", + "labels_selector_field", + "select-project dropdown", + "select-milestone dropdown", + "sidebar/branch_selector_field", + ].map(part => form.indexOf(part)); + expect(order.every(index => index > 0)).toBe(true); + expect([...order].sort((a, b) => a - b)).toEqual(order); + }); + it("matches GitHub's repository About, visibility, and code-search details", () => { const headerStyle = fs.readFileSync(path.join(ROOT_DIR, "styles", "templates", "repo", "header.ts"), "utf-8"); const headerTemplate = fs.readFileSync(path.join(ROOT_DIR, "templates", "repo", "home_header.tmpl"), "utf-8"); diff --git a/styles/components/issues/issue.ts b/styles/components/issues/issue.ts index 50d0a6b8..b97113df 100644 --- a/styles/components/issues/issue.ts +++ b/styles/components/issues/issue.ts @@ -96,6 +96,27 @@ const prBranch = css` } `; +// GitHub's Development section in the issue sidebar: the linked branch or tag under the heading. +const issueDevelopment = css` + .issue-content-right .ui.dropdown.theme-issue-development { + display: flex; + flex-direction: column; + align-items: stretch; + } + .issue-content-right .theme-issue-development-ref { + display: flex; + align-items: center; + gap: 4px; + min-width: 0; + color: ${themeVars.color.text.light.num1}; + font-size: 12px; + line-height: 18px; + > svg { + flex: none; + } + } +`; + const dropdown = css` .repository { /* Issue/PR 列表下的所有筛选菜单 */ @@ -148,4 +169,4 @@ const reactions = css` } `; -export default cssCombine(button, babel, prBranch, dropdown, issueTitle, reactions); +export default cssCombine(button, babel, prBranch, issueDevelopment, dropdown, issueTitle, reactions); diff --git a/templates/repo/issue/new_form.tmpl b/templates/repo/issue/new_form.tmpl new file mode 100644 index 00000000..3c86c3a4 --- /dev/null +++ b/templates/repo/issue/new_form.tmpl @@ -0,0 +1,161 @@ +{{/* Forgejo 17's new issue and pull request form with the sidebar in GitHub's order, as on an issue: assignees, +labels, projects, milestone, then Development (the branch or tag). */}} +{{if .Flash}} +{{template "base/alert" .}} +{{end}} +
+
+
+
+ {{ctx.AvatarUtils.Avatar .SignedUser 40}} +
+
+ + {{if .PageIsComparePull}} +
{{ctx.Locale.Tr "repo.pulls.title_wip_desc" (index .PullRequestWorkInProgressPrefixes 0)}}
+ {{end}} +
+ {{if .Fields}} + + {{range .Fields}} + {{if eq .Type "input"}} + {{template "repo/issue/fields/input" dict "Context" $.Context "item" .}} + {{else if eq .Type "markdown"}} + {{template "repo/issue/fields/markdown" dict "Context" $.Context "item" .}} + {{else if eq .Type "textarea"}} + {{template "repo/issue/fields/textarea" dict "Context" $.Context "item" . "root" $}} + {{else if eq .Type "dropdown"}} + {{template "repo/issue/fields/dropdown" dict "Context" $.Context "item" .}} + {{else if eq .Type "checkboxes"}} + {{template "repo/issue/fields/checkboxes" dict "Context" $.Context "item" .}} + {{end}} + {{end}} + {{else}} + {{template "repo/issue/comment_tab" .}} + {{end}} +
+ +
+
+
+
+
+ +
+ {{template "repo/issue/view_content/sidebar/assignees" dict "isExistingIssue" false "." .}} + +
+ + + {{template "repo/issue/labels/labels_selector_field" .}} + {{template "repo/issue/labels/labels_sidebar" dict "root" $}} + + {{if or .IsProjectsEnabled (and .OwnerHasProjects .IsOwnerProjectsEnabled)}} +
+ + + +
+ {{ctx.Locale.Tr "repo.issues.new.no_projects"}} + +
+ {{end}} + +
+ + + +
+ {{ctx.Locale.Tr "repo.issues.new.no_milestone"}} + +
+ + {{if not .PageIsComparePull}} +
+ {{template "repo/issue/view_content/sidebar/branch_selector_field" .}} + {{end}} + {{if and .PageIsComparePull (not (eq .HeadRepo.FullName .BaseCompareRepo.FullName)) .CanWriteToHeadRepo}} +
+
+
+ + +
+
+ {{end}} +
+ +
diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl index 64954142..a502738c 100644 --- a/templates/repo/issue/view_content/sidebar.tmpl +++ b/templates/repo/issue/view_content/sidebar.tmpl @@ -26,8 +26,10 @@
{{end}} - {{/* Ends with its own divider on issues. */}} - {{template "repo/issue/view_content/sidebar/branch_selector_field" .}} + {{if not .Issue.IsPull}} + {{template "repo/issue/view_content/sidebar/branch_selector_field" .}} +
+ {{end}} {{if and $.IssueWatch (not .Repository.IsArchived)}} {{template "repo/issue/view_content/sidebar/watch" .}} diff --git a/templates/repo/issue/view_content/sidebar/branch_selector_field.tmpl b/templates/repo/issue/view_content/sidebar/branch_selector_field.tmpl new file mode 100644 index 00000000..3b157b83 --- /dev/null +++ b/templates/repo/issue/view_content/sidebar/branch_selector_field.tmpl @@ -0,0 +1,57 @@ +{{/* Forgejo 17's branch and tag selector as GitHub's Development section: a heading with the gear like the other +sidebar sections, then the linked branch or tag. The menu and its scripts are Forgejo's; the caller places the +dividers. */}} +{{if and (not .Issue.IsPull) (not .PageIsComparePull)}} +{{$hasIssuesOrPullsWritePermission := and .HasIssuesOrPullsWritePermission (not .Repository.IsArchived)}} + + +
+
+{{/* TODO: share this branch selector dropdown with the same in repo page */}} + +{{end}}