Skip to content

Commit

Permalink
Merge pull request #29256 from gedu/edu/16935_delay_new_workspace
Browse files Browse the repository at this point in the history
[#16935] Workspace creation with Policy Draft info
  • Loading branch information
marcochavezf authored Oct 16, 2023
2 parents 608d46f + 8fdbc4e commit e213f7e
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 9 deletions.
2 changes: 2 additions & 0 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,8 @@ const ONYXKEYS = {
DOWNLOAD: 'download_',
POLICY: 'policy_',
POLICY_MEMBERS: 'policyMembers_',
POLICY_DRAFTS: 'policyDrafts_',
POLICY_MEMBERS_DRAFTS: 'policyMembersDrafts_',
POLICY_CATEGORIES: 'policyCategories_',
POLICY_RECENTLY_USED_CATEGORIES: 'policyRecentlyUsedCategories_',
POLICY_TAGS: 'policyTags_',
Expand Down
36 changes: 36 additions & 0 deletions src/libs/actions/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,40 @@ function createWorkspaceAndNavigateToIt(policyOwnerEmail = '', makeMeAdmin = fal
.then(endSignOnTransition);
}

/**
* Create a new draft workspace and navigate to it
*
* @param {String} [policyOwnerEmail] Optional, the email of the account to make the owner of the policy
* @param {String} [policyName] Optional, custom policy name we will use for created workspace
* @param {Boolean} [transitionFromOldDot] Optional, if the user is transitioning from old dot
*/
function createWorkspaceWithPolicyDraftAndNavigateToIt(policyOwnerEmail = '', policyName = '', transitionFromOldDot = false) {
const policyID = Policy.generatePolicyID();
Policy.createDraftInitialWorkspace(policyOwnerEmail, policyName, policyID);

Navigation.isNavigationReady()
.then(() => {
if (transitionFromOldDot) {
// We must call goBack() to remove the /transition route from history
Navigation.goBack(ROUTES.HOME);
}
Navigation.navigate(ROUTES.WORKSPACE_INITIAL.getRoute(policyID));
})
.then(endSignOnTransition);
}

/**
* Create a new workspace and delete the draft
*
* @param {String} [policyID] the ID of the policy to use
* @param {String} [policyName] custom policy name we will use for created workspace
* @param {String} [policyOwnerEmail] Optional, the email of the account to make the owner of the policy
* @param {Boolean} [makeMeAdmin] Optional, leave the calling account as an admin on the policy
*/
function savePolicyDraftByNewWorkspace(policyID, policyName, policyOwnerEmail = '', makeMeAdmin = false) {
Policy.createWorkspace(policyOwnerEmail, makeMeAdmin, policyName, policyID);
}

/**
* This action runs when the Navigator is ready and the current route changes
*
Expand Down Expand Up @@ -527,4 +561,6 @@ export {
createWorkspaceAndNavigateToIt,
getMissingOnyxUpdates,
finalReconnectAppAfterActivatingReliableUpdates,
savePolicyDraftByNewWorkspace,
createWorkspaceWithPolicyDraftAndNavigateToIt,
};
54 changes: 54 additions & 0 deletions src/libs/actions/Policy.js
Original file line number Diff line number Diff line change
Expand Up @@ -909,6 +909,48 @@ function buildOptimisticCustomUnits() {
};
}

/**
* Optimistically creates a Policy Draft for a new workspace
*
* @param {String} [policyOwnerEmail] Optional, the email of the account to make the owner of the policy
* @param {String} [policyName] Optional, custom policy name we will use for created workspace
* @param {String} [policyID] Optional, custom policy id we will use for created workspace
*/
function createDraftInitialWorkspace(policyOwnerEmail = '', policyName = '', policyID = generatePolicyID()) {
const workspaceName = policyName || generateDefaultWorkspaceName(policyOwnerEmail);
const {customUnits} = buildOptimisticCustomUnits();

const optimisticData = [
{
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.POLICY_DRAFTS}${policyID}`,
value: {
id: policyID,
type: CONST.POLICY.TYPE.FREE,
name: workspaceName,
role: CONST.POLICY.ROLE.ADMIN,
owner: sessionEmail,
isPolicyExpenseChatEnabled: true,
outputCurrency: lodashGet(allPersonalDetails, [sessionAccountID, 'localCurrencyCode'], CONST.CURRENCY.USD),
pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
customUnits,
},
},
{
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.POLICY_MEMBERS_DRAFTS}${policyID}`,
value: {
[sessionAccountID]: {
role: CONST.POLICY.ROLE.ADMIN,
errors: {},
},
},
},
];

Onyx.update(optimisticData);
}

/**
* Optimistically creates a new workspace and default workspace chats
*
Expand Down Expand Up @@ -1027,6 +1069,16 @@ function createWorkspace(policyOwnerEmail = '', makeMeAdmin = false, policyName
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseChatReportID}`,
value: expenseReportActionData,
},
{
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.POLICY_DRAFTS}${policyID}`,
value: null,
},
{
onyxMethod: Onyx.METHOD.SET,
key: `${ONYXKEYS.COLLECTION.POLICY_MEMBERS_DRAFTS}${policyID}`,
value: null,
},
],
successData: [
{
Expand Down Expand Up @@ -1131,6 +1183,7 @@ function createWorkspace(policyOwnerEmail = '', makeMeAdmin = false, policyName
],
},
);

return adminsChatReportID;
}

Expand Down Expand Up @@ -1259,4 +1312,5 @@ export {
clearErrors,
openDraftWorkspaceRequest,
buildOptimisticPolicyRecentlyUsedCategories,
createDraftInitialWorkspace,
};
18 changes: 15 additions & 3 deletions src/pages/workspace/WorkspaceInitialPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import Tooltip from '../../components/Tooltip';
import Text from '../../components/Text';
import ConfirmModal from '../../components/ConfirmModal';
import * as Expensicons from '../../components/Icon/Expensicons';
import * as App from '../../libs/actions/App';
import ScreenWrapper from '../../components/ScreenWrapper';
import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
import MenuItem from '../../components/MenuItem';
Expand Down Expand Up @@ -65,7 +66,7 @@ function dismissError(policyID) {
}

function WorkspaceInitialPage(props) {
const policy = props.policy;
const policy = props.policyDraft && props.policyDraft.id ? props.policyDraft : props.policy;
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const [isCurrencyModalOpen, setIsCurrencyModalOpen] = useState(false);
const hasPolicyCreationError = Boolean(policy.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD && policy.errors);
Expand All @@ -81,6 +82,17 @@ function WorkspaceInitialPage(props) {
Navigation.goBack(ROUTES.SETTINGS_WORKSPACES);
}, [props.reports, policy]);

useEffect(() => {
const policyDraftId = lodashGet(props.policyDraft, 'id', null);
if (!policyDraftId) {
return;
}

App.savePolicyDraftByNewWorkspace(props.policyDraft.id, props.policyDraft.name, '', false);
// We only care when the component renders the first time
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

useEffect(() => {
if (!isCurrencyModalOpen || policy.outputCurrency !== CONST.CURRENCY.USD) {
return;
Expand Down Expand Up @@ -189,8 +201,8 @@ function WorkspaceInitialPage(props) {
{({safeAreaPaddingBottomStyle}) => (
<FullPageNotFoundView
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)}
shouldShow={_.isEmpty(props.policy) || !PolicyUtils.isPolicyAdmin(props.policy) || PolicyUtils.isPendingDeletePolicy(props.policy)}
subtitleKey={_.isEmpty(props.policy) ? undefined : 'workspace.common.notAuthorized'}
shouldShow={_.isEmpty(policy) || !PolicyUtils.isPolicyAdmin(policy) || PolicyUtils.isPendingDeletePolicy(policy)}
subtitleKey={_.isEmpty(policy) ? undefined : 'workspace.common.notAuthorized'}
>
<HeaderWithBackButton
title={props.translate('workspace.common.workspace')}
Expand Down
4 changes: 1 addition & 3 deletions src/pages/workspace/WorkspacesListPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import * as App from '../../libs/actions/App';
import useLocalize from '../../hooks/useLocalize';
import useNetwork from '../../hooks/useNetwork';
import usePermissions from '../../hooks/usePermissions';
import useWindowDimensions from '../../hooks/useWindowDimensions';
import IllustratedHeaderPageLayout from '../../components/IllustratedHeaderPageLayout';
import SCREENS from '../../SCREENS';
import * as LottieAnimations from '../../components/LottieAnimations';
Expand Down Expand Up @@ -112,7 +111,6 @@ function WorkspacesListPage({policies, allPolicyMembers, reimbursementAccount, u
const {translate} = useLocalize();
const {isOffline} = useNetwork();
const {canUseWallet} = usePermissions();
const {isSmallScreenWidth} = useWindowDimensions();

/**
* @param {Boolean} isPaymentItem whether the item being rendered is the payments menu item
Expand Down Expand Up @@ -194,7 +192,7 @@ function WorkspacesListPage({policies, allPolicyMembers, reimbursementAccount, u
accessibilityLabel={translate('workspace.new.newWorkspace')}
success
text={translate('workspace.new.newWorkspace')}
onPress={() => App.createWorkspaceAndNavigateToIt('', false, '', false, !isSmallScreenWidth)}
onPress={() => App.createWorkspaceWithPolicyDraftAndNavigateToIt()}
/>
}
>
Expand Down
6 changes: 6 additions & 0 deletions src/pages/workspace/withPolicy.js
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,12 @@ export default function (WrappedComponent) {
policyMembers: {
key: (props) => `${ONYXKEYS.COLLECTION.POLICY_MEMBERS}${getPolicyIDFromRoute(props.route)}`,
},
policyDraft: {
key: (props) => `${ONYXKEYS.COLLECTION.POLICY_DRAFTS}${getPolicyIDFromRoute(props.route)}`,
},
policyMembersDraft: {
key: (props) => `${ONYXKEYS.COLLECTION.POLICY_MEMBERS_DRAFTS}${getPolicyIDFromRoute(props.route)}`,
},
})(withPolicy);
}

Expand Down
7 changes: 4 additions & 3 deletions src/pages/workspace/withPolicyAndFullscreenLoading.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import PropTypes from 'prop-types';
import React from 'react';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import isEmpty from 'lodash/isEmpty';
import omit from 'lodash/omit';
import compose from '../../libs/compose';
import ONYXKEYS from '../../ONYXKEYS';
import withPolicy, {policyPropTypes, policyDefaultProps} from './withPolicy';
Expand All @@ -27,11 +28,11 @@ export default function (WrappedComponent) {
};

function WithPolicyAndFullscreenLoading(props) {
if (props.isLoadingReportData && _.isEmpty(props.policy)) {
if (props.isLoadingReportData && isEmpty(props.policy) && isEmpty(props.policyDraft)) {
return <FullscreenLoadingIndicator />;
}

const rest = _.omit(props, ['forwardedRef']);
const rest = omit(props, ['forwardedRef']);
return (
<WrappedComponent
// eslint-disable-next-line react/jsx-props-no-spreading
Expand Down

0 comments on commit e213f7e

Please sign in to comment.