PLT-4481 Fix member count for team user lists and channel invite list (#4422)

* Fix member count for team user lists and channel invite list

* Fix client unit test
Этот коммит содержится в:
Joram Wilander
2016-11-04 12:27:19 -04:00
коммит произвёл Christopher Speller
родитель 263f290683
Коммит 00787974d0
11 изменённых файлов: 131 добавлений и 34 удалений

Просмотреть файл

@@ -902,16 +902,27 @@ func getTeamStats(c *Context, w http.ResponseWriter, r *http.Request) {
} }
} }
if result := <-Srv.Store.Team().GetMemberCount(c.TeamId); result.Err != nil { tchan := Srv.Store.Team().GetTotalMemberCount(c.TeamId)
achan := Srv.Store.Team().GetActiveMemberCount(c.TeamId)
stats := &model.TeamStats{}
stats.TeamId = c.TeamId
if result := <-tchan; result.Err != nil {
c.Err = result.Err c.Err = result.Err
return return
} else { } else {
stats := &model.TeamStats{} stats.TotalMemberCount = result.Data.(int64)
stats.MemberCount = result.Data.(int64)
stats.TeamId = c.TeamId
w.Write([]byte(stats.ToJson()))
return
} }
if result := <-achan; result.Err != nil {
c.Err = result.Err
return
} else {
stats.ActiveMemberCount = result.Data.(int64)
}
w.Write([]byte(stats.ToJson()))
} }
func importTeam(c *Context, w http.ResponseWriter, r *http.Request) { func importTeam(c *Context, w http.ResponseWriter, r *http.Request) {

Просмотреть файл

@@ -706,7 +706,25 @@ func TestGetTeamStats(t *testing.T) {
if result, err := th.SystemAdminClient.GetTeamStats(th.BasicTeam.Id); err != nil { if result, err := th.SystemAdminClient.GetTeamStats(th.BasicTeam.Id); err != nil {
t.Fatal(err) t.Fatal(err)
} else { } else {
if result.Data.(*model.TeamStats).MemberCount != 2 { if result.Data.(*model.TeamStats).TotalMemberCount != 2 {
t.Fatal("wrong count")
}
if result.Data.(*model.TeamStats).ActiveMemberCount != 2 {
t.Fatal("wrong count")
}
}
th.SystemAdminClient.Must(th.SystemAdminClient.UpdateActive(th.BasicUser2.Id, false))
if result, err := th.SystemAdminClient.GetTeamStats(th.BasicTeam.Id); err != nil {
t.Fatal(err)
} else {
if result.Data.(*model.TeamStats).TotalMemberCount != 2 {
t.Fatal("wrong count")
}
if result.Data.(*model.TeamStats).ActiveMemberCount != 1 {
t.Fatal("wrong count") t.Fatal("wrong count")
} }
} }
@@ -714,7 +732,11 @@ func TestGetTeamStats(t *testing.T) {
if result, err := th.SystemAdminClient.GetTeamStats("junk"); err != nil { if result, err := th.SystemAdminClient.GetTeamStats("junk"); err != nil {
t.Fatal(err) t.Fatal(err)
} else { } else {
if result.Data.(*model.TeamStats).MemberCount != 0 { if result.Data.(*model.TeamStats).TotalMemberCount != 0 {
t.Fatal("wrong count")
}
if result.Data.(*model.TeamStats).ActiveMemberCount != 0 {
t.Fatal("wrong count") t.Fatal("wrong count")
} }
} }
@@ -722,7 +744,7 @@ func TestGetTeamStats(t *testing.T) {
if result, err := th.SystemAdminClient.GetTeamStats(th.BasicTeam.Id); err != nil { if result, err := th.SystemAdminClient.GetTeamStats(th.BasicTeam.Id); err != nil {
t.Fatal(err) t.Fatal(err)
} else { } else {
if result.Data.(*model.TeamStats).MemberCount != 2 { if result.Data.(*model.TeamStats).TotalMemberCount != 2 {
t.Fatal("wrong count") t.Fatal("wrong count")
} }
} }

Просмотреть файл

@@ -9,8 +9,9 @@ import (
) )
type TeamStats struct { type TeamStats struct {
TeamId string `json:"team_id"` TeamId string `json:"team_id"`
MemberCount int64 `json:"member_count"` TotalMemberCount int64 `json:"total_member_count"`
ActiveMemberCount int64 `json:"active_member_count"`
} }
func (o *TeamStats) ToJson() string { func (o *TeamStats) ToJson() string {

Просмотреть файл

@@ -467,7 +467,7 @@ func (s SqlTeamStore) GetMembers(teamId string, offset int, limit int) StoreChan
return storeChannel return storeChannel
} }
func (s SqlTeamStore) GetMemberCount(teamId string) StoreChannel { func (s SqlTeamStore) GetTotalMemberCount(teamId string) StoreChannel {
storeChannel := make(StoreChannel, 1) storeChannel := make(StoreChannel, 1)
go func() { go func() {
@@ -482,10 +482,39 @@ func (s SqlTeamStore) GetMemberCount(teamId string) StoreChannel {
WHERE WHERE
TeamMembers.UserId = Users.Id TeamMembers.UserId = Users.Id
AND TeamMembers.TeamId = :TeamId AND TeamMembers.TeamId = :TeamId
AND TeamMembers.DeleteAt = 0 AND TeamMembers.DeleteAt = 0`, map[string]interface{}{"TeamId": teamId})
if err != nil {
result.Err = model.NewLocAppError("SqlTeamStore.GetTotalMemberCount", "store.sql_team.get_member_count.app_error", nil, "teamId="+teamId+" "+err.Error())
} else {
result.Data = count
}
storeChannel <- result
close(storeChannel)
}()
return storeChannel
}
func (s SqlTeamStore) GetActiveMemberCount(teamId string) StoreChannel {
storeChannel := make(StoreChannel, 1)
go func() {
result := StoreResult{}
count, err := s.GetReplica().SelectInt(`
SELECT
count(*)
FROM
TeamMembers,
Users
WHERE
TeamMembers.UserId = Users.Id
AND TeamMembers.TeamId = :TeamId
AND TeamMembers.DeleteAt = 0
AND Users.DeleteAt = 0`, map[string]interface{}{"TeamId": teamId}) AND Users.DeleteAt = 0`, map[string]interface{}{"TeamId": teamId})
if err != nil { if err != nil {
result.Err = model.NewLocAppError("SqlTeamStore.GetMemberCount", "store.sql_team.get_member_count.app_error", nil, "teamId="+teamId+" "+err.Error()) result.Err = model.NewLocAppError("SqlTeamStore.GetActiveMemberCount", "store.sql_team.get_member_count.app_error", nil, "teamId="+teamId+" "+err.Error())
} else { } else {
result.Data = count result.Data = count
} }

Просмотреть файл

@@ -482,11 +482,27 @@ func TestTeamStoreMemberCount(t *testing.T) {
u1.Email = model.NewId() u1.Email = model.NewId()
Must(store.User().Save(u1)) Must(store.User().Save(u1))
u2 := &model.User{}
u2.Email = model.NewId()
u2.DeleteAt = 1
Must(store.User().Save(u2))
teamId1 := model.NewId() teamId1 := model.NewId()
m1 := &model.TeamMember{TeamId: teamId1, UserId: u1.Id} m1 := &model.TeamMember{TeamId: teamId1, UserId: u1.Id}
Must(store.Team().SaveMember(m1)) Must(store.Team().SaveMember(m1))
if result := <-store.Team().GetMemberCount(teamId1); result.Err != nil { m2 := &model.TeamMember{TeamId: teamId1, UserId: u2.Id}
Must(store.Team().SaveMember(m2))
if result := <-store.Team().GetTotalMemberCount(teamId1); result.Err != nil {
t.Fatal(result.Err)
} else {
if result.Data.(int64) != 2 {
t.Fatal("wrong count")
}
}
if result := <-store.Team().GetActiveMemberCount(teamId1); result.Err != nil {
t.Fatal(result.Err) t.Fatal(result.Err)
} else { } else {
if result.Data.(int64) != 1 { if result.Data.(int64) != 1 {
@@ -494,10 +510,18 @@ func TestTeamStoreMemberCount(t *testing.T) {
} }
} }
m2 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()} m3 := &model.TeamMember{TeamId: teamId1, UserId: model.NewId()}
Must(store.Team().SaveMember(m2)) Must(store.Team().SaveMember(m3))
if result := <-store.Team().GetMemberCount(teamId1); result.Err != nil { if result := <-store.Team().GetTotalMemberCount(teamId1); result.Err != nil {
t.Fatal(result.Err)
} else {
if result.Data.(int64) != 2 {
t.Fatal("wrong count")
}
}
if result := <-store.Team().GetActiveMemberCount(teamId1); result.Err != nil {
t.Fatal(result.Err) t.Fatal(result.Err)
} else { } else {
if result.Data.(int64) != 1 { if result.Data.(int64) != 1 {

Просмотреть файл

@@ -70,7 +70,8 @@ type TeamStore interface {
GetMember(teamId string, userId string) StoreChannel GetMember(teamId string, userId string) StoreChannel
GetMembers(teamId string, offset int, limit int) StoreChannel GetMembers(teamId string, offset int, limit int) StoreChannel
GetMembersByIds(teamId string, userIds []string) StoreChannel GetMembersByIds(teamId string, userIds []string) StoreChannel
GetMemberCount(teamId string) StoreChannel GetTotalMemberCount(teamId string) StoreChannel
GetActiveMemberCount(teamId string) StoreChannel
GetTeamsForUser(userId string) StoreChannel GetTeamsForUser(userId string) StoreChannel
RemoveMember(teamId string, userId string) StoreChannel RemoveMember(teamId string, userId string) StoreChannel
RemoveAllMembersByTeam(teamId string) StoreChannel RemoveAllMembersByTeam(teamId string) StoreChannel

Просмотреть файл

@@ -49,7 +49,7 @@ export default class UserList extends React.Component {
team: AdminStore.getTeam(this.props.params.team), team: AdminStore.getTeam(this.props.params.team),
users: [], users: [],
teamMembers: TeamStore.getMembersInTeam(this.props.params.team), teamMembers: TeamStore.getMembersInTeam(this.props.params.team),
total: stats.member_count, total: stats.total_member_count,
serverError: null, serverError: null,
showPasswordModal: false, showPasswordModal: false,
loading: true, loading: true,
@@ -75,7 +75,7 @@ export default class UserList extends React.Component {
team: AdminStore.getTeam(nextProps.params.team), team: AdminStore.getTeam(nextProps.params.team),
users: [], users: [],
teamMembers: TeamStore.getMembersInTeam(nextProps.params.team), teamMembers: TeamStore.getMembersInTeam(nextProps.params.team),
total: stats.member_count total: stats.total_member_count
}); });
this.getTeamProfiles(nextProps.params.team); this.getTeamProfiles(nextProps.params.team);
@@ -102,7 +102,7 @@ export default class UserList extends React.Component {
onStatsChange() { onStatsChange() {
const stats = TeamStore.getStats(this.props.params.team); const stats = TeamStore.getStats(this.props.params.team);
this.setState({total: stats.member_count}); this.setState({total: stats.total_member_count});
} }
onUsersChange() { onUsersChange() {

Просмотреть файл

@@ -38,7 +38,7 @@ export default class ChannelInviteModal extends React.Component {
this.state = { this.state = {
users: null, users: null,
total: teamStats.member_count - channelStats.member_count, total: teamStats.active_member_count - channelStats.member_count,
show: true, show: true,
search: false, search: false,
statusChange: false statusChange: false
@@ -72,8 +72,8 @@ export default class ChannelInviteModal extends React.Component {
const teamStats = TeamStore.getCurrentStats(); const teamStats = TeamStore.getCurrentStats();
this.setState({ this.setState({
users: UserStore.getProfileListNotInChannel(this.props.channel.id), users: UserStore.getProfileListNotInChannel(this.props.channel.id, true),
total: teamStats.member_count - channelStats.member_count total: teamStats.active_member_count - channelStats.member_count
}); });
} }

Просмотреть файл

@@ -30,7 +30,7 @@ export default class MemberListTeam extends React.Component {
this.state = { this.state = {
users: UserStore.getProfileListInTeam(), users: UserStore.getProfileListInTeam(),
teamMembers: Object.assign([], TeamStore.getMembersInTeam()), teamMembers: Object.assign([], TeamStore.getMembersInTeam()),
total: stats.member_count, total: stats.total_member_count,
search: false, search: false,
loading: true loading: true
}; };
@@ -67,7 +67,7 @@ export default class MemberListTeam extends React.Component {
onStatsChange() { onStatsChange() {
const stats = TeamStore.getCurrentStats(); const stats = TeamStore.getCurrentStats();
this.setState({total: stats.member_count}); this.setState({total: stats.total_member_count});
} }
nextPage(page) { nextPage(page) {

Просмотреть файл

@@ -320,6 +320,10 @@ class UserStoreClass extends EventEmitter {
for (let i = 0; i < userIds.length; i++) { for (let i = 0; i < userIds.length; i++) {
const profile = this.getProfile(userIds[i]); const profile = this.getProfile(userIds[i]);
if (!profile) {
continue;
}
if (skipCurrent && profile.id === currentId) { if (skipCurrent && profile.id === currentId) {
continue; continue;
} }
@@ -328,9 +332,7 @@ class UserStoreClass extends EventEmitter {
continue; continue;
} }
if (profile) { profiles.push(profile);
profiles.push(profile);
}
} }
return profiles; return profiles;
@@ -473,15 +475,22 @@ class UserStoreClass extends EventEmitter {
userIds.splice(index, 1); userIds.splice(index, 1);
} }
getProfileListNotInChannel(channelId = ChannelStore.getCurrentId()) { getProfileListNotInChannel(channelId = ChannelStore.getCurrentId(), skipInactive = false) {
const userIds = this.profiles_not_in_channel[channelId] || []; const userIds = this.profiles_not_in_channel[channelId] || [];
const profiles = []; const profiles = [];
for (let i = 0; i < userIds.length; i++) { for (let i = 0; i < userIds.length; i++) {
const profile = this.getProfile(userIds[i]); const profile = this.getProfile(userIds[i]);
if (profile) {
profiles.push(profile); if (!profile) {
continue;
} }
if (skipInactive && profile.delete_at > 0) {
continue;
}
profiles.push(profile);
} }
return profiles; return profiles;

Просмотреть файл

@@ -169,7 +169,7 @@ describe('Client.Team', function() {
TestHelper.basicClient().getTeamStats( TestHelper.basicClient().getTeamStats(
TestHelper.basicTeam().id, TestHelper.basicTeam().id,
function(data) { function(data) {
assert.equal(data.member_count > 0, true); assert.equal(data.total_member_count > 0, true);
done(); done();
}, },
function(err) { function(err) {