mattermost-redux
Version:
Common code (API client, Redux stores, logic, utility functions) for building a Mattermost client
298 lines (253 loc) • 9.67 kB
text/typescript
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {createSelector} from 'reselect';
import {Permissions} from '../../constants';
import {getConfig, getCurrentUrl, isCompatibleWithJoinViewTeamPermissions} from 'selectors/entities/general';
import {haveISystemPermission} from 'selectors/entities/roles_helpers';
import {GlobalState} from 'types/store';
import {Team, TeamMembership, TeamStats} from 'types/teams';
import {UserProfile} from 'types/users';
import {$ID, IDMappedObjects, RelationOneToOne} from 'types/utilities';
import {createIdsSelector} from 'utils/helpers';
import {isTeamAdmin} from 'utils/user_utils';
import {sortTeamsWithLocale} from 'utils/team_utils';
export function getCurrentTeamId(state: GlobalState) {
return state.entities.teams.currentTeamId;
}
export function getTeamByName(state: GlobalState, name: string) {
const teams = getTeams(state);
return Object.values(teams).find((team) => team.name === name);
}
export function getTeams(state: GlobalState): IDMappedObjects<Team> {
return state.entities.teams.teams;
}
export function getTeamStats(state: GlobalState) {
return state.entities.teams.stats;
}
export function getTeamMemberships(state: GlobalState) {
return state.entities.teams.myMembers;
}
export function getMembersInTeams(state: GlobalState) {
return state.entities.teams.membersInTeam;
}
export const getTeamsList: (state: GlobalState) => Team[] = createSelector(
getTeams,
(teams) => {
return Object.values(teams);
},
);
export const getCurrentTeam: (state: GlobalState) => Team = createSelector(
getTeams,
getCurrentTeamId,
(teams, currentTeamId) => {
return teams[currentTeamId];
},
);
export function getTeam(state: GlobalState, id: string): Team {
const teams = getTeams(state);
return teams[id];
}
export const getCurrentTeamMembership: (state: GlobalState) => TeamMembership = createSelector(
getCurrentTeamId,
getTeamMemberships,
(currentTeamId: string, teamMemberships: {[teamId: string]: TeamMembership}): TeamMembership => {
return teamMemberships[currentTeamId];
},
);
export const isCurrentUserCurrentTeamAdmin: (state: GlobalState) => boolean = createSelector(
getCurrentTeamMembership,
(member) => {
if (member) {
const roles = member.roles || '';
return isTeamAdmin(roles);
}
return false;
},
);
export const getCurrentTeamUrl: (state: GlobalState) => string = createSelector(
getCurrentUrl,
getCurrentTeam,
(state) => getConfig(state).SiteURL,
(currentURL, currentTeam, siteURL) => {
const rootURL = `${currentURL || siteURL}`;
if (!currentTeam) {
return rootURL;
}
return `${rootURL}/${currentTeam.name}`;
},
);
export const getCurrentRelativeTeamUrl: (state: GlobalState) => string = createSelector(
getCurrentTeam,
(currentTeam) => {
if (!currentTeam) {
return '/';
}
return `/${currentTeam.name}`;
},
);
export const getCurrentTeamStats: (state: GlobalState) => TeamStats = createSelector(
getCurrentTeamId,
getTeamStats,
(currentTeamId, teamStats) => {
return teamStats[currentTeamId];
},
);
export const getMyTeams: (state: GlobalState) => Team[] = createSelector(
getTeams,
getTeamMemberships,
(teams, members) => {
return Object.values(teams).filter((t) => members[t.id] && t.delete_at === 0);
},
);
export const getMyTeamMember: (state: GlobalState, teamId: string) => TeamMembership = createSelector(
getTeamMemberships,
(state: GlobalState, teamId: string) => teamId,
(teamMemberships, teamId) => {
return teamMemberships[teamId] || {};
},
);
export const getMembersInCurrentTeam: (state: GlobalState) => RelationOneToOne<UserProfile, TeamMembership> = createSelector(
getCurrentTeamId,
getMembersInTeams,
(currentTeamId, teamMembers) => {
return teamMembers[currentTeamId];
},
);
export function getTeamMember(state: GlobalState, teamId: string, userId: string) {
const members = getMembersInTeams(state)[teamId];
if (members) {
return members[userId];
}
return null;
}
export const getListableTeamIds: (state: GlobalState) => Array<$ID<Team>> = createIdsSelector(
getTeams,
getTeamMemberships,
(state) => haveISystemPermission(state, {permission: Permissions.LIST_PUBLIC_TEAMS}),
(state) => haveISystemPermission(state, {permission: Permissions.LIST_PRIVATE_TEAMS}),
isCompatibleWithJoinViewTeamPermissions,
(teams, myMembers, canListPublicTeams, canListPrivateTeams, compatibleWithJoinViewTeamPermissions) => {
return Object.keys(teams).filter((id) => {
const team = teams[id];
const member = myMembers[id];
let canList = team.allow_open_invite;
if (compatibleWithJoinViewTeamPermissions) {
canList = (canListPrivateTeams && !team.allow_open_invite) || (canListPublicTeams && team.allow_open_invite);
}
return team.delete_at === 0 && canList && !member;
});
},
);
export const getListableTeams: (state: GlobalState) => Team[] = createSelector(
getTeams,
getListableTeamIds,
(teams, listableTeamIds) => {
return listableTeamIds.map((id) => teams[id]);
},
);
export const getSortedListableTeams: (state: GlobalState, locale: string) => Team[] = createSelector(
getTeams,
getListableTeamIds,
(state: GlobalState, locale: string) => locale,
(teams, listableTeamIds, locale) => {
const listableTeams: {[x: string]: Team} = {};
for (const id of listableTeamIds) {
listableTeams[id] = teams[id];
}
return Object.values(listableTeams).sort(sortTeamsWithLocale(locale));
},
);
export const getJoinableTeamIds: (state: GlobalState) => Array<$ID<Team>> = createIdsSelector(
getTeams,
getTeamMemberships,
(state: GlobalState) => haveISystemPermission(state, {permission: Permissions.JOIN_PUBLIC_TEAMS}),
(state: GlobalState) => haveISystemPermission(state, {permission: Permissions.JOIN_PRIVATE_TEAMS}),
isCompatibleWithJoinViewTeamPermissions,
(teams, myMembers, canJoinPublicTeams, canJoinPrivateTeams, compatibleWithJoinViewTeamPermissions) => {
return Object.keys(teams).filter((id) => {
const team = teams[id];
const member = myMembers[id];
let canJoin = team.allow_open_invite;
if (compatibleWithJoinViewTeamPermissions) {
canJoin = (canJoinPrivateTeams && !team.allow_open_invite) || (canJoinPublicTeams && team.allow_open_invite);
}
return team.delete_at === 0 && canJoin && !member;
});
},
);
export const getJoinableTeams: (state: GlobalState) => Team[] = createSelector(
getTeams,
getJoinableTeamIds,
(teams, joinableTeamIds) => {
return joinableTeamIds.map((id) => teams[id]);
},
);
export const getSortedJoinableTeams: (state: GlobalState, locale: string) => Team[] = createSelector(
getTeams,
getJoinableTeamIds,
(state: GlobalState, locale: string) => locale,
(teams, joinableTeamIds, locale) => {
const joinableTeams: {[x: string]: Team} = {};
for (const id of joinableTeamIds) {
joinableTeams[id] = teams[id];
}
return Object.values(joinableTeams).sort(sortTeamsWithLocale(locale));
},
);
export const getMySortedTeamIds: (state: GlobalState, locale: string) => Array<$ID<Team>> = createIdsSelector(
getMyTeams,
(state: GlobalState, locale: string) => locale,
(teams, locale) => {
return teams.sort(sortTeamsWithLocale(locale)).map((t) => t.id);
},
);
export function getMyTeamsCount(state: GlobalState) {
return getMyTeams(state).length;
}
// returns the badge number to show (excluding the current team)
// > 0 means is returning the mention count
// 0 means that there are no unread messages
// -1 means that there are unread messages but no mentions
export const getChannelDrawerBadgeCount: (state: GlobalState) => number = createSelector(
getCurrentTeamId,
getTeamMemberships,
(currentTeamId, teamMembers) => {
let mentionCount = 0;
let messageCount = 0;
Object.values(teamMembers).forEach((m: TeamMembership) => {
if (m.team_id !== currentTeamId) {
mentionCount += (m.mention_count || 0);
messageCount += (m.msg_count || 0);
}
});
let badgeCount = 0;
if (mentionCount) {
badgeCount = mentionCount;
} else if (messageCount) {
badgeCount = -1;
}
return badgeCount;
},
);
// returns the badge for a team
// > 0 means is returning the mention count
// 0 means that there are no unread messages
// -1 means that there are unread messages but no mentions
export function makeGetBadgeCountForTeamId(): (state: GlobalState, id: string) => number {
return createSelector(
getTeamMemberships,
(state: GlobalState, id: string) => id,
(members, teamId) => {
const member = members[teamId];
let badgeCount = 0;
if (member) {
if (member.mention_count) {
badgeCount = member.mention_count;
} else if (member.msg_count) {
badgeCount = -1;
}
}
return badgeCount;
},
);
}