Improve "generate new access token" form (#33730)

Fix: https://github.com/go-gitea/gitea/issues/33519

As discussed in [PR
#33614](https://github.com/go-gitea/gitea/pull/33614), the
ScopedAccessTokenSelector Vue component is not particularly useful.

This PR removes the component and reverts to using HTML templates. It
also introduces some (hopefully) useful refactoring.

The Vue component was causing the UX bug reported in the linked issue.
Required form fields are now properly working, as expected (see
screenshot).

![Screenshot from 2025-02-25
22-00-28](https://github.com/user-attachments/assets/41167854-0718-48b0-a3ee-75ca3a7b8b20)

---------

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Guillaume 2025-02-27 14:40:12 -05:00 committed by GitHub
parent 8362a41559
commit 303af554c9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
21 changed files with 138 additions and 298 deletions

View file

@ -50,49 +50,41 @@
</div>
</div>
<div class="ui bottom attached segment">
<h5 class="ui top header">
{{ctx.Locale.Tr "settings.generate_new_token"}}
</h5>
<form id="scoped-access-form" class="ui form ignore-dirty" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<div class="field {{if .Err_Name}}error{{end}}">
<label for="name">{{ctx.Locale.Tr "settings.token_name"}}</label>
<input id="name" name="name" value="{{.name}}" autofocus required maxlength="255">
</div>
<div class="field">
<label>{{ctx.Locale.Tr "settings.repo_and_org_access"}}</label>
<label class="tw-cursor-pointer">
<input class="enable-system tw-mt-1 tw-mr-1" type="radio" name="scope" value="{{$.AccessTokenScopePublicOnly}}">
{{ctx.Locale.Tr "settings.permissions_public_only"}}
</label>
<label class="tw-cursor-pointer">
<input class="enable-system tw-mt-1 tw-mr-1" type="radio" name="scope" value="" checked>
{{ctx.Locale.Tr "settings.permissions_access_all"}}
</label>
</div>
<details class="ui optional field">
<summary class="tw-pb-4 tw-pl-1">
{{ctx.Locale.Tr "settings.select_permissions"}}
</summary>
<p class="activity meta">
<i>{{ctx.Locale.Tr "settings.access_token_desc" (HTMLFormat `href="%s/api/swagger" target="_blank"` AppSubUrl) (`href="https://docs.gitea.com/development/oauth2-provider#scopes" target="_blank"`|SafeHTML)}}</i>
</p>
<div id="scoped-access-token-selector"
data-is-admin="{{if .IsAdmin}}true{{else}}false{{end}}"
data-no-access-label="{{ctx.Locale.Tr "settings.permission_no_access"}}"
data-read-label="{{ctx.Locale.Tr "settings.permission_read"}}"
data-write-label="{{ctx.Locale.Tr "settings.permission_write"}}"
data-locale-component-failed-to-load="{{ctx.Locale.Tr "graphs.component_failed_to_load"}}"
>
<details {{if or .name (not .Tokens)}}open{{end}}>
<summary><h4 class="ui header tw-inline-block tw-my-2">{{ctx.Locale.Tr "settings.generate_new_token"}}</h4></summary>
<form class="ui form ignore-dirty" action="{{.Link}}" method="post">
{{.CsrfTokenHtml}}
<div class="field {{if .Err_Name}}error{{end}}">
<label for="name">{{ctx.Locale.Tr "settings.token_name"}}</label>
<input id="name" name="name" value="{{.name}}" required maxlength="255">
</div>
</details>
<button id="scoped-access-submit" class="ui primary button">
{{ctx.Locale.Tr "settings.generate_token"}}
</button>
</form>{{/* Fomantic ".ui.form .warning.message" is hidden by default, so put the warning message out of the form*/}}
<div id="scoped-access-warning" class="ui warning message center tw-hidden">
{{ctx.Locale.Tr "settings.at_least_one_permission"}}
</div>
<div class="field">
<div class="tw-my-2">{{ctx.Locale.Tr "settings.repo_and_org_access"}}</div>
<label class="gt-checkbox">
<input type="radio" name="scope-public-only" value="{{$.AccessTokenScopePublicOnly}}"> {{ctx.Locale.Tr "settings.permissions_public_only"}}
</label>
<label class="gt-checkbox">
<input type="radio" name="scope-public-only" value="" checked> {{ctx.Locale.Tr "settings.permissions_access_all"}}
</label>
</div>
<div>
<div class="tw-my-2">{{ctx.Locale.Tr "settings.access_token_desc" (HTMLFormat `href="%s/api/swagger" target="_blank"` AppSubUrl) (`href="https://docs.gitea.com/development/oauth2-provider#scopes" target="_blank"`|SafeHTML)}}</div>
<table class="ui table unstackable tw-my-2">
{{range $category := .TokenCategories}}
<tr>
<td>{{$category}}</td>
<td><label class="gt-checkbox"><input type="radio" name="scope-{{$category}}" value="" checked> {{ctx.Locale.Tr "settings.permission_no_access"}}</label></td>
<td><label class="gt-checkbox"><input type="radio" name="scope-{{$category}}" value="read:{{$category}}"> {{ctx.Locale.Tr "settings.permission_read"}}</label></td>
<td><label class="gt-checkbox"><input type="radio" name="scope-{{$category}}" value="write:{{$category}}"> {{ctx.Locale.Tr "settings.permission_write"}}</label></td>
</tr>
{{end}}
</table>
</div>
<button class="ui primary button">
{{ctx.Locale.Tr "settings.generate_token"}}
</button>
</form>
</details>
</div>
{{if .EnableOAuth2}}

View file

@ -48,33 +48,33 @@
</div>
<div class="ui bottom attached segment">
<h5 class="ui top header">
{{ctx.Locale.Tr "settings.create_oauth2_application"}}
</h5>
<form class="ui form ignore-dirty" action="{{.Link}}/oauth2" method="post">
{{.CsrfTokenHtml}}
<div class="field {{if .Err_AppName}}error{{end}}">
<label for="application-name">{{ctx.Locale.Tr "settings.oauth2_application_name"}}</label>
<input id="application-name" name="application_name" value="{{.application_name}}" required maxlength="255">
</div>
<div class="field {{if .Err_RedirectURI}}error{{end}}">
<label for="redirect-uris">{{ctx.Locale.Tr "settings.oauth2_redirect_uris"}}</label>
<textarea name="redirect_uris" id="redirect-uris"></textarea>
</div>
<div class="field {{if .Err_ConfidentialClient}}error{{end}}">
<div class="ui checkbox">
<label>{{ctx.Locale.Tr "settings.oauth2_confidential_client"}}</label>
<input class="disable-setting" type="checkbox" name="confidential_client" data-target="#skip-secondary-authorization" checked>
<details {{if .application_name}}open{{end}}>
<summary><h4 class="ui header tw-inline-block tw-my-2">{{ctx.Locale.Tr "settings.create_oauth2_application"}}</h4></summary>
<form class="ui form ignore-dirty" action="{{.Link}}/oauth2" method="post">
{{.CsrfTokenHtml}}
<div class="field {{if .Err_AppName}}error{{end}}">
<label for="application-name">{{ctx.Locale.Tr "settings.oauth2_application_name"}}</label>
<input id="application-name" name="application_name" value="{{.application_name}}" required maxlength="255">
</div>
</div>
<div class="field {{if .Err_SkipSecondaryAuthorization}}error{{end}} disabled" id="skip-secondary-authorization">
<div class="ui checkbox">
<label>{{ctx.Locale.Tr "settings.oauth2_skip_secondary_authorization"}}</label>
<input type="checkbox" name="skip_secondary_authorization">
<div class="field {{if .Err_RedirectURI}}error{{end}}">
<label for="redirect-uris">{{ctx.Locale.Tr "settings.oauth2_redirect_uris"}}</label>
<textarea name="redirect_uris" id="redirect-uris"></textarea>
</div>
</div>
<button class="ui primary button">
{{ctx.Locale.Tr "settings.create_oauth2_application_button"}}
</button>
</form>
<div class="field {{if .Err_ConfidentialClient}}error{{end}}">
<div class="ui checkbox">
<label>{{ctx.Locale.Tr "settings.oauth2_confidential_client"}}</label>
<input class="disable-setting" type="checkbox" name="confidential_client" data-target="#skip-secondary-authorization" checked>
</div>
</div>
<div class="field {{if .Err_SkipSecondaryAuthorization}}error{{end}} disabled" id="skip-secondary-authorization">
<div class="ui checkbox">
<label>{{ctx.Locale.Tr "settings.oauth2_skip_secondary_authorization"}}</label>
<input type="checkbox" name="skip_secondary_authorization">
</div>
</div>
<button class="ui primary button">
{{ctx.Locale.Tr "settings.create_oauth2_application_button"}}
</button>
</form>
</details>
</div>