diff --git a/src/languages/en.js b/src/languages/en.js index 8ebd45991337..deb4bba810b4 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -727,7 +727,7 @@ export default { personalMessagePrompt: 'Add a personal message (optional)', pleaseSelectUser: 'Please select a user from contacts.', genericFailureMessage: 'An error occurred inviting the user to the workspace, please try again.', - welcomeNote: ({workspaceName}) => `You have been invited to ${workspaceName}! Download the Expensify mobile app to start tracking your expenses.`, + welcomeNote: ({workspaceName}) => `You have been invited to ${workspaceName || 'a workspace'}! Download the Expensify mobile app to start tracking your expenses.`, }, editor: { nameInputLabel: 'Name', diff --git a/src/libs/API.js b/src/libs/API.js index 19f70c63879a..f7a51a777900 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -474,11 +474,17 @@ function GetIOUReport(parameters) { /** * @returns {Promise} + * @param {String} policyID */ -function GetPolicyList() { +function GetFullPolicy(policyID) { + if (!_.isString(policyID)) { + throw new Error('[API] Must include a single policyID with calls to API.GetFullPolicy'); + } + const commandName = 'Get'; const parameters = { returnValueList: 'policyList', + policyIDList: [policyID], }; return Network.post(commandName, parameters); } @@ -1122,7 +1128,7 @@ export { GetAccountStatus, GetShortLivedAuthToken, GetIOUReport, - GetPolicyList, + GetFullPolicy, GetPolicySummaryList, GetReportSummaryList, GetRequestCountryCode, diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js index 4f6ec4c3c1c1..60026d65bd90 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.js +++ b/src/libs/Navigation/AppNavigator/AuthScreens.js @@ -52,7 +52,6 @@ import { SettingsModalStackNavigator, EnablePaymentsStackNavigator, AddPersonalBankAccountModalStackNavigator, - WorkspaceInviteModalStackNavigator, RequestCallModalStackNavigator, ReportDetailsModalStackNavigator, } from './ModalStackNavigators'; @@ -376,12 +375,6 @@ class AuthScreens extends React.Component { component={AddPersonalBankAccountModalStackNavigator} listeners={modalScreenListeners} /> - ( {_.map(screens, screen => ( } policyList - * @returns {Object} - */ -function transformPolicyListToOnyxCollection(policyList) { - return _.reduce(policyList, (memo, policy) => ({ - ...memo, - [`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`]: getSimplifiedPolicyObject(policy), - }), {}); -} - /** * Used to update ALL of the policies at once. If a policy is present locally, but not in the policies object passed here it will be removed. * @param {Object} policyCollection - object of policy key and partial policy object @@ -124,7 +112,8 @@ function create(name = '') { role: CONST.POLICY.ROLE.ADMIN, outputCurrency: response.policy.outputCurrency, }); - }).then(() => Promise.resolve(lodashGet(res, 'policyID'))); + }) + .then(() => Promise.resolve(lodashGet(res, 'policyID'))); } /** @@ -155,26 +144,18 @@ function createAndNavigate(name = '') { * and we also don't have to wait for full policies to load before navigating to the new policy. */ function getPolicyList() { - const policyCollection = {}; API.GetPolicySummaryList() .then((data) => { if (data.jsonCode === 200) { - lodashMerge(policyCollection, transformPolicyListToOnyxCollection(data.policySummaryList || [])); - } - - return API.GetPolicyList(); - }) - .then((data) => { - if (data.jsonCode === 200) { - lodashMerge(policyCollection, transformPolicyListToOnyxCollection(data.policyList || [])); - } - }) - .finally(() => { - if (_.isEmpty(policyCollection)) { - return; + const policyCollection = _.reduce(data.policySummaryList, (memo, policy) => ({ + ...memo, + [`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`]: getSimplifiedPolicyObject(policy), + }), {}); + + if (!_.isEmpty(policyCollection)) { + updateAllPolicies(policyCollection); + } } - - updateAllPolicies(policyCollection); }); } @@ -188,6 +169,21 @@ function createAndGetPolicyList() { .then(() => navigateToPolicy(newPolicyID)); } +/** + * @param {String} policyID + */ +function loadFullPolicy(policyID) { + API.GetFullPolicy(policyID) + .then((data) => { + if (data.jsonCode === 200) { + const policy = lodashGet(data, 'policyList[0]', {}); + if (policy.id) { + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, getSimplifiedPolicyObject(policy)); + } + } + }); +} + /** * Is the user an admin of a free policy (aka workspace)? * @@ -366,6 +362,7 @@ function hideWorkspaceAlertMessage(policyID) { export { getPolicyList, + loadFullPolicy, removeMembers, invite, isAdminOfFreePolicy, diff --git a/src/pages/settings/InitialPage.js b/src/pages/settings/InitialSettingsPage.js similarity index 100% rename from src/pages/settings/InitialPage.js rename to src/pages/settings/InitialSettingsPage.js diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index abbd07c04f26..3b68bf4eb88c 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -1,8 +1,6 @@ import _ from 'underscore'; import React from 'react'; import {View, ScrollView, Pressable} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; -import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; import {withNavigationFocus} from '@react-navigation/compat'; import Navigation from '../../libs/Navigation/Navigation'; @@ -29,30 +27,20 @@ import themedefault from '../../styles/themes/default'; import HeaderWithCloseButton from '../../components/HeaderWithCloseButton'; import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/withWindowDimensions'; import compose from '../../libs/compose'; -import ONYXKEYS from '../../ONYXKEYS'; import Avatar from '../../components/Avatar'; import FullScreenLoadingIndicator from '../../components/FullscreenLoadingIndicator'; +import withFullPolicy, {fullPolicyPropTypes, fullPolicyDefaultProps} from './withFullPolicy'; const propTypes = { /** Whether the current screen is focused. */ isFocused: PropTypes.bool.isRequired, - /** Policy for the current route */ - policy: PropTypes.shape({ - /** ID of the policy */ - id: PropTypes.string, - - /** Name of the policy */ - name: PropTypes.string, - }), - + ...fullPolicyPropTypes, ...withLocalizePropTypes, ...windowDimensionsPropTypes, }; -const defaultProps = { - policy: {}, -}; +const defaultProps = fullPolicyDefaultProps; const WorkspaceInitialPage = ({ translate, isSmallScreenWidth, policy, isFocused, @@ -154,27 +142,29 @@ const WorkspaceInitialPage = ({ )} - - - - {policy.name} - - - + {policy.name && ( + + + + {policy.name} + + + + )} {_.map(menuItems, (item) => { @@ -206,14 +196,5 @@ export default compose( withLocalize, withWindowDimensions, withNavigationFocus, - withOnyx({ - policy: { - key: (props) => { - const routes = lodashGet(props.navigation.getState(), 'routes', []); - const routeWithPolicyIDParam = _.find(routes, route => route.params && route.params.policyID); - const policyID = lodashGet(routeWithPolicyIDParam, ['params', 'policyID']); - return `${ONYXKEYS.COLLECTION.POLICY}${policyID}`; - }, - }, - }), + withFullPolicy, )(WorkspaceInitialPage); diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js index 6689a1961b50..8af1a9ccb809 100644 --- a/src/pages/workspace/WorkspaceInvitePage.js +++ b/src/pages/workspace/WorkspaceInvitePage.js @@ -21,6 +21,7 @@ import CONST, {EXPENSIFY_EMAILS} from '../../CONST'; import FullScreenLoadingIndicator from '../../components/FullscreenLoadingIndicator'; import {openExternalLink} from '../../libs/actions/Link'; import Text from '../../components/Text'; +import withFullPolicy, {fullPolicyPropTypes, fullPolicyDefaultProps} from './withFullPolicy'; const personalDetailsPropTypes = PropTypes.shape({ /** The login of the person (either email or phone number) */ @@ -41,12 +42,6 @@ const propTypes = { /** All of the personal details for everyone */ personalDetails: PropTypes.objectOf(personalDetailsPropTypes).isRequired, - /** The policy passed via the route */ - policy: PropTypes.shape({ - /** The policy name */ - name: PropTypes.string, - }), - /** URL Route params */ route: PropTypes.shape({ /** Params from the URL path */ @@ -56,15 +51,11 @@ const propTypes = { }), }).isRequired, + ...fullPolicyPropTypes, ...withLocalizePropTypes, - }; -const defaultProps = { - policy: { - name: '', - }, -}; +const defaultProps = fullPolicyDefaultProps; class WorkspaceInvitePage extends React.Component { constructor(props) { @@ -350,13 +341,11 @@ WorkspaceInvitePage.defaultProps = defaultProps; export default compose( withLocalize, + withFullPolicy, withOnyx({ personalDetails: { key: ONYXKEYS.PERSONAL_DETAILS, }, - policy: { - key: ({route}) => `${ONYXKEYS.COLLECTION.POLICY}${route.params.policyID}`, - }, betas: { key: ONYXKEYS.BETAS, }, diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index fbf51ef90833..bbf639f02256 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -27,24 +27,15 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/ import OptionRow from '../home/sidebar/OptionRow'; import CheckboxWithTooltip from '../../components/CheckboxWithTooltip'; import Hoverable from '../../components/Hoverable'; +import withFullPolicy, {fullPolicyPropTypes, fullPolicyDefaultProps} from './withFullPolicy'; const propTypes = { - ...withLocalizePropTypes, - - ...windowDimensionsPropTypes, - /** List of betas */ betas: PropTypes.arrayOf(PropTypes.string).isRequired, /** The personal details of the person who is logged in */ personalDetails: personalDetailsPropType.isRequired, - /** The policy passed via the route */ - policy: PropTypes.shape({ - /** The policy name */ - name: PropTypes.string, - }), - /** URL Route params */ route: PropTypes.shape({ /** Params from the URL path */ @@ -53,14 +44,14 @@ const propTypes = { policyID: PropTypes.string, }), }).isRequired, -}; -const defaultProps = { - policy: { - name: '', - }, + ...fullPolicyPropTypes, + ...withLocalizePropTypes, + ...windowDimensionsPropTypes, }; +const defaultProps = fullPolicyDefaultProps; + class WorkspaceMembersPage extends React.Component { constructor(props) { super(props); @@ -72,6 +63,7 @@ class WorkspaceMembersPage extends React.Component { }; this.renderItem = this.renderItem.bind(this); + this.inviteUser = this.inviteUser.bind(this); this.addUser = this.addUser.bind(this); this.removeUser = this.removeUser.bind(this); this.askForConfirmationToRemove = this.askForConfirmationToRemove.bind(this); @@ -284,7 +276,7 @@ class WorkspaceMembersPage extends React.Component { small success text={this.props.translate('common.invite')} - onPress={() => this.inviteUser()} + onPress={this.inviteUser} />