From b74c3a9f6cc3badf62ef196851d1998c37ab01e1 Mon Sep 17 00:00:00 2001 From: silverwind Date: Wed, 17 Jun 2026 08:35:53 +0200 Subject: [PATCH] refactor: replace legacy `delete-button` with `link-action` Migrate all remaining `delete-button` usages to the `link-action` and `show-modal` + `form-fetch-action` mechanisms and remove the `initGlobalDeleteButton` handler, as its FIXME requested. The new request shape required two backend tweaks: webauthn key delete reads `id` from the query string, and account deletion returns `JSONError` on validation failure so fetch-action can display it. Assisted-by: claude-code:opus-4.8 --- routers/web/user/setting/account.go | 16 ++--- routers/web/user/setting/security/webauthn.go | 3 +- routers/web/web.go | 2 +- services/forms/user_form.go | 11 --- templates/org/team/members.tmpl | 16 ++--- templates/org/team/new.tmpl | 4 +- templates/repo/branch/list.tmpl | 6 +- templates/shared/actions/runner_edit.tmpl | 4 +- templates/user/settings/account.tmpl | 10 +-- templates/user/settings/applications.tmpl | 4 +- .../settings/applications_oauth2_list.tmpl | 4 +- templates/user/settings/grants_oauth2.tmpl | 4 +- templates/user/settings/keys_gpg.tmpl | 4 +- templates/user/settings/keys_principal.tmpl | 4 +- templates/user/settings/keys_ssh.tmpl | 4 +- templates/user/settings/organization.tmpl | 17 ++--- .../user/settings/security/accountlinks.tmpl | 4 +- templates/user/settings/security/openid.tmpl | 4 +- templates/user/settings/security/twofa.tmpl | 6 +- .../user/settings/security/webauthn.tmpl | 4 +- tests/e2e/org.test.ts | 19 +++++ tests/integration/branches_test.go | 8 +-- web_src/css/modules/button.css | 5 -- web_src/js/features/common-button.ts | 69 ------------------- web_src/js/index.ts | 3 +- 25 files changed, 77 insertions(+), 158 deletions(-) diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go index 1927efb7fe..a8d270dd32 100644 --- a/routers/web/user/setting/account.go +++ b/routers/web/user/setting/account.go @@ -249,21 +249,13 @@ func DeleteAccount(ctx *context.Context) { if _, _, err := auth.UserSignIn(ctx, ctx.Doer.Name, ctx.FormString("password")); err != nil { switch { case user_model.IsErrUserNotExist(err): - loadAccountData(ctx) - - ctx.RenderWithErrDeprecated(ctx.Tr("form.user_not_exist"), tplSettingsAccount, nil) + ctx.JSONError(ctx.Tr("form.user_not_exist")) case errors.Is(err, smtp.ErrUnsupportedLoginType): - loadAccountData(ctx) - - ctx.RenderWithErrDeprecated(ctx.Tr("form.unsupported_login_type"), tplSettingsAccount, nil) + ctx.JSONError(ctx.Tr("form.unsupported_login_type")) case errors.As(err, &db.ErrUserPasswordNotSet{}): - loadAccountData(ctx) - - ctx.RenderWithErrDeprecated(ctx.Tr("form.unset_password"), tplSettingsAccount, nil) + ctx.JSONError(ctx.Tr("form.unset_password")) case errors.As(err, &db.ErrUserPasswordInvalid{}): - loadAccountData(ctx) - - ctx.RenderWithErrDeprecated(ctx.Tr("form.enterred_invalid_password"), tplSettingsAccount, nil) + ctx.JSONError(ctx.Tr("form.enterred_invalid_password")) default: ctx.ServerError("UserSignIn", err) } diff --git a/routers/web/user/setting/security/webauthn.go b/routers/web/user/setting/security/webauthn.go index a265fcdd10..4db7b47879 100644 --- a/routers/web/user/setting/security/webauthn.go +++ b/routers/web/user/setting/security/webauthn.go @@ -132,8 +132,7 @@ func WebauthnDelete(ctx *context.Context) { return } - form := web.GetForm(ctx).(*forms.WebauthnDeleteForm) - if _, err := auth.DeleteCredential(ctx, form.ID, ctx.Doer.ID); err != nil { + if _, err := auth.DeleteCredential(ctx, ctx.FormInt64("id"), ctx.Doer.ID); err != nil { ctx.ServerError("GetWebAuthnCredentialByID", err) return } diff --git a/routers/web/web.go b/routers/web/web.go index bde886177c..4525516f5a 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -643,7 +643,7 @@ func registerWebRoutes(m *web.Router, webAuth *AuthMiddleware) { m.Group("/webauthn", func() { m.Post("/request_register", web.Bind(forms.WebauthnRegistrationForm{}), security.WebAuthnRegister) m.Post("/register", security.WebauthnRegisterPost) - m.Post("/delete", web.Bind(forms.WebauthnDeleteForm{}), security.WebauthnDelete) + m.Post("/delete", security.WebauthnDelete) }) m.Group("/openid", func() { m.Post("", web.Bind(forms.AddOpenIDForm{}), security.OpenIDPost) diff --git a/services/forms/user_form.go b/services/forms/user_form.go index 195c746985..75275fb5c7 100644 --- a/services/forms/user_form.go +++ b/services/forms/user_form.go @@ -419,17 +419,6 @@ func (f *WebauthnRegistrationForm) Validate(req *http.Request, errs binding.Erro return middleware.Validate(errs, ctx.Data, f, ctx.Locale) } -// WebauthnDeleteForm for deleting WebAuthn keys -type WebauthnDeleteForm struct { - ID int64 `binding:"Required"` -} - -// Validate validates the fields -func (f *WebauthnDeleteForm) Validate(req *http.Request, errs binding.Errors) binding.Errors { - ctx := context.GetValidateContext(req) - return middleware.Validate(errs, ctx.Data, f, ctx.Locale) -} - // PackageSettingForm form for package settings type PackageSettingForm struct { Action string diff --git a/templates/org/team/members.tmpl b/templates/org/team/members.tmpl index ac4039e596..c652d9c481 100644 --- a/templates/org/team/members.tmpl +++ b/templates/org/team/members.tmpl @@ -34,12 +34,10 @@
{{if and $.IsOrganizationOwner (not (and ($.Team.IsOwnerTeam) (eq (len $.Team.Members) 1)))}} -
- -
+ {{end}}
@@ -74,13 +72,13 @@ - + {{template "base/footer" .}} diff --git a/templates/org/team/new.tmpl b/templates/org/team/new.tmpl index 7e0403a2f5..1aa306a3e9 100644 --- a/templates/org/team/new.tmpl +++ b/templates/org/team/new.tmpl @@ -176,7 +176,7 @@ {{else}} {{if not .Team.IsOwnerTeam}} - + {{end}} {{end}} @@ -187,7 +187,7 @@ -