From 86e1f996d020acb6325a7e95e00f40cc6cf75e7c Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Thu, 1 Jul 2021 17:49:55 -0300 Subject: [PATCH 01/15] [IMPROVE] Add convert team to a channel --- app/i18n/locales/en.json | 3 +- app/i18n/locales/pt-BR.json | 3 +- app/lib/methods/getPermissions.js | 3 +- app/views/RoomActionsView/index.js | 50 +++++++++++++++++++++++++++--- 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index 926b0c6746..fc1c5c89af 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -762,5 +762,6 @@ "Move_to_Team_Warning": "After reading the previous intructions about this behavior, do you still want to move this channel to the selected team?", "Load_More": "Load More", "Load_Newer": "Load Newer", - "Load_Older": "Load Older" + "Load_Older": "Load Older", + "Convert_to_Channel": "Convert to Channel" } \ No newline at end of file diff --git a/app/i18n/locales/pt-BR.json b/app/i18n/locales/pt-BR.json index 9b34d87d3f..e3c7c496a3 100644 --- a/app/i18n/locales/pt-BR.json +++ b/app/i18n/locales/pt-BR.json @@ -665,5 +665,6 @@ "Team_not_found": "Time não encontrado", "Private_Team": "Equipe Privada", "Add_Existing_Channel": "Adicionar Canal Existente", - "invalid-room": "Sala inválida" + "invalid-room": "Sala inválida", + "Convert_to_Channel": "Converter para um Canal" } \ No newline at end of file diff --git a/app/lib/methods/getPermissions.js b/app/lib/methods/getPermissions.js index 6e68f5c333..1c4c56b46b 100644 --- a/app/lib/methods/getPermissions.js +++ b/app/lib/methods/getPermissions.js @@ -47,7 +47,8 @@ const PERMISSIONS = [ 'view-statistics', 'view-user-administration', 'view-all-teams', - 'view-all-team-channels' + 'view-all-team-channels', + 'convert-team' ]; export async function setPermissions() { diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index d16ea57688..a21f4bd84e 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -65,7 +65,8 @@ class RoomActionsView extends React.Component { viewBroadcastMemberListPermission: PropTypes.array, transferLivechatGuestPermission: PropTypes.array, createTeamPermission: PropTypes.array, - addTeamChannelPermission: PropTypes.array + addTeamChannelPermission: PropTypes.array, + convertTeamPermission: PropTypes.array } constructor(props) { @@ -89,7 +90,8 @@ class RoomActionsView extends React.Component { canEdit: false, canToggleEncryption: false, canCreateTeam: false, - canAddChannelToTeam: false + canAddChannelToTeam: false, + canConvertTeam: false }; if (room && room.observe && room.rid) { this.roomObservable = room.observe(); @@ -140,9 +142,10 @@ class RoomActionsView extends React.Component { const canViewMembers = await this.canViewMembers(); const canCreateTeam = await this.canCreateTeam(); const canAddChannelToTeam = await this.canAddChannelToTeam(); + const canConvertTeam = await this.canConvertTeam(); this.setState({ - canAutoTranslate, canAddUser, canInviteUser, canEdit, canToggleEncryption, canViewMembers, canCreateTeam, canAddChannelToTeam + canAutoTranslate, canAddUser, canInviteUser, canEdit, canToggleEncryption, canViewMembers, canCreateTeam, canAddChannelToTeam, canConvertTeam }); // livechat permissions @@ -238,6 +241,16 @@ class RoomActionsView extends React.Component { return canAddChannelToTeam; } + canConvertTeam = async() => { + const { room } = this.state; + const { convertTeamPermission } = this.props; + const { rid } = room; + const permissions = await RocketChat.hasPermission([convertTeamPermission], rid); + + const canConvertTeam = permissions[0]; + return canConvertTeam; + } + canToggleEncryption = async() => { const { room } = this.state; const { toggleRoomE2EEncryptionPermission } = this.props; @@ -799,6 +812,32 @@ class RoomActionsView extends React.Component { ); } + teamToChannelActions = (t, room) => { + const { canEdit, canConvertTeam } = this.state; + const canConvertTeamToChannel = canEdit && canConvertTeam && !!room?.teamMain; + + return ( + <> + {['c', 'p'].includes(t) && canConvertTeamToChannel + ? ( + <> + this.onPressTouchable({ + event: this.convertToTeam + })} + testID='room-actions-convert-to-team' + left={() => } + showActionIndicator + /> + + + ) + : null} + + ); + } + render() { const { room, membersCount, canViewMembers, canAddUser, canInviteUser, joined, canAutoTranslate, canForwardGuest, canReturnQueue @@ -1000,7 +1039,9 @@ class RoomActionsView extends React.Component { ) : null} + { this.teamChannelActions(t, room) } + {this.teamToChannelActions(t, room)} {['l'].includes(t) && !this.isOmnichannelPreview ? ( @@ -1090,7 +1131,8 @@ const mapStateToProps = state => ({ viewBroadcastMemberListPermission: state.permissions['view-broadcast-member-list'], transferLivechatGuestPermission: state.permissions['transfer-livechat-guest'], createTeamPermission: state.permissions['create-team'], - addTeamChannelPermission: state.permissions['add-team-channel'] + addTeamChannelPermission: state.permissions['add-team-channel'], + convertTeamPermission: state.permissions['convert-team'] }); const mapDispatchToProps = dispatch => ({ From 9873a40880202790c70db7390228204be0ee8832 Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Thu, 1 Jul 2021 18:50:17 -0300 Subject: [PATCH 02/15] Action to SelectListView and new words to i18n --- app/i18n/locales/en.json | 5 +++- app/views/RoomActionsView/index.js | 38 +++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index fc1c5c89af..c59f8e5055 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -763,5 +763,8 @@ "Load_More": "Load More", "Load_Newer": "Load Newer", "Load_Older": "Load Older", - "Convert_to_Channel": "Convert to Channel" + "Convert_to_Channel": "Convert to Channel", + "Converting_Team_To_Channel": "Converting Team to Channel", + "Select_Team_Channels_To_Delete": "Select the Team’s Channels you would like to delete, the ones you do not select will be moved to the Workspace. \n\nNotice that public Channels will be public and visible to everyone.", + "You_are_converting_the_team": "You are converting this Team to a Channel" } \ No newline at end of file diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index a21f4bd84e..3f3243a459 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -444,6 +444,42 @@ class RoomActionsView extends React.Component { }); } + convertTeamToChannel = async() => { + const { room } = this.state; + const { navigation, leaveRoom } = this.props; + + try { + const result = await RocketChat.teamListRoomsOfUser({ teamId: room.teamId, userId: room.u._id }); + + if (result.rooms?.length) { + const teamChannels = result.rooms.map(r => ({ + rid: r._id, + name: r.name, + teamId: r.teamId + })); + navigation.navigate('SelectListView', { + title: 'Converting_Team_To_Channel', + data: teamChannels, + infoText: 'Select_Team_Channels_To_Delete', + nextAction: data => leaveRoom('team', room, data), + showAlert: () => showErrorAlert(I18n.t('Last_owner_team_room'), I18n.t('Cannot_leave')) + }); + } else { + showConfirmationAlert({ + message: I18n.t('You_are_converting_the_team'), + confirmationText: I18n.t('Yes_action_it', { action: I18n.t('Convert') }), + onPress: () => leaveRoom('team', room) + }); + } + } catch (e) { + showConfirmationAlert({ + message: I18n.t('You_are_converting_the_team'), + confirmationText: I18n.t('Yes_action_it', { action: I18n.t('Convert') }), + onPress: () => leaveRoom('team', room) + }); + } + } + leaveTeam = async() => { const { room } = this.state; const { navigation, leaveRoom } = this.props; @@ -824,7 +860,7 @@ class RoomActionsView extends React.Component { this.onPressTouchable({ - event: this.convertToTeam + event: this.convertTeamToChannel })} testID='room-actions-convert-to-team' left={() => } From 5a0cda9fb69ddd7a5bd5dc81911ccd5023590b90 Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Fri, 2 Jul 2021 11:44:16 -0300 Subject: [PATCH 03/15] Implemented the post and it's working with selected channels or not --- app/lib/rocketchat.js | 7 +++++ app/utils/log/events.js | 2 ++ app/views/RoomActionsView/index.js | 43 +++++++++++++++++++++--------- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 59b85b73d6..5625a9cb5e 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -834,6 +834,13 @@ const RocketChat = { }; return this.sdk.post(type === 'c' ? 'channels.convertToTeam' : 'groups.convertToTeam', params); }, + convertTeamToChannel({ teamId, selected }) { + const params = { + teamId, + ...(selected.length && { roomsToRemove: selected }) + }; + return this.sdk.post('teams.convertToChannel', params); + }, joinRoom(roomId, joinCode, type) { // TODO: join code // RC 0.48.0 diff --git a/app/utils/log/events.js b/app/utils/log/events.js index a183735ba4..2ab3f539bc 100644 --- a/app/utils/log/events.js +++ b/app/utils/log/events.js @@ -259,6 +259,8 @@ export default { RA_LEAVE_TEAM_F: 'ra_leave_team_f', RA_CONVERT_TO_TEAM: 'ra_convert_to_team', RA_CONVERT_TO_TEAM_F: 'ra_convert_to_team_f', + RA_CONVERT_TEAM_TO_CHANNEL: 'ra_convert_team_to_channel', + RA_CONVERT_TEAM_TO_CHANNEL_F: 'ra_convert_team_to_channel_f', RA_MOVE_TO_TEAM: 'ra_move_to_team', RA_MOVE_TO_TEAM_F: 'ra_move_to_team_f', RA_SEARCH_TEAM: 'ra_search_team', diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index 3f3243a459..ccb969d1ac 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -446,7 +446,7 @@ class RoomActionsView extends React.Component { convertTeamToChannel = async() => { const { room } = this.state; - const { navigation, leaveRoom } = this.props; + const { navigation } = this.props; try { const result = await RocketChat.teamListRoomsOfUser({ teamId: room.teamId, userId: room.u._id }); @@ -461,25 +461,42 @@ class RoomActionsView extends React.Component { title: 'Converting_Team_To_Channel', data: teamChannels, infoText: 'Select_Team_Channels_To_Delete', - nextAction: data => leaveRoom('team', room, data), - showAlert: () => showErrorAlert(I18n.t('Last_owner_team_room'), I18n.t('Cannot_leave')) + nextAction: data => this.convertTeam(data) }); } else { - showConfirmationAlert({ - message: I18n.t('You_are_converting_the_team'), - confirmationText: I18n.t('Yes_action_it', { action: I18n.t('Convert') }), - onPress: () => leaveRoom('team', room) - }); + this.convertTeam(); } } catch (e) { - showConfirmationAlert({ - message: I18n.t('You_are_converting_the_team'), - confirmationText: I18n.t('Yes_action_it', { action: I18n.t('Convert') }), - onPress: () => leaveRoom('team', room) - }); + this.convertTeam(); + } + } + + handleConvertTeamToChannel = async(selected) => { + logEvent(events.RA_CONVERT_TEAM_TO_CHANNEL); + try { + const { room } = this.state; + const { navigation } = this.props; + + const result = await RocketChat.convertTeamToChannel({ teamId: room.teamId, selected }); + + if (result.success) { + navigation.navigate('RoomView'); + } + } catch (e) { + logEvent(events.RA_CONVERT_TEAM_TO_CHANNEL_F); + log(e); } } + convertTeam = (selected = []) => { + showConfirmationAlert({ + title: I18n.t('Confirmation'), + message: I18n.t('You_are_converting_the_team'), + confirmationText: I18n.t('Convert'), + onPress: () => this.handleConvertTeamToChannel(selected) + }); + } + leaveTeam = async() => { const { room } = this.state; const { navigation, leaveRoom } = this.props; From 236c9060990cc6d4aef00e83fba6e4a3bb315260 Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Fri, 2 Jul 2021 11:55:17 -0300 Subject: [PATCH 04/15] Fixed the Convert Team Warning at english i18n and changed the function name --- app/i18n/locales/en.json | 2 +- app/views/RoomActionsView/index.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index c59f8e5055..4bdb922558 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -756,7 +756,7 @@ "member-does-not-exist": "Member does not exist", "Convert": "Convert", "Convert_to_Team": "Convert to Team", - "Convert_to_Team_Warning": "This can't be undone. Once you convert a channel to a team, you can not turn it back to a channel.", + "Convert_to_Team_Warning": "You are converting this Channel to a Team. All Members will be kept.", "Move_to_Team": "Move to Team", "Move_Channel_Paragraph": "Moving a channel inside a team means that this channel will be added in the team’s context, however, all channel’s members, which are not members of the respective team, will still have access to this channel, but will not be added as team’s members. \n\nAll channel’s management will still be made by the owners of this channel.\n\nTeam’s members and even team’s owners, if not a member of this channel, can not have access to the channel’s content. \n\nPlease notice that the Team’s owner will be able remove members from the Channel.", "Move_to_Team_Warning": "After reading the previous intructions about this behavior, do you still want to move this channel to the selected team?", diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index ccb969d1ac..69afebd35f 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -461,13 +461,13 @@ class RoomActionsView extends React.Component { title: 'Converting_Team_To_Channel', data: teamChannels, infoText: 'Select_Team_Channels_To_Delete', - nextAction: data => this.convertTeam(data) + nextAction: data => this.convertTeamToChannelConfirmation(data) }); } else { - this.convertTeam(); + this.convertTeamToChannelConfirmation(); } } catch (e) { - this.convertTeam(); + this.convertTeamToChannelConfirmation(); } } @@ -488,7 +488,7 @@ class RoomActionsView extends React.Component { } } - convertTeam = (selected = []) => { + convertTeamToChannelConfirmation = (selected = []) => { showConfirmationAlert({ title: I18n.t('Confirmation'), message: I18n.t('You_are_converting_the_team'), From 8d69978a6825b97d8f1af2923be5db2218d6e49b Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Fri, 2 Jul 2021 12:53:47 -0300 Subject: [PATCH 05/15] E2E test completed in sequence the convert/move teams --- app/views/RoomActionsView/index.js | 2 +- e2e/tests/team/03-moveconvert.spec.js | 29 ++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index 69afebd35f..dc76dd0f41 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -879,7 +879,7 @@ class RoomActionsView extends React.Component { onPress={() => this.onPressTouchable({ event: this.convertTeamToChannel })} - testID='room-actions-convert-to-team' + testID='room-actions-convert-channel-to-team' left={() => } showActionIndicator /> diff --git a/e2e/tests/team/03-moveconvert.spec.js b/e2e/tests/team/03-moveconvert.spec.js index 17143c6092..fc2b94d308 100644 --- a/e2e/tests/team/03-moveconvert.spec.js +++ b/e2e/tests/team/03-moveconvert.spec.js @@ -52,7 +52,7 @@ describe('Move/Convert Team', () => { await element(by.id('room-actions-scrollview')).scrollTo('bottom'); await waitFor(element(by.id('room-actions-convert-to-team'))).toExist().withTimeout(2000); await element(by.id('room-actions-convert-to-team')).tap(); - await waitFor(element(by.label('This can\'t be undone. Once you convert a channel to a team, you can not turn it back to a channel.'))).toExist().withTimeout(2000); + await waitFor(element(by.label('You are converting this Channel to a Team. All Members will be kept.'))).toExist().withTimeout(2000); await element(by.text('Convert')).tap(); await waitFor(element(by.id('room-view'))).toExist().withTimeout(20000); await waitFor(element(by.id(`room-view-title-${ toBeConverted }`))).toExist().withTimeout(6000); @@ -85,5 +85,32 @@ describe('Move/Convert Team', () => { await element(by.text('Yes, move it!')).tap(); await waitFor(element(by.id('room-view-header-team-channels'))).toExist().withTimeout(10000); }); + + after(async() => { + await tapBack(); + await waitFor(element(by.id('rooms-list-view'))).toExist().withTimeout(2000); + }) + }) + + describe('Convert Team to Channel and Delete toBeMoved channel within the Converted', () => { + it('should convert a team to a channel', async() => { + await navigateToRoomActions(toBeConverted); + await element(by.id('room-actions-scrollview')).scrollTo('bottom'); + await waitFor(element(by.id('room-actions-convert-channel-to-team'))).toExist().withTimeout(2000); + await element(by.id('room-actions-convert-channel-to-team')).tap(); + await sleep(2000); + await waitFor(element(by.id('select-list-view'))).toExist().withTimeout(2000); + await waitFor(element(by.id(`select-list-view-item-${toBeMoved}`))).toExist().withTimeout(2000); + await element(by.id(`select-list-view-item-${toBeMoved}`)).tap(); + await waitFor(element(by.id('select-list-view-submit'))).toExist().withTimeout(2000); + await element(by.id('select-list-view-submit')).tap(); + await waitFor(element(by.label('You are converting this Team to a Channel'))).toExist().withTimeout(2000); + await element(by.text('Convert')).tap(); + await waitFor(element(by.id('room-view'))).toExist().withTimeout(20000); + await waitFor(element(by.id(`room-view-title-${ toBeConverted }`))).toExist().withTimeout(6000); + await tapBack(); + await waitFor(element(by.id('rooms-list-view'))).toExist().withTimeout(2000); + await waitFor(element(by.id(`rooms-list-view-item-${ toBeMoved }`))).toBeNotVisible().withTimeout(60000); + }) }) }); From 31be26b109cfea936d448128f4bb0ebdaea727ad Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Thu, 1 Jul 2021 17:49:55 -0300 Subject: [PATCH 06/15] [IMPROVE] Add convert team to a channel --- app/i18n/locales/en.json | 3 +- app/i18n/locales/pt-BR.json | 3 +- app/lib/methods/getPermissions.js | 3 +- app/views/RoomActionsView/index.js | 50 +++++++++++++++++++++++++++--- 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index 926b0c6746..fc1c5c89af 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -762,5 +762,6 @@ "Move_to_Team_Warning": "After reading the previous intructions about this behavior, do you still want to move this channel to the selected team?", "Load_More": "Load More", "Load_Newer": "Load Newer", - "Load_Older": "Load Older" + "Load_Older": "Load Older", + "Convert_to_Channel": "Convert to Channel" } \ No newline at end of file diff --git a/app/i18n/locales/pt-BR.json b/app/i18n/locales/pt-BR.json index 9b34d87d3f..e3c7c496a3 100644 --- a/app/i18n/locales/pt-BR.json +++ b/app/i18n/locales/pt-BR.json @@ -665,5 +665,6 @@ "Team_not_found": "Time não encontrado", "Private_Team": "Equipe Privada", "Add_Existing_Channel": "Adicionar Canal Existente", - "invalid-room": "Sala inválida" + "invalid-room": "Sala inválida", + "Convert_to_Channel": "Converter para um Canal" } \ No newline at end of file diff --git a/app/lib/methods/getPermissions.js b/app/lib/methods/getPermissions.js index 6e68f5c333..1c4c56b46b 100644 --- a/app/lib/methods/getPermissions.js +++ b/app/lib/methods/getPermissions.js @@ -47,7 +47,8 @@ const PERMISSIONS = [ 'view-statistics', 'view-user-administration', 'view-all-teams', - 'view-all-team-channels' + 'view-all-team-channels', + 'convert-team' ]; export async function setPermissions() { diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index d16ea57688..a21f4bd84e 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -65,7 +65,8 @@ class RoomActionsView extends React.Component { viewBroadcastMemberListPermission: PropTypes.array, transferLivechatGuestPermission: PropTypes.array, createTeamPermission: PropTypes.array, - addTeamChannelPermission: PropTypes.array + addTeamChannelPermission: PropTypes.array, + convertTeamPermission: PropTypes.array } constructor(props) { @@ -89,7 +90,8 @@ class RoomActionsView extends React.Component { canEdit: false, canToggleEncryption: false, canCreateTeam: false, - canAddChannelToTeam: false + canAddChannelToTeam: false, + canConvertTeam: false }; if (room && room.observe && room.rid) { this.roomObservable = room.observe(); @@ -140,9 +142,10 @@ class RoomActionsView extends React.Component { const canViewMembers = await this.canViewMembers(); const canCreateTeam = await this.canCreateTeam(); const canAddChannelToTeam = await this.canAddChannelToTeam(); + const canConvertTeam = await this.canConvertTeam(); this.setState({ - canAutoTranslate, canAddUser, canInviteUser, canEdit, canToggleEncryption, canViewMembers, canCreateTeam, canAddChannelToTeam + canAutoTranslate, canAddUser, canInviteUser, canEdit, canToggleEncryption, canViewMembers, canCreateTeam, canAddChannelToTeam, canConvertTeam }); // livechat permissions @@ -238,6 +241,16 @@ class RoomActionsView extends React.Component { return canAddChannelToTeam; } + canConvertTeam = async() => { + const { room } = this.state; + const { convertTeamPermission } = this.props; + const { rid } = room; + const permissions = await RocketChat.hasPermission([convertTeamPermission], rid); + + const canConvertTeam = permissions[0]; + return canConvertTeam; + } + canToggleEncryption = async() => { const { room } = this.state; const { toggleRoomE2EEncryptionPermission } = this.props; @@ -799,6 +812,32 @@ class RoomActionsView extends React.Component { ); } + teamToChannelActions = (t, room) => { + const { canEdit, canConvertTeam } = this.state; + const canConvertTeamToChannel = canEdit && canConvertTeam && !!room?.teamMain; + + return ( + <> + {['c', 'p'].includes(t) && canConvertTeamToChannel + ? ( + <> + this.onPressTouchable({ + event: this.convertToTeam + })} + testID='room-actions-convert-to-team' + left={() => } + showActionIndicator + /> + + + ) + : null} + + ); + } + render() { const { room, membersCount, canViewMembers, canAddUser, canInviteUser, joined, canAutoTranslate, canForwardGuest, canReturnQueue @@ -1000,7 +1039,9 @@ class RoomActionsView extends React.Component { ) : null} + { this.teamChannelActions(t, room) } + {this.teamToChannelActions(t, room)} {['l'].includes(t) && !this.isOmnichannelPreview ? ( @@ -1090,7 +1131,8 @@ const mapStateToProps = state => ({ viewBroadcastMemberListPermission: state.permissions['view-broadcast-member-list'], transferLivechatGuestPermission: state.permissions['transfer-livechat-guest'], createTeamPermission: state.permissions['create-team'], - addTeamChannelPermission: state.permissions['add-team-channel'] + addTeamChannelPermission: state.permissions['add-team-channel'], + convertTeamPermission: state.permissions['convert-team'] }); const mapDispatchToProps = dispatch => ({ From d82c68152e7aebf74f643c229c14fa3be9b1e1b5 Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Thu, 1 Jul 2021 18:50:17 -0300 Subject: [PATCH 07/15] Action to SelectListView and new words to i18n --- app/i18n/locales/en.json | 5 +++- app/views/RoomActionsView/index.js | 38 +++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index fc1c5c89af..c59f8e5055 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -763,5 +763,8 @@ "Load_More": "Load More", "Load_Newer": "Load Newer", "Load_Older": "Load Older", - "Convert_to_Channel": "Convert to Channel" + "Convert_to_Channel": "Convert to Channel", + "Converting_Team_To_Channel": "Converting Team to Channel", + "Select_Team_Channels_To_Delete": "Select the Team’s Channels you would like to delete, the ones you do not select will be moved to the Workspace. \n\nNotice that public Channels will be public and visible to everyone.", + "You_are_converting_the_team": "You are converting this Team to a Channel" } \ No newline at end of file diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index a21f4bd84e..3f3243a459 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -444,6 +444,42 @@ class RoomActionsView extends React.Component { }); } + convertTeamToChannel = async() => { + const { room } = this.state; + const { navigation, leaveRoom } = this.props; + + try { + const result = await RocketChat.teamListRoomsOfUser({ teamId: room.teamId, userId: room.u._id }); + + if (result.rooms?.length) { + const teamChannels = result.rooms.map(r => ({ + rid: r._id, + name: r.name, + teamId: r.teamId + })); + navigation.navigate('SelectListView', { + title: 'Converting_Team_To_Channel', + data: teamChannels, + infoText: 'Select_Team_Channels_To_Delete', + nextAction: data => leaveRoom('team', room, data), + showAlert: () => showErrorAlert(I18n.t('Last_owner_team_room'), I18n.t('Cannot_leave')) + }); + } else { + showConfirmationAlert({ + message: I18n.t('You_are_converting_the_team'), + confirmationText: I18n.t('Yes_action_it', { action: I18n.t('Convert') }), + onPress: () => leaveRoom('team', room) + }); + } + } catch (e) { + showConfirmationAlert({ + message: I18n.t('You_are_converting_the_team'), + confirmationText: I18n.t('Yes_action_it', { action: I18n.t('Convert') }), + onPress: () => leaveRoom('team', room) + }); + } + } + leaveTeam = async() => { const { room } = this.state; const { navigation, leaveRoom } = this.props; @@ -824,7 +860,7 @@ class RoomActionsView extends React.Component { this.onPressTouchable({ - event: this.convertToTeam + event: this.convertTeamToChannel })} testID='room-actions-convert-to-team' left={() => } From a23030967dcecb23237235e3aab503cd71a558ff Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Fri, 2 Jul 2021 11:44:16 -0300 Subject: [PATCH 08/15] Implemented the post and it's working with selected channels or not --- app/lib/rocketchat.js | 7 +++++ app/utils/log/events.js | 2 ++ app/views/RoomActionsView/index.js | 43 +++++++++++++++++++++--------- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index dcb3358cb7..520b584355 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -866,6 +866,13 @@ const RocketChat = { }; return this.sdk.post(type === 'c' ? 'channels.convertToTeam' : 'groups.convertToTeam', params); }, + convertTeamToChannel({ teamId, selected }) { + const params = { + teamId, + ...(selected.length && { roomsToRemove: selected }) + }; + return this.sdk.post('teams.convertToChannel', params); + }, joinRoom(roomId, joinCode, type) { // TODO: join code // RC 0.48.0 diff --git a/app/utils/log/events.js b/app/utils/log/events.js index a183735ba4..2ab3f539bc 100644 --- a/app/utils/log/events.js +++ b/app/utils/log/events.js @@ -259,6 +259,8 @@ export default { RA_LEAVE_TEAM_F: 'ra_leave_team_f', RA_CONVERT_TO_TEAM: 'ra_convert_to_team', RA_CONVERT_TO_TEAM_F: 'ra_convert_to_team_f', + RA_CONVERT_TEAM_TO_CHANNEL: 'ra_convert_team_to_channel', + RA_CONVERT_TEAM_TO_CHANNEL_F: 'ra_convert_team_to_channel_f', RA_MOVE_TO_TEAM: 'ra_move_to_team', RA_MOVE_TO_TEAM_F: 'ra_move_to_team_f', RA_SEARCH_TEAM: 'ra_search_team', diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index 3f3243a459..ccb969d1ac 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -446,7 +446,7 @@ class RoomActionsView extends React.Component { convertTeamToChannel = async() => { const { room } = this.state; - const { navigation, leaveRoom } = this.props; + const { navigation } = this.props; try { const result = await RocketChat.teamListRoomsOfUser({ teamId: room.teamId, userId: room.u._id }); @@ -461,25 +461,42 @@ class RoomActionsView extends React.Component { title: 'Converting_Team_To_Channel', data: teamChannels, infoText: 'Select_Team_Channels_To_Delete', - nextAction: data => leaveRoom('team', room, data), - showAlert: () => showErrorAlert(I18n.t('Last_owner_team_room'), I18n.t('Cannot_leave')) + nextAction: data => this.convertTeam(data) }); } else { - showConfirmationAlert({ - message: I18n.t('You_are_converting_the_team'), - confirmationText: I18n.t('Yes_action_it', { action: I18n.t('Convert') }), - onPress: () => leaveRoom('team', room) - }); + this.convertTeam(); } } catch (e) { - showConfirmationAlert({ - message: I18n.t('You_are_converting_the_team'), - confirmationText: I18n.t('Yes_action_it', { action: I18n.t('Convert') }), - onPress: () => leaveRoom('team', room) - }); + this.convertTeam(); + } + } + + handleConvertTeamToChannel = async(selected) => { + logEvent(events.RA_CONVERT_TEAM_TO_CHANNEL); + try { + const { room } = this.state; + const { navigation } = this.props; + + const result = await RocketChat.convertTeamToChannel({ teamId: room.teamId, selected }); + + if (result.success) { + navigation.navigate('RoomView'); + } + } catch (e) { + logEvent(events.RA_CONVERT_TEAM_TO_CHANNEL_F); + log(e); } } + convertTeam = (selected = []) => { + showConfirmationAlert({ + title: I18n.t('Confirmation'), + message: I18n.t('You_are_converting_the_team'), + confirmationText: I18n.t('Convert'), + onPress: () => this.handleConvertTeamToChannel(selected) + }); + } + leaveTeam = async() => { const { room } = this.state; const { navigation, leaveRoom } = this.props; From b3d7e749bc65f03ffe8c2cbd81ccf7c1a97df49f Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Fri, 2 Jul 2021 11:55:17 -0300 Subject: [PATCH 09/15] Fixed the Convert Team Warning at english i18n and changed the function name --- app/i18n/locales/en.json | 2 +- app/views/RoomActionsView/index.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index c59f8e5055..4bdb922558 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -756,7 +756,7 @@ "member-does-not-exist": "Member does not exist", "Convert": "Convert", "Convert_to_Team": "Convert to Team", - "Convert_to_Team_Warning": "This can't be undone. Once you convert a channel to a team, you can not turn it back to a channel.", + "Convert_to_Team_Warning": "You are converting this Channel to a Team. All Members will be kept.", "Move_to_Team": "Move to Team", "Move_Channel_Paragraph": "Moving a channel inside a team means that this channel will be added in the team’s context, however, all channel’s members, which are not members of the respective team, will still have access to this channel, but will not be added as team’s members. \n\nAll channel’s management will still be made by the owners of this channel.\n\nTeam’s members and even team’s owners, if not a member of this channel, can not have access to the channel’s content. \n\nPlease notice that the Team’s owner will be able remove members from the Channel.", "Move_to_Team_Warning": "After reading the previous intructions about this behavior, do you still want to move this channel to the selected team?", diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index ccb969d1ac..69afebd35f 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -461,13 +461,13 @@ class RoomActionsView extends React.Component { title: 'Converting_Team_To_Channel', data: teamChannels, infoText: 'Select_Team_Channels_To_Delete', - nextAction: data => this.convertTeam(data) + nextAction: data => this.convertTeamToChannelConfirmation(data) }); } else { - this.convertTeam(); + this.convertTeamToChannelConfirmation(); } } catch (e) { - this.convertTeam(); + this.convertTeamToChannelConfirmation(); } } @@ -488,7 +488,7 @@ class RoomActionsView extends React.Component { } } - convertTeam = (selected = []) => { + convertTeamToChannelConfirmation = (selected = []) => { showConfirmationAlert({ title: I18n.t('Confirmation'), message: I18n.t('You_are_converting_the_team'), From cde48fdf587876af4ad5852a309a6dffa5da27be Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Fri, 2 Jul 2021 15:06:30 -0300 Subject: [PATCH 10/15] rebase develop into this branch --- app/views/RoomActionsView/index.js | 2 +- e2e/tests/team/03-moveconvert.spec.js | 29 ++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index 69afebd35f..dc76dd0f41 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -879,7 +879,7 @@ class RoomActionsView extends React.Component { onPress={() => this.onPressTouchable({ event: this.convertTeamToChannel })} - testID='room-actions-convert-to-team' + testID='room-actions-convert-channel-to-team' left={() => } showActionIndicator /> diff --git a/e2e/tests/team/03-moveconvert.spec.js b/e2e/tests/team/03-moveconvert.spec.js index 7c071442b0..754aafc09a 100644 --- a/e2e/tests/team/03-moveconvert.spec.js +++ b/e2e/tests/team/03-moveconvert.spec.js @@ -51,7 +51,7 @@ describe('Move/Convert Team', () => { await element(by.id('room-actions-scrollview')).scrollTo('bottom'); await waitFor(element(by.id('room-actions-convert-to-team'))).toExist().withTimeout(2000); await element(by.id('room-actions-convert-to-team')).tap(); - await waitFor(element(by.label('This can\'t be undone. Once you convert a channel to a team, you can not turn it back to a channel.'))).toExist().withTimeout(2000); + await waitFor(element(by.label('You are converting this Channel to a Team. All Members will be kept.'))).toExist().withTimeout(2000); await element(by.text('Convert')).tap(); await waitFor(element(by.id('room-view'))).toExist().withTimeout(20000); await waitFor(element(by.id(`room-view-title-${ toBeConverted }`))).toExist().withTimeout(6000); @@ -84,5 +84,32 @@ describe('Move/Convert Team', () => { await element(by.text('Yes, move it!')).tap(); await waitFor(element(by.id('room-view-header-team-channels'))).toExist().withTimeout(10000); }); + + after(async() => { + await tapBack(); + await waitFor(element(by.id('rooms-list-view'))).toExist().withTimeout(2000); + }); + }); + + describe('Convert Team to Channel and Delete toBeMoved channel within the Converted', () => { + it('should convert a team to a channel', async() => { + await navigateToRoomActions(toBeConverted); + await element(by.id('room-actions-scrollview')).scrollTo('bottom'); + await waitFor(element(by.id('room-actions-convert-channel-to-team'))).toExist().withTimeout(2000); + await element(by.id('room-actions-convert-channel-to-team')).tap(); + await sleep(2000); + await waitFor(element(by.id('select-list-view'))).toExist().withTimeout(2000); + await waitFor(element(by.id(`select-list-view-item-${ toBeMoved }`))).toExist().withTimeout(2000); + await element(by.id(`select-list-view-item-${ toBeMoved }`)).tap(); + await waitFor(element(by.id('select-list-view-submit'))).toExist().withTimeout(2000); + await element(by.id('select-list-view-submit')).tap(); + await waitFor(element(by.label('You are converting this Team to a Channel'))).toExist().withTimeout(2000); + await element(by.text('Convert')).tap(); + await waitFor(element(by.id('room-view'))).toExist().withTimeout(20000); + await waitFor(element(by.id(`room-view-title-${ toBeConverted }`))).toExist().withTimeout(6000); + await tapBack(); + await waitFor(element(by.id('rooms-list-view'))).toExist().withTimeout(2000); + await waitFor(element(by.id(`rooms-list-view-item-${ toBeMoved }`))).toBeNotVisible().withTimeout(60000); + }); }); }); From e1dd1e2dc68732404762bda41eb2ae451105e2f9 Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Thu, 1 Jul 2021 17:49:55 -0300 Subject: [PATCH 11/15] [IMPROVE] Add convert team to a channel --- app/i18n/locales/en.json | 3 +- app/i18n/locales/pt-BR.json | 3 +- app/lib/methods/getPermissions.js | 3 +- app/views/RoomActionsView/index.js | 50 +++++++++++++++++++++++++++--- 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index 723b4dd9e5..85c0ffe188 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -765,5 +765,6 @@ "Load_Older": "Load Older", "Left_The_Room_Successfully": "Left the room successfully", "Deleted_The_Team_Successfully": "Team deleted successfully", - "Deleted_The_Room_Successfully": "Room deleted successfully" + "Deleted_The_Room_Successfully": "Room deleted successfully", + "Convert_to_Channel": "Convert to Channel" } \ No newline at end of file diff --git a/app/i18n/locales/pt-BR.json b/app/i18n/locales/pt-BR.json index a56f169b87..aefd961067 100644 --- a/app/i18n/locales/pt-BR.json +++ b/app/i18n/locales/pt-BR.json @@ -669,5 +669,6 @@ "invalid-room": "Sala inválida", "Left_The_Room_Successfully": "Saiu da sala com sucesso", "Deleted_The_Team_Successfully": "Time deletado com sucesso", - "Deleted_The_Room_Successfully": "Sala deletada com sucesso" + "Deleted_The_Room_Successfully": "Sala deletada com sucesso", + "Convert_to_Channel": "Converter para um Canal" } \ No newline at end of file diff --git a/app/lib/methods/getPermissions.js b/app/lib/methods/getPermissions.js index 6e68f5c333..1c4c56b46b 100644 --- a/app/lib/methods/getPermissions.js +++ b/app/lib/methods/getPermissions.js @@ -47,7 +47,8 @@ const PERMISSIONS = [ 'view-statistics', 'view-user-administration', 'view-all-teams', - 'view-all-team-channels' + 'view-all-team-channels', + 'convert-team' ]; export async function setPermissions() { diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index 75c977a280..22b107ae2b 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -67,7 +67,8 @@ class RoomActionsView extends React.Component { viewBroadcastMemberListPermission: PropTypes.array, transferLivechatGuestPermission: PropTypes.array, createTeamPermission: PropTypes.array, - addTeamChannelPermission: PropTypes.array + addTeamChannelPermission: PropTypes.array, + convertTeamPermission: PropTypes.array } constructor(props) { @@ -91,7 +92,8 @@ class RoomActionsView extends React.Component { canEdit: false, canToggleEncryption: false, canCreateTeam: false, - canAddChannelToTeam: false + canAddChannelToTeam: false, + canConvertTeam: false }; if (room && room.observe && room.rid) { this.roomObservable = room.observe(); @@ -142,9 +144,10 @@ class RoomActionsView extends React.Component { const canViewMembers = await this.canViewMembers(); const canCreateTeam = await this.canCreateTeam(); const canAddChannelToTeam = await this.canAddChannelToTeam(); + const canConvertTeam = await this.canConvertTeam(); this.setState({ - canAutoTranslate, canAddUser, canInviteUser, canEdit, canToggleEncryption, canViewMembers, canCreateTeam, canAddChannelToTeam + canAutoTranslate, canAddUser, canInviteUser, canEdit, canToggleEncryption, canViewMembers, canCreateTeam, canAddChannelToTeam, canConvertTeam }); // livechat permissions @@ -240,6 +243,16 @@ class RoomActionsView extends React.Component { return canAddChannelToTeam; } + canConvertTeam = async() => { + const { room } = this.state; + const { convertTeamPermission } = this.props; + const { rid } = room; + const permissions = await RocketChat.hasPermission([convertTeamPermission], rid); + + const canConvertTeam = permissions[0]; + return canConvertTeam; + } + canToggleEncryption = async() => { const { room } = this.state; const { toggleRoomE2EEncryptionPermission } = this.props; @@ -806,6 +819,32 @@ class RoomActionsView extends React.Component { ); } + teamToChannelActions = (t, room) => { + const { canEdit, canConvertTeam } = this.state; + const canConvertTeamToChannel = canEdit && canConvertTeam && !!room?.teamMain; + + return ( + <> + {['c', 'p'].includes(t) && canConvertTeamToChannel + ? ( + <> + this.onPressTouchable({ + event: this.convertToTeam + })} + testID='room-actions-convert-to-team' + left={() => } + showActionIndicator + /> + + + ) + : null} + + ); + } + render() { const { room, membersCount, canViewMembers, canAddUser, canInviteUser, joined, canAutoTranslate, canForwardGuest, canReturnQueue @@ -1007,7 +1046,9 @@ class RoomActionsView extends React.Component { ) : null} + { this.teamChannelActions(t, room) } + {this.teamToChannelActions(t, room)} {['l'].includes(t) && !this.isOmnichannelPreview ? ( @@ -1099,7 +1140,8 @@ const mapStateToProps = state => ({ viewBroadcastMemberListPermission: state.permissions['view-broadcast-member-list'], transferLivechatGuestPermission: state.permissions['transfer-livechat-guest'], createTeamPermission: state.permissions['create-team'], - addTeamChannelPermission: state.permissions['add-team-channel'] + addTeamChannelPermission: state.permissions['add-team-channel'], + convertTeamPermission: state.permissions['convert-team'] }); const mapDispatchToProps = dispatch => ({ From b073c0672c091a80e133816cd6c897645e7ece5f Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Thu, 1 Jul 2021 18:50:17 -0300 Subject: [PATCH 12/15] Action to SelectListView and new words to i18n --- app/i18n/locales/en.json | 5 +++- app/views/RoomActionsView/index.js | 38 +++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index 85c0ffe188..0b4cd8236c 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -766,5 +766,8 @@ "Left_The_Room_Successfully": "Left the room successfully", "Deleted_The_Team_Successfully": "Team deleted successfully", "Deleted_The_Room_Successfully": "Room deleted successfully", - "Convert_to_Channel": "Convert to Channel" + "Convert_to_Channel": "Convert to Channel", + "Converting_Team_To_Channel": "Converting Team to Channel", + "Select_Team_Channels_To_Delete": "Select the Team’s Channels you would like to delete, the ones you do not select will be moved to the Workspace. \n\nNotice that public Channels will be public and visible to everyone.", + "You_are_converting_the_team": "You are converting this Team to a Channel" } \ No newline at end of file diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index 22b107ae2b..f816779982 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -446,6 +446,42 @@ class RoomActionsView extends React.Component { }); } + convertTeamToChannel = async() => { + const { room } = this.state; + const { navigation, leaveRoom } = this.props; + + try { + const result = await RocketChat.teamListRoomsOfUser({ teamId: room.teamId, userId: room.u._id }); + + if (result.rooms?.length) { + const teamChannels = result.rooms.map(r => ({ + rid: r._id, + name: r.name, + teamId: r.teamId + })); + navigation.navigate('SelectListView', { + title: 'Converting_Team_To_Channel', + data: teamChannels, + infoText: 'Select_Team_Channels_To_Delete', + nextAction: data => leaveRoom('team', room, data), + showAlert: () => showErrorAlert(I18n.t('Last_owner_team_room'), I18n.t('Cannot_leave')) + }); + } else { + showConfirmationAlert({ + message: I18n.t('You_are_converting_the_team'), + confirmationText: I18n.t('Yes_action_it', { action: I18n.t('Convert') }), + onPress: () => leaveRoom('team', room) + }); + } + } catch (e) { + showConfirmationAlert({ + message: I18n.t('You_are_converting_the_team'), + confirmationText: I18n.t('Yes_action_it', { action: I18n.t('Convert') }), + onPress: () => leaveRoom('team', room) + }); + } + } + leaveTeam = async() => { const { room } = this.state; const { navigation, leaveRoom } = this.props; @@ -831,7 +867,7 @@ class RoomActionsView extends React.Component { this.onPressTouchable({ - event: this.convertToTeam + event: this.convertTeamToChannel })} testID='room-actions-convert-to-team' left={() => } From 6fb98e713876ac556380d0e7649c15a99277b6a0 Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Fri, 2 Jul 2021 11:44:16 -0300 Subject: [PATCH 13/15] Implemented the post and it's working with selected channels or not --- app/lib/rocketchat.js | 7 +++++ app/utils/log/events.js | 2 ++ app/views/RoomActionsView/index.js | 43 +++++++++++++++++++++--------- 3 files changed, 39 insertions(+), 13 deletions(-) diff --git a/app/lib/rocketchat.js b/app/lib/rocketchat.js index 5b69b92ba4..59ee94fc51 100644 --- a/app/lib/rocketchat.js +++ b/app/lib/rocketchat.js @@ -866,6 +866,13 @@ const RocketChat = { }; return this.sdk.post(type === 'c' ? 'channels.convertToTeam' : 'groups.convertToTeam', params); }, + convertTeamToChannel({ teamId, selected }) { + const params = { + teamId, + ...(selected.length && { roomsToRemove: selected }) + }; + return this.sdk.post('teams.convertToChannel', params); + }, joinRoom(roomId, joinCode, type) { // TODO: join code // RC 0.48.0 diff --git a/app/utils/log/events.js b/app/utils/log/events.js index a183735ba4..2ab3f539bc 100644 --- a/app/utils/log/events.js +++ b/app/utils/log/events.js @@ -259,6 +259,8 @@ export default { RA_LEAVE_TEAM_F: 'ra_leave_team_f', RA_CONVERT_TO_TEAM: 'ra_convert_to_team', RA_CONVERT_TO_TEAM_F: 'ra_convert_to_team_f', + RA_CONVERT_TEAM_TO_CHANNEL: 'ra_convert_team_to_channel', + RA_CONVERT_TEAM_TO_CHANNEL_F: 'ra_convert_team_to_channel_f', RA_MOVE_TO_TEAM: 'ra_move_to_team', RA_MOVE_TO_TEAM_F: 'ra_move_to_team_f', RA_SEARCH_TEAM: 'ra_search_team', diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index f816779982..c7465ebc24 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -448,7 +448,7 @@ class RoomActionsView extends React.Component { convertTeamToChannel = async() => { const { room } = this.state; - const { navigation, leaveRoom } = this.props; + const { navigation } = this.props; try { const result = await RocketChat.teamListRoomsOfUser({ teamId: room.teamId, userId: room.u._id }); @@ -463,25 +463,42 @@ class RoomActionsView extends React.Component { title: 'Converting_Team_To_Channel', data: teamChannels, infoText: 'Select_Team_Channels_To_Delete', - nextAction: data => leaveRoom('team', room, data), - showAlert: () => showErrorAlert(I18n.t('Last_owner_team_room'), I18n.t('Cannot_leave')) + nextAction: data => this.convertTeam(data) }); } else { - showConfirmationAlert({ - message: I18n.t('You_are_converting_the_team'), - confirmationText: I18n.t('Yes_action_it', { action: I18n.t('Convert') }), - onPress: () => leaveRoom('team', room) - }); + this.convertTeam(); } } catch (e) { - showConfirmationAlert({ - message: I18n.t('You_are_converting_the_team'), - confirmationText: I18n.t('Yes_action_it', { action: I18n.t('Convert') }), - onPress: () => leaveRoom('team', room) - }); + this.convertTeam(); + } + } + + handleConvertTeamToChannel = async(selected) => { + logEvent(events.RA_CONVERT_TEAM_TO_CHANNEL); + try { + const { room } = this.state; + const { navigation } = this.props; + + const result = await RocketChat.convertTeamToChannel({ teamId: room.teamId, selected }); + + if (result.success) { + navigation.navigate('RoomView'); + } + } catch (e) { + logEvent(events.RA_CONVERT_TEAM_TO_CHANNEL_F); + log(e); } } + convertTeam = (selected = []) => { + showConfirmationAlert({ + title: I18n.t('Confirmation'), + message: I18n.t('You_are_converting_the_team'), + confirmationText: I18n.t('Convert'), + onPress: () => this.handleConvertTeamToChannel(selected) + }); + } + leaveTeam = async() => { const { room } = this.state; const { navigation, leaveRoom } = this.props; From 87263427b220843fa6fc8a24b949640230828a93 Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Fri, 2 Jul 2021 11:55:17 -0300 Subject: [PATCH 14/15] Fixed the Convert Team Warning at english i18n and changed the function name --- app/i18n/locales/en.json | 2 +- app/views/RoomActionsView/index.js | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/i18n/locales/en.json b/app/i18n/locales/en.json index 0b4cd8236c..426aaa77a8 100644 --- a/app/i18n/locales/en.json +++ b/app/i18n/locales/en.json @@ -756,7 +756,7 @@ "member-does-not-exist": "Member does not exist", "Convert": "Convert", "Convert_to_Team": "Convert to Team", - "Convert_to_Team_Warning": "This can't be undone. Once you convert a channel to a team, you can not turn it back to a channel.", + "Convert_to_Team_Warning": "You are converting this Channel to a Team. All Members will be kept.", "Move_to_Team": "Move to Team", "Move_Channel_Paragraph": "Moving a channel inside a team means that this channel will be added in the team’s context, however, all channel’s members, which are not members of the respective team, will still have access to this channel, but will not be added as team’s members. \n\nAll channel’s management will still be made by the owners of this channel.\n\nTeam’s members and even team’s owners, if not a member of this channel, can not have access to the channel’s content. \n\nPlease notice that the Team’s owner will be able remove members from the Channel.", "Move_to_Team_Warning": "After reading the previous intructions about this behavior, do you still want to move this channel to the selected team?", diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index c7465ebc24..2727ea5449 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -463,13 +463,13 @@ class RoomActionsView extends React.Component { title: 'Converting_Team_To_Channel', data: teamChannels, infoText: 'Select_Team_Channels_To_Delete', - nextAction: data => this.convertTeam(data) + nextAction: data => this.convertTeamToChannelConfirmation(data) }); } else { - this.convertTeam(); + this.convertTeamToChannelConfirmation(); } } catch (e) { - this.convertTeam(); + this.convertTeamToChannelConfirmation(); } } @@ -490,7 +490,7 @@ class RoomActionsView extends React.Component { } } - convertTeam = (selected = []) => { + convertTeamToChannelConfirmation = (selected = []) => { showConfirmationAlert({ title: I18n.t('Confirmation'), message: I18n.t('You_are_converting_the_team'), From c0ec2aae7527abf3266a7b4aaaa78f837f9ec0b8 Mon Sep 17 00:00:00 2001 From: Reinaldo Neto Date: Fri, 2 Jul 2021 15:06:30 -0300 Subject: [PATCH 15/15] rebase develop into this branch --- app/views/RoomActionsView/index.js | 2 +- e2e/tests/team/03-moveconvert.spec.js | 29 ++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/app/views/RoomActionsView/index.js b/app/views/RoomActionsView/index.js index 2727ea5449..914a42913f 100644 --- a/app/views/RoomActionsView/index.js +++ b/app/views/RoomActionsView/index.js @@ -886,7 +886,7 @@ class RoomActionsView extends React.Component { onPress={() => this.onPressTouchable({ event: this.convertTeamToChannel })} - testID='room-actions-convert-to-team' + testID='room-actions-convert-channel-to-team' left={() => } showActionIndicator /> diff --git a/e2e/tests/team/03-moveconvert.spec.js b/e2e/tests/team/03-moveconvert.spec.js index 7c071442b0..754aafc09a 100644 --- a/e2e/tests/team/03-moveconvert.spec.js +++ b/e2e/tests/team/03-moveconvert.spec.js @@ -51,7 +51,7 @@ describe('Move/Convert Team', () => { await element(by.id('room-actions-scrollview')).scrollTo('bottom'); await waitFor(element(by.id('room-actions-convert-to-team'))).toExist().withTimeout(2000); await element(by.id('room-actions-convert-to-team')).tap(); - await waitFor(element(by.label('This can\'t be undone. Once you convert a channel to a team, you can not turn it back to a channel.'))).toExist().withTimeout(2000); + await waitFor(element(by.label('You are converting this Channel to a Team. All Members will be kept.'))).toExist().withTimeout(2000); await element(by.text('Convert')).tap(); await waitFor(element(by.id('room-view'))).toExist().withTimeout(20000); await waitFor(element(by.id(`room-view-title-${ toBeConverted }`))).toExist().withTimeout(6000); @@ -84,5 +84,32 @@ describe('Move/Convert Team', () => { await element(by.text('Yes, move it!')).tap(); await waitFor(element(by.id('room-view-header-team-channels'))).toExist().withTimeout(10000); }); + + after(async() => { + await tapBack(); + await waitFor(element(by.id('rooms-list-view'))).toExist().withTimeout(2000); + }); + }); + + describe('Convert Team to Channel and Delete toBeMoved channel within the Converted', () => { + it('should convert a team to a channel', async() => { + await navigateToRoomActions(toBeConverted); + await element(by.id('room-actions-scrollview')).scrollTo('bottom'); + await waitFor(element(by.id('room-actions-convert-channel-to-team'))).toExist().withTimeout(2000); + await element(by.id('room-actions-convert-channel-to-team')).tap(); + await sleep(2000); + await waitFor(element(by.id('select-list-view'))).toExist().withTimeout(2000); + await waitFor(element(by.id(`select-list-view-item-${ toBeMoved }`))).toExist().withTimeout(2000); + await element(by.id(`select-list-view-item-${ toBeMoved }`)).tap(); + await waitFor(element(by.id('select-list-view-submit'))).toExist().withTimeout(2000); + await element(by.id('select-list-view-submit')).tap(); + await waitFor(element(by.label('You are converting this Team to a Channel'))).toExist().withTimeout(2000); + await element(by.text('Convert')).tap(); + await waitFor(element(by.id('room-view'))).toExist().withTimeout(20000); + await waitFor(element(by.id(`room-view-title-${ toBeConverted }`))).toExist().withTimeout(6000); + await tapBack(); + await waitFor(element(by.id('rooms-list-view'))).toExist().withTimeout(2000); + await waitFor(element(by.id(`rooms-list-view-item-${ toBeMoved }`))).toBeNotVisible().withTimeout(60000); + }); }); });