diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index c3b78e60bb47c..5c23f70d7ca7a 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -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. @@ -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 ;; @@ -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 = ;; diff --git a/modules/cache/cache_test.go b/modules/cache/cache_test.go index e0b82f86f2bf5..d0352947a831a 100644 --- a/modules/cache/cache_test.go +++ b/modules/cache/cache_test.go @@ -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) { diff --git a/modules/setting/service.go b/modules/setting/service.go index c858f803549d5..526ad64eb4001 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -41,6 +41,7 @@ var Service = struct { AllowOnlyInternalRegistration bool AllowOnlyExternalRegistration bool ShowRegistrationButton bool + EnablePasswordSignInForm bool ShowMilestonesDashboardPage bool RequireSignInView bool EnableNotifyMail bool @@ -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() diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index ffce4b7e2f301..1dc0c3cb81def 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -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 diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go index c9ef9193f12e4..3f16da3cddf8e 100644 --- a/routers/web/auth/auth.go +++ b/routers/web/auth/auth.go @@ -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 @@ -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 diff --git a/templates/repo/branch_dropdown.tmpl b/templates/repo/branch_dropdown.tmpl index c4f73875f2cfa..43568732fbba8 100644 --- a/templates/repo/branch_dropdown.tmpl +++ b/templates/repo/branch_dropdown.tmpl @@ -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. +*/}} +
- 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); - + 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}}" -
+ data-enable-feed="{{ctx.RootData.EnableFeed}}" +> {{/* show dummy elements before Vue componment is mounted, this code must match the code in BranchTagSelector.vue */}}

