diff --git a/src/libs/Navigation/AppNavigator/MainDrawerNavigator.js b/src/libs/Navigation/AppNavigator/MainDrawerNavigator.js index 5201453768c9..3f966d71e6bb 100644 --- a/src/libs/Navigation/AppNavigator/MainDrawerNavigator.js +++ b/src/libs/Navigation/AppNavigator/MainDrawerNavigator.js @@ -13,6 +13,8 @@ import ReportScreen from '../../../pages/home/ReportScreen'; import SidebarScreen from '../../../pages/home/sidebar/SidebarScreen'; import BaseDrawerNavigator from './BaseDrawerNavigator'; import * as ReportUtils from '../../ReportUtils'; +import * as PolicyUtils from '../../PolicyUtils'; +import CONST from '../../../CONST'; const propTypes = { /** Available reports that would be displayed in this navigator */ @@ -22,6 +24,15 @@ const propTypes = { /** Beta features list */ betas: PropTypes.arrayOf(PropTypes.string), + + /** The policies which the user has access to */ + policies: PropTypes.objectOf(PropTypes.shape({ + /** The policy name */ + name: PropTypes.string, + + /** The type of the policy */ + type: PropTypes.string, + })).isRequired, }; const defaultProps = { @@ -33,11 +44,11 @@ const defaultProps = { * Get the most recently accessed report for the user * * @param {Object} reports - * @param {Boolean} [ignoreDefaultRooms] + * @param {String[]} [reportTypesToIgnore] * @returns {Object} */ -const getInitialReportScreenParams = (reports, ignoreDefaultRooms) => { - const last = ReportUtils.findLastAccessedReport(reports, ignoreDefaultRooms); +const getInitialReportScreenParams = (reports, reportTypesToIgnore) => { + const last = ReportUtils.findLastAccessedReport(reports, reportTypesToIgnore); // Fallback to empty if for some reason reportID cannot be derived - prevents the app from crashing const reportID = lodashGet(last, 'reportID', ''); @@ -45,7 +56,20 @@ const getInitialReportScreenParams = (reports, ignoreDefaultRooms) => { }; const MainDrawerNavigator = (props) => { - const initialParams = getInitialReportScreenParams(props.reports, !Permissions.canUseDefaultRooms(props.betas)); + // If one is a member of a free policy, then they are allowed to see the Policy default rooms. + // For everyone else, one must be on the beta to see a default room. + let reportTypesToIgnore = []; + const isMemberOfFreePolicy = PolicyUtils.isMemberOfFreePolicy(props.policies); + if (isMemberOfFreePolicy && !Permissions.canUseDefaultRooms(props.betas)) { + reportTypesToIgnore = [CONST.REPORT.CHAT_TYPE.DOMAIN_ALL]; + } else if (!Permissions.canUseDefaultRooms(props.betas)) { + reportTypesToIgnore = [ + CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, + CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, + CONST.REPORT.CHAT_TYPE.DOMAIN_ALL, + ]; + } + const initialParams = getInitialReportScreenParams(props.reports, reportTypesToIgnore); // Wait until reports are fetched and there is a reportID in initialParams if (!initialParams.reportID) { @@ -81,5 +105,8 @@ export default withOnyx({ betas: { key: ONYXKEYS.BETAS, }, + policies: { + key: ONYXKEYS.COLLECTION.POLICY, + }, })(MainDrawerNavigator); export {getInitialReportScreenParams}; diff --git a/src/libs/OptionsListUtils.js b/src/libs/OptionsListUtils.js index 2151679dcd83..1c14871ba006 100644 --- a/src/libs/OptionsListUtils.js +++ b/src/libs/OptionsListUtils.js @@ -10,6 +10,7 @@ import * as ReportUtils from './ReportUtils'; import * as Localize from './Localize'; import Permissions from './Permissions'; import * as CollectionUtils from './CollectionUtils'; +import * as PolicyUtils from './PolicyUtils'; /** * OptionsListUtils is used to build a list options passed to the OptionsList component. Several different UI views can @@ -439,7 +440,14 @@ function getOptions(reports, personalDetails, activeReportID, { return; } - if (ReportUtils.isDefaultRoom(report) && !Permissions.canUseDefaultRooms(betas)) { + // If one is a member of a free policy, then they are allowed to see the Policy default rooms. + // For everyone else, one must be on the beta to see a default room. + const isMemberOfFreePolicy = PolicyUtils.isMemberOfFreePolicy(policies); + if (isMemberOfFreePolicy && !Permissions.canUseDefaultRooms(betas)) { + if (ReportUtils.isDomainRoom(report)) { + return; + } + } else if (ReportUtils.isDefaultRoom(report) && !Permissions.canUseDefaultRooms(betas)) { return; } diff --git a/src/libs/PolicyUtils.js b/src/libs/PolicyUtils.js new file mode 100644 index 000000000000..d225fd1982b7 --- /dev/null +++ b/src/libs/PolicyUtils.js @@ -0,0 +1,30 @@ +import _ from 'underscore'; +import CONST from '../CONST'; + +/** + * Is the user an admin of a free policy (aka workspace)? + * + * @param {Array} policies + * @returns {Boolean} + */ +function isAdminOfFreePolicy(policies) { + return _.some(policies, policy => policy + && policy.type === CONST.POLICY.TYPE.FREE + && policy.role === CONST.POLICY.ROLE.ADMIN); +} + +/** + * Is the user a member of a free policy (aka workspace)? + * + * @param {Array} policies + * @returns {Boolean} + */ +function isMemberOfFreePolicy(policies) { + return _.some(policies, policy => policy + && policy.type === CONST.POLICY.TYPE.FREE); +} + +export { + isAdminOfFreePolicy, + isMemberOfFreePolicy, +}; diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js index 0a47f9693fe3..1547c358b497 100644 --- a/src/libs/ReportUtils.js +++ b/src/libs/ReportUtils.js @@ -171,14 +171,14 @@ function isChatRoom(report) { * Given a collection of reports returns the most recently accessed one * * @param {Record|Array<{lastVisitedTimestamp, reportID}>} reports - * @param {Boolean} [ignoreDefaultRooms] + * @param {String[]} [reportTypesToIgnore] * @returns {Object} */ -function findLastAccessedReport(reports, ignoreDefaultRooms) { +function findLastAccessedReport(reports, reportTypesToIgnore) { let sortedReports = sortReportsByLastVisited(reports); - if (ignoreDefaultRooms) { - sortedReports = _.filter(sortedReports, report => !isDefaultRoom(report)); + if (reportTypesToIgnore) { + sortedReports = _.filter(sortedReports, report => !_.contains(reportTypesToIgnore, lodashGet(report, ['chatType'], ''))); } return _.last(sortedReports); @@ -512,6 +512,7 @@ export { isDefaultRoom, isAdminRoom, isAnnounceRoom, + isDomainRoom, isUserCreatedPolicyRoom, isChatRoom, getChatRoomSubtitle, diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index aa037a5cf692..ab522704268a 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -267,18 +267,6 @@ function loadFullPolicy(policyID) { }); } -/** - * Is the user an admin of a free policy (aka workspace)? - * - * @param {Array} policies - * @returns {Boolean} - */ -function isAdminOfFreePolicy(policies) { - return _.some(policies, policy => policy - && policy.type === CONST.POLICY.TYPE.FREE - && policy.role === CONST.POLICY.ROLE.ADMIN); -} - /** * Remove the passed members from the policy employeeList * @@ -550,7 +538,6 @@ export { loadFullPolicy, removeMembers, invite, - isAdminOfFreePolicy, create, uploadAvatar, update, diff --git a/src/libs/actions/Welcome.js b/src/libs/actions/Welcome.js index 41c559093941..0d2eeadff248 100644 --- a/src/libs/actions/Welcome.js +++ b/src/libs/actions/Welcome.js @@ -4,11 +4,11 @@ import lodashGet from 'lodash/get'; import Navigation from '../Navigation/Navigation'; import * as ReportUtils from '../ReportUtils'; import ROUTES from '../../ROUTES'; -import * as Policy from './Policy'; import ONYXKEYS from '../../ONYXKEYS'; import NameValuePair from './NameValuePair'; import CONST from '../../CONST'; import SCREENS from '../../SCREENS'; +import * as PolicyUtils from '../PolicyUtils'; let resolveIsReadyPromise; let isReadyPromise = new Promise((resolve) => { @@ -130,7 +130,7 @@ function show({routes, showCreateMenu}) { // If user is not already an admin of a free policy and we are not navigating them to their workspace or creating a new workspace via workspace/new then // we will show the create menu. - if (!Policy.isAdminOfFreePolicy(allPolicies) && !isDisplayingWorkspaceRoute) { + if (!PolicyUtils.isAdminOfFreePolicy(allPolicies) && !isDisplayingWorkspaceRoute) { showCreateMenu(); } }); diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 5d32a341c725..4b4faa4d7013 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -23,6 +23,7 @@ import FullScreenLoadingIndicator from '../../components/FullscreenLoadingIndica import reportActionPropTypes from './report/reportActionPropTypes'; import ArchivedReportFooter from '../../components/ArchivedReportFooter'; import toggleReportActionComposeView from '../../libs/toggleReportActionComposeView'; +import * as PolicyUtils from '../../libs/PolicyUtils'; const propTypes = { /** Navigation route context info provided by react navigation */ @@ -65,6 +66,15 @@ const propTypes = { /** Beta features list */ betas: PropTypes.arrayOf(PropTypes.string), + + /** The policies which the user has access to */ + policies: PropTypes.objectOf(PropTypes.shape({ + /** The policy name */ + name: PropTypes.string, + + /** The type of the policy */ + type: PropTypes.string, + })).isRequired, }; const defaultProps = { @@ -185,7 +195,14 @@ class ReportScreen extends React.Component { return null; } - if (!Permissions.canUseDefaultRooms(this.props.betas) && ReportUtils.isDefaultRoom(this.props.report)) { + // If one is a member of a free policy, then they are allowed to see the Policy default rooms. + // For everyone else, one must be on the beta to see a default room. + const isMemberOfFreePolicy = PolicyUtils.isMemberOfFreePolicy(this.props.policies); + if (isMemberOfFreePolicy && !Permissions.canUseDefaultRooms(this.props.betas)) { + if (ReportUtils.isDomainRoom(this.props.report)) { + return null; + } + } else if (ReportUtils.isDefaultRoom(this.props.report) && !Permissions.canUseDefaultRooms(this.props.betas)) { return null; } @@ -276,4 +293,7 @@ export default withOnyx({ betas: { key: ONYXKEYS.BETAS, }, + policies: { + key: ONYXKEYS.COLLECTION.POLICY, + }, })(ReportScreen); diff --git a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js index a939c5bf4e19..f1b77faf5736 100644 --- a/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js +++ b/src/pages/home/sidebar/SidebarScreen/BaseSidebarScreen.js @@ -18,6 +18,7 @@ import * as Policy from '../../../../libs/actions/Policy'; import Performance from '../../../../libs/Performance'; import * as Welcome from '../../../../libs/actions/Welcome'; import {sidebarPropTypes, sidebarDefaultProps} from './sidebarPropTypes'; +import * as PolicyUtils from '../../../../libs/PolicyUtils'; const propTypes = { @@ -163,7 +164,7 @@ class BaseSidebarScreen extends Component { onSelected: () => Navigation.navigate(ROUTES.IOU_BILL), }, ] : []), - ...(!this.props.isCreatingWorkspace && !Policy.isAdminOfFreePolicy(this.props.allPolicies) ? [ + ...(!this.props.isCreatingWorkspace && !PolicyUtils.isAdminOfFreePolicy(this.props.allPolicies) ? [ { icon: Expensicons.NewWorkspace, iconWidth: 46,