Remove insights (#23952)
* removed server side * Updated store layer * unused import * Updated autogenerated code template * Updated tests * lint fix * unused translations * webapp side * Updated i18n * lint fix: * type fix * Updated snapshots * Removed insights from API specs * updated e2e * Updated e2e tests * Updated e2e tests * Removed insights tests * Removed Insights as possible channel to load in sidebar from test * Removed more insights tests * More e2e fixed * More cleanup * Lint * More cleanup in client4 and boards api * More cleanup * Fixes * lint fix --------- Co-authored-by: maria.nunez <maria.nunez@mattermost.com> Co-authored-by: Mattermost Build <build@mattermost.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
e37459cd00
Коммит
26617fcbdc
@@ -3670,76 +3670,6 @@ func (c *Client4) AutocompleteChannelsForTeamForSearch(ctx context.Context, team
|
||||
return ch, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
// GetTopChannelsForTeamSince will return an ordered list of the top channels in a given team.
|
||||
func (c *Client4) GetTopChannelsForTeamSince(ctx context.Context, teamId string, timeRange string, page int, perPage int) (*TopChannelList, *Response, error) {
|
||||
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v", timeRange, page, perPage)
|
||||
r, err := c.DoAPIGet(ctx, c.teamRoute(teamId)+"/top/channels"+query, "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var topChannels *TopChannelList
|
||||
if err := json.NewDecoder(r.Body).Decode(&topChannels); err != nil {
|
||||
return nil, nil, NewAppError("GetTopChannelsForTeamSince", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
}
|
||||
return topChannels, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
// GetTopChannelsForUserSince will return an ordered list of your top channels in a given team.
|
||||
func (c *Client4) GetTopChannelsForUserSince(ctx context.Context, teamId string, timeRange string, page int, perPage int) (*TopChannelList, *Response, error) {
|
||||
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v", timeRange, page, perPage)
|
||||
|
||||
if teamId != "" {
|
||||
query += fmt.Sprintf("&team_id=%v", teamId)
|
||||
}
|
||||
|
||||
r, err := c.DoAPIGet(ctx, c.usersRoute()+"/me/top/channels"+query, "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var topChannels *TopChannelList
|
||||
if err := json.NewDecoder(r.Body).Decode(&topChannels); err != nil {
|
||||
return nil, nil, NewAppError("GetTopChannelsForUserSince", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
}
|
||||
return topChannels, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
// GetTopInactiveChannelsForTeamSince will return an ordered list of the top channels in a given team.
|
||||
func (c *Client4) GetTopInactiveChannelsForTeamSince(ctx context.Context, teamId string, timeRange string, page int, perPage int) (*TopInactiveChannelList, *Response, error) {
|
||||
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v", timeRange, page, perPage)
|
||||
r, err := c.DoAPIGet(ctx, c.teamRoute(teamId)+"/top/inactive_channels"+query, "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var topInactiveChannels *TopInactiveChannelList
|
||||
if jsonErr := json.NewDecoder(r.Body).Decode(&topInactiveChannels); jsonErr != nil {
|
||||
return nil, nil, NewAppError("GetTopInactiveChannelsForTeamSince", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return topInactiveChannels, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
// GetTopInactiveChannelsForUserSince will return an ordered list of your top channels in a given team.
|
||||
func (c *Client4) GetTopInactiveChannelsForUserSince(ctx context.Context, teamId string, timeRange string, page int, perPage int) (*TopInactiveChannelList, *Response, error) {
|
||||
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v", timeRange, page, perPage)
|
||||
|
||||
if teamId != "" {
|
||||
query += fmt.Sprintf("&team_id=%v", teamId)
|
||||
}
|
||||
|
||||
r, err := c.DoAPIGet(ctx, c.usersRoute()+"/me/top/inactive_channels"+query, "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var topInactiveChannels *TopInactiveChannelList
|
||||
if jsonErr := json.NewDecoder(r.Body).Decode(&topInactiveChannels); jsonErr != nil {
|
||||
return nil, nil, NewAppError("GetTopInactiveChannelsForUserSince", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return topInactiveChannels, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
// Post Section
|
||||
|
||||
// CreatePost creates a post based on the provided post struct.
|
||||
@@ -4322,41 +4252,6 @@ func (c *Client4) DoPostActionWithCookie(ctx context.Context, postId, actionId,
|
||||
return BuildResponse(r), nil
|
||||
}
|
||||
|
||||
// GetTopThreadsForTeamSince will return an ordered list of the top channels in a given team.
|
||||
func (c *Client4) GetTopThreadsForTeamSince(ctx context.Context, teamId string, timeRange string, page int, perPage int) (*TopThreadList, *Response, error) {
|
||||
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v", timeRange, page, perPage)
|
||||
r, err := c.DoAPIGet(ctx, c.teamRoute(teamId)+"/top/threads"+query, "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var topThreads *TopThreadList
|
||||
if err := json.NewDecoder(r.Body).Decode(&topThreads); err != nil {
|
||||
return nil, nil, NewAppError("GetTopThreadsForTeamSince", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
}
|
||||
return topThreads, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
// GetTopThreadsForUserSince will return an ordered list of your top channels in a given team.
|
||||
func (c *Client4) GetTopThreadsForUserSince(ctx context.Context, teamId string, timeRange string, page int, perPage int) (*TopThreadList, *Response, error) {
|
||||
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v", timeRange, page, perPage)
|
||||
|
||||
if teamId != "" {
|
||||
query += fmt.Sprintf("&team_id=%v", teamId)
|
||||
}
|
||||
|
||||
r, err := c.DoAPIGet(ctx, c.usersRoute()+"/me/top/threads"+query, "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var topThreads *TopThreadList
|
||||
if err := json.NewDecoder(r.Body).Decode(&topThreads); err != nil {
|
||||
return nil, nil, NewAppError("GetTopThreadsForUserSince", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
}
|
||||
return topThreads, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
// OpenInteractiveDialog sends a WebSocket event to a user's clients to
|
||||
// open interactive dialogs, based on the provided trigger ID and other
|
||||
// provided data. Used with interactive message buttons, menus and
|
||||
@@ -6849,54 +6744,6 @@ func (c *Client4) GetBulkReactions(ctx context.Context, postIds []string) (map[s
|
||||
return reactions, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) GetTopReactionsForTeamSince(ctx context.Context, teamId string, timeRange string, page int, perPage int) (*TopReactionList, *Response, error) {
|
||||
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v", timeRange, page, perPage)
|
||||
r, err := c.DoAPIGet(ctx, c.teamRoute(teamId)+"/top/reactions"+query, "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var topReactions *TopReactionList
|
||||
if err := json.NewDecoder(r.Body).Decode(&topReactions); err != nil {
|
||||
return nil, nil, NewAppError("GetTopReactionsForTeamSince", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
}
|
||||
return topReactions, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) GetTopReactionsForUserSince(ctx context.Context, teamId string, timeRange string, page int, perPage int) (*TopReactionList, *Response, error) {
|
||||
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v", timeRange, page, perPage)
|
||||
|
||||
if teamId != "" {
|
||||
query += fmt.Sprintf("&team_id=%v", teamId)
|
||||
}
|
||||
|
||||
r, err := c.DoAPIGet(ctx, c.usersRoute()+"/me/top/reactions"+query, "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var topReactions *TopReactionList
|
||||
if err := json.NewDecoder(r.Body).Decode(&topReactions); err != nil {
|
||||
return nil, nil, NewAppError("GetTopReactionsForUserSince", "api.unmarshal_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
||||
}
|
||||
return topReactions, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) GetTopDMsForUserSince(ctx context.Context, timeRange string, page int, perPage int) (*TopDMList, *Response, error) {
|
||||
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v", timeRange, page, perPage)
|
||||
|
||||
r, err := c.DoAPIGet(ctx, c.usersRoute()+"/me/top/dms"+query, "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var topDMs *TopDMList
|
||||
if jsonErr := json.NewDecoder(r.Body).Decode(&topDMs); jsonErr != nil {
|
||||
return nil, nil, NewAppError("GetTopReactionsForUserSince", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return topDMs, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
// Timezone Section
|
||||
|
||||
// GetSupportedTimezone returns a page of supported timezones on the system.
|
||||
@@ -8645,20 +8492,6 @@ func (c *Client4) GetTeamsUsage(ctx context.Context) (*TeamsUsage, *Response, er
|
||||
return usage, BuildResponse(r), err
|
||||
}
|
||||
|
||||
func (c *Client4) GetNewTeamMembersSince(ctx context.Context, teamID string, timeRange string, page int, perPage int) (*NewTeamMembersList, *Response, error) {
|
||||
query := fmt.Sprintf("?time_range=%v&page=%v&per_page=%v", timeRange, page, perPage)
|
||||
r, err := c.DoAPIGet(ctx, c.teamRoute(teamID)+"/top/team_members"+query, "")
|
||||
if err != nil {
|
||||
return nil, BuildResponse(r), err
|
||||
}
|
||||
defer closeBody(r)
|
||||
var newTeamMembersList *NewTeamMembersList
|
||||
if jsonErr := json.NewDecoder(r.Body).Decode(&newTeamMembersList); jsonErr != nil {
|
||||
return nil, nil, NewAppError("GetNewTeamMembersSince", "api.unmarshal_error", nil, jsonErr.Error(), http.StatusInternalServerError)
|
||||
}
|
||||
return newTeamMembersList, BuildResponse(r), nil
|
||||
}
|
||||
|
||||
func (c *Client4) SelfHostedSignupAvailable(ctx context.Context) (*Response, error) {
|
||||
r, err := c.DoAPIGet(ctx, c.hostedCustomerRoute()+"/signup_available", "")
|
||||
|
||||
|
||||
@@ -41,8 +41,6 @@ type FeatureFlags struct {
|
||||
// Enable GraphQL feature
|
||||
GraphQL bool
|
||||
|
||||
InsightsEnabled bool
|
||||
|
||||
PostPriority bool
|
||||
|
||||
// Enable WYSIWYG text editor
|
||||
@@ -71,7 +69,6 @@ func (f *FeatureFlags) SetDefaults() {
|
||||
f.BoardsDataRetention = false
|
||||
f.NormalizeLdapDNs = false
|
||||
f.GraphQL = false
|
||||
f.InsightsEnabled = false
|
||||
f.CallsEnabled = true
|
||||
f.PeopleProduct = false
|
||||
f.DeprecateCloudFree = false
|
||||
|
||||
@@ -1,363 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
type PostCountGrouping string
|
||||
|
||||
const (
|
||||
TimeRangeToday string = "today"
|
||||
TimeRange7Day string = "7_day"
|
||||
TimeRange28Day string = "28_day"
|
||||
|
||||
PostsByHour PostCountGrouping = "hour"
|
||||
PostsByDay PostCountGrouping = "day"
|
||||
)
|
||||
|
||||
type InsightsOpts struct {
|
||||
StartUnixMilli int64
|
||||
Page int
|
||||
PerPage int
|
||||
}
|
||||
|
||||
type InsightsListData struct {
|
||||
HasNext bool `json:"has_next"`
|
||||
}
|
||||
|
||||
// Top Reactions
|
||||
type TopReactionList struct {
|
||||
InsightsListData
|
||||
Items []*TopReaction `json:"items"`
|
||||
}
|
||||
|
||||
type TopReaction struct {
|
||||
EmojiName string `json:"emoji_name"`
|
||||
Count int64 `json:"count"`
|
||||
}
|
||||
|
||||
// Top Channels
|
||||
type TopChannelList struct {
|
||||
InsightsListData
|
||||
Items []*TopChannel `json:"items"`
|
||||
PostCountByDuration ChannelPostCountByDuration `json:"channel_post_counts_by_duration"`
|
||||
}
|
||||
|
||||
func (t *TopChannelList) ChannelIDs() []string {
|
||||
var ids []string
|
||||
for _, item := range t.Items {
|
||||
ids = append(ids, item.ID)
|
||||
}
|
||||
return ids
|
||||
}
|
||||
|
||||
type TopChannel struct {
|
||||
ID string `json:"id"`
|
||||
Type ChannelType `json:"type"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Name string `json:"name"`
|
||||
TeamID string `json:"team_id"`
|
||||
MessageCount int64 `json:"message_count"`
|
||||
}
|
||||
|
||||
// Top Channels
|
||||
type TopInactiveChannelList struct {
|
||||
InsightsListData
|
||||
Items []*TopInactiveChannel `json:"items"`
|
||||
}
|
||||
|
||||
type TopInactiveChannel struct {
|
||||
ID string `json:"id"`
|
||||
Type ChannelType `json:"type"`
|
||||
DisplayName string `json:"display_name"`
|
||||
Name string `json:"name"`
|
||||
LastActivityAt int64 `json:"last_activity_at"`
|
||||
Participants StringArray `json:"participants"`
|
||||
MessageCount int64 `json:"-"`
|
||||
}
|
||||
|
||||
// Top Threads
|
||||
type TopThreadList struct {
|
||||
InsightsListData
|
||||
Items []*TopThread `json:"items"`
|
||||
}
|
||||
|
||||
type TopThread struct {
|
||||
PostId string `json:"-"`
|
||||
ReplyCount int64 `json:"-"`
|
||||
ChannelId string `json:"channel_id"`
|
||||
DisplayName string `json:"channel_display_name"`
|
||||
Name string `json:"channel_name"`
|
||||
Participants StringArray `json:"participants"`
|
||||
UserId string `json:"-"`
|
||||
UserInformation *InsightUserInformation `json:"user_information"`
|
||||
Post *Post `json:"post"`
|
||||
}
|
||||
|
||||
type InsightUserInformation struct {
|
||||
Id string `json:"id"`
|
||||
LastPictureUpdate int64 `json:"last_picture_update"`
|
||||
FirstName string `json:"first_name"`
|
||||
LastName string `json:"last_name"`
|
||||
NickName string `json:"nickname"`
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
type TopDMInsightUserInformation struct {
|
||||
InsightUserInformation
|
||||
Position string `json:"position"`
|
||||
}
|
||||
type NewTeamMembersList struct {
|
||||
InsightsListData
|
||||
Items []*NewTeamMember `json:"items"`
|
||||
TotalCount int64 `json:"total_count"`
|
||||
}
|
||||
|
||||
type NewTeamMember struct {
|
||||
Id string `json:"id"`
|
||||
Username string `json:"username"`
|
||||
FirstName string `json:"first_name"`
|
||||
LastName string `json:"last_name"`
|
||||
Position string `json:"position"`
|
||||
Nickname string `json:"nickname"`
|
||||
LastPictureUpdate int64 `json:"last_picture_update,omitempty"`
|
||||
CreateAt int64 `json:"create_at"`
|
||||
}
|
||||
|
||||
type DurationPostCount struct {
|
||||
ChannelID string `db:"channelid"`
|
||||
// Duration is an ISO8601 date string.
|
||||
Duration string `db:"duration"`
|
||||
PostCount int `db:"postcount"`
|
||||
}
|
||||
|
||||
// Top DMs
|
||||
type TopDM struct {
|
||||
MessageCount int64 `json:"post_count"`
|
||||
OutgoingMessageCount int64 `json:"outgoing_message_count"`
|
||||
Participants string `json:"-"`
|
||||
ChannelId string `json:"-"`
|
||||
SecondParticipant *TopDMInsightUserInformation `json:"second_participant"`
|
||||
}
|
||||
|
||||
type OutgoingMessageQueryResult struct {
|
||||
ChannelId string
|
||||
MessageCount int
|
||||
}
|
||||
|
||||
type TopDMList struct {
|
||||
InsightsListData
|
||||
Items []*TopDM `json:"items"`
|
||||
}
|
||||
|
||||
func TimeRangeToNumberDays(timeRange string) int {
|
||||
var n int
|
||||
switch timeRange {
|
||||
case TimeRangeToday:
|
||||
n = 1
|
||||
case TimeRange7Day:
|
||||
n = 7
|
||||
case TimeRange28Day:
|
||||
n = 28
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// ChannelPostCountByDuration contains a count of posts by channel id, grouped by ISO8601 date string.
|
||||
// Example 1 (grouped by day):
|
||||
//
|
||||
// cpc := model.ChannelPostCountByDuration{
|
||||
// "2009-11-11": {
|
||||
// "ezbp7nqxzjgdir8riodyafr9ww": 90,
|
||||
// "p949c1xdojfgzffxma3p3s3ikr": 201,
|
||||
// },
|
||||
// "2009-11-12": {
|
||||
// "ezbp7nqxzjgdir8riodyafr9ww": 45,
|
||||
// "p949c1xdojfgzffxma3p3s3ikr": 68,
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// Example 2 (grouped by hour):
|
||||
//
|
||||
// cpc := model.ChannelPostCountByDuration{
|
||||
// "2009-11-11T01": {
|
||||
// "ezbp7nqxzjgdir8riodyafr9ww": 90,
|
||||
// "p949c1xdojfgzffxma3p3s3ikr": 201,
|
||||
// },
|
||||
// "2009-11-11T02": {
|
||||
// "ezbp7nqxzjgdir8riodyafr9ww": 45,
|
||||
// "p949c1xdojfgzffxma3p3s3ikr": 68,
|
||||
// },
|
||||
// }
|
||||
type ChannelPostCountByDuration map[string]map[string]int
|
||||
|
||||
func blankChannelCountsMap(channelIDs []string) map[string]int {
|
||||
blankChannelCounts := map[string]int{}
|
||||
for _, id := range channelIDs {
|
||||
blankChannelCounts[id] = 0
|
||||
}
|
||||
return blankChannelCounts
|
||||
}
|
||||
|
||||
func ToDailyPostCountViewModel(dpc []*DurationPostCount, startTime *time.Time, numDays int, channelIDs []string) ChannelPostCountByDuration {
|
||||
viewModel := ChannelPostCountByDuration{}
|
||||
|
||||
keyTime := *startTime
|
||||
nowAtLocation := time.Now().In(startTime.Location())
|
||||
|
||||
if numDays == 1 {
|
||||
for keyTime.Before(nowAtLocation) {
|
||||
dateTimeKey := keyTime.Format(time.RFC3339)
|
||||
viewModel[dateTimeKey] = blankChannelCountsMap(channelIDs)
|
||||
keyTime = keyTime.Add(time.Hour)
|
||||
}
|
||||
} else {
|
||||
for keyTime.Before(nowAtLocation) {
|
||||
dateTimeKey := keyTime.Format("2006-01-02")
|
||||
viewModel[dateTimeKey] = blankChannelCountsMap(channelIDs)
|
||||
keyTime = keyTime.Add(24 * time.Hour)
|
||||
}
|
||||
}
|
||||
|
||||
for _, item := range dpc {
|
||||
var parseFormat string
|
||||
var keyFormat string
|
||||
if numDays == 1 {
|
||||
parseFormat = "2006-01-02T15 "
|
||||
keyFormat = time.RFC3339
|
||||
} else {
|
||||
parseFormat = "2006-01-02"
|
||||
keyFormat = parseFormat
|
||||
}
|
||||
durTime, err := time.ParseInLocation(parseFormat, item.Duration, startTime.Location())
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
localizedKey := durTime.Format(keyFormat)
|
||||
_, hasKey := viewModel[localizedKey]
|
||||
if !hasKey {
|
||||
viewModel[localizedKey] = map[string]int{}
|
||||
}
|
||||
viewModel[localizedKey][item.ChannelID] = item.PostCount
|
||||
}
|
||||
|
||||
return viewModel
|
||||
}
|
||||
|
||||
// Deprecated: This method doesn't perform error checking.
|
||||
// Use GetStartOfDayForTimeRange instead.
|
||||
//
|
||||
// StartOfDayForTimeRange gets the unix start time in milliseconds from the given time range.
|
||||
// Time range can be one of: "today", "7_day", or "28_day".
|
||||
func StartOfDayForTimeRange(timeRange string, location *time.Location) *time.Time {
|
||||
now := time.Now().In(location)
|
||||
resultTime := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, location)
|
||||
switch timeRange {
|
||||
case TimeRange7Day:
|
||||
resultTime = resultTime.Add(time.Hour * time.Duration(-144))
|
||||
case TimeRange28Day:
|
||||
resultTime = resultTime.Add(time.Hour * time.Duration(-648))
|
||||
}
|
||||
return &resultTime
|
||||
}
|
||||
|
||||
// GetStartOfDayForTimeRange gets the unix start time in milliseconds from the given time range.
|
||||
// Time range can be one of: "today", "7_day", or "28_day".
|
||||
func GetStartOfDayForTimeRange(timeRange string, location *time.Location) (*time.Time, *AppError) {
|
||||
now := time.Now().In(location)
|
||||
resultTime := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, location)
|
||||
switch timeRange {
|
||||
case TimeRangeToday:
|
||||
case TimeRange7Day:
|
||||
resultTime = resultTime.Add(time.Hour * time.Duration(-144))
|
||||
case TimeRange28Day:
|
||||
resultTime = resultTime.Add(time.Hour * time.Duration(-648))
|
||||
default:
|
||||
return nil, NewAppError("GetStartOfDayForTimeRange", "model.insights.get_start_of_day_for_time_range.time_range.app_error", nil, "", http.StatusBadRequest)
|
||||
}
|
||||
return &resultTime, nil
|
||||
}
|
||||
|
||||
// GetTopReactionListWithPagination adds a rank to each item in the given list of TopReaction and checks if there is
|
||||
// another page that can be fetched based on the given limit and offset. The given list of TopReaction is assumed to be
|
||||
// sorted by Count. Returns a TopReactionList.
|
||||
func GetTopReactionListWithPagination(reactions []*TopReaction, limit int) *TopReactionList {
|
||||
// Add pagination support
|
||||
var hasNext bool
|
||||
if (limit != 0) && (len(reactions) == limit+1) {
|
||||
hasNext = true
|
||||
reactions = reactions[:len(reactions)-1]
|
||||
}
|
||||
|
||||
return &TopReactionList{InsightsListData: InsightsListData{HasNext: hasNext}, Items: reactions}
|
||||
}
|
||||
|
||||
// GetTopChannelListWithPagination adds a rank to each item in the given list of TopChannel and checks if there is
|
||||
// another page that can be fetched based on the given limit and offset. The given list of TopChannel is assumed to be
|
||||
// sorted by Score. Returns a TopChannelList.
|
||||
func GetTopChannelListWithPagination(channels []*TopChannel, limit int) *TopChannelList {
|
||||
// Add pagination support
|
||||
var hasNext bool
|
||||
if (limit != 0) && (len(channels) == limit+1) {
|
||||
hasNext = true
|
||||
channels = channels[:len(channels)-1]
|
||||
}
|
||||
|
||||
return &TopChannelList{InsightsListData: InsightsListData{HasNext: hasNext}, Items: channels}
|
||||
}
|
||||
|
||||
// GetTopThreadListWithPagination adds a rank to each item in the given list of TopThread and checks if there is
|
||||
// another page that can be fetched based on the given limit and offset. The given list of TopThread is assumed to be
|
||||
// sorted by ReplyCount(score). Returns a TopThreadList.
|
||||
func GetTopThreadListWithPagination(threads []*TopThread, limit int) *TopThreadList {
|
||||
// Add pagination support
|
||||
var hasNext bool
|
||||
if (limit != 0) && (len(threads) == limit+1) {
|
||||
hasNext = true
|
||||
threads = threads[:len(threads)-1]
|
||||
}
|
||||
|
||||
return &TopThreadList{InsightsListData: InsightsListData{HasNext: hasNext}, Items: threads}
|
||||
}
|
||||
|
||||
// GetTopInactiveChannelListWithPagination adds a rank to each item in the given list of TopInactiveChannel and checks if there is
|
||||
// another page that can be fetched based on the given limit and offset. The given list of TopInactiveChannel is assumed to be
|
||||
// sorted by Score. Returns a TopInactiveChannelList.
|
||||
func GetTopInactiveChannelListWithPagination(channels []*TopInactiveChannel, limit int) *TopInactiveChannelList {
|
||||
// Add pagination support
|
||||
var hasNext bool
|
||||
if (limit != 0) && (len(channels) == limit+1) {
|
||||
hasNext = true
|
||||
channels = channels[:len(channels)-1]
|
||||
}
|
||||
|
||||
return &TopInactiveChannelList{InsightsListData: InsightsListData{HasNext: hasNext}, Items: channels}
|
||||
}
|
||||
|
||||
// GetTopDMListWithPagination adds a rank to each item in the given list of TopDM and checks if there is
|
||||
// another page that can be fetched based on the given limit and offset. The given list of TopDM is assumed to be
|
||||
// sorted by MessageCount(score). Returns a TopDMList.
|
||||
func GetTopDMListWithPagination(dms []*TopDM, limit int) *TopDMList {
|
||||
// Add pagination support
|
||||
var hasNext bool
|
||||
if (limit != 0) && (len(dms) == limit+1) {
|
||||
hasNext = true
|
||||
dms = dms[:len(dms)-1]
|
||||
}
|
||||
|
||||
return &TopDMList{InsightsListData: InsightsListData{HasNext: hasNext}, Items: dms}
|
||||
}
|
||||
|
||||
func GetNewTeamMembersListWithPagination(teamMembers []*NewTeamMember, limit int) *NewTeamMembersList {
|
||||
var hasNext bool
|
||||
if (limit != 0) && (len(teamMembers) == limit+1) {
|
||||
hasNext = true
|
||||
teamMembers = teamMembers[:len(teamMembers)-1]
|
||||
}
|
||||
|
||||
return &NewTeamMembersList{InsightsListData: InsightsListData{HasNext: hasNext}, Items: teamMembers}
|
||||
}
|
||||
@@ -1,197 +0,0 @@
|
||||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
package model
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGetTopReactionListWithPagination(t *testing.T) {
|
||||
reactions := []*TopReaction{
|
||||
{EmojiName: "smile", Count: 200},
|
||||
{EmojiName: "+1", Count: 190},
|
||||
{EmojiName: "100", Count: 100},
|
||||
{EmojiName: "-1", Count: 75},
|
||||
{EmojiName: "checkmark", Count: 50},
|
||||
{EmojiName: "mattermost", Count: 49}}
|
||||
|
||||
hasNextTC := []struct {
|
||||
Description string
|
||||
Limit int
|
||||
Offset int
|
||||
Expected *TopReactionList
|
||||
}{
|
||||
{
|
||||
Description: "has one page",
|
||||
Limit: len(reactions),
|
||||
Offset: 0,
|
||||
Expected: &TopReactionList{InsightsListData: InsightsListData{HasNext: false}, Items: reactions},
|
||||
},
|
||||
{
|
||||
Description: "has more than one page",
|
||||
Limit: len(reactions) - 1,
|
||||
Offset: 0,
|
||||
Expected: &TopReactionList{InsightsListData: InsightsListData{HasNext: true}, Items: reactions},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range hasNextTC {
|
||||
t.Run(test.Description, func(t *testing.T) {
|
||||
actual := GetTopReactionListWithPagination(reactions, test.Limit)
|
||||
assert.Equal(t, test.Expected.HasNext, actual.HasNext)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTopChannelListWithPagination(t *testing.T) {
|
||||
channels := []*TopChannel{
|
||||
{ID: NewId(), MessageCount: 200},
|
||||
{ID: NewId(), MessageCount: 150},
|
||||
{ID: NewId(), MessageCount: 120},
|
||||
{ID: NewId(), MessageCount: 105},
|
||||
{ID: NewId(), MessageCount: 5},
|
||||
{ID: NewId(), MessageCount: 2}}
|
||||
|
||||
hasNextTC := []struct {
|
||||
Description string
|
||||
Limit int
|
||||
Offset int
|
||||
Expected *TopChannelList
|
||||
}{
|
||||
{
|
||||
Description: "has one page",
|
||||
Limit: len(channels),
|
||||
Offset: 0,
|
||||
Expected: &TopChannelList{InsightsListData: InsightsListData{HasNext: false}, Items: channels},
|
||||
},
|
||||
{
|
||||
Description: "has more than one page",
|
||||
Limit: len(channels) - 1,
|
||||
Offset: 0,
|
||||
Expected: &TopChannelList{InsightsListData: InsightsListData{HasNext: true}, Items: channels},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range hasNextTC {
|
||||
t.Run(test.Description, func(t *testing.T) {
|
||||
actual := GetTopChannelListWithPagination(channels, test.Limit)
|
||||
assert.Equal(t, test.Expected.HasNext, actual.HasNext)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTopThreadListWithPagination(t *testing.T) {
|
||||
threads := []*TopThread{
|
||||
{PostId: NewId(), ReplyCount: 100},
|
||||
{PostId: NewId(), ReplyCount: 80},
|
||||
{PostId: NewId(), ReplyCount: 90},
|
||||
{PostId: NewId(), ReplyCount: 76},
|
||||
{PostId: NewId(), ReplyCount: 43},
|
||||
{PostId: NewId(), ReplyCount: 2},
|
||||
{PostId: NewId(), ReplyCount: 1},
|
||||
}
|
||||
hasNextTT := []struct {
|
||||
Description string
|
||||
Limit int
|
||||
Offset int
|
||||
Expected *TopThreadList
|
||||
}{
|
||||
{
|
||||
Description: "has one page",
|
||||
Limit: len(threads),
|
||||
Offset: 0,
|
||||
Expected: &TopThreadList{InsightsListData: InsightsListData{HasNext: false}, Items: threads},
|
||||
},
|
||||
{
|
||||
Description: "has more than one page",
|
||||
Limit: len(threads) - 1,
|
||||
Offset: 0,
|
||||
Expected: &TopThreadList{InsightsListData: InsightsListData{HasNext: true}, Items: threads},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range hasNextTT {
|
||||
t.Run(test.Description, func(t *testing.T) {
|
||||
actual := GetTopThreadListWithPagination(threads, test.Limit)
|
||||
assert.Equal(t, test.Expected.HasNext, actual.HasNext)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTopInactiveChannelListWithPagination(t *testing.T) {
|
||||
channels := []*TopInactiveChannel{
|
||||
{ID: NewId(), MessageCount: 2},
|
||||
{ID: NewId(), MessageCount: 5},
|
||||
{ID: NewId(), MessageCount: 7},
|
||||
{ID: NewId(), MessageCount: 80},
|
||||
{ID: NewId(), MessageCount: 85},
|
||||
{ID: NewId(), MessageCount: 92}}
|
||||
|
||||
hasNextTC := []struct {
|
||||
Description string
|
||||
Limit int
|
||||
Offset int
|
||||
Expected *TopInactiveChannelList
|
||||
}{
|
||||
{
|
||||
Description: "has one page",
|
||||
Limit: len(channels),
|
||||
Offset: 0,
|
||||
Expected: &TopInactiveChannelList{InsightsListData: InsightsListData{HasNext: false}, Items: channels},
|
||||
},
|
||||
{
|
||||
Description: "has more than one page",
|
||||
Limit: len(channels) - 1,
|
||||
Offset: 0,
|
||||
Expected: &TopInactiveChannelList{InsightsListData: InsightsListData{HasNext: true}, Items: channels},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range hasNextTC {
|
||||
t.Run(test.Description, func(t *testing.T) {
|
||||
actual := GetTopInactiveChannelListWithPagination(channels, test.Limit)
|
||||
assert.Equal(t, test.Expected.HasNext, actual.HasNext)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTopDMsListWithPagination(t *testing.T) {
|
||||
dms := []*TopDM{
|
||||
{SecondParticipant: &TopDMInsightUserInformation{InsightUserInformation: InsightUserInformation{Id: NewId()}}, MessageCount: 100},
|
||||
{SecondParticipant: &TopDMInsightUserInformation{InsightUserInformation: InsightUserInformation{Id: NewId()}}, MessageCount: 80},
|
||||
{SecondParticipant: &TopDMInsightUserInformation{InsightUserInformation: InsightUserInformation{Id: NewId()}}, MessageCount: 90},
|
||||
{SecondParticipant: &TopDMInsightUserInformation{InsightUserInformation: InsightUserInformation{Id: NewId()}}, MessageCount: 76},
|
||||
{SecondParticipant: &TopDMInsightUserInformation{InsightUserInformation: InsightUserInformation{Id: NewId()}}, MessageCount: 43},
|
||||
{SecondParticipant: &TopDMInsightUserInformation{InsightUserInformation: InsightUserInformation{Id: NewId()}}, MessageCount: 2},
|
||||
{SecondParticipant: &TopDMInsightUserInformation{InsightUserInformation: InsightUserInformation{Id: NewId()}}, MessageCount: 1},
|
||||
}
|
||||
hasNextTT := []struct {
|
||||
Description string
|
||||
Limit int
|
||||
Offset int
|
||||
Expected *TopDMList
|
||||
}{
|
||||
{
|
||||
Description: "has one page",
|
||||
Limit: len(dms),
|
||||
Offset: 0,
|
||||
Expected: &TopDMList{InsightsListData: InsightsListData{HasNext: false}, Items: dms},
|
||||
},
|
||||
{
|
||||
Description: "has more than one page",
|
||||
Limit: len(dms) - 1,
|
||||
Offset: 0,
|
||||
Expected: &TopDMList{InsightsListData: InsightsListData{HasNext: true}, Items: dms},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range hasNextTT {
|
||||
t.Run(test.Description, func(t *testing.T) {
|
||||
actual := GetTopDMListWithPagination(dms, test.Limit)
|
||||
assert.Equal(t, test.Expected.HasNext, actual.HasNext)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,6 @@ const (
|
||||
PreferenceCategoryFlaggedPost = "flagged_post"
|
||||
PreferenceCategoryFavoriteChannel = "favorite_channel"
|
||||
PreferenceCategorySidebarSettings = "sidebar_settings"
|
||||
PreferenceCategoryInsights = "insights"
|
||||
|
||||
PreferenceCategoryDisplaySettings = "display_settings"
|
||||
PreferenceNameCollapsedThreadsEnabled = "collapsed_reply_threads"
|
||||
@@ -31,7 +30,6 @@ const (
|
||||
PreferenceNameNameFormat = "name_format"
|
||||
PreferenceNameUseMilitaryTime = "use_military_time"
|
||||
PreferenceRecommendedNextSteps = "recommended_next_steps"
|
||||
PreferenceNameInsights = "insights_tutorial_state"
|
||||
|
||||
PreferenceCategoryTheme = "theme"
|
||||
// the name for theme props is the team id
|
||||
|
||||
Ссылка в новой задаче
Block a user