From b1f0b1f620aadf5ccaa93da52cfb93572ea5d45b Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Wed, 27 Oct 2021 11:11:17 -0700 Subject: [PATCH 01/17] Only load full policies when needed --- src/libs/API.js | 8 +- .../AppNavigator/ModalStackNavigators.js | 93 +++++++++++-------- src/libs/Navigation/linkingConfig.js | 58 ++++++------ src/libs/actions/Policy.js | 66 ++++++------- ...{InitialPage.js => InitialSettingsPage.js} | 0 5 files changed, 125 insertions(+), 100 deletions(-) rename src/pages/settings/{InitialPage.js => InitialSettingsPage.js} (100%) diff --git a/src/libs/API.js b/src/libs/API.js index 19f70c63879a..d5a1c21ddb3f 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -474,11 +474,17 @@ function GetIOUReport(parameters) { /** * @returns {Promise} + * @param {Array} policyIDList */ -function GetPolicyList() { +function GetPolicyList(policyIDList = []) { + if (!policyIDList || policyIDList.length > 1) { + LogUtil.warn('[API] Attempting to load multiple full policies at once', {policyIDList}); + } + const commandName = 'Get'; const parameters = { returnValueList: 'policyList', + policyIDList, }; return Network.post(commandName, parameters); } diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 2d1c236e896b..34038073386f 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -1,6 +1,8 @@ import _ from 'underscore'; import React from 'react'; import {createStackNavigator, CardStyleInterpolators} from '@react-navigation/stack'; +import lodashGet from 'lodash/get'; +import * as Policy from '../../actions/Policy'; import styles from '../../../styles/styles'; import NewChatPage from '../../../pages/NewChatPage'; import NewGroupPage from '../../../pages/NewGroupPage'; @@ -10,7 +12,7 @@ import IOURequestPage from '../../../pages/iou/IOURequestPage'; import IOUBillPage from '../../../pages/iou/IOUBillPage'; import IOUSendPage from '../../../pages/iou/IOUSendPage'; import IOUDetailsModal from '../../../pages/iou/IOUDetailsModal'; -import SettingsInitialPage from '../../../pages/settings/InitialPage'; +import SettingsInitialPage from '../../../pages/settings/InitialSettingsPage'; import SettingsProfilePage from '../../../pages/settings/Profile/ProfilePage'; import SettingsPreferencesPage from '../../../pages/settings/PreferencesPage'; import SettingsAboutPage from '../../../pages/settings/AboutPage'; @@ -49,15 +51,15 @@ const defaultSubRouteOptions = { * Create a modal stack navigator with an array of sub-screens. * * @param {Object[]} screens array of screen config objects + * @param {Object|Function} [screenListeners] * @returns {Function} */ -function createModalStackNavigator(screens) { +function createModalStackNavigator(screens, screenListeners) { const ModalStackNavigator = createStackNavigator(); return () => ( {_.map(screens, screen => ( ({ + focus: () => { + const policyID = lodashGet(route, 'params.policyID'); + Policy.loadFullPolicy(policyID); + }, +})); + + const SettingsModalStackNavigator = createModalStackNavigator([ { Component: SettingsInitialPage, @@ -185,40 +232,8 @@ const SettingsModalStackNavigator = createModalStackNavigator([ name: 'Settings_Add_Debit_Card', }, { - Component: WorkspaceInitialPage, - name: 'Workspace_Initial', - }, - { - Component: WorkspaceSettingsPage, - name: 'Workspace_Settings', - }, - { - Component: WorkspaceCardPage, - name: 'Workspace_Card', - }, - { - Component: WorkspaceReimbursePage, - name: 'Workspace_Reimburse', - }, - { - Component: WorkspaceBillsPage, - name: 'Workspace_Bills', - }, - { - Component: WorkspaceInvoicesPage, - name: 'Workspace_Invoices', - }, - { - Component: WorkspaceTravelPage, - name: 'Workspace_Travel', - }, - { - Component: WorkspaceMembersPage, - name: 'Workspace_Members', - }, - { - Component: WorkspaceBankAccountPage, - name: 'Workspace_BankAccount', + Component: WorkspaceStackNavigator, + name: 'Workspace', }, { Component: ReimbursementAccountPage, diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index ace82c394f16..96fec2d63b83 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -70,33 +70,37 @@ export default { Settings_Add_Secondary_Login: { path: ROUTES.SETTINGS_ADD_LOGIN, }, - Workspace_Initial: { - path: ROUTES.WORKSPACE_INITIAL, - }, - Workspace_Settings: { - path: ROUTES.WORKSPACE_SETTINGS, - }, - Workspace_Card: { - path: ROUTES.WORKSPACE_CARD, - }, - Workspace_Reimburse: { - path: ROUTES.WORKSPACE_REIMBURSE, - }, - Workspace_Bills: { - path: ROUTES.WORKSPACE_BILLS, - }, - Workspace_Invoices: { - path: ROUTES.WORKSPACE_INVOICES, - }, - Workspace_Travel: { - path: ROUTES.WORKSPACE_TRAVEL, - }, - Workspace_Members: { - path: ROUTES.WORKSPACE_MEMBERS, - }, - Workspace_BankAccount: { - path: ROUTES.WORKSPACE_BANK_ACCOUNT, - exact: true, + Workspace: { + screens: { + Workspace_Initial: { + path: ROUTES.WORKSPACE_INITIAL, + }, + Workspace_Settings: { + path: ROUTES.WORKSPACE_SETTINGS, + }, + Workspace_Card: { + path: ROUTES.WORKSPACE_CARD, + }, + Workspace_Reimburse: { + path: ROUTES.WORKSPACE_REIMBURSE, + }, + Workspace_Bills: { + path: ROUTES.WORKSPACE_BILLS, + }, + Workspace_Invoices: { + path: ROUTES.WORKSPACE_INVOICES, + }, + Workspace_Travel: { + path: ROUTES.WORKSPACE_TRAVEL, + }, + Workspace_Members: { + path: ROUTES.WORKSPACE_MEMBERS, + }, + Workspace_BankAccount: { + path: ROUTES.WORKSPACE_BANK_ACCOUNT, + exact: true, + }, + }, }, ReimbursementAccount: { path: ROUTES.BANK_ACCOUNT, diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index fa6ff2b74df5..54fc2543b517 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -41,40 +41,29 @@ function getSimplifiedEmployeeList(employeeList) { * Takes a full policy that is returned from the policyList and simplifies it so we are only storing * the pieces of data that we need to in Onyx * - * @param {Object} fullPolicy - * @param {String} fullPolicy.id - * @param {String} fullPolicy.name - * @param {String} fullPolicy.role - * @param {String} fullPolicy.type - * @param {String} fullPolicy.outputCurrency - * @param {Object} fullPolicy.value.employeeList - * @param {String} [fullPolicy.value.avatarURL] + * @param {Object} fullPolicyOrPolicySummary + * @param {String} fullPolicyOrPolicySummary.id + * @param {String} fullPolicyOrPolicySummary.name + * @param {String} fullPolicyOrPolicySummary.role + * @param {String} fullPolicyOrPolicySummary.type + * @param {String} fullPolicyOrPolicySummary.outputCurrency + * @param {Object} fullPolicyOrPolicySummary.value.employeeList + * @param {String} [fullPolicyOrPolicySummary.value.avatarURL] * @returns {Object} */ -function getSimplifiedPolicyObject(fullPolicy) { +function getSimplifiedPolicyObject(fullPolicyOrPolicySummary) { return { - id: fullPolicy.id, - name: fullPolicy.name, - role: fullPolicy.role, - type: fullPolicy.type, - owner: fullPolicy.owner, - outputCurrency: fullPolicy.outputCurrency, - employeeList: getSimplifiedEmployeeList(lodashGet(fullPolicy, 'value.employeeList')), - avatarURL: lodashGet(fullPolicy, 'value.avatarURL', ''), + id: fullPolicyOrPolicySummary.id, + name: fullPolicyOrPolicySummary.name, + role: fullPolicyOrPolicySummary.role, + type: fullPolicyOrPolicySummary.type, + owner: fullPolicyOrPolicySummary.owner, + outputCurrency: fullPolicyOrPolicySummary.outputCurrency, + avatarURL: fullPolicyOrPolicySummary.avatarURL || '', + employeeList: getSimplifiedEmployeeList(lodashGet(fullPolicyOrPolicySummary, 'value.employeeList')), }; } -/** - * @param {Array} 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 @@ -159,7 +148,10 @@ function getPolicyList(shouldCreateNewPolicy = false) { }) .then((data) => { if (data.jsonCode === 200) { - const policyDataToStore = transformPolicyListToOnyxCollection(data.policySummaryList || []); + const policyDataToStore = _.reduce(data.policySummaryList, (memo, policy) => ({ + ...memo, + [`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`]: getSimplifiedPolicyObject(policy), + }), {}); updateAllPolicies(policyDataToStore); } @@ -167,13 +159,20 @@ function getPolicyList(shouldCreateNewPolicy = false) { Navigation.dismissModal(); Navigation.navigate(newPolicyID ? ROUTES.getWorkspaceInitialRoute(newPolicyID) : ROUTES.HOME); } + }); +} - return API.GetPolicyList(); - }) +/** + * @param {Number} policyID + */ +function loadFullPolicy(policyID) { + API.GetPolicyList([policyID]) .then((data) => { if (data.jsonCode === 200) { - const policyDataToStore = transformPolicyListToOnyxCollection(data.policyList || []); - updateAllPolicies(policyDataToStore); + const policy = data.policyList[0] || {}; + if (policy.id) { + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`, getSimplifiedPolicyObject(policy)); + } } }); } @@ -356,6 +355,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 From 1254b3d3e4051739b3b5a63da8f12a473ce9ff14 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Wed, 27 Oct 2021 13:33:25 -0700 Subject: [PATCH 02/17] Don't create separate subnavigator for workspaces --- .../AppNavigator/ModalStackNavigators.js | 104 +++++++++--------- src/libs/Navigation/Navigation.js | 2 +- src/libs/Navigation/linkingConfig.js | 58 +++++----- 3 files changed, 83 insertions(+), 81 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 34038073386f..da04747bcfc2 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -1,7 +1,6 @@ import _ from 'underscore'; import React from 'react'; import {createStackNavigator, CardStyleInterpolators} from '@react-navigation/stack'; -import lodashGet from 'lodash/get'; import * as Policy from '../../actions/Policy'; import styles from '../../../styles/styles'; import NewChatPage from '../../../pages/NewChatPage'; @@ -145,51 +144,7 @@ const NewChatModalStackNavigator = createModalStackNavigator([{ name: 'NewChat_Root', }]); -const WorkspaceStackNavigator = createModalStackNavigator([ - { - Component: WorkspaceInitialPage, - name: 'Workspace_Initial', - }, - { - Component: WorkspaceSettingsPage, - name: 'Workspace_Settings', - }, - { - Component: WorkspaceCardPage, - name: 'Workspace_Card', - }, - { - Component: WorkspaceReimbursePage, - name: 'Workspace_Reimburse', - }, - { - Component: WorkspaceBillsPage, - name: 'Workspace_Bills', - }, - { - Component: WorkspaceInvoicesPage, - name: 'Workspace_Invoices', - }, - { - Component: WorkspaceTravelPage, - name: 'Workspace_Travel', - }, - { - Component: WorkspaceMembersPage, - name: 'Workspace_Members', - }, - { - Component: WorkspaceBankAccountPage, - name: 'Workspace_BankAccount', - }, -], ({route}) => ({ - focus: () => { - const policyID = lodashGet(route, 'params.policyID'); - Policy.loadFullPolicy(policyID); - }, -})); - - +let previousRoute = ''; const SettingsModalStackNavigator = createModalStackNavigator([ { Component: SettingsInitialPage, @@ -232,15 +187,66 @@ const SettingsModalStackNavigator = createModalStackNavigator([ name: 'Settings_Add_Debit_Card', }, { - Component: WorkspaceStackNavigator, - name: 'Workspace', + Component: WorkspaceInitialPage, + name: 'Workspace_Initial', + }, + { + Component: WorkspaceSettingsPage, + name: 'Workspace_Settings', + }, + { + Component: WorkspaceCardPage, + name: 'Workspace_Card', + }, + { + Component: WorkspaceReimbursePage, + name: 'Workspace_Reimburse', + }, + { + Component: WorkspaceBillsPage, + name: 'Workspace_Bills', + }, + { + Component: WorkspaceInvoicesPage, + name: 'Workspace_Invoices', + }, + { + Component: WorkspaceTravelPage, + name: 'Workspace_Travel', + }, + { + Component: WorkspaceMembersPage, + name: 'Workspace_Members', + }, + { + Component: WorkspaceBankAccountPage, + name: 'Workspace_BankAccount', }, { Component: ReimbursementAccountPage, name: 'ReimbursementAccount', initialParams: {stepToOpen: CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT}, }, -]); +], { + state: ({data}) => { + // If current route is workspace route, and previous route was not, full-load the policy + const policyID = _.chain(data) + .get(['state', 'routes'], []) + .pluck('params') + .last() + .get('policyID', '') + .value(); + if (policyID && !previousRoute.includes(policyID)) { + Policy.loadFullPolicy(policyID); + } + + previousRoute = _.chain(data) + .get(['state', 'routes'], []) + .last() + .get('path', '') + .value(); + }, +}); const EnablePaymentsStackNavigator = createModalStackNavigator([{ Component: EnablePaymentsPage, diff --git a/src/libs/Navigation/Navigation.js b/src/libs/Navigation/Navigation.js index b2f98bba303e..94e7cd4dfc89 100644 --- a/src/libs/Navigation/Navigation.js +++ b/src/libs/Navigation/Navigation.js @@ -126,7 +126,7 @@ function navigate(route = ROUTES.HOME) { /** * Dismisses a screen presented modally and returns us back to the previous view. * - * @param {Boolean} shouldOpenDrawer + * @param {Boolean} [shouldOpenDrawer] */ function dismissModal(shouldOpenDrawer = false) { if (!navigationRef.isReady()) { diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index 96fec2d63b83..ace82c394f16 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -70,37 +70,33 @@ export default { Settings_Add_Secondary_Login: { path: ROUTES.SETTINGS_ADD_LOGIN, }, - Workspace: { - screens: { - Workspace_Initial: { - path: ROUTES.WORKSPACE_INITIAL, - }, - Workspace_Settings: { - path: ROUTES.WORKSPACE_SETTINGS, - }, - Workspace_Card: { - path: ROUTES.WORKSPACE_CARD, - }, - Workspace_Reimburse: { - path: ROUTES.WORKSPACE_REIMBURSE, - }, - Workspace_Bills: { - path: ROUTES.WORKSPACE_BILLS, - }, - Workspace_Invoices: { - path: ROUTES.WORKSPACE_INVOICES, - }, - Workspace_Travel: { - path: ROUTES.WORKSPACE_TRAVEL, - }, - Workspace_Members: { - path: ROUTES.WORKSPACE_MEMBERS, - }, - Workspace_BankAccount: { - path: ROUTES.WORKSPACE_BANK_ACCOUNT, - exact: true, - }, - }, + Workspace_Initial: { + path: ROUTES.WORKSPACE_INITIAL, + }, + Workspace_Settings: { + path: ROUTES.WORKSPACE_SETTINGS, + }, + Workspace_Card: { + path: ROUTES.WORKSPACE_CARD, + }, + Workspace_Reimburse: { + path: ROUTES.WORKSPACE_REIMBURSE, + }, + Workspace_Bills: { + path: ROUTES.WORKSPACE_BILLS, + }, + Workspace_Invoices: { + path: ROUTES.WORKSPACE_INVOICES, + }, + Workspace_Travel: { + path: ROUTES.WORKSPACE_TRAVEL, + }, + Workspace_Members: { + path: ROUTES.WORKSPACE_MEMBERS, + }, + Workspace_BankAccount: { + path: ROUTES.WORKSPACE_BANK_ACCOUNT, + exact: true, }, ReimbursementAccount: { path: ROUTES.BANK_ACCOUNT, From 1f6c23eb6126d6366aea9b3d91d757238f3b488a Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Wed, 27 Oct 2021 13:55:45 -0700 Subject: [PATCH 03/17] Fix type annotations to use strings not numbers --- src/libs/API.js | 2 +- src/libs/actions/Policy.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/API.js b/src/libs/API.js index d5a1c21ddb3f..c77e55d9f0a8 100644 --- a/src/libs/API.js +++ b/src/libs/API.js @@ -474,7 +474,7 @@ function GetIOUReport(parameters) { /** * @returns {Promise} - * @param {Array} policyIDList + * @param {Array} policyIDList */ function GetPolicyList(policyIDList = []) { if (!policyIDList || policyIDList.length > 1) { diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 54fc2543b517..a119f722b781 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -163,7 +163,7 @@ function getPolicyList(shouldCreateNewPolicy = false) { } /** - * @param {Number} policyID + * @param {String} policyID */ function loadFullPolicy(policyID) { API.GetPolicyList([policyID]) From 3c5dcf3bf1cf80ba4ba91326a6c9bc1857ad6ebe Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Thu, 28 Oct 2021 12:47:50 -0700 Subject: [PATCH 04/17] Add comment linking to docs --- src/libs/Navigation/AppNavigator/ModalStackNavigators.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index da04747bcfc2..c85794f090f2 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -50,7 +50,8 @@ const defaultSubRouteOptions = { * Create a modal stack navigator with an array of sub-screens. * * @param {Object[]} screens array of screen config objects - * @param {Object|Function} [screenListeners] + * @param {Object|Function} [screenListeners] – event listeners applied to all screens in this navigator. + * See docs: https://reactnavigation.org/docs/navigation-events/#screenlisteners-prop-on-the-navigator * @returns {Function} */ function createModalStackNavigator(screens, screenListeners) { From 0a1aa76288dba042525002b4689c110f76e60770 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Tue, 2 Nov 2021 17:47:17 -0700 Subject: [PATCH 05/17] Move policy loading logic to HOC --- .../AppNavigator/ModalStackNavigators.js | 28 +---------- .../workspace/WorkspaceBankAccountPage.js | 2 + src/pages/workspace/WorkspaceInitialPage.js | 2 + src/pages/workspace/WorkspaceInvitePage.js | 2 + src/pages/workspace/WorkspaceMembersPage.js | 2 + src/pages/workspace/WorkspaceSettingsPage.js | 2 + .../workspace/bills/WorkspaceBillsPage.js | 7 ++- src/pages/workspace/card/WorkspaceCardPage.js | 7 ++- .../invoices/WorkspaceInvoicesPage.js | 7 ++- .../reimburse/WorkspaceReimbursePage.js | 7 ++- .../workspace/travel/WorkspaceTravelPage.js | 7 ++- src/pages/workspace/withFullPolicy.js | 49 +++++++++++++++++++ 12 files changed, 91 insertions(+), 31 deletions(-) create mode 100644 src/pages/workspace/withFullPolicy.js diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index c85794f090f2..8cdfc0c6ad59 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -1,7 +1,6 @@ import _ from 'underscore'; import React from 'react'; import {createStackNavigator, CardStyleInterpolators} from '@react-navigation/stack'; -import * as Policy from '../../actions/Policy'; import styles from '../../../styles/styles'; import NewChatPage from '../../../pages/NewChatPage'; import NewGroupPage from '../../../pages/NewGroupPage'; @@ -50,16 +49,13 @@ const defaultSubRouteOptions = { * Create a modal stack navigator with an array of sub-screens. * * @param {Object[]} screens array of screen config objects - * @param {Object|Function} [screenListeners] – event listeners applied to all screens in this navigator. - * See docs: https://reactnavigation.org/docs/navigation-events/#screenlisteners-prop-on-the-navigator * @returns {Function} */ -function createModalStackNavigator(screens, screenListeners) { +function createModalStackNavigator(screens) { const ModalStackNavigator = createStackNavigator(); return () => ( {_.map(screens, screen => ( { - // If current route is workspace route, and previous route was not, full-load the policy - const policyID = _.chain(data) - .get(['state', 'routes'], []) - .pluck('params') - .last() - .get('policyID', '') - .value(); - if (policyID && !previousRoute.includes(policyID)) { - Policy.loadFullPolicy(policyID); - } - - previousRoute = _.chain(data) - .get(['state', 'routes'], []) - .last() - .get('path', '') - .value(); - }, -}); +]); const EnablePaymentsStackNavigator = createModalStackNavigator([{ Component: EnablePaymentsPage, diff --git a/src/pages/workspace/WorkspaceBankAccountPage.js b/src/pages/workspace/WorkspaceBankAccountPage.js index e4ced1e11611..e1d55ccbd4fb 100644 --- a/src/pages/workspace/WorkspaceBankAccountPage.js +++ b/src/pages/workspace/WorkspaceBankAccountPage.js @@ -16,6 +16,7 @@ import ROUTES from '../../ROUTES'; import reimbursementAccountPropTypes from '../ReimbursementAccount/reimbursementAccountPropTypes'; import WorkspaceSection from './WorkspaceSection'; import WorkspaceResetBankAccountModal from './WorkspaceResetBankAccountModal'; +import withFullPolicy from './withFullPolicy'; const propTypes = { /** ACH data for the withdrawal account actively being set up */ @@ -125,6 +126,7 @@ WorkspaceBankAccountPage.defaultProps = defaultProps; export default compose( withLocalize, + withFullPolicy, withOnyx({ reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index abbd07c04f26..61e5313a16b0 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -32,6 +32,7 @@ import compose from '../../libs/compose'; import ONYXKEYS from '../../ONYXKEYS'; import Avatar from '../../components/Avatar'; import FullScreenLoadingIndicator from '../../components/FullscreenLoadingIndicator'; +import withFullPolicy from './withFullPolicy'; const propTypes = { /** Whether the current screen is focused. */ @@ -206,6 +207,7 @@ export default compose( withLocalize, withWindowDimensions, withNavigationFocus, + withFullPolicy, withOnyx({ policy: { key: (props) => { diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js index 6689a1961b50..0722572ccfb2 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 from './withFullPolicy'; const personalDetailsPropTypes = PropTypes.shape({ /** The login of the person (either email or phone number) */ @@ -350,6 +351,7 @@ WorkspaceInvitePage.defaultProps = defaultProps; export default compose( withLocalize, + withFullPolicy, withOnyx({ personalDetails: { key: ONYXKEYS.PERSONAL_DETAILS, diff --git a/src/pages/workspace/WorkspaceMembersPage.js b/src/pages/workspace/WorkspaceMembersPage.js index fbf51ef90833..fa27b5b951ca 100644 --- a/src/pages/workspace/WorkspaceMembersPage.js +++ b/src/pages/workspace/WorkspaceMembersPage.js @@ -27,6 +27,7 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/ import OptionRow from '../home/sidebar/OptionRow'; import CheckboxWithTooltip from '../../components/CheckboxWithTooltip'; import Hoverable from '../../components/Hoverable'; +import withFullPolicy from './withFullPolicy'; const propTypes = { ...withLocalizePropTypes, @@ -328,6 +329,7 @@ WorkspaceMembersPage.defaultProps = defaultProps; export default compose( withLocalize, withWindowDimensions, + withFullPolicy, withOnyx({ personalDetails: { key: ONYXKEYS.PERSONAL_DETAILS, diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index 3ada85ede357..3a9d226a2475 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -25,6 +25,7 @@ import ExpensiTextInput from '../../components/ExpensiTextInput'; import FixedFooter from '../../components/FixedFooter'; import WorkspacePageWithSections from './WorkspacePageWithSections'; import FullScreenLoadingIndicator from '../../components/FullscreenLoadingIndicator'; +import withFullPolicy from './withFullPolicy'; const propTypes = { /** List of betas */ @@ -200,6 +201,7 @@ WorkspaceSettingsPage.propTypes = propTypes; WorkspaceSettingsPage.defaultProps = defaultProps; export default compose( + withFullPolicy, withOnyx({ betas: { key: ONYXKEYS.BETAS, diff --git a/src/pages/workspace/bills/WorkspaceBillsPage.js b/src/pages/workspace/bills/WorkspaceBillsPage.js index ec07dbcb7c65..72c6fab60f84 100644 --- a/src/pages/workspace/bills/WorkspaceBillsPage.js +++ b/src/pages/workspace/bills/WorkspaceBillsPage.js @@ -1,6 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; +import compose from '../../../libs/compose'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; +import withFullPolicy from '../withFullPolicy'; import WorkspaceBillsNoVBAView from './WorkspaceBillsNoVBAView'; import WorkspaceBillsVBAView from './WorkspaceBillsVBAView'; import WorkspacePageWithSections from '../WorkspacePageWithSections'; @@ -37,4 +39,7 @@ const WorkspaceBillsPage = ({translate, route}) => ( WorkspaceBillsPage.propTypes = propTypes; WorkspaceBillsPage.displayName = 'WorkspaceBillsPage'; -export default withLocalize(WorkspaceBillsPage); +export default compose( + withLocalize, + withFullPolicy, +)(WorkspaceBillsPage); diff --git a/src/pages/workspace/card/WorkspaceCardPage.js b/src/pages/workspace/card/WorkspaceCardPage.js index 8b97933330b4..4cad2844975c 100644 --- a/src/pages/workspace/card/WorkspaceCardPage.js +++ b/src/pages/workspace/card/WorkspaceCardPage.js @@ -1,6 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; +import compose from '../../../libs/compose'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; +import withFullPolicy from '../withFullPolicy'; import WorkspaceCardNoVBAView from './WorkspaceCardNoVBAView'; import WorkspaceCardVBANoECardView from './WorkspaceCardVBANoECardView'; import WorkspaceCardVBAWithECardView from './WorkspaceCardVBAWithECardView'; @@ -45,4 +47,7 @@ const WorkspaceCardPage = ({translate, route}) => ( WorkspaceCardPage.propTypes = propTypes; WorkspaceCardPage.displayName = 'WorkspaceCardPage'; -export default withLocalize(WorkspaceCardPage); +export default compose( + withLocalize, + withFullPolicy, +)(WorkspaceCardPage); diff --git a/src/pages/workspace/invoices/WorkspaceInvoicesPage.js b/src/pages/workspace/invoices/WorkspaceInvoicesPage.js index 47a4fea43b30..cf15a108cc13 100644 --- a/src/pages/workspace/invoices/WorkspaceInvoicesPage.js +++ b/src/pages/workspace/invoices/WorkspaceInvoicesPage.js @@ -1,6 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; +import compose from '../../../libs/compose'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; +import withFullPolicy from '../withFullPolicy'; import WorkspacePageWithSections from '../WorkspacePageWithSections'; import WorkspaceInvoicesNoVBAView from './WorkspaceInvoicesNoVBAView'; import WorkspaceInvoicesVBAView from './WorkspaceInvoicesVBAView'; @@ -38,4 +40,7 @@ const WorkspaceInvoicesPage = ({translate, route}) => ( WorkspaceInvoicesPage.propTypes = propTypes; WorkspaceInvoicesPage.displayName = 'WorkspaceInvoicesPage'; -export default withLocalize(WorkspaceInvoicesPage); +export default compose( + withLocalize, + withFullPolicy, +)(WorkspaceInvoicesPage); diff --git a/src/pages/workspace/reimburse/WorkspaceReimbursePage.js b/src/pages/workspace/reimburse/WorkspaceReimbursePage.js index ed2f79d1f766..626fba556f55 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimbursePage.js +++ b/src/pages/workspace/reimburse/WorkspaceReimbursePage.js @@ -1,6 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; +import compose from '../../../libs/compose'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; +import withFullPolicy from '../withFullPolicy'; import WorkspaceReimburseNoVBAView from './WorkspaceReimburseNoVBAView'; import WorkspaceReimburseVBAView from './WorkspaceReimburseVBAView'; import WorkspacePageWithSections from '../WorkspacePageWithSections'; @@ -38,4 +40,7 @@ const WorkspaceReimbursePage = ({translate, route}) => ( WorkspaceReimbursePage.propTypes = propTypes; WorkspaceReimbursePage.displayName = 'WorkspaceReimbursePage'; -export default withLocalize(WorkspaceReimbursePage); +export default compose( + withLocalize, + withFullPolicy, +)(WorkspaceReimbursePage); diff --git a/src/pages/workspace/travel/WorkspaceTravelPage.js b/src/pages/workspace/travel/WorkspaceTravelPage.js index 3e23c251f4fb..bc9fdaf6fed2 100644 --- a/src/pages/workspace/travel/WorkspaceTravelPage.js +++ b/src/pages/workspace/travel/WorkspaceTravelPage.js @@ -1,6 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; +import compose from '../../../libs/compose'; import withLocalize, {withLocalizePropTypes} from '../../../components/withLocalize'; +import withFullPolicy from '../withFullPolicy'; import WorkspacePageWithSections from '../WorkspacePageWithSections'; import WorkspaceTravelNoVBAView from './WorkspaceTravelNoVBAView'; import WorkspaceTravelVBAView from './WorkspaceTravelVBAView'; @@ -38,4 +40,7 @@ const WorkspaceTravelPage = ({translate, route}) => ( WorkspaceTravelPage.propTypes = propTypes; WorkspaceTravelPage.displayName = 'WorkspaceTravelPage'; -export default withLocalize(WorkspaceTravelPage); +export default compose( + withLocalize, + withFullPolicy, +)(WorkspaceTravelPage); diff --git a/src/pages/workspace/withFullPolicy.js b/src/pages/workspace/withFullPolicy.js new file mode 100644 index 000000000000..226e20f1d43a --- /dev/null +++ b/src/pages/workspace/withFullPolicy.js @@ -0,0 +1,49 @@ +import _ from 'underscore'; +import React from 'react'; +import PropTypes from 'prop-types'; +import {useNavigationState} from '@react-navigation/native'; +import getComponentDisplayName from '../../libs/getComponentDisplayName'; +import * as Policy from '../../libs/actions/Policy'; + +let previousRoute = ''; + +/* + * HOC for loading a full policy. It checks the route params and if current route has a policyID that the previous route did not, it full-loads that policy. + */ +export default function (WrappedComponent) { + const propTypes = { + forwardedRef: PropTypes.func, + }; + + const defaultProps = { + forwardedRef: () => {}, + }; + + const WithFullPolicy = (props) => { + const currentRoute = _.last(useNavigationState(state => state.routes || [])); + const policyID = _.get(currentRoute, ['params', 'policyID'], ''); + + if (policyID && !previousRoute.includes(policyID)) { + Policy.loadFullPolicy(policyID); + } + + previousRoute = _.get(currentRoute, 'path', ''); + + const {forwardedRef, ...rest} = props; + return ( + + ); + }; + + WithFullPolicy.propTypes = propTypes; + WithFullPolicy.defaultProps = defaultProps; + WithFullPolicy.displayName = `withFullPolicy(${getComponentDisplayName(WrappedComponent)})`; + return React.forwardRef((props, ref) => ( + // eslint-disable-next-line react/jsx-props-no-spreading + + )); +} From 760718d2b8b21ec90bad198d13fff8d4d2b4e7d9 Mon Sep 17 00:00:00 2001 From: Rory Abraham Date: Tue, 2 Nov 2021 18:21:14 -0700 Subject: [PATCH 06/17] Move workspace invite page to the settings modal stack --- src/libs/Navigation/AppNavigator/AuthScreens.js | 7 ------- .../Navigation/AppNavigator/ModalStackNavigators.js | 10 ++++------ src/libs/Navigation/linkingConfig.js | 8 +++----- src/pages/workspace/WorkspaceMembersPage.js | 3 ++- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js index 73a390a7967d..9d8b78be0b59 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'; @@ -355,12 +354,6 @@ class AuthScreens extends React.Component { component={AddPersonalBankAccountModalStackNavigator} listeners={modalScreenListeners} /> - this.inviteUser()} + onPress={this.inviteUser} />