{{ctx.Locale.Tr "org.members.leave.detail" (HTMLFormat `` "dataOrganizationName")}}
-diff --git a/options/locale/locale_en-US.json b/options/locale/locale_en-US.json index 2ffa130751..199637d76b 100644 --- a/options/locale/locale_en-US.json +++ b/options/locale/locale_en-US.json @@ -2778,9 +2778,9 @@ "org.settings.labels_desc": "Add labels which can be used on issues for all repositories under this organization.", "org.members.membership_visibility": "Membership Visibility:", "org.members.public": "Visible", - "org.members.public_helper": "make hidden", + "org.members.public_helper": "Make hidden", "org.members.private": "Hidden", - "org.members.private_helper": "make visible", + "org.members.private_helper": "Make visible", "org.members.member_role": "Member Role:", "org.members.owner": "Owner", "org.members.member": "Member", @@ -2808,7 +2808,10 @@ "org.teams.no_desc": "This team has no description", "org.teams.settings": "Settings", "org.teams.owners_permission_desc": "Owners have full access to all repositories and have administrator access to the organization.", + "org.teams.owners_permission_suggestion": "You can create new teams for members to get fine-grained access control.", "org.teams.members": "Team Members", + "org.teams.manage_team_member": "Manage teams and members", + "org.teams.manage_team_member_prompt": "Members are managed through teams. Add users to a team to invite them to this organization.", "org.teams.update_settings": "Update Settings", "org.teams.delete_team": "Delete Team", "org.teams.add_team_member": "Add Team Member", diff --git a/routers/web/org/members.go b/routers/web/org/members.go index 6523bbf38d..5d7a0a28cd 100644 --- a/routers/web/org/members.go +++ b/routers/web/org/members.go @@ -5,6 +5,7 @@ package org import ( + "errors" "net/http" "code.gitea.io/gitea/models/organization" @@ -12,6 +13,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/templates" + "code.gitea.io/gitea/modules/util" shared_user "code.gitea.io/gitea/routers/web/shared/user" "code.gitea.io/gitea/services/context" org_service "code.gitea.io/gitea/services/org" @@ -76,11 +78,11 @@ func Members(ctx *context.Context) { // MembersAction response for operation to a member of organization func MembersAction(ctx *context.Context) { member, err := user_model.GetUserByID(ctx, ctx.FormInt64("uid")) - if err != nil { - log.Error("GetUserByID: %v", err) - } - if member == nil { - ctx.Redirect(ctx.Org.OrgLink + "/members") + if errors.Is(err, util.ErrNotExist) { + ctx.HTTPError(http.StatusNotFound) + return + } else if err != nil { + ctx.ServerError("GetUserByID", err) return } @@ -105,40 +107,25 @@ func MembersAction(ctx *context.Context) { return } err = org_service.RemoveOrgUser(ctx, org, member) - if organization.IsErrLastOrgOwner(err) { - ctx.Flash.Error(ctx.Tr("form.last_org_owner")) - ctx.JSONRedirect(ctx.Org.OrgLink + "/members") - return - } case "leave": err = org_service.RemoveOrgUser(ctx, org, ctx.Doer) if err == nil { ctx.Flash.Success(ctx.Tr("form.organization_leave_success", org.DisplayName())) - ctx.JSON(http.StatusOK, map[string]any{ - "redirect": "", // keep the user stay on current page, in case they want to do other operations. - }) - } else if organization.IsErrLastOrgOwner(err) { - ctx.Flash.Error(ctx.Tr("form.last_org_owner")) - ctx.JSONRedirect(ctx.Org.OrgLink + "/members") - } else { - log.Error("RemoveOrgUser(%d,%d): %v", org.ID, ctx.Doer.ID, err) + ctx.JSONRedirect(setting.AppSubURL + "/") + return } + } + + if err == nil { + ctx.JSONOK() return } - if err != nil { - log.Error("Action(%s): %v", ctx.PathParam("action"), err) - ctx.JSON(http.StatusOK, map[string]any{ - "ok": false, - "err": err.Error(), - }) + if organization.IsErrLastOrgOwner(err) { + ctx.JSONError(ctx.Tr("form.last_org_owner")) return } - redirect := ctx.Org.OrgLink + "/members" - if ctx.PathParam("action") == "leave" { - redirect = setting.AppSubURL + "/" - } - - ctx.JSONRedirect(redirect) + log.Error("Action(%s): %v", ctx.PathParam("action"), err) + ctx.JSONError(err.Error()) // FIXME: legacy logic, errors are handled together, it's not right, need to distinguish between different errors } diff --git a/services/org/team.go b/services/org/team.go index f62e638514..6c92ee4f44 100644 --- a/services/org/team.go +++ b/services/org/team.go @@ -5,6 +5,7 @@ package org import ( "context" + "errors" "fmt" "strings" @@ -306,19 +307,19 @@ func removeTeamMember(ctx context.Context, team *organization.Team, user *user_m return err } - // Delete access to team repositories. + // Delete access to team repositories. If any user or repo is missing, we can continue. for _, repo := range repos { - if err := access_model.RecalculateUserAccess(ctx, repo, user.ID); err != nil { + if err := access_model.RecalculateUserAccess(ctx, repo, user.ID); err != nil && !errors.Is(err, util.ErrNotExist) { return err } // Remove watches from now inaccessible - if err := repo_service.ReconsiderWatches(ctx, repo, user); err != nil { + if err := repo_service.ReconsiderWatches(ctx, repo, user); err != nil && !errors.Is(err, util.ErrNotExist) { return err } // Remove issue assignments from now inaccessible - if err := repo_service.ReconsiderRepoIssuesAssignee(ctx, repo, user); err != nil { + if err := repo_service.ReconsiderRepoIssuesAssignee(ctx, repo, user); err != nil && !errors.Is(err, util.ErrNotExist) { return err } } diff --git a/templates/org/member/members.tmpl b/templates/org/member/members.tmpl index 9b9f060770..1cb50f785b 100644 --- a/templates/org/member/members.tmpl +++ b/templates/org/member/members.tmpl @@ -4,6 +4,13 @@
{{ctx.Locale.Tr "org.members.leave.detail" (HTMLFormat `` "dataOrganizationName")}}
-{{ctx.Locale.Tr "org.members.remove.detail" (HTMLFormat `` "name") (HTMLFormat `` "dataOrganizationName")}}
-