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.", "Select_Teams": "Select the Team's channels you would like to leave.",
"Cannot_leave": "Cannot 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_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-c-room',
'add-user-to-any-p-room', 'add-user-to-any-p-room',
'add-user-to-joined-room', 'add-user-to-joined-room',
'add-team-member',
'add-team-channel', 'add-team-channel',
'archive-room', 'archive-room',
'auto-translate', 'auto-translate',
@ -22,6 +23,7 @@ const PERMISSIONS = [
'delete-p', 'delete-p',
'edit-message', 'edit-message',
'edit-room', 'edit-room',
'edit-team-member',
'edit-team-channel', 'edit-team-channel',
'force-delete-message', 'force-delete-message',
'mute-user', 'mute-user',

View File

@ -762,6 +762,16 @@ const RocketChat = {
// RC 3.13.0 // RC 3.13.0
return this.post('teams.leave', { teamName }); 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) { joinRoom(roomId, joinCode, type) {
// TODO: join code // TODO: join code
// RC 0.48.0 // RC 0.48.0

View File

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

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { FlatList } from 'react-native'; import { FlatList, Alert } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Q } from '@nozbe/watermelondb'; import { Q } from '@nozbe/watermelondb';
import * as List from '../../containers/List'; 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_OWNER = 'set-owner';
const PERMISSION_SET_MODERATOR = 'set-moderator'; const PERMISSION_SET_MODERATOR = 'set-moderator';
const PERMISSION_REMOVE_USER = 'remove-user'; const PERMISSION_REMOVE_USER = 'remove-user';
const PERMISSION_EDIT_TEAM_MEMBER = 'edit-team-member';
class RoomMembersView extends React.Component { class RoomMembersView extends React.Component {
static propTypes = { static propTypes = {
@ -55,7 +56,8 @@ class RoomMembersView extends React.Component {
setLeaderPermission: PropTypes.array, setLeaderPermission: PropTypes.array,
setOwnerPermission: PropTypes.array, setOwnerPermission: PropTypes.array,
setModeratorPermission: PropTypes.array, setModeratorPermission: PropTypes.array,
removeUserPermission: PropTypes.array removeUserPermission: PropTypes.array,
editTeamMemberPermission: PropTypes.array
} }
constructor(props) { constructor(props) {
@ -94,18 +96,44 @@ class RoomMembersView extends React.Component {
const { room } = this.state; const { room } = this.state;
const { const {
muteUserPermission, setLeaderPermission, setOwnerPermission, setModeratorPermission, removeUserPermission muteUserPermission, setLeaderPermission, setOwnerPermission, setModeratorPermission, removeUserPermission, editTeamMemberPermission
} = this.props; } = this.props;
const result = await RocketChat.hasPermission([ let result;
muteUserPermission, setLeaderPermission, setOwnerPermission, setModeratorPermission, removeUserPermission
], room.rid); 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 = { this.permissions = {
[PERMISSION_MUTE_USER]: result[0], [PERMISSION_MUTE_USER]: result[0],
[PERMISSION_SET_LEADER]: result[1], [PERMISSION_SET_LEADER]: result[1],
[PERMISSION_SET_OWNER]: result[2], [PERMISSION_SET_OWNER]: result[2],
[PERMISSION_SET_MODERATOR]: result[3], [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); 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) => { onPressUser = (selectedUser) => {
const { room } = this.state; const { room } = this.state;
const { showActionSheet, user } = this.props; const { showActionSheet, user } = this.props;
@ -173,6 +251,46 @@ class RoomMembersView extends React.Component {
onPress: () => this.navToDirectMessage(selectedUser) 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 // Owner
if (this.permissions['set-owner']) { if (this.permissions['set-owner']) {
const userRoleResult = this.roomRoles.find(r => r.u._id === selectedUser._id); 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 // Remove from room
if (this.permissions['remove-user']) { if (this.permissions['remove-user']) {
options.push({ options.push({
@ -292,6 +380,7 @@ class RoomMembersView extends React.Component {
this.setState({ isLoading: true }); this.setState({ isLoading: true });
try { try {
const membersResult = await RocketChat.getRoomMembers(rid, allUsers, members.length, PAGE_SIZE); const membersResult = await RocketChat.getRoomMembers(rid, allUsers, members.length, PAGE_SIZE);
console.log({ membersResult });
const newMembers = membersResult.records; const newMembers = membersResult.records;
this.setState({ this.setState({
members: members.concat(newMembers || []), members: members.concat(newMembers || []),
@ -477,7 +566,8 @@ const mapStateToProps = state => ({
setLeaderPermission: state.permissions[PERMISSION_SET_LEADER], setLeaderPermission: state.permissions[PERMISSION_SET_LEADER],
setOwnerPermission: state.permissions[PERMISSION_SET_OWNER], setOwnerPermission: state.permissions[PERMISSION_SET_OWNER],
setModeratorPermission: state.permissions[PERMISSION_SET_MODERATOR], 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))); export default connect(mapStateToProps)(withActionSheet(withTheme(RoomMembersView)));

View File

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

View File

@ -21,6 +21,9 @@ import { withTheme } from '../theme';
import SafeAreaView from '../containers/SafeAreaView'; import SafeAreaView from '../containers/SafeAreaView';
import { animateNextTransition } from '../utils/layoutAnimation'; import { animateNextTransition } from '../utils/layoutAnimation';
import Loading from '../containers/Loading'; import Loading from '../containers/Loading';
import { LISTENER } from '../containers/Toast';
import EventEmitter from '../utils/events';
import log from '../utils/log';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
button: { button: {
@ -65,7 +68,9 @@ class SelectListView extends React.Component {
super(props); super(props);
const teamChannels = props.route?.params?.teamChannels; const teamChannels = props.route?.params?.teamChannels;
this.title = props.route?.params?.title; this.title = props.route?.params?.title;
this.subtitle = props.route?.params?.subtitle;
this.teamName = props.route?.params?.teamName; this.teamName = props.route?.params?.teamName;
this.room = props.route?.params?.room;
this.state = { this.state = {
data: teamChannels, data: teamChannels,
selected: [], 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 = ({ renderChannel = ({
onPress, testID, title, icon, checked, alert onPress, testID, title, icon, checked, alert
}) => { }) => {