diff --git a/app/lib/methods/getPermissions.ts b/app/lib/methods/getPermissions.ts index f79de0121d..7bbd870950 100644 --- a/app/lib/methods/getPermissions.ts +++ b/app/lib/methods/getPermissions.ts @@ -61,7 +61,12 @@ export const SUPPORTED_PERMISSIONS = [ 'mobile-upload-file', 'delete-own-message', 'call-management', - 'test-push-notifications' + 'test-push-notifications', + 'move-room-to-team', + 'create-team-channel', + 'create-team-group', + 'delete-team-channel', + 'delete-team-group' ] as const; export async function setPermissions(): Promise { diff --git a/app/stacks/types.ts b/app/stacks/types.ts index 27fbdba913..c3c9142216 100644 --- a/app/stacks/types.ts +++ b/app/stacks/types.ts @@ -148,6 +148,8 @@ export type ChatsStackParamList = { }; AddChannelTeamView: { teamId: string; + rid: string; + t: 'c' | 'p'; }; AddExistingChannelView: { teamId: string; diff --git a/app/views/AddChannelTeamView.tsx b/app/views/AddChannelTeamView.tsx index c21c50778d..64f2f14fef 100644 --- a/app/views/AddChannelTeamView.tsx +++ b/app/views/AddChannelTeamView.tsx @@ -10,6 +10,9 @@ import SafeAreaView from '../containers/SafeAreaView'; import I18n from '../i18n'; import { ChatsStackParamList, DrawerParamList, NewMessageStackParamList } from '../stacks/types'; import { IApplicationState } from '../definitions'; +import { usePermissions } from '../lib/hooks'; +import { compareServerVersion } from '../lib/methods/helpers'; +import { TSupportedPermissions } from '../reducers/permissions'; type TRoute = RouteProp; @@ -18,13 +21,40 @@ type TNavigation = CompositeNavigationProp< CompositeNavigationProp, NativeStackNavigationProp> >; +const useCreateNewPermission = (rid: string, t: 'c' | 'p') => { + const permissions: TSupportedPermissions[] = t === 'c' ? ['create-c'] : ['create-p']; + + const serverVersion = useSelector((state: IApplicationState) => state.server.version); + if (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '7.0.0')) { + permissions.push(t === 'c' ? 'create-team-channel' : 'create-team-group'); + } + + const result = usePermissions(permissions, rid); + return result.some(Boolean); +}; + +const useAddExistingPermission = (rid: string) => { + let permissions: TSupportedPermissions[] = ['add-team-channel']; + + const serverVersion = useSelector((state: IApplicationState) => state.server.version); + if (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '7.0.0')) { + permissions = ['move-room-to-team']; + } + + const result = usePermissions(permissions, rid); + return result[0]; +}; + const AddChannelTeamView = () => { const navigation = useNavigation(); const isMasterDetail = useSelector((state: IApplicationState) => state.app.isMasterDetail); const { - params: { teamId } + params: { teamId, rid, t } } = useRoute(); + const canCreateNew = useCreateNewPermission(rid, t); + const canAddExisting = useAddExistingPermission(rid); + useLayoutEffect(() => { navigation.setOptions({ title: I18n.t('Add_Channel_to_Team') }); }, [navigation]); @@ -34,31 +64,39 @@ const AddChannelTeamView = () => { - - isMasterDetail - ? navigation.navigate('SelectedUsersViewCreateChannel', { - nextAction: () => navigation.navigate('CreateChannelView', { teamId }) - }) - : navigation.navigate('SelectedUsersView', { - nextAction: () => - navigation.navigate('ChatsStackNavigator', { screen: 'CreateChannelView', params: { teamId } }) - }) - } - testID='add-channel-team-view-create-channel' - left={() => } - right={() => } - /> - - navigation.navigate('AddExistingChannelView', { teamId })} - testID='add-channel-team-view-add-existing' - left={() => } - right={() => } - /> - + {canCreateNew ? ( + <> + + isMasterDetail + ? navigation.navigate('SelectedUsersViewCreateChannel', { + nextAction: () => navigation.navigate('CreateChannelView', { teamId }) + }) + : navigation.navigate('SelectedUsersView', { + nextAction: () => + navigation.navigate('ChatsStackNavigator', { screen: 'CreateChannelView', params: { teamId } }) + }) + } + testID='add-channel-team-view-create-channel' + left={() => } + right={() => } + /> + + + ) : null} + {canAddExisting ? ( + <> + navigation.navigate('AddExistingChannelView', { teamId })} + testID='add-channel-team-view-add-existing' + left={() => } + right={() => } + /> + + + ) : null} ); diff --git a/app/views/AddExistingChannelView/index.tsx b/app/views/AddExistingChannelView/index.tsx index 09367a9b08..f04d0d2407 100644 --- a/app/views/AddExistingChannelView/index.tsx +++ b/app/views/AddExistingChannelView/index.tsx @@ -18,7 +18,7 @@ import { animateNextTransition } from '../../lib/methods/helpers/layoutAnimation import { showErrorAlert } from '../../lib/methods/helpers/info'; import { ChatsStackParamList } from '../../stacks/types'; import { TSubscriptionModel, SubscriptionType } from '../../definitions'; -import { getRoomTitle, hasPermission, useDebounce } from '../../lib/methods/helpers'; +import { compareServerVersion, getRoomTitle, hasPermission, useDebounce } from '../../lib/methods/helpers'; import { Services } from '../../lib/services'; import { useAppSelector } from '../../lib/hooks'; @@ -38,9 +38,11 @@ const AddExistingChannelView = () => { params: { teamId } } = useRoute(); - const { addTeamChannelPermission, isMasterDetail } = useAppSelector(state => ({ + const { serverVersion, addTeamChannelPermission, isMasterDetail, moveRoomToTeamPermission } = useAppSelector(state => ({ + serverVersion: state.server.version, isMasterDetail: state.app.isMasterDetail, - addTeamChannelPermission: state.permissions['add-team-channel'] + addTeamChannelPermission: state.permissions['add-team-channel'], + moveRoomToTeamPermission: state.permissions['move-room-to-team'] })); useLayoutEffect(() => { @@ -70,6 +72,15 @@ const AddExistingChannelView = () => { navigation.setOptions(options); }; + const hasCreatePermission = async (id: string) => { + if (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '7.0.0')) { + const result = await hasPermission([moveRoomToTeamPermission], id); + return result[0]; + } + const result = await hasPermission([addTeamChannelPermission], id); + return result[0]; + }; + const query = async (stringToSearch = '') => { try { const db = database.active; @@ -90,11 +101,8 @@ const AddExistingChannelView = () => { if (channel.prid) { return false; } - const permissions = await hasPermission([addTeamChannelPermission], channel.rid); - if (!permissions[0]) { - return false; - } - return true; + const result = await hasCreatePermission(channel.rid); + return result; }) ); diff --git a/app/views/RoomActionsView/index.tsx b/app/views/RoomActionsView/index.tsx index 80806de3fc..1f4fc76d0c 100644 --- a/app/views/RoomActionsView/index.tsx +++ b/app/views/RoomActionsView/index.tsx @@ -75,6 +75,7 @@ interface IRoomActionsViewProps extends IActionSheetProvider, IBaseScreen { - const { room } = this.state; - const { addTeamChannelPermission } = this.props; - const { rid } = room; - const permissions = await hasPermission([addTeamChannelPermission], rid); - - const canAddChannelToTeam = permissions[0]; - return canAddChannelToTeam; + hasMoveToTeamPermission = async (rid: string) => { + const { addTeamChannelPermission, moveRoomToTeamPermission, serverVersion } = this.props; + if (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '7.0.0')) { + const result = await hasPermission([moveRoomToTeamPermission], rid); + return result[0]; + } + const result = await hasPermission([addTeamChannelPermission], rid); + return result[0]; }; canConvertTeam = async () => { @@ -693,7 +694,6 @@ class RoomActionsView extends React.Component { logEvent(events.RA_SEARCH_TEAM); try { - const { addTeamChannelPermission, createTeamPermission } = this.props; const QUERY_SIZE = 50; const db = database.active; const teams = await db @@ -709,11 +709,8 @@ class RoomActionsView extends React.Component { const results = await Promise.all( teamArray.map(async team => { - const permissions = await hasPermission([addTeamChannelPermission, createTeamPermission], team.rid); - if (!permissions[0]) { - return false; - } - return true; + const result = await this.hasMoveToTeamPermission(team.rid); + return result; }) ); @@ -1290,6 +1287,7 @@ const mapStateToProps = (state: IApplicationState) => ({ viewBroadcastMemberListPermission: state.permissions['view-broadcast-member-list'], createTeamPermission: state.permissions['create-team'], addTeamChannelPermission: state.permissions['add-team-channel'], + moveRoomToTeamPermission: state.permissions['move-room-to-team'], convertTeamPermission: state.permissions['convert-team'], viewCannedResponsesPermission: state.permissions['view-canned-responses'], livechatAllowManualOnHold: state.settings.Livechat_allow_manual_on_hold as boolean, diff --git a/app/views/TeamChannelsView.tsx b/app/views/TeamChannelsView.tsx index ef9c81b1ec..bbaa25a2cd 100644 --- a/app/views/TeamChannelsView.tsx +++ b/app/views/TeamChannelsView.tsx @@ -21,13 +21,12 @@ import I18n from '../i18n'; import database from '../lib/database'; import { CustomIcon } from '../containers/CustomIcon'; import RoomItem, { ROW_HEIGHT } from '../containers/RoomItem'; -import { getUserSelector } from '../selectors/login'; import { ChatsStackParamList } from '../stacks/types'; import { withTheme } from '../theme'; import { goRoom } from '../lib/methods/helpers/goRoom'; import { showErrorAlert } from '../lib/methods/helpers/info'; import log, { events, logEvent } from '../lib/methods/helpers/log'; -import { getRoomAvatar, getRoomTitle, hasPermission, debounce, isIOS } from '../lib/methods/helpers'; +import { getRoomAvatar, getRoomTitle, hasPermission, debounce, isIOS, compareServerVersion } from '../lib/methods/helpers'; import { Services } from '../lib/services'; const API_FETCH_COUNT = 25; @@ -71,14 +70,22 @@ interface ITeamChannelsViewState { } interface ITeamChannelsViewProps extends IBaseScreen { + serverVersion: string; useRealName: boolean; width: number; StoreLastMessage: boolean; addTeamChannelPermission: string[]; + moveRoomToTeamPermission: string[]; editTeamChannelPermission: string[]; removeTeamChannelPermission: string[]; + createCPermission: string[]; + createTeamChannelPermission: string[]; + createPPermission: string[]; + createTeamGroupPermission: string[]; deleteCPermission: string[]; deletePPermission: string[]; + deleteTeamChannelPermission: string[]; + deleteTeamGroupPermission: string[]; showActionSheet: (options: TActionSheetOptions) => void; showAvatar: boolean; displayMode: DisplayMode; @@ -113,8 +120,28 @@ class TeamChannelsView extends React.Component { + const { + addTeamChannelPermission, + moveRoomToTeamPermission, + serverVersion, + createCPermission, + createPPermission, + createTeamChannelPermission, + createTeamGroupPermission + } = this.props; + if (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '7.0.0')) { + const createPermissions = + this.team.t === 'c' ? [createCPermission, createTeamChannelPermission] : [createPPermission, createTeamGroupPermission]; + const result = await hasPermission([moveRoomToTeamPermission, ...createPermissions], this.team.rid); + return result.some(Boolean); + } + const createPermissions = this.team.t === 'c' ? [createCPermission] : [createPPermission]; + const result = await hasPermission([addTeamChannelPermission, ...createPermissions], this.team.rid); + return result.some(Boolean); + }; + loadTeam = async () => { - const { addTeamChannelPermission } = this.props; const { loading, data } = this.state; const db = database.active; @@ -128,8 +155,8 @@ class TeamChannelsView extends React.Component this.setHeader()); } @@ -219,7 +246,9 @@ class TeamChannelsView extends React.Component navigation.navigate('AddChannelTeamView', { teamId: this.teamId })} + onPress={() => + navigation.navigate('AddChannelTeamView', { teamId: this.teamId, rid: this.team.rid, t: this.team.t as any }) + } /> ) : null} @@ -405,6 +434,20 @@ class TeamChannelsView extends React.Component { + const { serverVersion, deleteCPermission, deletePPermission, deleteTeamChannelPermission, deleteTeamGroupPermission } = + this.props; + if (compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '7.0.0')) { + const permissions = + t === 'c' ? [deleteTeamChannelPermission, deleteTeamGroupPermission] : [deletePPermission, deletePPermission]; + const result = await hasPermission(permissions, rid); + return result[0] && result[1]; + } + + const result = await hasPermission([t === 'c' ? deleteCPermission : deletePPermission], rid); + return result[0]; + }; + showChannelActions = async (item: IItem) => { logEvent(events.ROOM_SHOW_BOX_ACTIONS); const { @@ -535,16 +578,21 @@ class TeamChannelsView extends React.Component ({ - baseUrl: state.server.server, - user: getUserSelector(state), + serverVersion: state.server.version, useRealName: state.settings.UI_Use_Real_Name, isMasterDetail: state.app.isMasterDetail, StoreLastMessage: state.settings.Store_Last_Message, addTeamChannelPermission: state.permissions['add-team-channel'], + moveRoomToTeamPermission: state.permissions['move-room-to-team'], editTeamChannelPermission: state.permissions['edit-team-channel'], removeTeamChannelPermission: state.permissions['remove-team-channel'], - deleteCPermission: state.permissions['delete-c'], + createCPermission: state.permissions['create-c'], + createTeamChannelPermission: state.permissions['create-team-channel'], + createPPermission: state.permissions['create-p'], + createTeamGroupPermission: state.permissions['create-team-group'], + deleteTeamChannelPermission: state.permissions['delete-team-channel'], deletePPermission: state.permissions['delete-p'], + deleteTeamGroupPermission: state.permissions['delete-team-group'], showAvatar: state.sortPreferences.showAvatar, displayMode: state.sortPreferences.displayMode });