From 037d6c47391886f32d683c7d71902b9c8781f2a0 Mon Sep 17 00:00:00 2001 From: Aldo Canepa Date: Tue, 23 Aug 2022 18:33:39 +0200 Subject: [PATCH 01/11] WIP: Use new API pattern B --- src/libs/actions/Policy.js | 98 +++++++++++++++------ src/pages/settings/InitialSettingsPage.js | 47 +++++++--- src/pages/workspace/WorkspaceInitialPage.js | 3 +- 3 files changed, 108 insertions(+), 40 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 9470ea25f4e0..04145a9e85a2 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -13,6 +13,7 @@ import ROUTES from '../../ROUTES'; import * as OptionsListUtils from '../OptionsListUtils'; import * as Report from './Report'; import * as Pusher from '../Pusher/pusher'; +import * as API from '../API'; const allPolicies = {}; Onyx.connect({ @@ -22,7 +23,7 @@ Onyx.connect({ return; } - allPolicies[key] = {...allPolicies[key], ...val}; + allPolicies[key] = val; }, }); let sessionEmail = ''; @@ -170,31 +171,63 @@ function createAndNavigate(name = '') { } /** - * Delete the policy + * Delete the workspace * - * @param {String} [policyID] - * @returns {Promise} + * @param {String} policyID */ -function deletePolicy(policyID) { - return DeprecatedAPI.Policy_Delete({policyID}) - .then((response) => { - if (response.jsonCode !== 200) { - // Show the user feedback - const errorMessage = Localize.translateLocal('workspace.common.growlMessageOnDeleteError'); - Growl.error(errorMessage, 5000); - return; - } - - Growl.show(Localize.translateLocal('workspace.common.growlMessageOnDelete'), CONST.GROWL.SUCCESS, 3000); - - // Removing the workspace data from Onyx as well - return Onyx.set(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, null); - }) - .then(() => Report.fetchAllReports(false)) - .then(() => { - Navigation.goBack(); - return Promise.resolve(); - }); +function deleteWorkspace(policyID) { + const optimisticData = [ + { + onyxMethod: 'merge', + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + 'pendingAction': 'delete', + }, + }, + ]; + + // We don't need success data since the push notification will update + // the onyxData for all connected clients. + const failureData = []; + const successData = []; + // const failureData = [ + // { + // onyxMethod: 'merge', + // key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + // value: { + // 'pendingAction': null, + // 'errors': { + // : '', + // } + // }, + // }, + // ]; + + API.write('DeleteWorkspace', {policyID}, {optimisticData, successData, failureData}); + + // const optimisticData = [{ + // onyxMethod: CONST.ONYX.METHOD.MERGE, + // key: ONYXKEYS.ACCOUNT, + // value: {isLoading: true}, + // }]; + // const successData = [{ + // onyxMethod: CONST.ONYX.METHOD.MERGE, + // key: ONYXKEYS.ACCOUNT, + // value: { + // isLoading: false, + // message: Localize.translateLocal('resendValidationForm.linkHasBeenResent'), + // }, + // }]; + // const failureData = [{ + // onyxMethod: CONST.ONYX.METHOD.MERGE, + // key: ONYXKEYS.ACCOUNT, + // value: { + // isLoading: false, + // message: '', + // }, + // }]; + + // API.read('DeleteWorkspace', {policyID}, {optimisticData, successData, failureData}); } /** @@ -544,7 +577,7 @@ function subscribeToPolicyEvents() { * @param {String} policyID * @param {String} memberEmail */ -function clearDeleteMemberError(policyID, memberEmail) { + function clearDeleteMemberError(policyID, memberEmail) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, { [memberEmail]: { pendingAction: null, @@ -565,6 +598,18 @@ function clearAddMemberError(policyID, memberEmail) { }); } +/** + * Removes an error after trying to delete a workspace + * + * @param {String} policyID + */ +function clearDeleteWorkspaceError(policyID) { + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, { + pendingAction: null, + errors: null, + }); +} + /** * Checks if we have any errors stored within the POLICY_MEMBER_LIST. Determines whether we should show a red brick road error or not * Data structure: {email: {role:'bla', errors: []}, email2: {role:'bla', errors: [{1231312313: 'Unable to do X'}]}, ...} @@ -586,7 +631,8 @@ export { update, setWorkspaceErrors, hideWorkspaceAlertMessage, - deletePolicy, + deleteWorkspace, + clearDeleteWorkspaceError, createAndNavigate, createAndGetPolicyList, setCustomUnit, diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 785e00322716..e9bfed075ae5 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -29,6 +29,7 @@ import policyMemberPropType from '../policyMemberPropType'; import * as PaymentMethods from '../../libs/actions/PaymentMethods'; import bankAccountPropTypes from '../../components/bankAccountPropTypes'; import cardPropTypes from '../../components/cardPropTypes'; +import OfflineWithFeedback from '../../components/OfflineWithFeedback'; const propTypes = { /* Onyx Props */ @@ -87,6 +88,20 @@ const defaultProps = { ...withCurrentUserPersonalDetailsDefaultProps, }; +/** + * Dismisses the errors on one item + * + * @param {string} policyID + * @param {string} pendingAction + */ +function dismissWorkspaceError(policyID, pendingAction) { + if (pendingAction === 'delete') { + Policy.clearDeleteWorkspaceError(policyID); + return; + } + throw new Error('Not implemented'); +} + const InitialSettingsPage = (props) => { // On the very first sign in or after clearing storage these // details will not be present on the first render so we'll just @@ -146,6 +161,9 @@ const InitialSettingsPage = (props) => { iconFill: themeColors.iconReversed, fallbackIcon: Expensicons.FallbackWorkspaceAvatar, brickRoadIndicator: Policy.hasPolicyMemberError(lodashGet(props.policyMembers, `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policy.id}`, {})) ? 'error' : null, + pendingAction: policy.pendingAction, + errors: policy.errors, + dismissError: () => dismissWorkspaceError(policy.id, policy.pendingAction), })) .value(); menuItems.push(...defaultMenuItems); @@ -190,20 +208,23 @@ const InitialSettingsPage = (props) => { {_.map(menuItems, (item, index) => { const keyTitle = item.translationKey ? props.translate(item.translationKey) : item.title; const isPaymentItem = item.translationKey === 'common.payments'; + const doNothing = () => {}; return ( - + + + ); })} diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index a4b086c31962..dbae6423d9fb 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -70,8 +70,9 @@ class WorkspaceInitialPage extends React.Component { * Call the delete policy and hide the modal */ confirmDeleteAndHideModal() { - PolicyActions.deletePolicy(this.props.policy.id); + PolicyActions.deleteWorkspace(this.props.policy.id); this.toggleDeleteModal(false); + Navigation.navigate(ROUTES.SETTINGS); } render() { From f084a68e62a5a5bb8adf66568cb847b84c099109 Mon Sep 17 00:00:00 2001 From: Aldo Canepa Date: Wed, 24 Aug 2022 10:38:27 +0200 Subject: [PATCH 02/11] Add padding --- src/pages/settings/InitialSettingsPage.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index e9bfed075ae5..235376c83874 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -210,7 +210,11 @@ const InitialSettingsPage = (props) => { const isPaymentItem = item.translationKey === 'common.payments'; const doNothing = () => {}; return ( - + Date: Thu, 25 Aug 2022 11:41:03 +0200 Subject: [PATCH 03/11] Correct menu item padding --- src/pages/settings/InitialSettingsPage.js | 2 +- src/styles/styles.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 235376c83874..6ca169a77c89 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -211,7 +211,7 @@ const InitialSettingsPage = (props) => { const doNothing = () => {}; return ( diff --git a/src/styles/styles.js b/src/styles/styles.js index 36a4d7eaea40..109ebd5a462c 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -2408,6 +2408,10 @@ const styles = { errorDot: { marginRight: 12, }, + menuItemErrorPadding: { + paddingLeft: 44, + paddingRight: 20, + } }, sidebarPopover: { From 75e635e22a51bd3e598397284af4d00e7ab67aa6 Mon Sep 17 00:00:00 2001 From: Aldo Canepa Date: Thu, 25 Aug 2022 18:30:24 +0200 Subject: [PATCH 04/11] Clear errors, fix key prop --- src/libs/actions/Policy.js | 16 ++-------------- src/pages/settings/InitialSettingsPage.js | 2 +- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 04145a9e85a2..816146b74f7f 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -181,7 +181,8 @@ function deleteWorkspace(policyID) { onyxMethod: 'merge', key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - 'pendingAction': 'delete', + pendingAction: 'delete', + errors: null, }, }, ]; @@ -190,19 +191,6 @@ function deleteWorkspace(policyID) { // the onyxData for all connected clients. const failureData = []; const successData = []; - // const failureData = [ - // { - // onyxMethod: 'merge', - // key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, - // value: { - // 'pendingAction': null, - // 'errors': { - // : '', - // } - // }, - // }, - // ]; - API.write('DeleteWorkspace', {policyID}, {optimisticData, successData, failureData}); // const optimisticData = [{ diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 6ca169a77c89..9281a4b89e7d 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -211,12 +211,12 @@ const InitialSettingsPage = (props) => { const doNothing = () => {}; return ( Date: Fri, 26 Aug 2022 10:08:40 +0200 Subject: [PATCH 05/11] Disable the workspace menu item while the delete request has not resolved --- src/pages/settings/InitialSettingsPage.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 9281a4b89e7d..93183bffe87d 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -164,6 +164,7 @@ const InitialSettingsPage = (props) => { pendingAction: policy.pendingAction, errors: policy.errors, dismissError: () => dismissWorkspaceError(policy.id, policy.pendingAction), + disabled: policy.pendingAction === 'delete' && _.isEmpty(policy.errors), })) .value(); menuItems.push(...defaultMenuItems); @@ -217,6 +218,7 @@ const InitialSettingsPage = (props) => { pendingAction={item.pendingAction} errors={item.errors}> Date: Fri, 26 Aug 2022 10:09:39 +0200 Subject: [PATCH 06/11] Remove comments --- src/libs/actions/Policy.js | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 816146b74f7f..fd096eb08bc2 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -192,30 +192,6 @@ function deleteWorkspace(policyID) { const failureData = []; const successData = []; API.write('DeleteWorkspace', {policyID}, {optimisticData, successData, failureData}); - - // const optimisticData = [{ - // onyxMethod: CONST.ONYX.METHOD.MERGE, - // key: ONYXKEYS.ACCOUNT, - // value: {isLoading: true}, - // }]; - // const successData = [{ - // onyxMethod: CONST.ONYX.METHOD.MERGE, - // key: ONYXKEYS.ACCOUNT, - // value: { - // isLoading: false, - // message: Localize.translateLocal('resendValidationForm.linkHasBeenResent'), - // }, - // }]; - // const failureData = [{ - // onyxMethod: CONST.ONYX.METHOD.MERGE, - // key: ONYXKEYS.ACCOUNT, - // value: { - // isLoading: false, - // message: '', - // }, - // }]; - - // API.read('DeleteWorkspace', {policyID}, {optimisticData, successData, failureData}); } /** From 79be75b24a067836f9de3ffeb8ccfe291be849a8 Mon Sep 17 00:00:00 2001 From: Aldo Canepa Date: Fri, 26 Aug 2022 10:10:56 +0200 Subject: [PATCH 07/11] Remove whitespace --- src/libs/actions/Policy.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index fd096eb08bc2..98e6a17d9bf6 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -541,7 +541,7 @@ function subscribeToPolicyEvents() { * @param {String} policyID * @param {String} memberEmail */ - function clearDeleteMemberError(policyID, memberEmail) { +function clearDeleteMemberError(policyID, memberEmail) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policyID}`, { [memberEmail]: { pendingAction: null, From ffcb9f86181e380cbeafafd22267677b28ccc992 Mon Sep 17 00:00:00 2001 From: Aldo Canepa Date: Tue, 30 Aug 2022 00:55:51 +0200 Subject: [PATCH 08/11] Style --- src/libs/actions/Policy.js | 4 ++-- src/pages/settings/InitialSettingsPage.js | 11 ++++++----- src/styles/styles.js | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index c978fbc14dbc..65dc2a23e579 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -2,6 +2,7 @@ import _ from 'underscore'; import Onyx from 'react-native-onyx'; import lodashGet from 'lodash/get'; import * as DeprecatedAPI from '../deprecatedAPI'; +import * as API from '../API'; import ONYXKEYS from '../../ONYXKEYS'; import * as PersonalDetails from './PersonalDetails'; import Growl from '../Growl'; @@ -13,7 +14,6 @@ import ROUTES from '../../ROUTES'; import * as OptionsListUtils from '../OptionsListUtils'; import * as Report from './Report'; import * as Pusher from '../Pusher/pusher'; -import * as API from '../API'; import DateUtils from '../DateUtils'; const allPolicies = {}; @@ -173,7 +173,7 @@ function deleteWorkspace(policyID) { }, ]; - // We don't need success data since the push notification will update + // We don't need success data since the push notification will update // the onyxData for all connected clients. const failureData = []; const successData = []; diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 4a506805229c..02c087283140 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -8,6 +8,7 @@ import styles from '../../styles/styles'; import themeColors from '../../styles/themes/default'; import Text from '../../components/Text'; import * as Session from '../../libs/actions/Session'; +import * as Policy from '../../libs/actions/Policy'; import ONYXKEYS from '../../ONYXKEYS'; import Tooltip from '../../components/Tooltip'; import Avatar from '../../components/Avatar'; @@ -94,7 +95,7 @@ const defaultProps = { * @param {string} policyID * @param {string} pendingAction */ - function dismissWorkspaceError(policyID, pendingAction) { +function dismissWorkspaceError(policyID, pendingAction) { if (pendingAction === 'delete') { Policy.clearDeleteWorkspaceError(policyID); return; @@ -205,7 +206,6 @@ class InitialSettingsPage extends React.Component { if (_.isEmpty(this.props.currentUserPersonalDetails)) { return null; } - const doNothing = () => {}; return ( {})} pendingAction={item.pendingAction} - errors={item.errors}> + errors={item.errors} + > Date: Fri, 2 Sep 2022 18:01:44 +0200 Subject: [PATCH 09/11] Fix error indicator for workspace delete --- src/libs/PolicyUtils.js | 2 +- src/pages/settings/InitialSettingsPage.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libs/PolicyUtils.js b/src/libs/PolicyUtils.js index 7dc18f3b395c..3def54c19f98 100644 --- a/src/libs/PolicyUtils.js +++ b/src/libs/PolicyUtils.js @@ -48,7 +48,7 @@ function hasCustomUnitsError(policy) { */ function getPolicyBrickRoadIndicatorStatus(policy, policyMembers) { const policyMemberList = lodashGet(policyMembers, `${ONYXKEYS.COLLECTION.POLICY_MEMBER_LIST}${policy.id}`, {}); - if (hasPolicyMemberError(policyMemberList) || hasPolicyError(policy) || hasCustomUnitsError(policy)) { + if (hasPolicyMemberError(policyMemberList) || hasCustomUnitsError(policy)) { return CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR; } return ''; diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index f6ed93b6feea..470fe443da05 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -192,7 +192,7 @@ class InitialSettingsPage extends React.Component { isPolicy: true, errors: policy.errors, dismissError: () => dismissWorkspaceError(policy.id, policy.pendingAction), - disabled: policy.pendingAction === 'delete' && _.isEmpty(policy.errors), + disabled: policy.pendingAction === 'delete', })) .value(); menuItems.push(...this.getDefaultMenuItems()); @@ -224,6 +224,7 @@ class InitialSettingsPage extends React.Component { badgeText={this.getWalletBalance(isPaymentItem)} fallbackIcon={item.fallbackIcon} brickRoadIndicator={item.brickRoadIndicator} + disabled={item.disabled} /> ); From 7407995b3bed6bc02840eb478cda4da7a56877fa Mon Sep 17 00:00:00 2001 From: Aldo Canepa Date: Fri, 2 Sep 2022 18:33:27 +0200 Subject: [PATCH 10/11] Use const for 'delete' pending action --- src/libs/actions/Policy.js | 2 +- src/pages/settings/InitialSettingsPage.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 94fefa481347..45676838001d 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -174,7 +174,7 @@ function deleteWorkspace(policyID) { onyxMethod: 'merge', key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - pendingAction: 'delete', + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, errors: null, }, }, diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 470fe443da05..e10aeb056d1f 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -192,7 +192,7 @@ class InitialSettingsPage extends React.Component { isPolicy: true, errors: policy.errors, dismissError: () => dismissWorkspaceError(policy.id, policy.pendingAction), - disabled: policy.pendingAction === 'delete', + disabled: policy.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, })) .value(); menuItems.push(...this.getDefaultMenuItems()); From f740a07602a819e539a108a7c126a9269b545ae4 Mon Sep 17 00:00:00 2001 From: Aldo Canepa Date: Sat, 3 Sep 2022 20:48:34 +0100 Subject: [PATCH 11/11] Use CONST! --- src/libs/actions/Policy.js | 2 +- src/pages/settings/InitialSettingsPage.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index 45676838001d..641eb40d6e47 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -171,7 +171,7 @@ function createAndNavigate(name = '') { function deleteWorkspace(policyID) { const optimisticData = [ { - onyxMethod: 'merge', + onyxMethod: CONST.ONYX.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE, diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index e10aeb056d1f..f58556cd536d 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -99,7 +99,7 @@ const defaultProps = { * @param {string} pendingAction */ function dismissWorkspaceError(policyID, pendingAction) { - if (pendingAction === 'delete') { + if (pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE) { Policy.clearDeleteWorkspaceError(policyID); return; }