diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index 76d60f21f..29a3b2422 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -91,6 +91,7 @@ "alert": "alert", "alerts": "alerts", "All_users_in_the_channel_can_write_new_messages": "All users in the channel can write new messages", + "All_users_in_the_team_can_write_new_messages": "All users in the team can write new messages", "A_meaningful_name_for_the_discussion_room": "A meaningful name for the discussion room", "All": "All", "All_Messages": "All Messages", @@ -226,6 +227,7 @@ "Encryption_error_title": "Your encryption password seems wrong", "Encryption_error_desc": "It wasn't possible to decode your encryption key to be imported.", "Everyone_can_access_this_channel": "Everyone can access this channel", + "Everyone_can_access_this_team": "Everyone can access this team", "Error_uploading": "Error uploading", "Expiration_Days": "Expiration (Days)", "Favorite": "Favorite", @@ -287,6 +289,7 @@ "Join_our_open_workspace": "Join our open workspace", "Join_your_workspace": "Join your workspace", "Just_invited_people_can_access_this_channel": "Just invited people can access this channel", + "Just_invited_people_can_access_this_team": "Just invited people can access this team", "Language": "Language", "last_message": "last message", "Leave_channel": "Leave channel", @@ -723,7 +726,7 @@ "Add_Existing_Channel": "Add Existing Channel", "Remove_from_Team": "Remove from Team", "Auto-join": "Auto-join", - "Delete_Team_Room_Warning": "Woud you like to remove this channel from the team? The channel will be moved back to the workspace", + "Remove_Team_Room_Warning": "Woud you like to remove this channel from the team? The channel will be moved back to the workspace", "Confirmation": "Confirmation", "invalid-room": "Invalid room", "You_are_leaving_the_team": "You are leaving the team '{{team}}'", @@ -731,13 +734,19 @@ "Select_Team_Channels": "Select the Team's channels you would like to leave.", "Cannot_leave": "Cannot leave", "Cannot_remove": "Cannot remove", + "Cannot_delete": "Cannot delete", "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", + "Remove_User_Teams": "Select channels you want the user to be removed from.", + "Delete_Team": "Delete Team", + "Select_channels_to_delete": "This can't be undone. Once you delete a team, all chat content and configuration will be deleted. \n\nSelect the channels you would like to delete. The ones you decide to keep will be available on your workspace. Notice that public channels will still be public and visible to everyone.", + "You_are_deleting_the_team": "You are deleting this team.", "Removing_user_from_this_team": "You are removing {{user}} from this team", "Remove_User_Team_Channels": "Select the channels you want the user to be removed from.", "Remove_Member": "Remove Member", "leaving_team": "leaving team", "removing_team": "removing from team", + "deleting_team": "deleting team", "member-does-not-exist": "Member does not exist", "Load_More": "Load More", "Load_Newer": "Load Newer", diff --git a/app/lib/methods/getPermissions.js b/app/lib/methods/getPermissions.js index cc1dd46e0..99a18a6c0 100644 --- a/app/lib/methods/getPermissions.js +++ b/app/lib/methods/getPermissions.js @@ -20,6 +20,7 @@ const PERMISSIONS = [ 'delete-c', 'delete-message', 'delete-p', + 'delete-team', 'edit-message', 'edit-room', 'edit-team-member', diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 3660b3195..4774b4272 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -790,6 +790,10 @@ const RocketChat = { // RC 3.13.0 return this.post('teams.updateRoom', { roomId, isDefault }); }, + deleteTeam({ teamId, roomsToRemove }) { + // RC 3.13.0 + return this.post('teams.delete', { teamId, roomsToRemove }); + }, teamListRoomsOfUser({ teamId, userId }) { // RC 3.13.0 return this.sdk.get('teams.listRoomsOfUser', { teamId, userId }); diff --git a/app/views/RoomInfoEditView/index.js b/app/views/RoomInfoEditView/index.js index 7552b093a..90d8b28f5 100644 --- a/app/views/RoomInfoEditView/index.js +++ b/app/views/RoomInfoEditView/index.js @@ -8,15 +8,16 @@ import { BLOCK_CONTEXT } from '@rocket.chat/ui-kit'; import ImagePicker from 'react-native-image-crop-picker'; import { dequal } from 'dequal'; import isEmpty from 'lodash/isEmpty'; -import { compareServerVersion, methods } from '../../lib/utils'; +import { Q } from '@nozbe/watermelondb'; +import { compareServerVersion, methods } from '../../lib/utils'; import database from '../../lib/database'; import { deleteRoom as deleteRoomAction } from '../../actions/room'; import KeyboardView from '../../presentation/KeyboardView'; import sharedStyles from '../Styles'; import styles from './styles'; import scrollPersistTaps from '../../utils/scrollPersistTaps'; -import { showErrorAlert } from '../../utils/info'; +import { showConfirmationAlert, showErrorAlert } from '../../utils/info'; import { LISTENER } from '../../containers/Toast'; import EventEmitter from '../../utils/events'; import RocketChat from '../../lib/rocketchat'; @@ -41,6 +42,7 @@ const PERMISSION_ARCHIVE = 'archive-room'; const PERMISSION_UNARCHIVE = 'unarchive-room'; const PERMISSION_DELETE_C = 'delete-c'; const PERMISSION_DELETE_P = 'delete-p'; +const PERMISSION_DELETE_TEAM = 'delete-team'; class RoomInfoEditView extends React.Component { static navigationOptions = () => ({ @@ -48,6 +50,7 @@ class RoomInfoEditView extends React.Component { }) static propTypes = { + navigation: PropTypes.object, route: PropTypes.object, deleteRoom: PropTypes.func, serverVersion: PropTypes.string, @@ -58,7 +61,9 @@ class RoomInfoEditView extends React.Component { archiveRoomPermission: PropTypes.array, unarchiveRoomPermission: PropTypes.array, deleteCPermission: PropTypes.array, - deletePPermission: PropTypes.array + deletePPermission: PropTypes.array, + deleteTeamPermission: PropTypes.array, + isMasterDetail: PropTypes.bool }; constructor(props) { @@ -100,7 +105,8 @@ class RoomInfoEditView extends React.Component { archiveRoomPermission, unarchiveRoomPermission, deleteCPermission, - deletePPermission + deletePPermission, + deleteTeamPermission } = this.props; const rid = route.params?.rid; if (!rid) { @@ -122,7 +128,8 @@ class RoomInfoEditView extends React.Component { archiveRoomPermission, unarchiveRoomPermission, deleteCPermission, - deletePPermission + deletePPermission, + ...(this.room.teamMain ? [deleteTeamPermission] : []) ], rid); this.setState({ @@ -132,7 +139,8 @@ class RoomInfoEditView extends React.Component { [PERMISSION_ARCHIVE]: result[2], [PERMISSION_UNARCHIVE]: result[3], [PERMISSION_DELETE_C]: result[4], - [PERMISSION_DELETE_P]: result[5] + [PERMISSION_DELETE_P]: result[5], + ...(this.room.teamMain && { [PERMISSION_DELETE_TEAM]: result[6] }) } }); } catch (e) { @@ -284,6 +292,72 @@ class RoomInfoEditView extends React.Component { }, 100); } + handleDeleteTeam = async(selected) => { + const { navigation, isMasterDetail } = this.props; + const { room } = this.state; + try { + const result = await RocketChat.deleteTeam({ teamId: room.teamId, ...(selected && { roomsToRemove: selected }) }); + if (result.success) { + if (isMasterDetail) { + navigation.navigate('DrawerNavigator'); + } else { + navigation.navigate('RoomsListView'); + } + } + } catch (e) { + log(e); + showErrorAlert( + e.data.error + ? I18n.t(e.data.error) + : I18n.t('There_was_an_error_while_action', { action: I18n.t('deleting_team') }), + I18n.t('Cannot_delete') + ); + } + } + + deleteTeam = async() => { + const { room } = this.state; + const { navigation } = this.props; + + try { + const db = database.active; + const subCollection = db.get('subscriptions'); + const teamChannels = await subCollection.query( + Q.where('team_id', room.teamId), + Q.where('team_main', null) + ); + + if (teamChannels.length) { + navigation.navigate('SelectListView', { + title: 'Delete_Team', + data: teamChannels, + infoText: 'Select_channels_to_delete', + nextAction: (selected) => { + showConfirmationAlert({ + message: I18n.t('You_are_deleting_the_team', { team: RocketChat.getRoomTitle(room) }), + confirmationText: I18n.t('Yes_action_it', { action: I18n.t('delete') }), + onPress: () => this.handleDeleteTeam(selected) + }); + } + }); + } else { + showConfirmationAlert({ + message: I18n.t('You_are_deleting_the_team', { team: RocketChat.getRoomTitle(room) }), + confirmationText: I18n.t('Yes_action_it', { action: I18n.t('delete') }), + onPress: () => this.handleDeleteTeam() + }); + } + } catch (e) { + log(e); + showErrorAlert( + e.data.error + ? I18n.t(e.data.error) + : I18n.t('There_was_an_error_while_action', { action: I18n.t('deleting_team') }), + I18n.t('Cannot_delete') + ); + } + } + delete = () => { const { room } = this.state; const { deleteRoom } = this.props; @@ -339,9 +413,16 @@ class RoomInfoEditView extends React.Component { hasDeletePermission = () => { const { room, permissions } = this.state; - return ( - room.t === 'p' ? permissions[PERMISSION_DELETE_P] : permissions[PERMISSION_DELETE_C] - ); + + if (room.teamMain) { + return permissions[PERMISSION_DELETE_TEAM]; + } + + if (room.t === 'p') { + return permissions[PERMISSION_DELETE_P]; + } + + return permissions[PERMISSION_DELETE_C]; } hasArchivePermission = () => { @@ -513,9 +594,9 @@ class RoomInfoEditView extends React.Component { @@ -678,7 +759,9 @@ const mapStateToProps = state => ({ archiveRoomPermission: state.permissions[PERMISSION_ARCHIVE], unarchiveRoomPermission: state.permissions[PERMISSION_UNARCHIVE], deleteCPermission: state.permissions[PERMISSION_DELETE_C], - deletePPermission: state.permissions[PERMISSION_DELETE_P] + deletePPermission: state.permissions[PERMISSION_DELETE_P], + deleteTeamPermission: state.permissions[PERMISSION_DELETE_TEAM], + isMasterDetail: state.app.isMasterDetail }); const mapDispatchToProps = dispatch => ({ diff --git a/app/views/TeamChannelsView.js b/app/views/TeamChannelsView.js index 1d4b09246..15905a9ee 100644 --- a/app/views/TeamChannelsView.js +++ b/app/views/TeamChannelsView.js @@ -321,7 +321,7 @@ class TeamChannelsView extends React.Component { remove = (item) => { Alert.alert( I18n.t('Confirmation'), - I18n.t('Delete_Team_Room_Warning'), + I18n.t('Remove_Team_Room_Warning'), [ { text: I18n.t('Cancel'),