diff options
-rw-r--r-- | routers/web/repo/repo.go | 4 | ||||
-rw-r--r-- | templates/repo/create.tmpl | 24 | ||||
-rw-r--r-- | tests/integration/repo_generate_test.go | 8 | ||||
-rw-r--r-- | web_src/js/features/repo-new.ts | 28 |
4 files changed, 37 insertions, 27 deletions
diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 73baf683ed..54b7448a89 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -154,8 +154,8 @@ func createCommon(ctx *context.Context) { ctx.Data["Licenses"] = repo_module.Licenses ctx.Data["Readmes"] = repo_module.Readmes ctx.Data["IsForcedPrivate"] = setting.Repository.ForcePrivate - ctx.Data["CanCreateRepo"] = ctx.Doer.CanCreateRepo() - ctx.Data["MaxCreationLimit"] = ctx.Doer.MaxCreationLimit() + ctx.Data["CanCreateRepoInDoer"] = ctx.Doer.CanCreateRepo() + ctx.Data["MaxCreationLimitOfDoer"] = ctx.Doer.MaxCreationLimit() ctx.Data["SupportedObjectFormats"] = git.DefaultFeatures().SupportedObjectFormats ctx.Data["DefaultObjectFormat"] = git.Sha1ObjectFormat } diff --git a/templates/repo/create.tmpl b/templates/repo/create.tmpl index ad308c857c..a90c26b423 100644 --- a/templates/repo/create.tmpl +++ b/templates/repo/create.tmpl @@ -7,25 +7,21 @@ <div class="ui attached segment"> {{template "base/alert" .}} {{template "repo/create_helper" .}} - - {{if not .CanCreateRepo}} - <div class="ui negative message"> - <p>{{ctx.Locale.TrN .MaxCreationLimit "repo.form.reach_limit_of_creation_1" "repo.form.reach_limit_of_creation_n" .MaxCreationLimit}}</p> - </div> - {{end}} <form class="ui form left-right-form new-repo-form" action="{{.Link}}" method="post"> {{.CsrfTokenHtml}} + <div id="create-repo-error-message" class="ui negative message tw-text-center tw-hidden"></div> <div class="inline required field {{if .Err_Owner}}error{{end}}"> <label>{{ctx.Locale.Tr "repo.owner"}}</label> - <div class="ui selection owner dropdown"> - <input type="hidden" id="uid" name="uid" value="{{.ContextUser.ID}}" required> - <span class="text truncated-item-container" title="{{.ContextUser.Name}}"> - {{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}} - <span class="truncated-item-name">{{.ContextUser.ShortName 40}}</span> - </span> + <div class="ui selection dropdown" id="repo_owner_dropdown"> + <input type="hidden" name="uid" value="{{.ContextUser.ID}}"> + <span class="text truncated-item-name"></span> {{svg "octicon-triangle-down" 14 "dropdown icon"}} <div class="menu"> - <div class="item truncated-item-container" data-value="{{.SignedUser.ID}}" title="{{.SignedUser.Name}}"> + <div class="item truncated-item-container" data-value="{{.SignedUser.ID}}" title="{{.SignedUser.Name}}" + {{if not .CanCreateRepoInDoer}} + data-create-repo-disallowed-prompt="{{ctx.Locale.TrN .MaxCreationLimit "repo.form.reach_limit_of_creation_1" "repo.form.reach_limit_of_creation_n" .MaxCreationLimitOfDoer}}" + {{end}} + > {{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}} <span class="truncated-item-name">{{.SignedUser.ShortName 40}}</span> </div> @@ -212,7 +208,7 @@ <br> <div class="inline field"> <label></label> - <button class="ui primary button{{if not .CanCreateRepo}} disabled{{end}}"> + <button class="ui primary button"> {{ctx.Locale.Tr "repo.create_repo"}} </button> </div> diff --git a/tests/integration/repo_generate_test.go b/tests/integration/repo_generate_test.go index ff2aa220d3..f5645d62bc 100644 --- a/tests/integration/repo_generate_test.go +++ b/tests/integration/repo_generate_test.go @@ -31,16 +31,16 @@ func testRepoGenerate(t *testing.T, session *TestSession, templateID, templateOw // Step2: click the "Use this template" button htmlDoc := NewHTMLParser(t, resp.Body) - link, exists := htmlDoc.doc.Find("a.ui.button[href^=\"/repo/create\"]").Attr("href") + link, exists := htmlDoc.doc.Find(`a.ui.button[href^="/repo/create"]`).Attr("href") assert.True(t, exists, "The template has changed") req = NewRequest(t, "GET", link) resp = session.MakeRequest(t, req, http.StatusOK) - // Step3: fill the form of the create + // Step3: fill the form on the "create" page htmlDoc = NewHTMLParser(t, resp.Body) - link, exists = htmlDoc.doc.Find("form.ui.form[action^=\"/repo/create\"]").Attr("action") + link, exists = htmlDoc.doc.Find(`form.ui.form[action^="/repo/create"]`).Attr("action") assert.True(t, exists, "The template has changed") - _, exists = htmlDoc.doc.Find(fmt.Sprintf(".owner.dropdown .item[data-value=\"%d\"]", generateOwner.ID)).Attr("data-value") + _, exists = htmlDoc.doc.Find(fmt.Sprintf(`#repo_owner_dropdown .item[data-value="%d"]`, generateOwner.ID)).Attr("data-value") assert.True(t, exists, "Generate owner '%s' is not present in select box", generateOwnerName) req = NewRequestWithValues(t, "POST", link, map[string]string{ "_csrf": htmlDoc.GetCSRF(), diff --git a/web_src/js/features/repo-new.ts b/web_src/js/features/repo-new.ts index 5128942465..0e4d78872d 100644 --- a/web_src/js/features/repo-new.ts +++ b/web_src/js/features/repo-new.ts @@ -1,4 +1,4 @@ -import {hideElem, showElem, toggleElem} from '../utils/dom.ts'; +import {hideElem, querySingleVisibleElem, showElem, toggleElem} from '../utils/dom.ts'; import {htmlEscape} from 'escape-goat'; import {fomanticQuery} from '../modules/fomantic/base.ts'; import {sanitizeRepoName} from './repo-common.ts'; @@ -6,7 +6,9 @@ import {sanitizeRepoName} from './repo-common.ts'; const {appSubUrl} = window.config; function initRepoNewTemplateSearch(form: HTMLFormElement) { - const inputRepoOwnerUid = form.querySelector<HTMLInputElement>('#uid'); + const elSubmitButton = querySingleVisibleElem<HTMLInputElement>(form, '.ui.primary.button'); + const elCreateRepoErrorMessage = form.querySelector('#create-repo-error-message'); + const elRepoOwnerDropdown = form.querySelector('#repo_owner_dropdown'); const elRepoTemplateDropdown = form.querySelector<HTMLInputElement>('#repo_template_search'); const inputRepoTemplate = form.querySelector<HTMLInputElement>('#repo_template'); const elTemplateUnits = form.querySelector('#template_units'); @@ -19,11 +21,23 @@ function initRepoNewTemplateSearch(form: HTMLFormElement) { inputRepoTemplate.addEventListener('change', checkTemplate); checkTemplate(); - const $dropdown = fomanticQuery(elRepoTemplateDropdown); + const $repoOwnerDropdown = fomanticQuery(elRepoOwnerDropdown); + const $repoTemplateDropdown = fomanticQuery(elRepoTemplateDropdown); const onChangeOwner = function () { - $dropdown.dropdown('setting', { + const ownerId = $repoOwnerDropdown.dropdown('get value'); + const $ownerItem = $repoOwnerDropdown.dropdown('get item', ownerId); + hideElem(elCreateRepoErrorMessage); + elSubmitButton.disabled = false; + if ($ownerItem?.length) { + const elOwnerItem = $ownerItem[0]; + elCreateRepoErrorMessage.textContent = elOwnerItem.getAttribute('data-create-repo-disallowed-prompt') ?? ''; + const hasError = Boolean(elCreateRepoErrorMessage.textContent); + toggleElem(elCreateRepoErrorMessage, hasError); + elSubmitButton.disabled = hasError; + } + $repoTemplateDropdown.dropdown('setting', { apiSettings: { - url: `${appSubUrl}/repo/search?q={query}&template=true&priority_owner_id=${inputRepoOwnerUid.value}`, + url: `${appSubUrl}/repo/search?q={query}&template=true&priority_owner_id=${ownerId}`, onResponse(response: any) { const results = []; results.push({name: '', value: ''}); // empty item means not using template @@ -33,14 +47,14 @@ function initRepoNewTemplateSearch(form: HTMLFormElement) { value: String(tmplRepo.repository.id), }); } - $dropdown.fomanticExt.onResponseKeepSelectedItem($dropdown, inputRepoTemplate.value); + $repoTemplateDropdown.fomanticExt.onResponseKeepSelectedItem($repoTemplateDropdown, inputRepoTemplate.value); return {results}; }, cache: false, }, }); }; - inputRepoOwnerUid.addEventListener('change', onChangeOwner); + $repoOwnerDropdown.dropdown('setting', 'onChange', onChangeOwner); onChangeOwner(); } |