[MM-56206] Allow for proper paging and sorting (#25726)
Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
485ae6ae4e
Коммит
5c061a6f75
@@ -20,6 +20,12 @@
|
|||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
default: 'Username'
|
default: 'Username'
|
||||||
|
- name: direction
|
||||||
|
in: query
|
||||||
|
description: The direction in which to accept paging values from. Will return values ahead of the cursor if "up", and below the cursor if "down". Default is "down".
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
default: 'down'
|
||||||
- name: sort_direction
|
- name: sort_direction
|
||||||
in: query
|
in: query
|
||||||
description: The sorting direction. Must be one of ("asc", "desc"). Will default to 'asc' if not specified or the input is invalid.
|
description: The sorting direction. Must be one of ("asc", "desc"). Will default to 'asc' if not specified or the input is invalid.
|
||||||
@@ -34,14 +40,14 @@
|
|||||||
default: 50
|
default: 50
|
||||||
minimum: 1
|
minimum: 1
|
||||||
maximum: 100
|
maximum: 100
|
||||||
- name: last_column_value
|
- name: from_column_value
|
||||||
in: query
|
in: query
|
||||||
description: The value of the sorted column belonging to the last user returned in the page. Should be blank for the first page asked for.
|
description: The value of the sorted column corresponding to the cursor to read from. Should be blank for the first page asked for.
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
- name: last_id
|
- name: from_id
|
||||||
in: query
|
in: query
|
||||||
description: The value of the user id belonging to the last user returned in the page. Should be blank for the first page asked for.
|
description: The value of the user id corresponding to the cursor to read from. Should be blank for the first page asked for.
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
- name: date_range
|
- name: date_range
|
||||||
|
|||||||
@@ -28,6 +28,11 @@ func getUsersForReporting(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
sortColumn = r.URL.Query().Get("sort_column")
|
sortColumn = r.URL.Query().Get("sort_column")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
direction := "down"
|
||||||
|
if r.URL.Query().Get("direction") == "up" {
|
||||||
|
direction = "up"
|
||||||
|
}
|
||||||
|
|
||||||
pageSize := 50
|
pageSize := 50
|
||||||
if pageSizeStr, err := strconv.ParseInt(r.URL.Query().Get("page_size"), 10, 64); err == nil {
|
if pageSizeStr, err := strconv.ParseInt(r.URL.Query().Get("page_size"), 10, 64); err == nil {
|
||||||
pageSize = int(pageSizeStr)
|
pageSize = int(pageSizeStr)
|
||||||
@@ -48,14 +53,15 @@ func getUsersForReporting(c *Context, w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
options := &model.UserReportOptions{
|
options := &model.UserReportOptions{
|
||||||
ReportingBaseOptions: model.ReportingBaseOptions{
|
ReportingBaseOptions: model.ReportingBaseOptions{
|
||||||
SortColumn: sortColumn,
|
Direction: direction,
|
||||||
SortDesc: r.URL.Query().Get("sort_direction") == "desc",
|
SortColumn: sortColumn,
|
||||||
PageSize: pageSize,
|
SortDesc: r.URL.Query().Get("sort_direction") == "desc",
|
||||||
LastSortColumnValue: r.URL.Query().Get("last_column_value"),
|
PageSize: pageSize,
|
||||||
DateRange: r.URL.Query().Get("date_range"),
|
FromColumnValue: r.URL.Query().Get("from_column_value"),
|
||||||
|
FromId: r.URL.Query().Get("from_id"),
|
||||||
|
DateRange: r.URL.Query().Get("date_range"),
|
||||||
},
|
},
|
||||||
Team: teamFilter,
|
Team: teamFilter,
|
||||||
LastUserId: r.URL.Query().Get("last_id"),
|
|
||||||
Role: r.URL.Query().Get("role_filter"),
|
Role: r.URL.Query().Get("role_filter"),
|
||||||
HasNoTeam: r.URL.Query().Get("has_no_team") == "true",
|
HasNoTeam: r.URL.Query().Get("has_no_team") == "true",
|
||||||
HideActive: hideActive,
|
HideActive: hideActive,
|
||||||
|
|||||||
@@ -2297,17 +2297,28 @@ func (us SqlUserStore) GetUserReport(filter *model.UserReportOptions) ([]*model.
|
|||||||
Select(selectColumns...).
|
Select(selectColumns...).
|
||||||
From("Users u").
|
From("Users u").
|
||||||
LeftJoin("Status s ON s.UserId = u.Id").
|
LeftJoin("Status s ON s.UserId = u.Id").
|
||||||
Where(sq.Or{
|
|
||||||
sq.Gt{filter.SortColumn: filter.LastSortColumnValue},
|
|
||||||
sq.And{
|
|
||||||
sq.Eq{filter.SortColumn: filter.LastSortColumnValue},
|
|
||||||
sq.Gt{"u.Id": filter.LastUserId},
|
|
||||||
},
|
|
||||||
}).
|
|
||||||
Where(sq.Expr("u.Id NOT IN (SELECT UserId FROM Bots)")).
|
Where(sq.Expr("u.Id NOT IN (SELECT UserId FROM Bots)")).
|
||||||
GroupBy("u.Id").
|
GroupBy("u.Id").
|
||||||
OrderBy(sortColumnValue, "u.Id")
|
OrderBy(sortColumnValue, "u.Id")
|
||||||
|
|
||||||
|
if (filter.Direction == "up" && !filter.SortDesc) || (filter.Direction == "down" && filter.SortDesc) {
|
||||||
|
query = query.Where(sq.Or{
|
||||||
|
sq.Lt{filter.SortColumn: filter.FromColumnValue},
|
||||||
|
sq.And{
|
||||||
|
sq.Eq{filter.SortColumn: filter.FromColumnValue},
|
||||||
|
sq.Lt{"u.Id": filter.FromId},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
query = query.Where(sq.Or{
|
||||||
|
sq.Gt{filter.SortColumn: filter.FromColumnValue},
|
||||||
|
sq.And{
|
||||||
|
sq.Eq{filter.SortColumn: filter.FromColumnValue},
|
||||||
|
sq.Gt{"u.Id": filter.FromId},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
if filter.PageSize > 0 {
|
if filter.PageSize > 0 {
|
||||||
query = query.Limit(uint64(filter.PageSize))
|
query = query.Limit(uint64(filter.PageSize))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6321,11 +6321,62 @@ func testGetUserReport(t *testing.T, rctx request.CTX, ss store.Store) {
|
|||||||
t.Run("should return correct paging", func(t *testing.T) {
|
t.Run("should return correct paging", func(t *testing.T) {
|
||||||
userReport, err := ss.User().GetUserReport(&model.UserReportOptions{
|
userReport, err := ss.User().GetUserReport(&model.UserReportOptions{
|
||||||
ReportingBaseOptions: model.ReportingBaseOptions{
|
ReportingBaseOptions: model.ReportingBaseOptions{
|
||||||
SortColumn: "Username",
|
SortColumn: "Username",
|
||||||
PageSize: 50,
|
Direction: "down",
|
||||||
LastSortColumnValue: u2.Username,
|
PageSize: 50,
|
||||||
|
FromColumnValue: u2.Username,
|
||||||
|
FromId: u2.Id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, userReport)
|
||||||
|
require.Equal(t, 1, len(userReport))
|
||||||
|
|
||||||
|
require.NotNil(t, userReport[0])
|
||||||
|
require.Equal(t, u3.Username, userReport[0].Username)
|
||||||
|
|
||||||
|
userReport, err = ss.User().GetUserReport(&model.UserReportOptions{
|
||||||
|
ReportingBaseOptions: model.ReportingBaseOptions{
|
||||||
|
SortColumn: "Username",
|
||||||
|
SortDesc: true,
|
||||||
|
Direction: "down",
|
||||||
|
PageSize: 50,
|
||||||
|
FromColumnValue: u2.Username,
|
||||||
|
FromId: u2.Id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, userReport)
|
||||||
|
require.Equal(t, 1, len(userReport))
|
||||||
|
|
||||||
|
require.NotNil(t, userReport[0])
|
||||||
|
require.Equal(t, u1.Username, userReport[0].Username)
|
||||||
|
|
||||||
|
userReport, err = ss.User().GetUserReport(&model.UserReportOptions{
|
||||||
|
ReportingBaseOptions: model.ReportingBaseOptions{
|
||||||
|
SortColumn: "Username",
|
||||||
|
Direction: "up",
|
||||||
|
PageSize: 50,
|
||||||
|
FromColumnValue: u2.Username,
|
||||||
|
FromId: u2.Id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotNil(t, userReport)
|
||||||
|
require.Equal(t, 1, len(userReport))
|
||||||
|
|
||||||
|
require.NotNil(t, userReport[0])
|
||||||
|
require.Equal(t, u1.Username, userReport[0].Username)
|
||||||
|
|
||||||
|
userReport, err = ss.User().GetUserReport(&model.UserReportOptions{
|
||||||
|
ReportingBaseOptions: model.ReportingBaseOptions{
|
||||||
|
SortColumn: "Username",
|
||||||
|
SortDesc: true,
|
||||||
|
Direction: "up",
|
||||||
|
PageSize: 50,
|
||||||
|
FromColumnValue: u2.Username,
|
||||||
|
FromId: u2.Id,
|
||||||
},
|
},
|
||||||
LastUserId: u2.Id,
|
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.NotNil(t, userReport)
|
require.NotNil(t, userReport)
|
||||||
|
|||||||
@@ -1924,6 +1924,9 @@ func (c *Client4) EnableUserAccessToken(ctx context.Context, tokenId string) (*R
|
|||||||
|
|
||||||
func (c *Client4) GetUsersForReporting(ctx context.Context, options *UserReportOptions) ([]*UserReport, *Response, error) {
|
func (c *Client4) GetUsersForReporting(ctx context.Context, options *UserReportOptions) ([]*UserReport, *Response, error) {
|
||||||
values := url.Values{}
|
values := url.Values{}
|
||||||
|
if options.Direction != "" {
|
||||||
|
values.Set("direction", options.Direction)
|
||||||
|
}
|
||||||
if options.SortColumn != "" {
|
if options.SortColumn != "" {
|
||||||
values.Set("sort_column", options.SortColumn)
|
values.Set("sort_column", options.SortColumn)
|
||||||
}
|
}
|
||||||
@@ -1942,11 +1945,11 @@ func (c *Client4) GetUsersForReporting(ctx context.Context, options *UserReportO
|
|||||||
if options.SortDesc {
|
if options.SortDesc {
|
||||||
values.Set("sort_direction", "desc")
|
values.Set("sort_direction", "desc")
|
||||||
}
|
}
|
||||||
if options.LastSortColumnValue != "" {
|
if options.FromColumnValue != "" {
|
||||||
values.Set("last_column_value", options.LastSortColumnValue)
|
values.Set("from_column_value", options.FromColumnValue)
|
||||||
}
|
}
|
||||||
if options.LastUserId != "" {
|
if options.FromId != "" {
|
||||||
values.Set("last_id", options.LastUserId)
|
values.Set("from_id", options.FromId)
|
||||||
}
|
}
|
||||||
if options.Role != "" {
|
if options.Role != "" {
|
||||||
values.Set("role_filter", options.Role)
|
values.Set("role_filter", options.Role)
|
||||||
|
|||||||
@@ -23,13 +23,15 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ReportingBaseOptions struct {
|
type ReportingBaseOptions struct {
|
||||||
SortDesc bool
|
SortDesc bool
|
||||||
PageSize int
|
Direction string // Accepts only "up" or "down"
|
||||||
SortColumn string
|
PageSize int
|
||||||
LastSortColumnValue string
|
SortColumn string
|
||||||
DateRange string
|
FromColumnValue string
|
||||||
StartAt int64
|
FromId string
|
||||||
EndAt int64
|
DateRange string
|
||||||
|
StartAt int64
|
||||||
|
EndAt int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func (options *ReportingBaseOptions) PopulateDateRange(now time.Time) {
|
func (options *ReportingBaseOptions) PopulateDateRange(now time.Time) {
|
||||||
@@ -75,7 +77,6 @@ type UserReport struct {
|
|||||||
|
|
||||||
type UserReportOptions struct {
|
type UserReportOptions struct {
|
||||||
ReportingBaseOptions
|
ReportingBaseOptions
|
||||||
LastUserId string
|
|
||||||
Role string
|
Role string
|
||||||
Team string
|
Team string
|
||||||
HasNoTeam bool
|
HasNoTeam bool
|
||||||
|
|||||||
@@ -48,9 +48,10 @@ export type UserReportOptions = {
|
|||||||
sort_column: 'CreateAt' | 'Username' | 'FirstName' | 'LastName' | 'Nickname' | 'Email',
|
sort_column: 'CreateAt' | 'Username' | 'FirstName' | 'LastName' | 'Nickname' | 'Email',
|
||||||
page_size: number,
|
page_size: number,
|
||||||
sort_direction?: 'asc' | 'desc',
|
sort_direction?: 'asc' | 'desc',
|
||||||
|
direction?: 'up' | 'down',
|
||||||
date_range?: ReportDuration,
|
date_range?: ReportDuration,
|
||||||
last_column_value?: string,
|
from_column_value?: string,
|
||||||
last_id?: string,
|
from_id?: string,
|
||||||
role_filter?: string,
|
role_filter?: string,
|
||||||
has_no_team?: boolean,
|
has_no_team?: boolean,
|
||||||
team_filter?: string,
|
team_filter?: string,
|
||||||
|
|||||||
Ссылка в новой задаче
Block a user