From e37342db0c102ef12ae70072d9f4bbef89338085 Mon Sep 17 00:00:00 2001 From: zeripath Date: Fri, 27 Aug 2021 03:57:40 +0100 Subject: [PATCH] Add modals to Organization and Team remove/leave (#16471) * Add modals to Organization and Team remove/leave Add confirmation modals to Organization and Team remove and leave. Fix #16215 Signed-off-by: Andrew Thornton * avoid for-in Signed-off-by: Andrew Thornton * Revert "avoid for-in" This reverts commit 2af9a6f9d46ed31b6fc6e3a29e695577dcf09f75. * Apply suggestions from code review Co-authored-by: silverwind Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: silverwind Co-authored-by: techknowlogick --- options/locale/locale_en-US.ini | 3 ++ routers/web/org/members.go | 19 +++++++--- routers/web/org/teams.go | 34 +++++++++++++++++ templates/org/member/members.tmpl | 37 ++++++++++++++++--- templates/org/team/members.tmpl | 20 ++++++++-- templates/org/team/sidebar.tmpl | 18 +++++++-- templates/org/team/teams.tmpl | 17 +++++++-- templates/user/settings/account.tmpl | 4 +- templates/user/settings/applications.tmpl | 2 +- .../user/settings/applications_oauth2.tmpl | 2 +- templates/user/settings/grants_oauth2.tmpl | 2 +- templates/user/settings/keys_gpg.tmpl | 2 +- templates/user/settings/keys_principal.tmpl | 2 +- templates/user/settings/keys_ssh.tmpl | 2 +- .../user/settings/security_accountlinks.tmpl | 2 +- templates/user/settings/security_openid.tmpl | 2 +- templates/user/settings/security_twofa.tmpl | 2 +- templates/user/settings/security_u2f.tmpl | 2 +- web_src/js/index.js | 25 ++++++++++--- 19 files changed, 157 insertions(+), 40 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 0a030b9b0..76536f2d4 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -2176,12 +2176,15 @@ members.member_role = Member Role: members.owner = Owner members.member = Member members.remove = Remove +members.remove.detail = Remove %[1]s from %[2]s? members.leave = Leave +members.leave.detail = Leave %s? members.invite_desc = Add a new member to %s: members.invite_now = Invite Now teams.join = Join teams.leave = Leave +teams.leave.detail = Leave %s? teams.can_create_org_repo = Create repositories teams.can_create_org_repo_helper = Members can create new repositories in organization. Creator will get administrator access to the new repository. teams.read_access = Read Access diff --git a/routers/web/org/members.go b/routers/web/org/members.go index 84aaa28f6..ef5a69e15 100644 --- a/routers/web/org/members.go +++ b/routers/web/org/members.go @@ -99,14 +99,18 @@ func MembersAction(ctx *context.Context) { err = org.RemoveMember(uid) if models.IsErrLastOrgOwner(err) { ctx.Flash.Error(ctx.Tr("form.last_org_owner")) - ctx.Redirect(ctx.Org.OrgLink + "/members") + ctx.JSON(http.StatusOK, map[string]interface{}{ + "redirect": ctx.Org.OrgLink + "/members", + }) return } case "leave": err = org.RemoveMember(ctx.User.ID) if models.IsErrLastOrgOwner(err) { ctx.Flash.Error(ctx.Tr("form.last_org_owner")) - ctx.Redirect(ctx.Org.OrgLink + "/members") + ctx.JSON(http.StatusOK, map[string]interface{}{ + "redirect": ctx.Org.OrgLink + "/members", + }) return } } @@ -120,9 +124,12 @@ func MembersAction(ctx *context.Context) { return } - if ctx.Params(":action") != "leave" { - ctx.Redirect(ctx.Org.OrgLink + "/members") - } else { - ctx.Redirect(setting.AppSubURL + "/") + redirect := ctx.Org.OrgLink + "/members" + if ctx.Params(":action") == "leave" { + redirect = setting.AppSubURL + "/" } + + ctx.JSON(http.StatusOK, map[string]interface{}{ + "redirect": redirect, + }) } diff --git a/routers/web/org/teams.go b/routers/web/org/teams.go index 4725f19b3..c93fcd062 100644 --- a/routers/web/org/teams.go +++ b/routers/web/org/teams.go @@ -66,6 +66,23 @@ func TeamsAction(ctx *context.Context) { err = ctx.Org.Team.AddMember(ctx.User.ID) case "leave": err = ctx.Org.Team.RemoveMember(ctx.User.ID) + if err != nil { + if models.IsErrLastOrgOwner(err) { + ctx.Flash.Error(ctx.Tr("form.last_org_owner")) + } else { + log.Error("Action(%s): %v", ctx.Params(":action"), err) + ctx.JSON(http.StatusOK, map[string]interface{}{ + "ok": false, + "err": err.Error(), + }) + return + } + } + ctx.JSON(http.StatusOK, + map[string]interface{}{ + "redirect": ctx.Org.OrgLink + "/teams/", + }) + return case "remove": if !ctx.Org.IsOwner { ctx.Error(http.StatusNotFound) @@ -73,6 +90,23 @@ func TeamsAction(ctx *context.Context) { } err = ctx.Org.Team.RemoveMember(uid) page = "team" + if err != nil { + if models.IsErrLastOrgOwner(err) { + ctx.Flash.Error(ctx.Tr("form.last_org_owner")) + } else { + log.Error("Action(%s): %v", ctx.Params(":action"), err) + ctx.JSON(http.StatusOK, map[string]interface{}{ + "ok": false, + "err": err.Error(), + }) + return + } + } + ctx.JSON(http.StatusOK, + map[string]interface{}{ + "redirect": ctx.Org.OrgLink + "/teams/" + ctx.Org.Team.LowerName, + }) + return case "add": if !ctx.Org.IsOwner { ctx.Error(http.StatusNotFound) diff --git a/templates/org/member/members.tmpl b/templates/org/member/members.tmpl index 0952d1276..ecb535d57 100644 --- a/templates/org/member/members.tmpl +++ b/templates/org/member/members.tmpl @@ -54,14 +54,18 @@
{{if eq $.SignedUser.ID .ID}} -
- {{$.CsrfTokenHtml}} - + +
{{else if $.IsOrganizationOwner}} -
- {{$.CsrfTokenHtml}} - + +
{{end}}
@@ -73,4 +77,25 @@ {{template "base/paginate" .}}
+ + + {{template "base/footer" .}} diff --git a/templates/org/team/members.tmpl b/templates/org/team/members.tmpl index bfc151d00..f2c89e065 100644 --- a/templates/org/team/members.tmpl +++ b/templates/org/team/members.tmpl @@ -26,10 +26,12 @@
{{range .Team.Members}}
- {{if $.IsOrganizationOwner}} -
- {{$.CsrfTokenHtml}} - + {{if and $.IsOrganizationOwner (not (eq $.SignedUser.ID .ID))}} + +
{{end}} @@ -47,4 +49,14 @@
+ {{template "base/footer" .}} diff --git a/templates/org/team/sidebar.tmpl b/templates/org/team/sidebar.tmpl index 9ab6e8f4c..84729a084 100644 --- a/templates/org/team/sidebar.tmpl +++ b/templates/org/team/sidebar.tmpl @@ -3,10 +3,10 @@ {{.Team.Name}}
{{if .Team.IsMember $.SignedUser.ID}} -
- {{$.CsrfTokenHtml}} - - + +
{{else if .IsOrganizationOwner}}
@@ -59,3 +59,13 @@
{{end}} + diff --git a/templates/org/team/teams.tmpl b/templates/org/team/teams.tmpl index 4e877bef2..6f4f15507 100644 --- a/templates/org/team/teams.tmpl +++ b/templates/org/team/teams.tmpl @@ -17,9 +17,10 @@
{{.Name}}
{{if .IsMember $.SignedUser.ID}} - - {{$.CsrfTokenHtml}} - + + {{else if $.IsOrganizationOwner}}
@@ -44,4 +45,14 @@
+ {{template "base/footer" .}} diff --git a/templates/user/settings/account.tmpl b/templates/user/settings/account.tmpl index 2e1976aaa..0468eb7e2 100644 --- a/templates/user/settings/account.tmpl +++ b/templates/user/settings/account.tmpl @@ -72,7 +72,7 @@
{{if not .IsPrimary}}
-
@@ -185,7 +185,7 @@
-
+
{{.i18n.Tr "settings.confirm_delete_account"}}
{{.i18n.Tr "auth.forgot_password"}} diff --git a/templates/user/settings/applications.tmpl b/templates/user/settings/applications.tmpl index 0455b5e22..811ce5d64 100644 --- a/templates/user/settings/applications.tmpl +++ b/templates/user/settings/applications.tmpl @@ -14,7 +14,7 @@ {{range .Tokens}}
- diff --git a/templates/user/settings/applications_oauth2.tmpl b/templates/user/settings/applications_oauth2.tmpl index 4de3f27ec..8218674bc 100644 --- a/templates/user/settings/applications_oauth2.tmpl +++ b/templates/user/settings/applications_oauth2.tmpl @@ -13,7 +13,7 @@ {{svg "octicon-pencil" 16 "mr-2"}} {{$.i18n.Tr "settings.oauth2_application_edit"}} - {{if and (not .Verified) (ne $.VerifyingID .KeyID)}} diff --git a/templates/user/settings/keys_principal.tmpl b/templates/user/settings/keys_principal.tmpl index e8057c7cf..9d8ebab60 100644 --- a/templates/user/settings/keys_principal.tmpl +++ b/templates/user/settings/keys_principal.tmpl @@ -17,7 +17,7 @@ {{range .Principals}}
-
diff --git a/templates/user/settings/keys_ssh.tmpl b/templates/user/settings/keys_ssh.tmpl index 62e697ad1..3d0557866 100644 --- a/templates/user/settings/keys_ssh.tmpl +++ b/templates/user/settings/keys_ssh.tmpl @@ -16,7 +16,7 @@ {{range $index, $key := .Keys}}
-
diff --git a/templates/user/settings/security_accountlinks.tmpl b/templates/user/settings/security_accountlinks.tmpl index 5aa928208..7a9935d03 100644 --- a/templates/user/settings/security_accountlinks.tmpl +++ b/templates/user/settings/security_accountlinks.tmpl @@ -10,7 +10,7 @@ {{range $loginSource, $provider := .AccountLinks}}
-
diff --git a/templates/user/settings/security_openid.tmpl b/templates/user/settings/security_openid.tmpl index 118f16203..2a167a712 100644 --- a/templates/user/settings/security_openid.tmpl +++ b/templates/user/settings/security_openid.tmpl @@ -9,7 +9,7 @@ {{range .OpenIDs}}
-
diff --git a/templates/user/settings/security_twofa.tmpl b/templates/user/settings/security_twofa.tmpl index 860bfdf56..f48b2f4cb 100644 --- a/templates/user/settings/security_twofa.tmpl +++ b/templates/user/settings/security_twofa.tmpl @@ -13,7 +13,7 @@ {{.CsrfTokenHtml}}

{{.i18n.Tr "settings.twofa_disable_note"}}

-
{{$.i18n.Tr "settings.twofa_disable"}}
+
{{$.i18n.Tr "settings.twofa_disable"}}
{{else}}

{{.i18n.Tr "settings.twofa_not_enrolled"}}

diff --git a/templates/user/settings/security_u2f.tmpl b/templates/user/settings/security_u2f.tmpl index dcc56d872..8fe01d8c7 100644 --- a/templates/user/settings/security_u2f.tmpl +++ b/templates/user/settings/security_u2f.tmpl @@ -8,7 +8,7 @@ {{range .U2FRegistrations}}
-
diff --git a/web_src/js/index.js b/web_src/js/index.js index d34909271..7e4970c3a 100644 --- a/web_src/js/index.js +++ b/web_src/js/index.js @@ -2956,13 +2956,19 @@ $(() => { function showDeletePopup() { const $this = $(this); + const dataArray = $this.data(); let filter = ''; - if ($this.attr('id')) { - filter += `#${$this.attr('id')}`; + if ($this.data('modal-id')) { + filter += `#${$this.data('modal-id')}`; } const dialog = $(`.delete.modal${filter}`); dialog.find('.name').text($this.data('name')); + for (const [key, value] of Object.entries(dataArray)) { + if (key && key.startsWith('data')) { + dialog.find(`.${key}`).text(value); + } + } dialog.modal({ closable: false, @@ -2972,10 +2978,19 @@ function showDeletePopup() { return; } - $.post($this.data('url'), { + const postData = { _csrf: csrf, - id: $this.data('id') - }).done((data) => { + }; + for (const [key, value] of Object.entries(dataArray)) { + if (key && key.startsWith('data')) { + postData[key.substr(4)] = value; + } + if (key === 'id') { + postData['id'] = value; + } + } + + $.post($this.data('url'), postData).done((data) => { window.location.href = data.redirect; }); }