Retry fetching teams if no teams are found (#2288)

* Retry fetching teams if no teams are found

* Remove flow
This commit is contained in:
Elias Nahum 2018-10-27 00:50:19 -03:00 committed by GitHub
parent 94ddee15b2
commit 9db040bcf7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 95 additions and 30 deletions

View file

@ -3,16 +3,18 @@
import {batchActions} from 'redux-batched-actions';
import {markChannelAsRead, markChannelAsViewed} from 'mattermost-redux/actions/channels';
import {ChannelTypes, TeamTypes} from 'mattermost-redux/action_types';
import EventEmitter from 'mattermost-redux/utils/event_emitter';
import {getCurrentChannelId} from 'mattermost-redux/selectors/entities/channels';
import {markChannelAsRead, markChannelAsViewed} from 'mattermost-redux/actions/channels';
import {getMyTeams} from 'mattermost-redux/actions/teams';
import {RequestStatus} from 'mattermost-redux/constants';
import {getCurrentChannelId} from 'mattermost-redux/selectors/entities/channels';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
import EventEmitter from 'mattermost-redux/utils/event_emitter';
import {NavigationTypes} from 'app/constants';
import {selectFirstAvailableTeam} from 'app/utils/teams';
import {setChannelDisplayName} from './channel';
import {getConfig} from 'mattermost-redux/selectors/entities/general';
export function handleTeamChange(teamId, selectChannel = true) {
return async (dispatch, getState) => {
@ -46,21 +48,30 @@ export function selectDefaultTeam() {
const {teams: allTeams, myMembers} = state.entities.teams;
const teams = Object.keys(myMembers).map((key) => allTeams[key]);
let defaultTeam;
if (ExperimentalPrimaryTeam) {
defaultTeam = teams.find((t) => t.name === ExperimentalPrimaryTeam.toLowerCase());
}
if (!defaultTeam) {
defaultTeam = Object.values(teams).sort((a, b) => a.display_name.localeCompare(b.display_name))[0];
}
let defaultTeam = selectFirstAvailableTeam(teams, ExperimentalPrimaryTeam);
if (defaultTeam) {
handleTeamChange(defaultTeam.id)(dispatch, getState);
dispatch(handleTeamChange(defaultTeam.id));
} else if (state.requests.teams.getTeams.status === RequestStatus.FAILURE || state.requests.teams.getMyTeams.status === RequestStatus.FAILURE) {
EventEmitter.emit(NavigationTypes.NAVIGATION_ERROR_TEAMS);
} else {
EventEmitter.emit(NavigationTypes.NAVIGATION_NO_TEAMS);
// If for some reason we reached this point cause of a failure in rehydration or something
// lets fetch the teams one more time to make sure the user does not belong to any team
const {data, error} = await dispatch(getMyTeams());
if (error) {
EventEmitter.emit(NavigationTypes.NAVIGATION_ERROR_TEAMS);
return;
}
if (data) {
defaultTeam = selectFirstAvailableTeam(data, ExperimentalPrimaryTeam);
}
if (defaultTeam) {
dispatch(handleTeamChange(defaultTeam.id));
} else {
EventEmitter.emit(NavigationTypes.NAVIGATION_NO_TEAMS);
}
}
};
}

View file

@ -197,7 +197,7 @@ function cleanupState(action, keepCurrent = false) {
const {currentChannelId} = payload.entities.channels;
const {lastChannelForTeam} = resetPayload.views.team;
const nextEntitites = {
const nextEntities = {
posts: {
posts: {},
postsInChannel: {},
@ -224,14 +224,14 @@ function cleanupState(action, keepCurrent = false) {
// we need to check that the channel id is not already included
// the reason it can be included is cause at least one of the last channels viewed
// in a team can be a DM or GM and the id can be duplicate
if (!nextEntitites.posts.postsInChannel[id] && payload.entities.posts.postsInChannel[id]) {
if (!nextEntities.posts.postsInChannel[id] && payload.entities.posts.postsInChannel[id]) {
let postIds;
if (keepCurrent && currentChannelId === id) {
postIds = payload.entities.posts.postsInChannel[id];
} else {
postIds = payload.entities.posts.postsInChannel[id].slice(0, 60);
}
nextEntitites.posts.postsInChannel[id] = postIds;
nextEntities.posts.postsInChannel[id] = postIds;
return result.concat(postIds);
}
@ -261,7 +261,7 @@ function cleanupState(action, keepCurrent = false) {
if (post) {
if (retentionPeriod && post.create_at < retentionPeriod) {
const postsInChannel = nextEntitites.posts.postsInChannel[post.channel_id] || [];
const postsInChannel = nextEntities.posts.postsInChannel[post.channel_id] || [];
const index = postsInChannel.indexOf(postId);
if (index !== -1) {
postsInChannel.splice(index, 1);
@ -269,31 +269,31 @@ function cleanupState(action, keepCurrent = false) {
return;
}
nextEntitites.posts.posts[postId] = post;
nextEntities.posts.posts[postId] = post;
const reaction = payload.entities.posts.reactions[postId];
if (reaction) {
nextEntitites.posts.reactions[postId] = reaction;
nextEntities.posts.reactions[postId] = reaction;
}
const fileIds = payload.entities.files.fileIdsByPostId[postId];
if (fileIds) {
nextEntitites.files.fileIdsByPostId[postId] = fileIds;
nextEntities.files.fileIdsByPostId[postId] = fileIds;
fileIds.forEach((fileId) => {
nextEntitites.files.files[fileId] = payload.entities.files.files[fileId];
nextEntities.files.files[fileId] = payload.entities.files.files[fileId];
});
}
const postsInThread = payload.entities.posts.postsInThread[postId];
if (postsInThread) {
nextEntitites.posts.postsInThread[postId] = postsInThread;
nextEntities.posts.postsInThread[postId] = postsInThread;
}
} else {
// If the post is not in the store we need to remove it from the postsInChannel
const channelIds = Object.keys(nextEntitites.posts.postsInChannel);
const channelIds = Object.keys(nextEntities.posts.postsInChannel);
for (let i = 0; i < channelIds.length; i++) {
const channelId = channelIds[i];
const posts = nextEntitites.posts.postsInChannel[channelId];
const posts = nextEntities.posts.postsInChannel[channelId];
const index = posts.indexOf(postId);
if (index !== -1) {
posts.splice(index, 1);
@ -307,17 +307,17 @@ function cleanupState(action, keepCurrent = false) {
if (payload.entities.posts && payload.entities.posts.pendingPostIds && payload.entities.posts.pendingPostIds.length) {
const nextPendingPostIds = [...payload.entities.posts.pendingPostIds];
payload.entities.posts.pendingPostIds.forEach((id) => {
const posts = nextEntitites.posts.posts;
const posts = nextEntities.posts.posts;
const post = posts[id];
if (post) {
const postsInChannel = [...nextEntitites.posts.postsInChannel[post.channel_id]] || [];
const postsInChannel = [...nextEntities.posts.postsInChannel[post.channel_id]] || [];
if (!post.failed) {
Reflect.deleteProperty(posts, id);
const index = postsInChannel.indexOf(id);
if (index !== -1) {
postsInChannel.splice(index, 1);
nextEntitites.posts.postsInChannel[post.channel_id] = postsInChannel;
nextEntities.posts.postsInChannel[post.channel_id] = postsInChannel;
}
removePendingPost(nextPendingPostIds, id);
}
@ -326,13 +326,13 @@ function cleanupState(action, keepCurrent = false) {
}
});
nextEntitites.posts.pendingPostIds = nextPendingPostIds;
nextEntities.posts.pendingPostIds = nextPendingPostIds;
}
const nextState = {
app: resetPayload.app,
entities: {
...nextEntitites,
...nextEntities,
channels: payload.entities.channels,
emojis: payload.entities.emojis,
general: resetPayload.entities.general,

16
app/utils/teams.js Normal file
View file

@ -0,0 +1,16 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
// @flow
export function selectFirstAvailableTeam(teams, primaryTeam) {
let defaultTeam;
if (primaryTeam) {
defaultTeam = teams.find((t) => t.name === primaryTeam.toLowerCase());
}
if (!defaultTeam) {
defaultTeam = Object.values(teams).sort((a, b) => a.display_name.localeCompare(b.display_name))[0];
}
return defaultTeam;
}

38
app/utils/teams.test.js Normal file
View file

@ -0,0 +1,38 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {selectFirstAvailableTeam} from 'app/utils/teams';
describe('TeamUtils', () => {
describe('selectFirstAvailableTeam', () => {
const myTeams = [{
id: 'team-id-1',
display_name: 'Zeta Team',
name: 'zeta-team',
}, {
id: 'team-id-2',
display_name: 'Alpha Team',
name: 'alpha-team',
}];
it('should return the primary team', () => {
const defaultTeam = selectFirstAvailableTeam(myTeams, 'zeTa-teAM');
expect(defaultTeam).toBe(myTeams[0]);
});
it('should return the first team ordered by display_name', () => {
const defaultTeam = selectFirstAvailableTeam(myTeams);
expect(defaultTeam).toBe(myTeams[1]);
});
it('should return the first team ordered by display_name if primary team is not found', () => {
const defaultTeam = selectFirstAvailableTeam(myTeams, 'non-existent-team');
expect(defaultTeam).toBe(myTeams[1]);
});
it('should return undefined is no team is found', () => {
const defaultTeam = selectFirstAvailableTeam([]);
expect(defaultTeam).toBe(undefined);
});
});
});