PLT-5604 Add/Remove members from pubic channels doesn't match the webapp functionality (#289)
* PLT-5604 Add/Remove members from pubic channels doesn't match the webapp functionality * Review feedback * Fix spelling of ChannelMembersTitle * Use selector to consolidate auth logic for channel member mgmt
This commit is contained in:
parent
80edba14da
commit
9e8fb26f4b
8 changed files with 53 additions and 55 deletions
|
|
@ -31,7 +31,6 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
|
|||
color: theme.centerChannelColor
|
||||
},
|
||||
textContainer: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
marginLeft: 5
|
||||
},
|
||||
|
|
@ -99,7 +98,7 @@ function MemberListRow(props) {
|
|||
size={40}
|
||||
/>
|
||||
<View style={style.textContainer}>
|
||||
<View style={{flexGrow: 1, flexDirection: 'column'}}>
|
||||
<View style={{flexDirection: 'column'}}>
|
||||
<Text style={style.displayName}>
|
||||
{displayName}
|
||||
</Text>
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class ChannelInfo extends PureComponent {
|
|||
currentChannelMemberCount: PropTypes.number,
|
||||
isFavorite: PropTypes.bool.isRequired,
|
||||
leaveChannelRequest: PropTypes.object.isRequired,
|
||||
isAdmin: PropTypes.bool.isRequired,
|
||||
canManageUsers: PropTypes.bool.isRequired,
|
||||
actions: PropTypes.shape({
|
||||
getChannelStats: PropTypes.func.isRequired,
|
||||
goToChannelMembers: PropTypes.func.isRequired,
|
||||
|
|
@ -143,7 +143,7 @@ class ChannelInfo extends PureComponent {
|
|||
currentChannel,
|
||||
currentChannelCreatorName,
|
||||
currentChannelMemberCount,
|
||||
isAdmin
|
||||
canManageUsers
|
||||
} = this.props;
|
||||
|
||||
return (
|
||||
|
|
@ -180,15 +180,15 @@ class ChannelInfo extends PureComponent {
|
|||
</View>
|
||||
<ChannelInfoRow
|
||||
action={this.props.actions.goToChannelMembers}
|
||||
defaultMessage={(isAdmin && currentChannel.type !== Constants.DM_CHANNEL) ? 'Manage Members' : 'View Members'}
|
||||
defaultMessage={canManageUsers ? 'Manage Members' : 'View Members'}
|
||||
detail={currentChannelMemberCount}
|
||||
icon='users'
|
||||
textId={(isAdmin && currentChannel.type !== Constants.DM_CHANNEL) ? 'channel_header.manageMembers' : 'channel_header.viewMembers'}
|
||||
textId={canManageUsers ? 'channel_header.manageMembers' : 'channel_header.viewMembers'}
|
||||
/>
|
||||
<View style={style.separatorContainer}>
|
||||
<View style={style.separator}/>
|
||||
</View>
|
||||
{isAdmin && this.renderLeaveOrDeleteChannelRow() &&
|
||||
{canManageUsers && this.renderLeaveOrDeleteChannelRow() &&
|
||||
<View>
|
||||
<ChannelInfoRow
|
||||
action={this.props.actions.goToChannelAddMembers}
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@ import navigationSceneConnect from '../navigationSceneConnect';
|
|||
import {goToChannelMembers, goToChannelAddMembers, goBack} from 'app/actions/navigation';
|
||||
import {getChannelStats, deleteChannel} from 'service/actions/channels';
|
||||
import {markFavorite, unmarkFavorite, leaveChannel} from 'app/actions/views/channel';
|
||||
import {getCurrentChannel, getCurrentChannelStats, getChannelsByCategory} from 'service/selectors/entities/channels';
|
||||
import {getCurrentChannel, getCurrentChannelStats, getChannelsByCategory, canManageChannelMembers} from 'service/selectors/entities/channels';
|
||||
import {getTheme} from 'service/selectors/entities/preferences';
|
||||
import {getUser, getCurrentUserRoles} from 'service/selectors/entities/users';
|
||||
import {getUser} from 'service/selectors/entities/users';
|
||||
|
||||
import ChannelInfo from './channel_info';
|
||||
|
||||
|
|
@ -22,8 +22,6 @@ function mapStateToProps(state, ownProps) {
|
|||
const favoriteChannels = getChannelsByCategory(state).favoriteChannels.map((f) => f.id);
|
||||
const isFavorite = favoriteChannels.indexOf(currentChannel.id) > -1;
|
||||
const leaveChannelRequest = state.requests.channels.leaveChannel;
|
||||
const currentUserRoles = getCurrentUserRoles(state);
|
||||
const isAdmin = currentUserRoles.includes('_admin');
|
||||
|
||||
return {
|
||||
...ownProps,
|
||||
|
|
@ -34,7 +32,7 @@ function mapStateToProps(state, ownProps) {
|
|||
isFavorite,
|
||||
leaveChannelRequest,
|
||||
theme: getTheme(state),
|
||||
isAdmin
|
||||
canManageUsers: canManageChannelMembers(state)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ import MemberList from 'app/components/custom_list';
|
|||
import {createMembersSections, loadingText} from 'app/utils/member_list';
|
||||
import MemberListRow from 'app/components/custom_list/member_list_row';
|
||||
import {displayUsername} from 'service/utils/user_utils';
|
||||
import {Constants} from 'service/constants';
|
||||
import {makeStyleSheetFromTheme} from 'app/utils/theme';
|
||||
|
||||
import ChannelMembersTitle from './channel_members_title';
|
||||
|
|
@ -40,7 +39,7 @@ class ChannelMembers extends PureComponent {
|
|||
currentTeam: PropTypes.object,
|
||||
preferences: PropTypes.object,
|
||||
requestStatus: PropTypes.string,
|
||||
isAdmin: PropTypes.bool.isRequired,
|
||||
canManageUsers: PropTypes.bool.isRequired,
|
||||
subscribeToHeaderEvent: React.PropTypes.func,
|
||||
unsubscribeFromHeaderEvent: React.PropTypes.func,
|
||||
actions: PropTypes.shape({
|
||||
|
|
@ -171,8 +170,7 @@ class ChannelMembers extends PureComponent {
|
|||
}
|
||||
|
||||
render() {
|
||||
const {currentChannel, isAdmin, theme} = this.props;
|
||||
const canManage = (isAdmin && currentChannel.type !== Constants.DM_CHANNEL && currentChannel.name !== Constants.DEFAULT_CHANNEL);
|
||||
const {canManageUsers, theme} = this.props;
|
||||
const style = getStyleFromTheme(theme);
|
||||
|
||||
return (
|
||||
|
|
@ -184,7 +182,7 @@ class ChannelMembers extends PureComponent {
|
|||
preferences={this.props.preferences}
|
||||
loading={this.props.requestStatus === 'started'}
|
||||
loadingText={loadingText}
|
||||
selectable={canManage}
|
||||
selectable={canManageUsers}
|
||||
onRowSelect={this.handleRowSelect}
|
||||
renderRow={this.renderMemberRow}
|
||||
createSections={createMembersSections}
|
||||
|
|
|
|||
|
|
@ -7,19 +7,16 @@ import navigationSceneConnect from '../navigationSceneConnect';
|
|||
|
||||
import {goBack} from 'app/actions/navigation';
|
||||
import {handleRemoveChannelMembers} from 'app/actions/views/channel_members';
|
||||
import {getCurrentChannel, getCurrentChannelStats} from 'service/selectors/entities/channels';
|
||||
import {getCurrentChannel, getCurrentChannelStats, canManageChannelMembers} from 'service/selectors/entities/channels';
|
||||
import {getMyPreferences, getTheme} from 'service/selectors/entities/preferences';
|
||||
import {getCurrentTeam} from 'service/selectors/entities/teams';
|
||||
import {getProfilesInCurrentChannel, getCurrentUserRoles} from 'service/selectors/entities/users';
|
||||
import {getProfilesInCurrentChannel} from 'service/selectors/entities/users';
|
||||
import {getProfilesInChannel} from 'service/actions/users';
|
||||
|
||||
import ChannelMembers from './channel_members';
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const currentChannelMemberCount = getCurrentChannelStats(state) && getCurrentChannelStats(state).member_count;
|
||||
const currentUserRoles = getCurrentUserRoles(state);
|
||||
|
||||
const isAdmin = currentUserRoles.includes('_admin');
|
||||
|
||||
return {
|
||||
theme: getTheme(state),
|
||||
|
|
@ -30,7 +27,7 @@ function mapStateToProps(state) {
|
|||
currentTeam: getCurrentTeam(state),
|
||||
preferences: getMyPreferences(state),
|
||||
requestStatus: state.requests.users.getProfilesInChannel.status,
|
||||
isAdmin
|
||||
canManageUsers: canManageChannelMembers(state)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,51 +3,42 @@
|
|||
|
||||
import React, {PropTypes} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {
|
||||
View
|
||||
} from 'react-native';
|
||||
import {View} from 'react-native';
|
||||
|
||||
import {getCurrentUserRoles} from 'service/selectors/entities/users';
|
||||
import {getCurrentChannel} from 'service/selectors/entities/channels';
|
||||
import {getCurrentChannel, canManageChannelMembers} from 'service/selectors/entities/channels';
|
||||
import {getTheme} from 'service/selectors/entities/preferences';
|
||||
import {Constants} from 'service/constants';
|
||||
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
|
||||
function ChannelMemberTitle(props) {
|
||||
const {currentChannel, isAdmin} = props;
|
||||
const manage = (isAdmin && currentChannel.type !== Constants.DM_CHANNEL && currentChannel.name !== Constants.DEFAULT_CHANNEL);
|
||||
function ChannelMembersTitle(props) {
|
||||
const {canManageUsers} = props;
|
||||
return (
|
||||
<View style={{alignItems: 'center', justifyContent: 'center', flex: 1, marginHorizontal: 50}}>
|
||||
<FormattedText
|
||||
id={manage ? 'channel_header.manageMembers' : 'channel_header.viewMembers'}
|
||||
defaultMessage={manage ? 'Manage Members' : 'View Members'}
|
||||
id={canManageUsers ? 'channel_header.manageMembers' : 'channel_header.viewMembers'}
|
||||
defaultMessage={canManageUsers ? 'Manage Members' : 'View Members'}
|
||||
style={{color: props.theme.sidebarHeaderTextColor, fontSize: 15, fontWeight: 'bold', textAlign: 'center'}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
ChannelMemberTitle.propTypes = {
|
||||
isAdmin: PropTypes.bool,
|
||||
ChannelMembersTitle.propTypes = {
|
||||
canManageUsers: PropTypes.bool.isRequired,
|
||||
currentChannel: PropTypes.object.isRequired,
|
||||
theme: PropTypes.object
|
||||
theme: PropTypes.object.isRequired
|
||||
};
|
||||
|
||||
ChannelMemberTitle.defaultProps = {
|
||||
ChannelMembersTitle.defaultProps = {
|
||||
theme: {}
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const currentUserRoles = getCurrentUserRoles(state);
|
||||
|
||||
const isAdmin = currentUserRoles.includes('_admin');
|
||||
|
||||
return {
|
||||
isAdmin,
|
||||
canManageUsers: canManageChannelMembers(state),
|
||||
currentChannel: getCurrentChannel(state),
|
||||
theme: getTheme(state)
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(ChannelMemberTitle);
|
||||
export default connect(mapStateToProps)(ChannelMembersTitle);
|
||||
|
|
|
|||
|
|
@ -10,14 +10,12 @@ import {
|
|||
|
||||
import FormattedText from 'app/components/formatted_text';
|
||||
|
||||
import {getCurrentUserRoles} from 'service/selectors/entities/users';
|
||||
import {getCurrentChannel} from 'service/selectors/entities/channels';
|
||||
import {getCurrentChannel, canManageChannelMembers} from 'service/selectors/entities/channels';
|
||||
import {getTheme} from 'service/selectors/entities/preferences';
|
||||
import {Constants} from 'service/constants';
|
||||
|
||||
function RemoveMemberButton(props) {
|
||||
const {currentChannel, isAdmin} = props;
|
||||
if (!isAdmin || currentChannel.type === Constants.DM_CHANNEL || currentChannel.name === Constants.DEFAULT_CHANNEL) {
|
||||
const {canManageUsers} = props;
|
||||
if (!canManageUsers) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -39,7 +37,7 @@ function RemoveMemberButton(props) {
|
|||
|
||||
RemoveMemberButton.propTypes = {
|
||||
emitter: PropTypes.func.isRequired,
|
||||
isAdmin: PropTypes.bool.isRequired,
|
||||
canManageUsers: PropTypes.bool.isRequired,
|
||||
currentChannel: PropTypes.object.isRequired,
|
||||
theme: PropTypes.object
|
||||
};
|
||||
|
|
@ -49,11 +47,8 @@ RemoveMemberButton.defaultProps = {
|
|||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
const currentUserRoles = getCurrentUserRoles(state);
|
||||
|
||||
const isAdmin = currentUserRoles.includes('_admin');
|
||||
return {
|
||||
isAdmin,
|
||||
canManageUsers: canManageChannelMembers(state),
|
||||
currentChannel: getCurrentChannel(state),
|
||||
theme: getTheme(state)
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@
|
|||
// See License.txt for license information.
|
||||
|
||||
import {createSelector} from 'reselect';
|
||||
import {getCurrentTeamId} from 'service/selectors/entities/teams';
|
||||
import {getCurrentTeamId, getCurrentTeamMembership} from 'service/selectors/entities/teams';
|
||||
import {getCurrentUserId, getUsers} from 'service/selectors/entities/users';
|
||||
import {buildDisplayableChannelList, getNotMemberChannels, completeDirectChannelInfo} from 'service/utils/channel_utils';
|
||||
import {Constants} from 'service/constants';
|
||||
|
||||
|
|
@ -150,3 +151,22 @@ export const getAutocompleteChannelWithSections = createSelector(
|
|||
return channels;
|
||||
}
|
||||
);
|
||||
|
||||
export const canManageChannelMembers = createSelector(
|
||||
getCurrentChannel,
|
||||
getCurrentChannelMembership,
|
||||
getCurrentTeamMembership,
|
||||
getUsers,
|
||||
getCurrentUserId,
|
||||
(channel, channelMembership, teamMembership, allUsers, currentUserId) => {
|
||||
const user = allUsers[currentUserId];
|
||||
const roles = `${channelMembership.roles} ${teamMembership.roles} ${user.roles}`;
|
||||
if (channel.type === Constants.DM_CHANNEL || channel.name === Constants.DEFAULT_CHANNEL) {
|
||||
return false;
|
||||
}
|
||||
if (channel.type === Constants.OPEN_CHANNEL) {
|
||||
return true;
|
||||
}
|
||||
return roles.includes('_admin');
|
||||
}
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue