mirror of
https://github.com/go-gitea/gitea.git
synced 2025-04-08 17:05:45 +02:00
Update per feedback
This commit is contained in:
parent
9234ef5ecc
commit
f601501fc1
@ -46,14 +46,25 @@ func GetUserBadges(ctx context.Context, u *User) ([]*Badge, int64, error) {
|
||||
return badges, count, err
|
||||
}
|
||||
|
||||
// GetBadgeUsers returns the users that have a specific badge.
|
||||
func GetBadgeUsers(ctx context.Context, b *Badge) ([]*User, int64, error) {
|
||||
// GetBadgeUsersOptions contains options for getting users with a specific badge
|
||||
type GetBadgeUsersOptions struct {
|
||||
db.ListOptions
|
||||
Badge *Badge
|
||||
}
|
||||
|
||||
// GetBadgeUsers returns the users that have a specific badge with pagination support.
|
||||
func GetBadgeUsers(ctx context.Context, opts *GetBadgeUsersOptions) ([]*User, int64, error) {
|
||||
sess := db.GetEngine(ctx).
|
||||
Select("`user`.*").
|
||||
Join("INNER", "user_badge", "`user_badge`.user_id=user.id").
|
||||
Join("INNER", "badge", "`user_badge`.badge_id=badge.id").
|
||||
Where("badge.slug=?", b.Slug)
|
||||
users := make([]*User, 0, 8)
|
||||
Where("badge.slug=?", opts.Badge.Slug)
|
||||
|
||||
if opts.Page > 0 {
|
||||
sess = db.SetSessionPagination(sess, opts)
|
||||
}
|
||||
|
||||
users := make([]*User, 0, opts.PageSize)
|
||||
count, err := sess.FindAndCount(&users)
|
||||
return users, count, err
|
||||
}
|
||||
@ -82,10 +93,22 @@ func UpdateBadge(ctx context.Context, badge *Badge) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteBadge deletes a badge.
|
||||
// DeleteBadge deletes a badge and all associated user_badge entries.
|
||||
func DeleteBadge(ctx context.Context, badge *Badge) error {
|
||||
_, err := db.GetEngine(ctx).Where("slug=?", badge.Slug).Delete(badge)
|
||||
return err
|
||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||
// First delete all user_badge entries for this badge
|
||||
if _, err := db.GetEngine(ctx).
|
||||
Where("badge_id = (SELECT id FROM badge WHERE slug = ?)", badge.Slug).
|
||||
Delete(&UserBadge{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Then delete the badge itself
|
||||
if _, err := db.GetEngine(ctx).Where("slug=?", badge.Slug).Delete(badge); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// AddUserBadge adds a badge to a user.
|
||||
@ -123,18 +146,18 @@ func RemoveUserBadge(ctx context.Context, u *User, badge *Badge) error {
|
||||
// RemoveUserBadges removes specific badges from a user.
|
||||
func RemoveUserBadges(ctx context.Context, u *User, badges []*Badge) error {
|
||||
return db.WithTx(ctx, func(ctx context.Context) error {
|
||||
for _, badge := range badges {
|
||||
subQuery := builder.
|
||||
Select("id").
|
||||
From("badge").
|
||||
Where(builder.Eq{"slug": badge.Slug})
|
||||
slugs := make([]string, len(badges))
|
||||
for i, badge := range badges {
|
||||
slugs[i] = badge.Slug
|
||||
}
|
||||
|
||||
if _, err := db.GetEngine(ctx).
|
||||
Where("`user_badge`.user_id=?", u.ID).
|
||||
And(builder.In("badge_id", subQuery)).
|
||||
Delete(&UserBadge{}); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := db.GetEngine(ctx).
|
||||
Table("user_badge").
|
||||
Join("INNER", "badge", "`user_badge`.badge_id = badge.id").
|
||||
Where("`user_badge`.user_id = ?", u.ID).
|
||||
And(builder.In("badge.slug", slugs)).
|
||||
Delete(&UserBadge{}); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@ -155,8 +178,6 @@ type SearchBadgeOptions struct {
|
||||
ID int64
|
||||
OrderBy db.SearchOrderBy
|
||||
Actor *User // The user doing the search
|
||||
|
||||
ExtraParamStrings map[string]string
|
||||
}
|
||||
|
||||
func (opts *SearchBadgeOptions) ToConds() builder.Cond {
|
||||
@ -174,15 +195,6 @@ func (opts *SearchBadgeOptions) ToOrders() string {
|
||||
return orderBy
|
||||
}
|
||||
|
||||
func (opts *SearchBadgeOptions) ToJoins() []db.JoinFunc {
|
||||
return []db.JoinFunc{
|
||||
func(e db.Engine) error {
|
||||
e.Join("INNER", "badge", "`user_badge`.badge_id=badge.id")
|
||||
return nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func SearchBadges(ctx context.Context, opts *SearchBadgeOptions) (badges []*Badge, _ int64, _ error) {
|
||||
sessCount := opts.toSearchQueryBase(ctx)
|
||||
count, err := sessCount.Count(new(Badge))
|
||||
@ -233,3 +245,16 @@ func (opts *SearchBadgeOptions) toSearchQueryBase(ctx context.Context) *xorm.Ses
|
||||
|
||||
return e.Where(cond)
|
||||
}
|
||||
|
||||
// GetBadgeByID returns a specific badge by ID
|
||||
func GetBadgeByID(ctx context.Context, id int64) (*Badge, error) {
|
||||
badge := new(Badge)
|
||||
has, err := db.GetEngine(ctx).ID(id).Get(badge)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !has {
|
||||
return nil, ErrBadgeNotExist{ID: id}
|
||||
}
|
||||
return badge, nil
|
||||
}
|
||||
|
@ -131,6 +131,14 @@ func (err ErrBadgeAlreadyExist) Unwrap() error {
|
||||
// ErrBadgeNotExist represents a "BadgeNotExist" kind of error.
|
||||
type ErrBadgeNotExist struct {
|
||||
Slug string
|
||||
ID int64
|
||||
}
|
||||
|
||||
func (err ErrBadgeNotExist) Error() string {
|
||||
if err.ID > 0 {
|
||||
return fmt.Sprintf("badge does not exist [id: %d]", err.ID)
|
||||
}
|
||||
return fmt.Sprintf("badge does not exist [slug: %s]", err.Slug)
|
||||
}
|
||||
|
||||
// IsErrBadgeNotExist checks if an error is a ErrBadgeNotExist.
|
||||
@ -139,10 +147,6 @@ func IsErrBadgeNotExist(err error) bool {
|
||||
return ok
|
||||
}
|
||||
|
||||
func (err ErrBadgeNotExist) Error() string {
|
||||
return fmt.Sprintf("badge does not exist [slug: %s]", err.Slug)
|
||||
}
|
||||
|
||||
// Unwrap unwraps this error as a ErrNotExist error
|
||||
func (err ErrBadgeNotExist) Unwrap() error {
|
||||
return util.ErrNotExist
|
||||
|
@ -7,14 +7,13 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/web"
|
||||
"code.gitea.io/gitea/routers/web/explore"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
@ -23,11 +22,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
tplBadges base.TplName = "admin/badge/list"
|
||||
tplBadgeNew base.TplName = "admin/badge/new"
|
||||
tplBadgeView base.TplName = "admin/badge/view"
|
||||
tplBadgeEdit base.TplName = "admin/badge/edit"
|
||||
tplBadgeUsers base.TplName = "admin/badge/users"
|
||||
tplBadges templates.TplName = "admin/badge/list"
|
||||
tplBadgeNew templates.TplName = "admin/badge/new"
|
||||
tplBadgeView templates.TplName = "admin/badge/view"
|
||||
tplBadgeEdit templates.TplName = "admin/badge/edit"
|
||||
tplBadgeUsers templates.TplName = "admin/badge/users"
|
||||
)
|
||||
|
||||
// BadgeSearchDefaultAdminSort is the default sort type for admin view
|
||||
@ -97,14 +96,14 @@ func NewBadgePost(ctx *context.Context) {
|
||||
log.Trace("Badge created by admin (%s): %s", ctx.Doer.Name, b.Slug)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.badges.new_success", b.Slug))
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/badges/" + strconv.FormatInt(b.ID, 10))
|
||||
ctx.Redirect(setting.AppSubURL + "/-/admin/badges/" + url.PathEscape(b.Slug))
|
||||
}
|
||||
|
||||
func prepareBadgeInfo(ctx *context.Context) *user_model.Badge {
|
||||
b, err := user_model.GetBadge(ctx, ctx.PathParam(":badge_slug"))
|
||||
if err != nil {
|
||||
if user_model.IsErrBadgeNotExist(err) {
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/badges")
|
||||
ctx.Redirect(setting.AppSubURL + "/-/admin/badges")
|
||||
} else {
|
||||
ctx.ServerError("GetBadge", err)
|
||||
}
|
||||
@ -112,10 +111,16 @@ func prepareBadgeInfo(ctx *context.Context) *user_model.Badge {
|
||||
}
|
||||
ctx.Data["Badge"] = b
|
||||
|
||||
users, count, err := user_model.GetBadgeUsers(ctx, b)
|
||||
opts := &user_model.GetBadgeUsersOptions{
|
||||
ListOptions: db.ListOptions{
|
||||
PageSize: setting.UI.User.RepoPagingNum,
|
||||
},
|
||||
Badge: b,
|
||||
}
|
||||
users, count, err := user_model.GetBadgeUsers(ctx, opts)
|
||||
if err != nil {
|
||||
if user_model.IsErrUserNotExist(err) {
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/badges")
|
||||
ctx.Redirect(setting.AppSubURL + "/-/admin/badges")
|
||||
} else {
|
||||
ctx.ServerError("GetBadgeUsers", err)
|
||||
}
|
||||
@ -187,7 +192,7 @@ func EditBadgePost(ctx *context.Context) {
|
||||
log.Trace("Badge updated by admin (%s): %s", ctx.Doer.Name, b.Slug)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.badges.update_success"))
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/badges/" + url.PathEscape(ctx.PathParam(":badge_slug")))
|
||||
ctx.Redirect(setting.AppSubURL + "/-/admin/badges/" + url.PathEscape(ctx.PathParam(":badge_slug")))
|
||||
}
|
||||
|
||||
// DeleteBadge response for deleting a badge
|
||||
@ -206,20 +211,35 @@ func DeleteBadge(ctx *context.Context) {
|
||||
log.Trace("Badge deleted by admin (%s): %s", ctx.Doer.Name, b.Slug)
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("admin.badges.deletion_success"))
|
||||
ctx.Redirect(setting.AppSubURL + "/admin/badges")
|
||||
ctx.Redirect(setting.AppSubURL + "/-/admin/badges")
|
||||
}
|
||||
|
||||
func BadgeUsers(ctx *context.Context) {
|
||||
ctx.Data["Title"] = ctx.Tr("admin.badges.users_with_badge", ctx.PathParam(":badge_slug"))
|
||||
ctx.Data["PageIsAdminBadges"] = true
|
||||
|
||||
users, _, err := user_model.GetBadgeUsers(ctx, &user_model.Badge{Slug: ctx.PathParam(":badge_slug")})
|
||||
page := ctx.FormInt("page")
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
badge := &user_model.Badge{Slug: ctx.PathParam(":badge_slug")}
|
||||
opts := &user_model.GetBadgeUsersOptions{
|
||||
ListOptions: db.ListOptions{
|
||||
Page: page,
|
||||
PageSize: setting.UI.User.RepoPagingNum,
|
||||
},
|
||||
Badge: badge,
|
||||
}
|
||||
users, count, err := user_model.GetBadgeUsers(ctx, opts)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetBadgeUsers", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Users"] = users
|
||||
ctx.Data["Total"] = count
|
||||
ctx.Data["Page"] = context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5)
|
||||
|
||||
ctx.HTML(http.StatusOK, tplBadgeUsers)
|
||||
}
|
||||
@ -267,8 +287,41 @@ func DeleteBadgeUser(ctx *context.Context) {
|
||||
ctx.Flash.Success(ctx.Tr("admin.badges.user_remove_success"))
|
||||
} else {
|
||||
ctx.Flash.Error("DeleteUser: " + err.Error())
|
||||
}
|
||||
|
||||
ctx.JSONRedirect(fmt.Sprintf("%s/-/admin/badges/%s/users", setting.AppSubURL, ctx.PathParam(":badge_slug")))
|
||||
}
|
||||
|
||||
// ViewBadgeUsers render badge's users page
|
||||
func ViewBadgeUsers(ctx *context.Context) {
|
||||
badge, err := user_model.GetBadge(ctx, ctx.PathParam(":slug"))
|
||||
if err != nil {
|
||||
ctx.ServerError("GetBadge", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.JSONRedirect(fmt.Sprintf("%s/admin/badges/%s/users", setting.AppSubURL, ctx.PathParam(":badge_slug")))
|
||||
page := ctx.FormInt("page")
|
||||
if page <= 0 {
|
||||
page = 1
|
||||
}
|
||||
|
||||
opts := &user_model.GetBadgeUsersOptions{
|
||||
ListOptions: db.ListOptions{
|
||||
Page: page,
|
||||
PageSize: setting.UI.User.RepoPagingNum,
|
||||
},
|
||||
Badge: badge,
|
||||
}
|
||||
users, count, err := user_model.GetBadgeUsers(ctx, opts)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetBadgeUsers", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["Title"] = badge.Description
|
||||
ctx.Data["Badge"] = badge
|
||||
ctx.Data["Users"] = users
|
||||
ctx.Data["Total"] = count
|
||||
ctx.Data["Pages"] = context.NewPagination(int(count), setting.UI.User.RepoPagingNum, page, 5)
|
||||
ctx.HTML(http.StatusOK, tplBadgeUsers)
|
||||
}
|
||||
|
@ -8,12 +8,12 @@ import (
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/services/context"
|
||||
)
|
||||
|
||||
func RenderBadgeSearch(ctx *context.Context, opts *user_model.SearchBadgeOptions, tplName base.TplName) {
|
||||
func RenderBadgeSearch(ctx *context.Context, opts *user_model.SearchBadgeOptions, tplName templates.TplName) {
|
||||
// Sitemap index for sitemap paths
|
||||
opts.Page = int(ctx.PathParamInt64("idx"))
|
||||
if opts.Page <= 1 {
|
||||
@ -68,10 +68,7 @@ func RenderBadgeSearch(ctx *context.Context, opts *user_model.SearchBadgeOptions
|
||||
ctx.Data["Badges"] = badges
|
||||
|
||||
pager := context.NewPagination(int(count), opts.PageSize, opts.Page, 5)
|
||||
pager.SetDefaultParams(ctx)
|
||||
for paramKey, paramVal := range opts.ExtraParamStrings {
|
||||
pager.AddParamString(paramKey, paramVal)
|
||||
}
|
||||
pager.AddParamFromRequest(ctx.Req)
|
||||
ctx.Data["Page"] = pager
|
||||
|
||||
ctx.HTML(http.StatusOK, tplName)
|
||||
|
@ -44,3 +44,15 @@ func DeleteBadge(ctx context.Context, b *user_model.Badge) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetBadgeUsers returns the users that have a specific badge
|
||||
func GetBadgeUsers(ctx context.Context, badge *user_model.Badge, page, pageSize int) ([]*user_model.User, int64, error) {
|
||||
opts := &user_model.GetBadgeUsersOptions{
|
||||
ListOptions: db.ListOptions{
|
||||
Page: page,
|
||||
PageSize: pageSize,
|
||||
},
|
||||
Badge: badge,
|
||||
}
|
||||
return user_model.GetBadgeUsers(ctx, opts)
|
||||
}
|
||||
|
@ -3,7 +3,7 @@
|
||||
<h4 class="ui top attached header">
|
||||
{{ctx.Locale.Tr "admin.badges.badges_manage_panel"}} ({{ctx.Locale.Tr "admin.total" .Total}})
|
||||
<div class="ui right">
|
||||
<a class="ui primary tiny button" href="{{AppSubUrl}}/admin/badges/new">{{ctx.Locale.Tr "admin.badges.new_badge"}}</a>
|
||||
<a class="ui primary tiny button" href="{{AppSubUrl}}/-/admin/badges/new">{{ctx.Locale.Tr "admin.badges.new_badge"}}</a>
|
||||
</div>
|
||||
</h4>
|
||||
<div class="ui attached segment">
|
||||
|
@ -26,6 +26,7 @@
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
{{template "base/paginate" .}}
|
||||
<div class="ui bottom attached segment">
|
||||
<form class="ui form" id="search-badge-user-form" action="{{.Link}}" method="post">
|
||||
{{.CsrfTokenHtml}}
|
||||
|
Loading…
x
Reference in New Issue
Block a user