Retry fetching teams if no teams are found (#2288)
* Retry fetching teams if no teams are found * Remove flow
This commit is contained in:
parent
94ddee15b2
commit
9db040bcf7
4 changed files with 95 additions and 30 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
16
app/utils/teams.js
Normal 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
38
app/utils/teams.test.js
Normal 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);
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Reference in a new issue