Added addTeamMember and removeTeamMember

This commit is contained in:
Gerzon Z 2021-05-06 08:57:53 -04:00
parent 4b6e691d8a
commit b961fa05d9
7 changed files with 207 additions and 45 deletions

View File

@ -733,5 +733,9 @@
"Select_Teams": "Select the Team's channels you would like to leave.",
"Cannot_leave": "Cannot leave",
"Last_owner_team_room": "You are the last owner of this channel. Once you leave the team, the channel will be kept inside the team but you will be managing it from outside.",
"last-owner-can-not-be-removed": "Last owner cannot be removed"
"last-owner-can-not-be-removed": "Last owner cannot be removed",
"Removing_user_from_this_Team": "You are removing {{user}} from this Team",
"Remove_User_Teams": "Select channels you want the user to be removed from.",
"Remove_Member": "Remove Member",
"Error": "Error"
}

View File

@ -13,6 +13,7 @@ const PERMISSIONS = [
'add-user-to-any-c-room',
'add-user-to-any-p-room',
'add-user-to-joined-room',
'add-team-member',
'add-team-channel',
'archive-room',
'auto-translate',
@ -22,6 +23,7 @@ const PERMISSIONS = [
'delete-p',
'edit-message',
'edit-room',
'edit-team-member',
'edit-team-channel',
'force-delete-message',
'mute-user',

View File

@ -762,6 +762,16 @@ const RocketChat = {
// RC 3.13.0
return this.post('teams.leave', { teamName });
},
addTeamMember(teamName) {
const { users } = reduxStore.getState().selectedUsers;
const members = users.map(u => ({ userId: u._id, roles: ['member'] }));
// RC 3.13.0
return this.post('teams.addMembers', { teamName, members });
},
removeTeamMember({ teamName, userId }) {
// RC 3.13.0
return this.post('teams.removeMember', { teamName, userId });
},
joinRoom(roomId, joinCode, type) {
// TODO: join code
// RC 0.48.0

View File

@ -61,7 +61,8 @@ class RoomActionsView extends React.Component {
editRoomPermission: PropTypes.array,
toggleRoomE2EEncryptionPermission: PropTypes.array,
viewBroadcastMemberListPermission: PropTypes.array,
transferLivechatGuestPermission: PropTypes.array
transferLivechatGuestPermission: PropTypes.array,
addTeamMemberPermission: PropTypes.array
}
constructor(props) {
@ -171,12 +172,19 @@ class RoomActionsView extends React.Component {
canAddUser = async() => {
const { room, joined } = this.state;
const { addUserToJoinedRoomPermission, addUserToAnyCRoomPermission, addUserToAnyPRoomPermission } = this.props;
const {
addUserToJoinedRoomPermission, addUserToAnyCRoomPermission, addUserToAnyPRoomPermission, addTeamMemberPermission
} = this.props;
const { rid, t } = room;
let canAddUser = false;
let permissions;
const userInRoom = joined;
const permissions = await RocketChat.hasPermission([addUserToJoinedRoomPermission, addUserToAnyCRoomPermission, addUserToAnyPRoomPermission], rid);
if (room.teamMain) {
permissions = await RocketChat.hasPermission([addTeamMemberPermission], rid);
} else {
permissions = await RocketChat.hasPermission([addUserToJoinedRoomPermission, addUserToAnyCRoomPermission, addUserToAnyPRoomPermission], rid);
}
if (userInRoom && permissions[0]) {
canAddUser = true;
@ -321,6 +329,31 @@ class RoomActionsView extends React.Component {
setLoadingInvite(true);
await RocketChat.addUsersToRoom(rid);
navigation.pop();
} catch (e) {
log(e);
Alert.alert(
I18n.t('Confirmation'),
I18n.t('Removing_user_from_this_Team'),
[
{
text: I18n.t('OK'),
style: 'cancel'
}
],
{ cancelable: false }
);
} finally {
setLoadingInvite(false);
}
}
addMemberToTeam = async() => {
const { room } = this.state;
const { setLoadingInvite, navigation } = this.props;
try {
setLoadingInvite(true);
await RocketChat.addTeamMember(room.name);
navigation.pop();
} catch (e) {
log(e);
} finally {
@ -438,7 +471,9 @@ class RoomActionsView extends React.Component {
);
if (teamChannels) {
navigation.navigate('SelectListView', { title: 'Leave_Team', teamChannels, teamName: room.name });
navigation.navigate('SelectListView', {
title: 'Leave_Team', teamChannels, teamName: room.name, subtitle: 'Select_Teams'
});
} else {
Alert.alert(
I18n.t('Confirmation'),
@ -678,7 +713,7 @@ class RoomActionsView extends React.Component {
params: {
rid,
title: I18n.t('Add_users'),
nextAction: this.addUser
nextAction: room.teamId ? this.addMemberToTeam : this.addUser
}
})}
testID='room-actions-add-user'
@ -930,6 +965,7 @@ const mapStateToProps = state => ({
encryptionEnabled: state.encryption.enabled,
serverVersion: state.server.version,
addUserToJoinedRoomPermission: state.permissions['add-user-to-joined-room'],
addTeamMemberPermission: state.permissions['add-team-member'],
addUserToAnyCRoomPermission: state.permissions['add-user-to-any-c-room'],
addUserToAnyPRoomPermission: state.permissions['add-user-to-any-p-room'],
createInviteLinksPermission: state.permissions['create-invite-links'],

View File

@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import { FlatList } from 'react-native';
import { FlatList, Alert } from 'react-native';
import { connect } from 'react-redux';
import { Q } from '@nozbe/watermelondb';
import * as List from '../../containers/List';
@ -34,6 +34,7 @@ const PERMISSION_SET_LEADER = 'set-leader';
const PERMISSION_SET_OWNER = 'set-owner';
const PERMISSION_SET_MODERATOR = 'set-moderator';
const PERMISSION_REMOVE_USER = 'remove-user';
const PERMISSION_EDIT_TEAM_MEMBER = 'edit-team-member';
class RoomMembersView extends React.Component {
static propTypes = {
@ -55,7 +56,8 @@ class RoomMembersView extends React.Component {
setLeaderPermission: PropTypes.array,
setOwnerPermission: PropTypes.array,
setModeratorPermission: PropTypes.array,
removeUserPermission: PropTypes.array
removeUserPermission: PropTypes.array,
editTeamMemberPermission: PropTypes.array
}
constructor(props) {
@ -94,18 +96,44 @@ class RoomMembersView extends React.Component {
const { room } = this.state;
const {
muteUserPermission, setLeaderPermission, setOwnerPermission, setModeratorPermission, removeUserPermission
muteUserPermission, setLeaderPermission, setOwnerPermission, setModeratorPermission, removeUserPermission, editTeamMemberPermission
} = this.props;
const result = await RocketChat.hasPermission([
muteUserPermission, setLeaderPermission, setOwnerPermission, setModeratorPermission, removeUserPermission
], room.rid);
let result;
if (room.teamId) {
result = await RocketChat.hasPermission([
muteUserPermission, setLeaderPermission, setOwnerPermission, setModeratorPermission, removeUserPermission, editTeamMemberPermission
], room.rid);
this.permissions = {
[PERMISSION_MUTE_USER]: result[0],
[PERMISSION_SET_LEADER]: result[1],
[PERMISSION_SET_OWNER]: result[2],
[PERMISSION_SET_MODERATOR]: result[3],
[PERMISSION_REMOVE_USER]: result[4],
[PERMISSION_EDIT_TEAM_MEMBER]: result[5]
};
} else {
result = await RocketChat.hasPermission([
muteUserPermission, setLeaderPermission, setOwnerPermission, setModeratorPermission, removeUserPermission
], room.rid);
this.permissions = {
[PERMISSION_MUTE_USER]: result[0],
[PERMISSION_SET_LEADER]: result[1],
[PERMISSION_SET_OWNER]: result[2],
[PERMISSION_SET_MODERATOR]: result[3],
[PERMISSION_REMOVE_USER]: result[4]
};
}
this.permissions = {
[PERMISSION_MUTE_USER]: result[0],
[PERMISSION_SET_LEADER]: result[1],
[PERMISSION_SET_OWNER]: result[2],
[PERMISSION_SET_MODERATOR]: result[3],
[PERMISSION_REMOVE_USER]: result[4]
[PERMISSION_REMOVE_USER]: result[4],
[PERMISSION_EDIT_TEAM_MEMBER]: result[5]
};
const hasSinglePermission = Object.values(this.permissions).some(p => !!p);
@ -163,6 +191,56 @@ class RoomMembersView extends React.Component {
}
}
handleRemoveFromTeam = async(selectedUser) => {
const { navigation } = this.props;
const { room } = this.state;
const db = database.active;
const subCollection = db.get('subscriptions');
const teamChannels = await subCollection.query(
Q.where('team_id', Q.eq(room.teamId))
);
if (teamChannels) {
navigation.navigate('SelectListView', {
title: 'Remove_Member', subtitle: 'Remove_User_Teams', teamChannels, selectedUser
});
} else {
Alert.alert(
I18n.t('Confirmation'),
I18n.t('Removing_user_from_this_Team', { user: selectedUser.username }),
[
{
text: I18n.t('Cancel'),
style: 'cancel'
},
{
text: I18n.t('Yes_action_it', { action: I18n.t('remove') }),
style: 'destructive',
onPress: () => this.removeFromTeam(selectedUser)
}
],
{ cancelable: false }
);
}
}
removeFromTeam = async(selectedUser) => {
try {
const { members, membersFiltered, room } = this.state;
const userId = selectedUser._id;
const result = await RocketChat.removeTeamMember({ teamName: room.name, userId });
if (result.success) {
const message = I18n.t('User_has_been_removed_from_s', { s: RocketChat.getRoomTitle(room) });
EventEmitter.emit(LISTENER, { message });
this.setState({
members: members.filter(member => member._id !== userId),
membersFiltered: membersFiltered.filter(member => member._id !== userId)
});
}
} catch (e) {
log(e);
}
}
onPressUser = (selectedUser) => {
const { room } = this.state;
const { showActionSheet, user } = this.props;
@ -173,6 +251,46 @@ class RoomMembersView extends React.Component {
onPress: () => this.navToDirectMessage(selectedUser)
}];
// Ignore
if (selectedUser._id !== user.id) {
const { ignored } = room;
const isIgnored = ignored?.includes?.(selectedUser._id);
options.push({
icon: 'ignore',
title: I18n.t(isIgnored ? 'Unignore' : 'Ignore'),
onPress: () => this.handleIgnore(selectedUser, !isIgnored)
});
}
if (this.permissions['mute-user']) {
const { muted = [] } = room;
const userIsMuted = muted.find?.(m => m === selectedUser.username);
selectedUser.muted = !!userIsMuted;
options.push({
icon: userIsMuted ? 'audio' : 'audio-disabled',
title: I18n.t(userIsMuted ? 'Unmute' : 'Mute'),
onPress: () => {
showConfirmationAlert({
message: I18n.t(`The_user_${ userIsMuted ? 'will' : 'wont' }_be_able_to_type_in_roomName`, {
roomName: RocketChat.getRoomTitle(room)
}),
confirmationText: I18n.t(userIsMuted ? 'Unmute' : 'Mute'),
onPress: () => this.handleMute(selectedUser)
});
}
});
}
// Remove from team
if (this.permissions['edit-team-member']) {
options.push({
icon: 'close',
danger: true,
title: I18n.t('Remove_from_Team'),
onPress: () => this.handleRemoveFromTeam(selectedUser)
});
}
// Owner
if (this.permissions['set-owner']) {
const userRoleResult = this.roomRoles.find(r => r.u._id === selectedUser._id);
@ -206,36 +324,6 @@ class RoomMembersView extends React.Component {
});
}
// Ignore
if (selectedUser._id !== user.id) {
const { ignored } = room;
const isIgnored = ignored?.includes?.(selectedUser._id);
options.push({
icon: 'ignore',
title: I18n.t(isIgnored ? 'Unignore' : 'Ignore'),
onPress: () => this.handleIgnore(selectedUser, !isIgnored)
});
}
if (this.permissions['mute-user']) {
const { muted = [] } = room;
const userIsMuted = muted.find?.(m => m === selectedUser.username);
selectedUser.muted = !!userIsMuted;
options.push({
icon: userIsMuted ? 'audio' : 'audio-disabled',
title: I18n.t(userIsMuted ? 'Unmute' : 'Mute'),
onPress: () => {
showConfirmationAlert({
message: I18n.t(`The_user_${ userIsMuted ? 'will' : 'wont' }_be_able_to_type_in_roomName`, {
roomName: RocketChat.getRoomTitle(room)
}),
confirmationText: I18n.t(userIsMuted ? 'Unmute' : 'Mute'),
onPress: () => this.handleMute(selectedUser)
});
}
});
}
// Remove from room
if (this.permissions['remove-user']) {
options.push({
@ -292,6 +380,7 @@ class RoomMembersView extends React.Component {
this.setState({ isLoading: true });
try {
const membersResult = await RocketChat.getRoomMembers(rid, allUsers, members.length, PAGE_SIZE);
console.log({ membersResult });
const newMembers = membersResult.records;
this.setState({
members: members.concat(newMembers || []),
@ -477,7 +566,8 @@ const mapStateToProps = state => ({
setLeaderPermission: state.permissions[PERMISSION_SET_LEADER],
setOwnerPermission: state.permissions[PERMISSION_SET_OWNER],
setModeratorPermission: state.permissions[PERMISSION_SET_MODERATOR],
removeUserPermission: state.permissions[PERMISSION_REMOVE_USER]
removeUserPermission: state.permissions[PERMISSION_REMOVE_USER],
editTeamMemberPermission: state.permissions['edit-team-member']
});
export default connect(mapStateToProps)(withActionSheet(withTheme(RoomMembersView)));

View File

@ -1033,7 +1033,7 @@ class RoomView extends React.Component {
renderActions = () => {
const { room, readOnly } = this.state;
const { user } = this.props;
console.log({ room });
return (
<>
<MessageActions

View File

@ -21,6 +21,9 @@ import { withTheme } from '../theme';
import SafeAreaView from '../containers/SafeAreaView';
import { animateNextTransition } from '../utils/layoutAnimation';
import Loading from '../containers/Loading';
import { LISTENER } from '../containers/Toast';
import EventEmitter from '../utils/events';
import log from '../utils/log';
const styles = StyleSheet.create({
button: {
@ -65,7 +68,9 @@ class SelectListView extends React.Component {
super(props);
const teamChannels = props.route?.params?.teamChannels;
this.title = props.route?.params?.title;
this.subtitle = props.route?.params?.subtitle;
this.teamName = props.route?.params?.teamName;
this.room = props.route?.params?.room;
this.state = {
data: teamChannels,
selected: [],
@ -172,6 +177,21 @@ class SelectListView extends React.Component {
);
}
removeFromTeam = async(selectedUser) => {
try {
const { data, room } = this.state;
const userId = selectedUser._id;
const result = await RocketChat.removeTeamMember({ teamName: room.name, userId });
if (result.success) {
const message = I18n.t('User_has_been_removed_from_s', { s: RocketChat.getRoomTitle(room) });
EventEmitter.emit(LISTENER, { message });
this.setState({ data: data.filter(member => member._id !== userId) });
}
} catch (e) {
log(e);
}
}
renderChannel = ({
onPress, testID, title, icon, checked, alert
}) => {