- {{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}} -
- - + + + {{template "repo/branch_dropdown" dict + "Repository" .Repository + "ShowTabBranches" true + "CurrentRefType" "branch" + "CurrentRefShortName" (Iif $.BranchName $.Repository.DefaultBranch) + "RefFormActionTemplate" (print "{RepoLink}/_cherrypick/" .CommitID "/{RefShortName}") + }}
diff --git a/templates/repo/commits.tmpl b/templates/repo/commits.tmpl index 6bce58577442b..e79f3d775182e 100644 --- a/templates/repo/commits.tmpl +++ b/templates/repo/commits.tmpl @@ -5,7 +5,24 @@ {{template "repo/sub_menu" .}}
- {{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 + }} + {{svg "octicon-git-branch"}} {{ctx.Locale.Tr "repo.commit_graph"}} diff --git a/templates/repo/home.tmpl b/templates/repo/home.tmpl index 12c4a17234d3a..c2f1be782a475 100644 --- a/templates/repo/home.tmpl +++ b/templates/repo/home.tmpl @@ -47,7 +47,22 @@ {{$isHomepage := (eq $n 0)}}
- {{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}} diff --git a/templates/repo/issue/filter_actions.tmpl b/templates/repo/issue/filter_actions.tmpl index 4cdad7a7480df..8e2410393d871 100644 --- a/templates/repo/issue/filter_actions.tmpl +++ b/templates/repo/issue/filter_actions.tmpl @@ -58,7 +58,7 @@ {{end}} {{if .ClosedMilestones}}
-
{{ctx.Locale.Tr "repo.issues.filter_milestone_open"}}
+
{{ctx.Locale.Tr "repo.issues.filter_milestone_closed"}}
{{range .ClosedMilestones}}
{{.Name}} diff --git a/templates/repo/issue/sidebar/milestone_list.tmpl b/templates/repo/issue/sidebar/milestone_list.tmpl index 2a7b6f6009f15..0e926f7b03329 100644 --- a/templates/repo/issue/sidebar/milestone_list.tmpl +++ b/templates/repo/issue/sidebar/milestone_list.tmpl @@ -22,7 +22,7 @@
{{ctx.Locale.Tr "repo.issues.new.clear_milestone"}}
diff --git a/templates/user/auth/oauth_container.tmpl b/templates/user/auth/oauth_container.tmpl index 7599b49fbbf4b..d01aaefe1aa2d 100644 --- a/templates/user/auth/oauth_container.tmpl +++ b/templates/user/auth/oauth_container.tmpl @@ -1,7 +1,3 @@ -{{if or .OAuth2Providers .EnableOpenIDSignIn}} -
- {{ctx.Locale.Tr "sign_in_or"}} -
@@ -26,4 +22,3 @@
-{{end}} diff --git a/templates/user/auth/signin_inner.tmpl b/templates/user/auth/signin_inner.tmpl index ec61e56f4db7d..e0a19a974330a 100644 --- a/templates/user/auth/signin_inner.tmpl +++ b/templates/user/auth/signin_inner.tmpl @@ -10,6 +10,7 @@ {{end}}
+ {{if .EnablePasswordSignInForm}}
{{.CsrfTokenHtml}}
@@ -46,8 +47,13 @@
- - {{template "user/auth/oauth_container" .}} + {{end}}{{/*if .EnablePasswordSignInForm*/}} + {{if and .OAuth2Providers .EnableOpenIDSignIn .EnablePasswordSignInForm}} +
{{ctx.Locale.Tr "sign_in_or"}}
+ {{end}} + {{if and .OAuth2Providers .EnableOpenIDSignIn}} + {{template "user/auth/oauth_container" .}} + {{end}}
diff --git a/templates/user/auth/signup_inner.tmpl b/templates/user/auth/signup_inner.tmpl index 08507e545dc84..6969003968670 100644 --- a/templates/user/auth/signup_inner.tmpl +++ b/templates/user/auth/signup_inner.tmpl @@ -48,7 +48,10 @@
{{end}} - {{template "user/auth/oauth_container" .}} + {{if and .OAuth2Providers .EnableOpenIDSignIn}} +
{{ctx.Locale.Tr "sign_in_or"}}
+ {{template "user/auth/oauth_container" .}} + {{end}}
diff --git a/tests/integration/signin_test.go b/tests/integration/signin_test.go index 886d4a825932e..abad9eb5e55f1 100644 --- a/tests/integration/signin_test.go +++ b/tests/integration/signin_test.go @@ -12,6 +12,7 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/tests" @@ -91,3 +92,31 @@ func TestSigninWithRememberMe(t *testing.T) { req = NewRequest(t, "GET", "/user/settings") session.MakeRequest(t, req, http.StatusOK) } + +func TestEnablePasswordSignInForm(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + t.Run("EnablePasswordSignInForm=false", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + defer test.MockVariableValue(&setting.Service.EnablePasswordSignInForm, false)() + + req := NewRequest(t, "GET", "/user/login") + resp := MakeRequest(t, req, http.StatusOK) + NewHTMLParser(t, resp.Body).AssertElement(t, "form[action='/user/login']", false) + + req = NewRequest(t, "POST", "/user/login") + MakeRequest(t, req, http.StatusForbidden) + }) + + t.Run("EnablePasswordSignInForm=true", func(t *testing.T) { + defer tests.PrintCurrentTest(t)() + defer test.MockVariableValue(&setting.Service.EnablePasswordSignInForm, true)() + + req := NewRequest(t, "GET", "/user/login") + resp := MakeRequest(t, req, http.StatusOK) + NewHTMLParser(t, resp.Body).AssertElement(t, "form[action='/user/login']", true) + + req = NewRequest(t, "POST", "/user/login") + MakeRequest(t, req, http.StatusOK) + }) +} diff --git a/web_src/js/components/RepoBranchTagSelector.vue b/web_src/js/components/RepoBranchTagSelector.vue index 7aecb1e351d9b..05f7b59a66609 100644 --- a/web_src/js/components/RepoBranchTagSelector.vue +++ b/web_src/js/components/RepoBranchTagSelector.vue @@ -1,244 +1,217 @@