Skip to content

Commit

Permalink
Merge remote-tracking branch 'giteaofficial/main'
Browse files Browse the repository at this point in the history
* giteaofficial/main:
  Refactor RepoBranchTagSelector (go-gitea#32681)
  Allow to disable the password-based login (sign-in) form (go-gitea#32687)
  Fix JS error when reply comment on Conversation page (go-gitea#32685)
  fix(go-gitea#32667): 🐛 Fixe a keystring misuse and refactor duplicates keystrings (go-gitea#32668)
  • Loading branch information
zjjhot committed Dec 2, 2024
2 parents 24e46aa + e3e3260 commit 5ebe735
Show file tree
Hide file tree
Showing 20 changed files with 370 additions and 354 deletions.
22 changes: 13 additions & 9 deletions custom/conf/app.example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,10 @@ LEVEL = Info
;; Please note that setting this to false will not disable OAuth Basic or Basic authentication using a token
;ENABLE_BASIC_AUTHENTICATION = true
;;
;; Show the password sign-in form (for password-based login), otherwise, only show OAuth2 login methods.
;; If you set it to false, maybe it also needs to set ENABLE_BASIC_AUTHENTICATION to false to completely disable password-based authentication.
;ENABLE_PASSWORD_SIGNIN_FORM = true
;;
;; More detail: https://github.com/gogits/gogs/issues/165
;ENABLE_REVERSE_PROXY_AUTHENTICATION = false
; Enable this to allow reverse proxy authentication for API requests, the reverse proxy is responsible for ensuring that no CSRF is possible.
Expand Down Expand Up @@ -1944,13 +1948,13 @@ LEVEL = Info
;; Minio secretAccessKey to connect only available when STORAGE_TYPE is `minio`
;MINIO_SECRET_ACCESS_KEY =
;;
;; Preferred IAM Endpoint to override Minio's default IAM Endpoint resolution only available when STORAGE_TYPE is `minio`.
;; If not provided and STORAGE_TYPE is `minio`, will search for and derive endpoint from known environment variables
;; (AWS_CONTAINER_AUTHORIZATION_TOKEN, AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,
;; AWS_CONTAINER_CREDENTIALS_FULL_URI, AWS_WEB_IDENTITY_TOKEN_FILE, AWS_ROLE_ARN, AWS_ROLE_SESSION_NAME, AWS_REGION),
;; Preferred IAM Endpoint to override Minio's default IAM Endpoint resolution only available when STORAGE_TYPE is `minio`.
;; If not provided and STORAGE_TYPE is `minio`, will search for and derive endpoint from known environment variables
;; (AWS_CONTAINER_AUTHORIZATION_TOKEN, AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,
;; AWS_CONTAINER_CREDENTIALS_FULL_URI, AWS_WEB_IDENTITY_TOKEN_FILE, AWS_ROLE_ARN, AWS_ROLE_SESSION_NAME, AWS_REGION),
;; or the DefaultIAMRoleEndpoint if not provided otherwise.
;MINIO_IAM_ENDPOINT =
;;
;;
;; Minio bucket to store the attachments only available when STORAGE_TYPE is `minio`
;MINIO_BUCKET = gitea
;;
Expand Down Expand Up @@ -2695,10 +2699,10 @@ LEVEL = Info
;; Minio secretAccessKey to connect only available when STORAGE_TYPE is `minio`
;MINIO_SECRET_ACCESS_KEY =
;;
;; Preferred IAM Endpoint to override Minio's default IAM Endpoint resolution only available when STORAGE_TYPE is `minio`.
;; If not provided and STORAGE_TYPE is `minio`, will search for and derive endpoint from known environment variables
;; (AWS_CONTAINER_AUTHORIZATION_TOKEN, AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,
;; AWS_CONTAINER_CREDENTIALS_FULL_URI, AWS_WEB_IDENTITY_TOKEN_FILE, AWS_ROLE_ARN, AWS_ROLE_SESSION_NAME, AWS_REGION),
;; Preferred IAM Endpoint to override Minio's default IAM Endpoint resolution only available when STORAGE_TYPE is `minio`.
;; If not provided and STORAGE_TYPE is `minio`, will search for and derive endpoint from known environment variables
;; (AWS_CONTAINER_AUTHORIZATION_TOKEN, AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI,
;; AWS_CONTAINER_CREDENTIALS_FULL_URI, AWS_WEB_IDENTITY_TOKEN_FILE, AWS_ROLE_ARN, AWS_ROLE_SESSION_NAME, AWS_REGION),
;; or the DefaultIAMRoleEndpoint if not provided otherwise.
;MINIO_IAM_ENDPOINT =
;;
Expand Down
2 changes: 1 addition & 1 deletion modules/cache/cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func TestTest(t *testing.T) {
elapsed, err := Test()
assert.NoError(t, err)
// mem cache should take from 300ns up to 1ms on modern hardware ...
assert.Less(t, elapsed, SlowCacheThreshold)
assert.Less(t, elapsed, time.Millisecond)
}

func TestGetCache(t *testing.T) {
Expand Down
2 changes: 2 additions & 0 deletions modules/setting/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ var Service = struct {
AllowOnlyInternalRegistration bool
AllowOnlyExternalRegistration bool
ShowRegistrationButton bool
EnablePasswordSignInForm bool
ShowMilestonesDashboardPage bool
RequireSignInView bool
EnableNotifyMail bool
Expand Down Expand Up @@ -159,6 +160,7 @@ func loadServiceFrom(rootCfg ConfigProvider) {
Service.ShowMilestonesDashboardPage = sec.Key("SHOW_MILESTONES_DASHBOARD_PAGE").MustBool(true)
Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool()
Service.EnableBasicAuth = sec.Key("ENABLE_BASIC_AUTHENTICATION").MustBool(true)
Service.EnablePasswordSignInForm = sec.Key("ENABLE_PASSWORD_SIGNIN_FORM").MustBool(true)
Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
Service.EnableReverseProxyAuthAPI = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION_API").MustBool()
Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool()
Expand Down
2 changes: 0 additions & 2 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -1461,8 +1461,6 @@ issues.new.no_items = No items
issues.new.milestone = Milestone
issues.new.no_milestone = No Milestone
issues.new.clear_milestone = Clear milestone
issues.new.open_milestone = Open Milestones
issues.new.closed_milestone = Closed Milestones
issues.new.assignees = Assignees
issues.new.clear_assignees = Clear assignees
issues.new.no_assignees = No Assignees
Expand Down
48 changes: 17 additions & 31 deletions routers/web/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,54 +160,42 @@ func CheckAutoLogin(ctx *context.Context) bool {
return false
}

// SignIn render sign in page
func SignIn(ctx *context.Context) {
func prepareSignInPageData(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("sign_in")

if CheckAutoLogin(ctx) {
return
}

if ctx.IsSigned {
RedirectAfterLogin(ctx)
return
}

oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, optional.Some(true))
if err != nil {
ctx.ServerError("UserSignIn", err)
return
}
ctx.Data["OAuth2Providers"] = oauth2Providers
ctx.Data["OAuth2Providers"], _ = oauth2.GetOAuth2Providers(ctx, optional.Some(true))
ctx.Data["Title"] = ctx.Tr("sign_in")
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
ctx.Data["PageIsSignIn"] = true
ctx.Data["PageIsLogin"] = true
ctx.Data["EnableSSPI"] = auth.IsSSPIEnabled(ctx)
ctx.Data["EnablePasswordSignInForm"] = setting.Service.EnablePasswordSignInForm

if setting.Service.EnableCaptcha && setting.Service.RequireCaptchaForLogin {
context.SetCaptchaData(ctx)
}
}

// SignIn render sign in page
func SignIn(ctx *context.Context) {
if CheckAutoLogin(ctx) {
return
}
if ctx.IsSigned {
RedirectAfterLogin(ctx)
return
}
prepareSignInPageData(ctx)
ctx.HTML(http.StatusOK, tplSignIn)
}

// SignInPost response for sign in request
func SignInPost(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("sign_in")

oauth2Providers, err := oauth2.GetOAuth2Providers(ctx, optional.Some(true))
if err != nil {
ctx.ServerError("UserSignIn", err)
if !setting.Service.EnablePasswordSignInForm {
ctx.Error(http.StatusForbidden)
return
}
ctx.Data["OAuth2Providers"] = oauth2Providers
ctx.Data["Title"] = ctx.Tr("sign_in")
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
ctx.Data["PageIsSignIn"] = true
ctx.Data["PageIsLogin"] = true
ctx.Data["EnableSSPI"] = auth.IsSSPIEnabled(ctx)

prepareSignInPageData(ctx)
if ctx.HasError() {
ctx.HTML(http.StatusOK, tplSignIn)
return
Expand All @@ -216,8 +204,6 @@ func SignInPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.SignInForm)

if setting.Service.EnableCaptcha && setting.Service.RequireCaptchaForLogin {
context.SetCaptchaData(ctx)

context.VerifyCaptcha(ctx, tplSignIn, form)
if ctx.Written() {
return
Expand Down
110 changes: 40 additions & 70 deletions templates/repo/branch_dropdown.tmpl
Original file line number Diff line number Diff line change
@@ -1,87 +1,57 @@
{{/* Attributes:
* root
* ContainerClasses
* (TODO: search "branch_dropdown" in the template directory)
*/}}
{{$defaultSelectedRefName := $.root.BranchName}}
{{if and .root.IsViewTag (not .noTag)}}
{{$defaultSelectedRefName = .root.TagName}}
{{end}}
{{if eq $defaultSelectedRefName ""}}
{{$defaultSelectedRefName = $.root.Repository.DefaultBranch}}
{{end}}

{{$type := ""}}
{{if and .root.IsViewTag (not .noTag)}}
{{$type = "tag"}}
{{else if .root.IsViewBranch}}
{{$type = "branch"}}
{{else}}
{{$type = "tree"}}
{{end}}
* Repository
* CurrentRefType: eg. "branch", "tag"
* CurrentRefShortName: eg. "master", "v1.0"
* CurrentTreePath
* RefLinkTemplate: redirect to the link when a branch/tag is selected
* RefFormActionTemplate: change the parent form's action when a branch/tag is selected
* DropdownFixedText: the text to show in the dropdown (mainly used by "release page"), if empty, the text will be the branch/tag name
* ShowTabBranches
* ShowTabTagsTab
* AllowCreateNewRef

{{$showBranchesInDropdown := not .root.HideBranchesInDropdown}}
Search "repo/branch_dropdown" in the template directory to find all occurrences.
*/}}
<div class="js-branch-tag-selector {{if .ContainerClasses}}{{.ContainerClasses}}{{end}}"
data-text-release-compare="{{ctx.Locale.Tr "repo.release.compare"}}"
data-text-branches="{{ctx.Locale.Tr "repo.branches"}}"
data-text-tags="{{ctx.Locale.Tr "repo.tags"}}"
data-text-filter-branch="{{ctx.Locale.Tr "repo.pulls.filter_branch"}}"
data-text-filter-tag="{{ctx.Locale.Tr "repo.find_tag"}}"
data-text-default-branch-label="{{ctx.Locale.Tr "repo.default_branch_label"}}"
data-text-create-tag="{{ctx.Locale.Tr "repo.tag.create_tag"}}"
data-text-create-branch="{{ctx.Locale.Tr "repo.branch.create_branch"}}"
data-text-create-ref-from="{{ctx.Locale.Tr "repo.branch.create_from"}}"
data-text-no-results="{{ctx.Locale.Tr "no_results_found"}}"

<script type="module">
const data = {
'textReleaseCompare': {{ctx.Locale.Tr "repo.release.compare"}},
'textCreateTag': {{ctx.Locale.Tr "repo.tag.create_tag"}},
'textCreateBranch': {{ctx.Locale.Tr "repo.branch.create_branch"}},
'textCreateBranchFrom': {{ctx.Locale.Tr "repo.branch.create_from"}},
'textBranches': {{ctx.Locale.Tr "repo.branches"}},
'textTags': {{ctx.Locale.Tr "repo.tags"}},
'textDefaultBranchLabel': {{ctx.Locale.Tr "repo.default_branch_label"}},
data-current-repo-default-branch="{{.Repository.DefaultBranch}}"
data-current-repo-link="{{.Repository.Link}}"
data-current-tree-path="{{.CurrentTreePath}}"
data-current-ref-type="{{.CurrentRefType}}"
data-current-ref-short-name="{{.CurrentRefShortName}}"

'mode': '{{if or .root.IsViewTag .isTag}}tags{{else}}branches{{end}}',
'showBranchesInDropdown': {{$showBranchesInDropdown}},
'searchFieldPlaceholder': '{{if $.noTag}}{{ctx.Locale.Tr "repo.pulls.filter_branch"}}{{else if $showBranchesInDropdown}}{{ctx.Locale.Tr "repo.filter_branch_and_tag"}}{{else}}{{ctx.Locale.Tr "repo.find_tag"}}{{end}}...',
'branchForm': {{$.branchForm}},
'disableCreateBranch': {{if .disableCreateBranch}}{{.disableCreateBranch}}{{else}}{{not .root.CanCreateBranch}}{{end}},
'setAction': {{.setAction}},
'submitForm': {{.submitForm}},
'viewType': {{$type}},
'refName': {{if and .root.IsViewTag (not .noTag)}}{{.root.TagName}}{{else if .root.IsViewBranch}}{{.root.BranchName}}{{else}}{{ShortSha .root.CommitID}}{{end}},
'commitIdShort': {{ShortSha .root.CommitID}},
'tagName': {{.root.TagName}},
'branchName': {{.root.BranchName}},
'noTag': {{.noTag}},
'defaultSelectedRefName': {{$defaultSelectedRefName}},
'repoDefaultBranch': {{.root.Repository.DefaultBranch}},
'enableFeed': {{.root.EnableFeed}},
'rssURLPrefix': '{{$.root.RepoLink}}/rss/branch/',
'branchURLPrefix': '{{if .branchURLPrefix}}{{.branchURLPrefix}}{{else}}{{$.root.RepoLink}}/{{if $.root.PageIsCommits}}commits{{else}}src{{end}}/branch/{{end}}',
'branchURLSuffix': '{{if .branchURLSuffix}}{{.branchURLSuffix}}{{else}}{{if $.root.TreePath}}/{{PathEscapeSegments $.root.TreePath}}{{end}}{{end}}',
'tagURLPrefix': '{{if .tagURLPrefix}}{{.tagURLPrefix}}{{else if .release}}{{$.root.RepoLink}}/compare/{{else}}{{$.root.RepoLink}}/{{if $.root.PageIsCommits}}commits{{else}}src{{end}}/tag/{{end}}',
'tagURLSuffix': '{{if .tagURLSuffix}}{{.tagURLSuffix}}{{else if .release}}...{{if .release.IsDraft}}{{PathEscapeSegments .release.Target}}{{else}}{{if .release.TagName}}{{PathEscapeSegments .release.TagName}}{{else}}{{PathEscapeSegments .release.Sha1}}{{end}}{{end}}{{else}}{{if $.root.TreePath}}/{{PathEscapeSegments $.root.TreePath}}{{end}}{{end}}',
'repoLink': {{.root.RepoLink}},
'treePath': {{.root.TreePath}},
'branchNameSubURL': {{.root.BranchNameSubURL}},
'noResults': {{ctx.Locale.Tr "no_results_found"}},
};
{{if .release}}
data.release = {
'tagName': {{.release.TagName}},
};
{{end}}
window.config.pageData.branchDropdownDataList = window.config.pageData.branchDropdownDataList || [];
window.config.pageData.branchDropdownDataList.push(data);
</script>
data-ref-link-template="{{.RefLinkTemplate}}"
data-ref-form-action-template="{{.RefFormActionTemplate}}"
data-dropdown-fixed-text="{{.DropdownFixedText}}"
data-show-tab-branches="{{.ShowTabBranches}}"
data-show-tab-tags="{{.ShowTabTags}}"
data-allow-create-new-ref="{{.AllowCreateNewRef}}"

<div class="js-branch-tag-selector {{if .ContainerClasses}}{{.ContainerClasses}}{{end}}">
data-enable-feed="{{ctx.RootData.EnableFeed}}"
>
{{/* show dummy elements before Vue componment is mounted, this code must match the code in BranchTagSelector.vue */}}
<div class="ui dropdown custom branch-selector-dropdown ellipsis-items-nowrap">
<div class="ui button branch-dropdown-button">
<span class="flex-text-block gt-ellipsis">
{{if .release}}
{{ctx.Locale.Tr "repo.release.compare"}}
{{else}}
{{if eq $type "tag"}}
{{if not .DropdownFixedText}}
{{if .ShowTabTags}}
{{svg "octicon-tag"}}
{{else}}
{{else if .ShowTabBranches}}
{{svg "octicon-git-branch"}}
{{end}}
<strong ref="dropdownRefName" class="tw-ml-2 tw-inline-block gt-ellipsis">{{if and .root.IsViewTag (not .noTag)}}{{.root.TagName}}{{else if .root.IsViewBranch}}{{.root.BranchName}}{{else}}{{ShortSha .root.CommitID}}{{end}}</strong>
{{end}}
<strong class="tw-ml-2 tw-inline-block gt-ellipsis">{{Iif .DropdownFixedText .SelectedRefShortName}}</strong>
</span>
{{svg "octicon-triangle-down" 14 "dropdown icon"}}
</div>
Expand Down
17 changes: 9 additions & 8 deletions templates/repo/commit_page.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,15 @@
</div>
<div class="content">
<p id="cherry-pick-content" class="branch-dropdown"></p>
{{template "repo/branch_dropdown" dict "root" .
"noTag" true "disableCreateBranch" true
"branchForm" "branch-dropdown-form"
"branchURLPrefix" (printf "%s/_cherrypick/%s/" $.RepoLink .CommitID) "branchURLSuffix" ""
"setAction" true "submitForm" true}}
<form method="get" action="{{$.RepoLink}}/_cherrypick/{{.CommitID}}/{{if $.BranchName}}{{PathEscapeSegments $.BranchName}}{{else}}{{PathEscapeSegments $.Repository.DefaultBranch}}{{end}}" id="branch-dropdown-form">
<input type="hidden" name="ref" value="{{if $.BranchName}}{{$.BranchName}}{{else}}{{$.Repository.DefaultBranch}}{{end}}">
<input type="hidden" name="refType" value="branch">

<form method="get">
{{template "repo/branch_dropdown" dict
"Repository" .Repository
"ShowTabBranches" true
"CurrentRefType" "branch"
"CurrentRefShortName" (Iif $.BranchName $.Repository.DefaultBranch)
"RefFormActionTemplate" (print "{RepoLink}/_cherrypick/" .CommitID "/{RefShortName}")
}}
<input type="hidden" id="cherry-pick-type" name="cherry-pick-type"><br>
<button type="submit" id="cherry-pick-submit" class="ui primary button"></button>
</form>
Expand Down
19 changes: 18 additions & 1 deletion templates/repo/commits.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,24 @@
{{template "repo/sub_menu" .}}
<div class="repo-button-row">
<div class="repo-button-row-left">
{{template "repo/branch_dropdown" dict "root" .}}

{{$branchDropdownCurrentRefType := "branch"}}
{{$branchDropdownCurrentRefShortName := .BranchName}}
{{if .IsViewTag}}
{{$branchDropdownCurrentRefType := "tag"}}
{{$branchDropdownCurrentRefShortName := .TagName}}
{{end}}
{{template "repo/branch_dropdown" dict
"Repository" .Repository
"ShowTabBranches" true
"ShowTabTags" true
"CurrentRefType" $branchDropdownCurrentRefType
"CurrentRefShortName" $branchDropdownCurrentRefShortName
"CurrentTreePath" .TreePath
"RefLinkTemplate" "{RepoLink}/commits/{RefType}/{RefShortName}/{TreePath}"
"AllowCreateNewRef" .CanCreateBranch
}}

<a href="{{.RepoLink}}/graph" class="ui basic small compact button">
{{svg "octicon-git-branch"}}
{{ctx.Locale.Tr "repo.commit_graph"}}
Expand Down
17 changes: 16 additions & 1 deletion templates/repo/home.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,22 @@
{{$isHomepage := (eq $n 0)}}
<div class="repo-button-row" data-is-homepage="{{$isHomepage}}">
<div class="repo-button-row-left">
{{template "repo/branch_dropdown" dict "root" .}}
{{$branchDropdownCurrentRefType := "branch"}}
{{$branchDropdownCurrentRefShortName := .BranchName}}
{{if .IsViewTag}}
{{$branchDropdownCurrentRefType := "tag"}}
{{$branchDropdownCurrentRefShortName := .TagName}}
{{end}}
{{template "repo/branch_dropdown" dict
"Repository" .Repository
"ShowTabBranches" true
"ShowTabTags" true
"CurrentRefType" $branchDropdownCurrentRefType
"CurrentRefShortName" $branchDropdownCurrentRefShortName
"CurrentTreePath" .TreePath
"RefLinkTemplate" "{RepoLink}/src/{RefType}/{RefShortName}/{TreePath}"
"AllowCreateNewRef" .CanCreateBranch
}}
{{if and .CanCompareOrPull .IsViewBranch (not .Repository.IsArchived)}}
{{$cmpBranch := ""}}
{{if ne .Repository.ID .BaseRepo.ID}}
Expand Down
2 changes: 1 addition & 1 deletion templates/repo/issue/filter_actions.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
{{end}}
{{if .ClosedMilestones}}
<div class="divider"></div>
<div class="header">{{ctx.Locale.Tr "repo.issues.filter_milestone_open"}}</div>
<div class="header">{{ctx.Locale.Tr "repo.issues.filter_milestone_closed"}}</div>
{{range .ClosedMilestones}}
<div class="item issue-action" data-element-id="{{.ID}}" data-url="{{$.RepoLink}}/issues/milestone">
{{.Name}}
Expand Down
4 changes: 2 additions & 2 deletions templates/repo/issue/sidebar/milestone_list.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
<div class="item clear-selection">{{ctx.Locale.Tr "repo.issues.new.clear_milestone"}}</div>
<div class="scrolling menu">
{{if $data.OpenMilestones}}
<div class="header">{{ctx.Locale.Tr "repo.issues.new.open_milestone"}}</div>
<div class="header">{{ctx.Locale.Tr "repo.issues.filter_milestone_open"}}</div>
{{range $data.OpenMilestones}}
<a class="item muted" data-value="{{.ID}}" href="{{$pageMeta.RepoLink}}/issues?milestone={{.ID}}">
{{svg "octicon-milestone" 18}} {{.Name}}
Expand All @@ -31,7 +31,7 @@
{{end}}
{{if and $data.OpenMilestones $data.ClosedMilestones}}<div class="divider"></div>{{end}}
{{if $data.ClosedMilestones}}
<div class="header">{{ctx.Locale.Tr "repo.issues.new.closed_milestone"}}</div>
<div class="header">{{ctx.Locale.Tr "repo.issues.filter_milestone_closed"}}</div>
{{range $data.ClosedMilestones}}
<a class="item muted" data-value="{{.ID}}" href="{{$pageMeta.RepoLink}}/issues?milestone={{.ID}}">
{{svg "octicon-milestone" 18}} {{.Name}}
Expand Down
Loading

0 comments on commit 5ebe735

Please sign in to comment.