forked from Ivasoft/mattermost-mobile
Properly sync teams (#5793)
This commit is contained in:
@@ -279,6 +279,7 @@ const fetchAppEntryData = async (serverUrl: string, initialTeamId: string): Prom
|
||||
fetchMe(serverUrl, fetchOnly),
|
||||
];
|
||||
|
||||
const removeTeamIds: string[] = [];
|
||||
const resolution = await Promise.all(promises);
|
||||
const [teamData, , prefData, meData] = resolution;
|
||||
let [, chData] = resolution;
|
||||
@@ -287,7 +288,7 @@ const fetchAppEntryData = async (serverUrl: string, initialTeamId: string): Prom
|
||||
// If no initial team was set in the database but got teams in the response
|
||||
const config = await queryConfig(database);
|
||||
const teamOrderPreference = getPreferenceValue(prefData.preferences || [], Preferences.TEAMS_ORDER, '', '') as string;
|
||||
const teamMembers = teamData.memberships.map((m) => m.team_id);
|
||||
const teamMembers = teamData.memberships.filter((m) => m.delete_at === 0).map((m) => m.team_id);
|
||||
const myTeams = teamData.teams!.filter((t) => teamMembers?.includes(t.id));
|
||||
const defaultTeam = selectDefaultTeam(myTeams, meData.user?.locale || DEFAULT_LOCALE, teamOrderPreference, config.ExperimentalPrimaryTeam);
|
||||
if (defaultTeam?.id) {
|
||||
@@ -295,18 +296,24 @@ const fetchAppEntryData = async (serverUrl: string, initialTeamId: string): Prom
|
||||
}
|
||||
}
|
||||
|
||||
const removedFromTeam = teamData.memberships?.filter((m) => m.delete_at > 0);
|
||||
if (removedFromTeam?.length) {
|
||||
removeTeamIds.push(...removedFromTeam.map((m) => m.team_id));
|
||||
}
|
||||
|
||||
let data: AppEntryData = {
|
||||
initialTeamId,
|
||||
teamData,
|
||||
chData,
|
||||
prefData,
|
||||
meData,
|
||||
removeTeamIds,
|
||||
};
|
||||
|
||||
if (teamData.teams?.length === 0) {
|
||||
// User is no longer a member of any team
|
||||
const myTeams = await queryMyTeams(database);
|
||||
const removeTeamIds: string[] = myTeams?.map((myTeam) => myTeam.id) || [];
|
||||
removeTeamIds.push(...(myTeams?.map((myTeam) => myTeam.id) || []));
|
||||
|
||||
return {
|
||||
...data,
|
||||
@@ -319,7 +326,9 @@ const fetchAppEntryData = async (serverUrl: string, initialTeamId: string): Prom
|
||||
const chError = chData?.error as ClientError | undefined;
|
||||
if (!inTeam || chError?.status_code === 403) {
|
||||
// User is no longer a member of the current team
|
||||
const removeTeamIds = [initialTeamId];
|
||||
if (!removeTeamIds.includes(initialTeamId)) {
|
||||
removeTeamIds.push(initialTeamId);
|
||||
}
|
||||
|
||||
const availableTeamIds = await queryAvailableTeamIds(database, initialTeamId, teamData.teams, prefData.preferences, meData.user?.locale);
|
||||
const alternateTeamData = await fetchAlternateTeamData(serverUrl, availableTeamIds, removeTeamIds, includeDeletedChannels, lastDisconnected, fetchOnly);
|
||||
|
||||
@@ -8,7 +8,7 @@ import DatabaseManager from '@database/manager';
|
||||
import NetworkManager from '@init/network_manager';
|
||||
import {prepareMyChannelsForTeam, queryDefaultChannelForTeam} from '@queries/servers/channel';
|
||||
import {queryWebSocketLastDisconnected} from '@queries/servers/system';
|
||||
import {prepareMyTeams, syncTeamTable} from '@queries/servers/team';
|
||||
import {prepareDeleteTeam, prepareMyTeams, queryTeamsById, syncTeamTable} from '@queries/servers/team';
|
||||
import {isTablet} from '@utils/helpers';
|
||||
|
||||
import {fetchMyChannelsForTeam} from './channel';
|
||||
@@ -92,10 +92,23 @@ export const fetchMyTeams = async (serverUrl: string, fetchOnly = false): Promis
|
||||
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
|
||||
const modelPromises: Array<Promise<Model[]>> = [];
|
||||
if (operator) {
|
||||
const prepare = prepareMyTeams(operator, teams, memberships);
|
||||
const removeTeamIds = memberships.filter((m) => m.delete_at > 0).map((m) => m.team_id);
|
||||
const remainingTeams = teams.filter((t) => !removeTeamIds.includes(t.id));
|
||||
const prepare = prepareMyTeams(operator, remainingTeams, memberships);
|
||||
if (prepare) {
|
||||
modelPromises.push(...prepare);
|
||||
}
|
||||
|
||||
if (removeTeamIds.length) {
|
||||
if (removeTeamIds?.length) {
|
||||
// Immediately delete myTeams so that the UI renders only teams the user is a member of.
|
||||
const removeTeams = await queryTeamsById(operator.database, removeTeamIds);
|
||||
removeTeams?.forEach((team) => {
|
||||
modelPromises.push(prepareDeleteTeam(team));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (modelPromises.length) {
|
||||
const models = await Promise.all(modelPromises);
|
||||
const flattenedModels = models.flat() as Model[];
|
||||
|
||||
@@ -22,18 +22,17 @@ import type UserModel from '@typings/database/models/servers/user';
|
||||
|
||||
const {SERVER: {SYSTEM, MY_TEAM, TEAM, USER, ROLE}} = MM_TABLES;
|
||||
|
||||
type PropsInput = WithDatabaseArgs & {
|
||||
currentUser: UserModel;
|
||||
}
|
||||
const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
|
||||
const currentUser = database.get<SystemModel>(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
|
||||
switchMap(({value}) => database.get<UserModel>(USER).findAndObserve(value)),
|
||||
);
|
||||
const rolesArray = currentUser.pipe(
|
||||
switchMap((u) => of$(u.roles.split(' '))),
|
||||
);
|
||||
const roles = rolesArray.pipe(
|
||||
switchMap((values) => database.get<RoleModel>(ROLE).query(Q.where('name', Q.oneOf(values))).observe()),
|
||||
);
|
||||
|
||||
const withSystem = withObservables([], ({database}: WithDatabaseArgs) => ({
|
||||
currentUser: database.get(SYSTEM).findAndObserve(SYSTEM_IDENTIFIERS.CURRENT_USER_ID).pipe(
|
||||
switchMap((currentUserId: SystemModel) => database.get(USER).findAndObserve(currentUserId.value))),
|
||||
}));
|
||||
|
||||
const withTeams = withObservables([], ({currentUser, database}: PropsInput) => {
|
||||
const rolesArray = [...currentUser.roles.split(' ')];
|
||||
const roles = database.get<RoleModel>(ROLE).query(Q.where('name', Q.oneOf(rolesArray))).observe();
|
||||
const canCreateTeams = roles.pipe(switchMap((r) => of$(hasPermission(r, Permissions.CREATE_TEAM, false))));
|
||||
|
||||
const otherTeams = database.get<MyTeam>(MY_TEAM).query().observe().pipe(
|
||||
@@ -50,4 +49,4 @@ const withTeams = withObservables([], ({currentUser, database}: PropsInput) => {
|
||||
};
|
||||
});
|
||||
|
||||
export default withDatabase(withSystem(withTeams(TeamSidebar)));
|
||||
export default withDatabase(enhanced(TeamSidebar));
|
||||
|
||||
@@ -130,13 +130,19 @@ export const queryLastTeam = async (database: Database) => {
|
||||
|
||||
export const syncTeamTable = async (operator: ServerDataOperator, teams: Team[]) => {
|
||||
try {
|
||||
const notAvailable = await operator.database.get<TeamModel>(TEAM).query(Q.where('id', Q.notIn(teams.map((t) => t.id)))).fetch();
|
||||
const deletedTeams = teams.filter((t) => t.delete_at > 0).map((t) => t.id);
|
||||
const availableTeams = teams.filter((a) => !deletedTeams.includes(a.id));
|
||||
const models = [];
|
||||
const deletions = await Promise.all(notAvailable.map((t) => prepareDeleteTeam(t)));
|
||||
for (const d of deletions) {
|
||||
models.push(...d);
|
||||
|
||||
if (deletedTeams.length) {
|
||||
const notAvailable = await operator.database.get<TeamModel>(TEAM).query(Q.where('id', Q.oneOf(deletedTeams))).fetch();
|
||||
const deletions = await Promise.all(notAvailable.map((t) => prepareDeleteTeam(t)));
|
||||
for (const d of deletions) {
|
||||
models.push(...d);
|
||||
}
|
||||
}
|
||||
models.push(...await operator.handleTeam({teams, prepareRecordsOnly: true}));
|
||||
|
||||
models.push(...await operator.handleTeam({teams: availableTeams, prepareRecordsOnly: true}));
|
||||
await operator.batchRecords(models);
|
||||
return {};
|
||||
} catch (error) {
|
||||
@@ -163,7 +169,7 @@ export const queryDefaultTeam = async (database: Database) => {
|
||||
export const prepareMyTeams = (operator: ServerDataOperator, teams: Team[], memberships: TeamMembership[]) => {
|
||||
try {
|
||||
const teamRecords = operator.handleTeam({prepareRecordsOnly: true, teams});
|
||||
const teamMemberships = memberships.filter((m) => teams.find((t) => t.id === m.team_id));
|
||||
const teamMemberships = memberships.filter((m) => teams.find((t) => t.id === m.team_id) && m.delete_at === 0);
|
||||
const teamMembershipRecords = operator.handleTeamMemberships({prepareRecordsOnly: true, teamMemberships});
|
||||
const myTeams: MyTeam[] = teamMemberships.map((tm) => {
|
||||
return {id: tm.team_id, roles: tm.roles ?? ''};
|
||||
|
||||
Reference in New Issue
Block a user