From 9f101864133aa645298ca76fabf7cd68747e7179 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Sat, 2 Mar 2024 00:23:59 +0530 Subject: [PATCH 01/74] adds workflow payer page --- src/ROUTES.ts | 4 ++++ src/SCREENS.ts | 1 + src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx | 1 + .../linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts | 1 + src/libs/Navigation/linkingConfig/config.ts | 3 +++ .../workspace/workflows/WorkspaceWorkflowsPayerPage.tsx | 8 ++++++++ 6 files changed, 18 insertions(+) create mode 100644 src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 22ebffd52eec..bd3d37e21ed1 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -486,6 +486,10 @@ const ROUTES = { route: 'workspace/:policyID/workflows', getRoute: (policyID: string) => `workspace/${policyID}/workflows` as const, }, + WORKSPACE_WORKFLOWS_PAYER: { + route: 'workspace/:policyID/settings/workflows/payer', + getRoute: (policyId: string) => `workspace/${policyId}/settings/workflows/payer` as const, + }, WORKSPACE_CARD: { route: 'workspace/:policyID/card', getRoute: (policyID: string) => `workspace/${policyID}/card` as const, diff --git a/src/SCREENS.ts b/src/SCREENS.ts index ac75968e68b9..0bb74424cd40 100644 --- a/src/SCREENS.ts +++ b/src/SCREENS.ts @@ -216,6 +216,7 @@ const SCREENS = { CATEGORIES: 'Workspace_Categories', CURRENCY: 'Workspace_Profile_Currency', WORKFLOWS: 'Workspace_Workflows', + WORKFLOWS_PAYER: 'Workspace_Workflows_Payer', DESCRIPTION: 'Workspace_Profile_Description', SHARE: 'Workspace_Profile_Share', NAME: 'Workspace_Profile_Name', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx index 3d0144d8cf77..3effc82fbf0f 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.tsx @@ -244,6 +244,7 @@ const SettingsModalStackNavigator = createModalStackNavigator require('../../../pages/workspace/reimburse/WorkspaceRateAndUnitPage/UnitPage').default as React.ComponentType, [SCREENS.WORKSPACE.INVITE]: () => require('../../../pages/workspace/WorkspaceInvitePage').default as React.ComponentType, [SCREENS.WORKSPACE.INVITE_MESSAGE]: () => require('../../../pages/workspace/WorkspaceInviteMessagePage').default as React.ComponentType, + [SCREENS.WORKSPACE.WORKFLOWS_PAYER]: () => require('../../../pages/workspace/workflows/WorkspaceWorkflowsPayerPage').default as React.ComponentType, [SCREENS.WORKSPACE.NAME]: () => require('../../../pages/workspace/WorkspaceNamePage').default as React.ComponentType, [SCREENS.WORKSPACE.DESCRIPTION]: () => require('../../../pages/workspace/WorkspaceProfileDescriptionPage').default as React.ComponentType, [SCREENS.WORKSPACE.SHARE]: () => require('../../../pages/workspace/WorkspaceProfileSharePage').default as React.ComponentType, diff --git a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts index 7e38ed99105e..2f0c5350716d 100755 --- a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts @@ -5,6 +5,7 @@ const CENTRAL_PANE_TO_RHP_MAPPING: Partial> = [SCREENS.WORKSPACE.PROFILE]: [SCREENS.WORKSPACE.NAME, SCREENS.WORKSPACE.CURRENCY, SCREENS.WORKSPACE.DESCRIPTION, SCREENS.WORKSPACE.SHARE], [SCREENS.WORKSPACE.REIMBURSE]: [SCREENS.WORKSPACE.RATE_AND_UNIT, SCREENS.WORKSPACE.RATE_AND_UNIT_RATE, SCREENS.WORKSPACE.RATE_AND_UNIT_UNIT], [SCREENS.WORKSPACE.MEMBERS]: [SCREENS.WORKSPACE.INVITE, SCREENS.WORKSPACE.INVITE_MESSAGE], + [SCREENS.WORKSPACE.WORKFLOWS]: [SCREENS.WORKSPACE.WORKFLOWS_PAYER], }; export default CENTRAL_PANE_TO_RHP_MAPPING; diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 7a6211ebd283..6f9c93529814 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -262,6 +262,9 @@ const config: LinkingOptions['config'] = { [SCREENS.WORKSPACE.CATEGORIES_SETTINGS]: { path: ROUTES.WORKSPACE_CATEGORIES_SETTINGS.route, }, + [SCREENS.WORKSPACE.WORKFLOWS_PAYER]: { + path: ROUTES.WORKSPACE_WORKFLOWS_PAYER.route, + }, [SCREENS.REIMBURSEMENT_ACCOUNT]: { path: ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.route, exact: true, diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx new file mode 100644 index 000000000000..9008db10daa1 --- /dev/null +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import {View} from 'react-native'; + +function WorkspaceWorkflowsPayerPage() { + return some text; +} + +export default WorkspaceWorkflowsPayerPage; From 6492353af3dca520de1bfa25118126b1b2bd3b3f Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Sat, 2 Mar 2024 00:25:08 +0530 Subject: [PATCH 02/74] fixes scrollins issue and adds submenuitem for payer --- src/languages/en.ts | 1 + src/languages/es.ts | 1 + .../workflows/WorkspaceWorkflowsPage.tsx | 139 ++++++++++++++---- src/types/onyx/Policy.ts | 2 + 4 files changed, 114 insertions(+), 29 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 995279033a3e..29533dc63ec4 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1049,6 +1049,7 @@ export default { addApprovalsDescription: 'Require additional approval before authorizing a payment.', makeOrTrackPaymentsTitle: 'Make or track payments', makeOrTrackPaymentsDescription: 'Add an authorized payer for payments made in Expensify, or simply track payments made elsewhere.', + authorizedPayer: 'Authorized payer', }, reportFraudPage: { title: 'Report virtual card fraud', diff --git a/src/languages/es.ts b/src/languages/es.ts index f4b4e6a2f21e..936d0b3c957b 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1045,6 +1045,7 @@ export default { addApprovalsDescription: 'Requiere una aprobación adicional antes de autorizar un pago.', makeOrTrackPaymentsTitle: 'Realizar o seguir pagos', makeOrTrackPaymentsDescription: 'Añade un pagador autorizado para los pagos realizados en Expensify, o simplemente realiza un seguimiento de los pagos realizados en otro lugar.', + authorizedPayer: 'Authorized payer', }, reportFraudPage: { title: 'Reportar fraude con la tarjeta virtual', diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index fc1ed1d19560..5b0f5b52c931 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,43 +1,95 @@ +import {useIsFocused} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useMemo} from 'react'; -import {FlatList, View} from 'react-native'; +import React, {useCallback, useEffect, useMemo} from 'react'; +import {View} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; import * as Illustrations from '@components/Icon/Illustrations'; import MenuItem from '@components/MenuItem'; import Section from '@components/Section'; import Text from '@components/Text'; +import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; +import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; +import usePrevious from '@hooks/usePrevious'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import BankAccount from '@libs/models/BankAccount'; +import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import type {CentralPaneNavigatorParamList} from '@navigation/types'; import withPolicy from '@pages/workspace/withPolicy'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections'; +import * as BankAccounts from '@userActions/BankAccounts'; import * as Policy from '@userActions/Policy'; +import {navigateToBankAccountRoute} from '@userActions/ReimbursementAccount'; import CONST from '@src/CONST'; +import ONYXKEYS from '@src/ONYXKEYS'; +import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; +import type {ReimbursementAccount} from '@src/types/onyx'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; -type WorkspaceWorkflowsPageProps = WithPolicyProps & StackScreenProps; +type WorkspaceWorkflowsPageWithReimbursementAccountProps = { + /** Reimbursement account details */ + reimbursementAccount: OnyxEntry; +}; -function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { +type WorkspaceWorkflowsPageProps = WithCurrentUserPersonalDetailsProps & + WorkspaceWorkflowsPageWithReimbursementAccountProps & + WithPolicyProps & + StackScreenProps; + +function WorkspaceWorkflowsPage({policy, route, reimbursementAccount, currentUserPersonalDetails}: WorkspaceWorkflowsPageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const {isSmallScreenWidth} = useWindowDimensions(); const {isOffline} = useNetwork(); + const isFocused = useIsFocused(); + const prevIsFocused = usePrevious(isFocused); + const ownerPersonalDetails = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs([policy?.ownerAccountID ?? 0], CONST.EMPTY_OBJECT), false); const policyOwnerDisplayName = ownerPersonalDetails[0]?.displayName; const containerStyle = useMemo(() => [styles.ph8, styles.mhn8, styles.ml11, styles.pv3, styles.pr0, styles.pl4, styles.mr0, styles.widthAuto, styles.mt4], [styles]); - const items: ToggleSettingOptionRowProps[] = useMemo( - () => [ + const authorizedPayerAccountID = policy?.authorizedPayerAccountID ?? policy?.ownerAccountID ?? 0; + + const displayNameForAuthorizedPayer = PersonalDetailsUtils.getPersonalDetailsByIDs([authorizedPayerAccountID], currentUserPersonalDetails.accountID)[0]?.displayName; + + const fetchData = useCallback(() => { + // Instead of setting the reimbursement account loading within the optimistic data of the API command, use a separate action so that the Onyx value is updated right away. + // openWorkspaceReimburseView uses API.read which will not make the request until all WRITE requests in the sequential queue have finished responding, so there would be a delay in + // updating Onyx with the optimistic data. + if (!policy?.id) { + return; + } + BankAccounts.setReimbursementAccountLoading(true); + Policy.openWorkspaceReimburseView(policy?.id); + }, [policy]); + + useEffect(() => { + if (isOffline || !isFocused || prevIsFocused === isFocused) { + return; + } + fetchData(); + }, [fetchData, isOffline, isFocused, prevIsFocused]); + + const activeRoute = Navigation.getActiveRouteWithoutParams(); + + const items: ToggleSettingOptionRowProps[] = useMemo(() => { + const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; + const hasVBA = state === BankAccount.STATE.OPEN; + const bankDisplayName = bankName ? `${bankName} ${accountNumber ? `${accountNumber.slice(-5)}` : ''}` : ''; + return [ { icon: Illustrations.ReceiptEnvelope, title: translate('workflowsPage.delaySubmissionTitle'), @@ -92,27 +144,50 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 }, subMenuItems: ( - Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_CONNECT_BANK_ACCOUNT.getRoute(route.params.policyID))} - // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 - shouldShowRightIcon - wrapperStyle={containerStyle} - hoverAndPressStyle={[styles.mr0, styles.br2]} - /> + <> + navigateToBankAccountRoute(route.params.policyID, activeRoute)} + // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 + shouldShowRightIcon + wrapperStyle={containerStyle} + hoverAndPressStyle={[styles.mr0, styles.br2]} + /> + {hasVBA && ( + Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_PAYER.getRoute(route.params.policyID))} + // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 + shouldShowRightIcon + wrapperStyle={containerStyle} + hoverAndPressStyle={[styles.mr0, styles.br2]} + /> + )} + ), isEndOptionRow: true, - isActive: false, // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 + isActive: true, // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 }, - ], - [policy, route.params.policyID, styles, translate, policyOwnerDisplayName, containerStyle, isOffline, StyleUtils], - ); + ]; + }, [policy, route.params.policyID, styles, translate, policyOwnerDisplayName, containerStyle, isOffline, StyleUtils, activeRoute, reimbursementAccount, displayNameForAuthorizedPayer]); - const renderItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( - + const renderOptionItem = (item: ToggleSettingOptionRowProps, index: number) => ( +
{translate('workflowsPage.workflowDescription')} - item.title} - /> + {items.map((item, index) => renderOptionItem(item, index))}
@@ -159,4 +233,11 @@ function WorkspaceWorkflowsPage({policy, route}: WorkspaceWorkflowsPageProps) { WorkspaceWorkflowsPage.displayName = 'WorkspaceWorkflowsPage'; -export default withPolicy(WorkspaceWorkflowsPage); +const WorkspaceWorkflowsPageWithReimbursementAccount = withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM + reimbursementAccount: { + key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, + }, +})(WorkspaceWorkflowsPage); + +export default withCurrentUserPersonalDetails(withPolicy(WorkspaceWorkflowsPageWithReimbursementAccount)); diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index fc07e1e1760a..93f75901d019 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -102,6 +102,8 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< /** The accountID of the policy owner */ ownerAccountID?: number; + /** The accountID of the authorized payer */ + authorizedPayerAccountID: number; /** The output currency for the policy */ outputCurrency: string; From 3bc84784ec108799549d5b7d403f8dfda7e21093 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Sat, 2 Mar 2024 00:44:17 +0530 Subject: [PATCH 03/74] fixes type error --- src/ROUTES.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 4386f7c822c5..a9c8f0ed2e17 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -489,7 +489,7 @@ const ROUTES = { WORKSPACE_WORKFLOWS_PAYER: { route: 'workspace/:policyID/settings/workflows/payer', getRoute: (policyId: string) => `workspace/${policyId}/settings/workflows/payer` as const, - } + }, WORKSPACE_WORKFLOWS_APPROVER: { route: 'workspace/:policyID/settings/workflows/approver', getRoute: (policyId: string) => `workspace/${policyId}/settings/workflows/approver` as const, From f5bcfa5a5b3208b0754586701da58f16a9268126 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Sat, 2 Mar 2024 00:54:28 +0530 Subject: [PATCH 04/74] fix failing tests --- .../workflows/WorkspaceWorkflowsPage.tsx | 71 ++++++++++--------- src/types/onyx/Policy.ts | 5 +- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 79f942b5eac3..978f8cc6c259 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -17,10 +17,10 @@ import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import BankAccount from '@libs/models/BankAccount'; -import * as OptionsListUtils from '@libs/OptionsListUtils'; -import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import Navigation from '@libs/Navigation/Navigation'; +import * as OptionsListUtils from '@libs/OptionsListUtils'; import Permissions from '@libs/Permissions'; +import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import type {CentralPaneNavigatorParamList} from '@navigation/types'; @@ -34,20 +34,22 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type {ReimbursementAccount, Beta} from '@src/types/onyx'; +import type {Beta, ReimbursementAccount} from '@src/types/onyx'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; import {getAutoReportingFrequencyDisplayNames} from './WorkspaceAutoReportingFrequencyPage'; import type {AutoReportingFrequencyKey} from './WorkspaceAutoReportingFrequencyPage'; - type WorkspaceWorkflowsPageOnyxProps = { /** Beta features list */ betas: OnyxEntry; /** Reimbursement account details */ reimbursementAccount: OnyxEntry; }; -type WorkspaceWorkflowsPageProps = WithCurrentUserPersonalDetailsProps & WithPolicyProps & WorkspaceWorkflowsPageOnyxProps & StackScreenProps; +type WorkspaceWorkflowsPageProps = WithCurrentUserPersonalDetailsProps & + WithPolicyProps & + WorkspaceWorkflowsPageOnyxProps & + StackScreenProps; function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, currentUserPersonalDetails}: WorkspaceWorkflowsPageProps) { const {translate, preferredLocale} = useLocalize(); @@ -66,7 +68,6 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur const onPressAutoReportingFrequency = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY.getRoute(policy?.id ?? '')), [policy?.id]); - const authorizedPayerAccountID = policy?.authorizedPayerAccountID ?? policy?.ownerAccountID ?? 0; const displayNameForAuthorizedPayer = PersonalDetailsUtils.getPersonalDetailsByIDs([authorizedPayerAccountID], currentUserPersonalDetails.accountID)[0]?.displayName; @@ -194,24 +195,22 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur isActive: true, // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 }, ]; - }, - [ - policy, - route.params.policyID, - styles, - translate, - policyOwnerDisplayName, - containerStyle, - isOffline, - StyleUtils, - onPressAutoReportingFrequency, - preferredLocale, - canUseDelayedSubmission, - activeRoute, - reimbursementAccount, - displayNameForAuthorizedPayer - ], - ); + }, [ + policy, + route.params.policyID, + styles, + translate, + policyOwnerDisplayName, + containerStyle, + isOffline, + StyleUtils, + onPressAutoReportingFrequency, + preferredLocale, + canUseDelayedSubmission, + activeRoute, + reimbursementAccount, + displayNameForAuthorizedPayer, + ]); const renderOptionItem = (item: ToggleSettingOptionRowProps, index: number) => ( ({ - betas: { - key: ONYXKEYS.BETAS, - }, - // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM - reimbursementAccount: { - key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, - }, - })(WorkspaceWorkflowsPage), -)); \ No newline at end of file +export default withCurrentUserPersonalDetails( + withPolicy( + withOnyx({ + betas: { + key: ONYXKEYS.BETAS, + }, + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM + reimbursementAccount: { + key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, + }, + })(WorkspaceWorkflowsPage), + ), +); diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 93f75901d019..4a133d2eeed8 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -103,14 +103,15 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< ownerAccountID?: number; /** The accountID of the authorized payer */ - authorizedPayerAccountID: number; + authorizedPayerAccountID?: number; + /** The output currency for the policy */ outputCurrency: string; /** The URL for the policy avatar */ avatar?: string; - /** Error objects keyed by field name containing errors keyed by microtime */ + /** Error objects keyed by field name containing errors keyeod by microtime */ errorFields?: OnyxCommon.ErrorFields; /** A list of errors keyed by microtime */ From 5ac67c2be848691187e20f277bef62e6eda07d8d Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Sat, 2 Mar 2024 01:28:53 +0530 Subject: [PATCH 05/74] fixes type errors --- src/libs/Navigation/types.ts | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index a1e558869ebe..297f9f4d9d37 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -63,9 +63,6 @@ type CentralPaneNavigatorParamList = { [SCREENS.WORKSPACE.WORKFLOWS]: { policyID: string; }; - [SCREENS.WORKSPACE.WORKFLOWS_APPROVER]: { - policyID: string; - }; [SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY]: { policyID: string; }; @@ -161,6 +158,12 @@ type SettingsNavigatorParamList = { /** domain passed via route /settings/wallet/card/:domain */ domain: string; }; + [SCREENS.WORKSPACE.WORKFLOWS_APPROVER]: { + policyID: string; + }; + [SCREENS.WORKSPACE.WORKFLOWS_PAYER]: { + policyID: string; + }; [SCREENS.SETTINGS.WALLET.TRANSFER_BALANCE]: undefined; [SCREENS.SETTINGS.WALLET.CHOOSE_TRANSFER_ACCOUNT]: undefined; [SCREENS.SETTINGS.WALLET.ENABLE_PAYMENTS]: undefined; From b9e0dc02c57c68d2c9075ba096d2e29b79fa8a4b Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Sat, 2 Mar 2024 01:33:12 +0530 Subject: [PATCH 06/74] fixes conflicts with mail --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 978f8cc6c259..837cf38bbe9c 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -140,7 +140,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur titleStyle={styles.textLabelSupportingNormal} descriptionTextStyle={styles.textNormalThemeText} description={policyOwnerDisplayName ?? ''} - // onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} + onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} // TODO will be done in https://github.com/Expensify/Expensify/issues/368334 shouldShowRightIcon wrapperStyle={containerStyle} From 927aacc6280fbd38e4c88a708f83b6d4d9c408cf Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Sat, 2 Mar 2024 02:15:55 +0530 Subject: [PATCH 07/74] basic structure for payer page --- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 47 +++++++++++++++++-- src/types/onyx/Policy.ts | 2 +- 2 files changed, 44 insertions(+), 5 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 9008db10daa1..3935f0104f5c 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -1,8 +1,47 @@ +// import { View } from 'react-native'; +import type {StackScreenProps} from '@react-navigation/stack'; import React from 'react'; -import {View} from 'react-native'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; +// import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import ScreenWrapper from '@components/ScreenWrapper'; +import useLocalize from '@hooks/useLocalize'; +// import type * as OnyxTypes from '@src/types/onyx'; +import Navigation from '@libs/Navigation/Navigation'; +// import useThemeStyles from '@hooks/useThemeStyles'; +// import * as ErrorUtils from '@libs/ErrorUtils'; +import type {SettingsNavigatorParamList} from '@navigation/types'; +import AdminPolicyAccessOrNotFoundWrapper from '@pages/workspace/AdminPolicyAccessOrNotFoundWrapper'; +import PaidPolicyAccessOrNotFoundWrapper from '@pages/workspace/PaidPolicyAccessOrNotFoundWrapper'; +import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading'; +import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading'; +// import ONYXKEYS from '@src/ONYXKEYS'; +import type SCREENS from '@src/SCREENS'; -function WorkspaceWorkflowsPayerPage() { - return some text; +type WorkspaceWorkflowsPayerPageProps = WithPolicyAndFullscreenLoadingProps & StackScreenProps; + +function WorkspaceWorkflowsPayerPage({route, policy}: WorkspaceWorkflowsPayerPageProps) { + const {translate} = useLocalize(); + // const styles = useThemeStyles(); + const policyName = policy?.name ?? ''; + + return ( + + + + + + + + ); } -export default WorkspaceWorkflowsPayerPage; +WorkspaceWorkflowsPayerPage.displayName = 'WorkspaceWorkflowsPayerPage'; + +export default withPolicyAndFullscreenLoading(WorkspaceWorkflowsPayerPage); diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 4a133d2eeed8..e21f765d8fb8 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -111,7 +111,7 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< /** The URL for the policy avatar */ avatar?: string; - /** Error objects keyed by field name containing errors keyeod by microtime */ + /** Error objects keyed by field name containing errors keyed by microtime */ errorFields?: OnyxCommon.ErrorFields; /** A list of errors keyed by microtime */ From 654e080fc461f28e93d38afbc190415250af4a9d Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Sat, 2 Mar 2024 03:16:37 +0530 Subject: [PATCH 08/74] toggle setWorkspaceReimbursement v1 --- .../SetWorkspaceReimbursementParams.ts | 7 ++ src/libs/API/parameters/index.ts | 1 + src/libs/API/types.ts | 2 + src/libs/actions/Policy.ts | 41 +++++++ .../workflows/WorkspaceWorkflowsPage.tsx | 106 +++++++++--------- 5 files changed, 107 insertions(+), 50 deletions(-) create mode 100644 src/libs/API/parameters/SetWorkspaceReimbursementParams.ts diff --git a/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts b/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts new file mode 100644 index 000000000000..787688b6d64b --- /dev/null +++ b/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts @@ -0,0 +1,7 @@ + +type SetWorkspaceReimbursementParams = { + policyID: string; + value: string; +}; + +export default SetWorkspaceReimbursementParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index 4fbc597b8186..3ce07c05f850 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -152,4 +152,5 @@ export type {default as SetWorkspaceAutoReportingParams} from './SetWorkspaceAut export type {default as SetWorkspaceAutoReportingFrequencyParams} from './SetWorkspaceAutoReportingFrequencyParams'; export type {default as SetWorkspaceAutoReportingMonthlyOffsetParams} from './SetWorkspaceAutoReportingMonthlyOffsetParams'; export type {default as SetWorkspaceApprovalModeParams} from './SetWorkspaceApprovalModeParams'; +export type {default as SetWorkspaceReimbursementParams} from './SetWorkspaceReimbursementParams'; export type {default as SwitchToOldDotParams} from './SwitchToOldDotParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index ba49bc5fa27b..84a9487ea2b5 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -12,6 +12,7 @@ const WRITE_COMMANDS = { SET_WORKSPACE_AUTO_REPORTING_FREQUENCY: 'SetWorkspaceAutoReportingFrequency', SET_WORKSPACE_AUTO_REPORTING_MONTHLY_OFFSET: 'UpdatePolicy', SET_WORKSPACE_APPROVAL_MODE: 'SetWorkspaceApprovalMode', + SET_WORKSPACE_REIMBURSEMENT: 'SetWorkspaceReimbursement', DISMISS_REFERRAL_BANNER: 'DismissReferralBanner', UPDATE_PREFERRED_LOCALE: 'UpdatePreferredLocale', OPEN_APP: 'OpenApp', @@ -309,6 +310,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING_FREQUENCY]: Parameters.SetWorkspaceAutoReportingFrequencyParams; [WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING_MONTHLY_OFFSET]: Parameters.SetWorkspaceAutoReportingMonthlyOffsetParams; [WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE]: Parameters.SetWorkspaceApprovalModeParams; + [WRITE_COMMANDS.SET_WORKSPACE_REIMBURSEMENT]: Parameters.SetWorkspaceReimbursementParams; [WRITE_COMMANDS.SWITCH_TO_OLD_DOT]: Parameters.SwitchToOldDotParams; }; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 313c4deb9934..98bbe7c0511d 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -24,6 +24,7 @@ import type { SetWorkspaceAutoReportingFrequencyParams, SetWorkspaceAutoReportingMonthlyOffsetParams, SetWorkspaceAutoReportingParams, + SetWorkspaceReimbursementParams, UpdateWorkspaceAvatarParams, UpdateWorkspaceCustomUnitAndRateParams, UpdateWorkspaceDescriptionParams, @@ -560,6 +561,45 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo API.write(WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE, params, {optimisticData, failureData, successData}); } +function setWorkspaceReimbursement(policyID: string, reimburserEmail: string, reimbursementChoice: ValueOf) { + const value = {reimburserEmail, reimbursementChoice}; + + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + ...value, + pendingFields: {reimbursementChoice: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, + }, + }, + ]; + + const failureData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + pendingFields: {reimbursementChoice: null}, + }, + }, + ]; + + const successData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + pendingFields: {reimbursementChoice: null}, + }, + }, + ]; + + const params: SetWorkspaceReimbursementParams = {policyID, value: JSON.stringify(value)}; + + API.write(WRITE_COMMANDS.SET_WORKSPACE_REIMBURSEMENT, params, {optimisticData, failureData, successData}); +} + /** * Build optimistic data for removing users from the announcement room */ @@ -2536,4 +2576,5 @@ export { setWorkspaceCategoryEnabled, setWorkspaceRequiresCategory, clearCategoryErrors, + setWorkspaceReimbursement, }; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 837cf38bbe9c..5b8b42b2aa9f 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,15 +1,15 @@ -import {useIsFocused} from '@react-navigation/native'; -import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useCallback, useEffect, useMemo} from 'react'; -import {View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; +import { useIsFocused } from '@react-navigation/native'; +import type { StackScreenProps } from '@react-navigation/stack'; +import React, { useCallback, useEffect, useMemo } from 'react'; +import { View } from 'react-native'; +import type { OnyxEntry } from 'react-native-onyx'; +import { withOnyx } from 'react-native-onyx'; import * as Illustrations from '@components/Icon/Illustrations'; import MenuItem from '@components/MenuItem'; import Section from '@components/Section'; import Text from '@components/Text'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; -import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; +import type { WithCurrentUserPersonalDetailsProps } from '@components/withCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import usePrevious from '@hooks/usePrevious'; @@ -23,22 +23,22 @@ import Permissions from '@libs/Permissions'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; -import type {CentralPaneNavigatorParamList} from '@navigation/types'; -import type {WithPolicyProps} from '@pages/workspace/withPolicy'; +import type { CentralPaneNavigatorParamList } from '@navigation/types'; +import type { WithPolicyProps } from '@pages/workspace/withPolicy'; import withPolicy from '@pages/workspace/withPolicy'; import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections'; import * as BankAccounts from '@userActions/BankAccounts'; import * as Policy from '@userActions/Policy'; -import {navigateToBankAccountRoute} from '@userActions/ReimbursementAccount'; +import { navigateToBankAccountRoute } from '@userActions/ReimbursementAccount'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type {Beta, ReimbursementAccount} from '@src/types/onyx'; +import type { Beta, ReimbursementAccount } from '@src/types/onyx'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; -import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; -import {getAutoReportingFrequencyDisplayNames} from './WorkspaceAutoReportingFrequencyPage'; -import type {AutoReportingFrequencyKey} from './WorkspaceAutoReportingFrequencyPage'; +import type { ToggleSettingOptionRowProps } from './ToggleSettingsOptionRow'; +import { getAutoReportingFrequencyDisplayNames } from './WorkspaceAutoReportingFrequencyPage'; +import type { AutoReportingFrequencyKey } from './WorkspaceAutoReportingFrequencyPage'; type WorkspaceWorkflowsPageOnyxProps = { /** Beta features list */ @@ -51,12 +51,12 @@ type WorkspaceWorkflowsPageProps = WithCurrentUserPersonalDetailsProps & WorkspaceWorkflowsPageOnyxProps & StackScreenProps; -function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, currentUserPersonalDetails}: WorkspaceWorkflowsPageProps) { - const {translate, preferredLocale} = useLocalize(); +function WorkspaceWorkflowsPage({ policy, betas, route, reimbursementAccount, currentUserPersonalDetails }: WorkspaceWorkflowsPageProps) { + const { translate, preferredLocale } = useLocalize(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); - const {isSmallScreenWidth} = useWindowDimensions(); - const {isOffline} = useNetwork(); + const { isSmallScreenWidth } = useWindowDimensions(); + const { isOffline } = useNetwork(); const isFocused = useIsFocused(); const prevIsFocused = usePrevious(isFocused); @@ -93,39 +93,40 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur const activeRoute = Navigation.getActiveRouteWithoutParams(); const items: ToggleSettingOptionRowProps[] = useMemo(() => { - const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; + const { accountNumber, state, bankName } = reimbursementAccount?.achData ?? {}; const hasVBA = state === BankAccount.STATE.OPEN; const bankDisplayName = bankName ? `${bankName} ${accountNumber ? `${accountNumber.slice(-5)}` : ''}` : ''; + console.log(reimbursementAccount, 'reimbursementAccount---------------->', policy) return [ ...(canUseDelayedSubmission ? [ - { - icon: Illustrations.ReceiptEnvelope, - title: translate('workflowsPage.delaySubmissionTitle'), - subtitle: translate('workflowsPage.delaySubmissionDescription'), - onToggle: (isEnabled: boolean) => { - Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled); - }, - subMenuItems: ( - - ), - isActive: policy?.harvesting?.enabled ?? false, - pendingAction: policy?.pendingFields?.isAutoApprovalEnabled, - }, - ] + { + icon: Illustrations.ReceiptEnvelope, + title: translate('workflowsPage.delaySubmissionTitle'), + subtitle: translate('workflowsPage.delaySubmissionDescription'), + onToggle: (isEnabled: boolean) => { + Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled); + }, + subMenuItems: ( + + ), + isActive: policy?.harvesting?.enabled ?? false, + pendingAction: policy?.pendingFields?.isAutoApprovalEnabled, + }, + ] : []), { icon: Illustrations.Approval, @@ -141,7 +142,6 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur descriptionTextStyle={styles.textNormalThemeText} description={policyOwnerDisplayName ?? ''} onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} - // TODO will be done in https://github.com/Expensify/Expensify/issues/368334 shouldShowRightIcon wrapperStyle={containerStyle} hoverAndPressStyle={[styles.mr0, styles.br2]} @@ -155,7 +155,14 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur title: translate('workflowsPage.makeOrTrackPaymentsTitle'), subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), onToggle: () => { - // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 + if(!hasVBA) { + navigateToBankAccountRoute(route.params.policyID, activeRoute); + return; + } + const isAutoReimbursable = policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; + const newReimbursementChoice = isAutoReimbursable ? CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_NO : CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; + const reimburserEmail = newReimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES ? policy?.owner ?? '' : ''; + Policy.setWorkspaceReimbursement(route.params.policyID, reimburserEmail, newReimbursementChoice); }, subMenuItems: ( <> @@ -183,7 +190,6 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur titleStyle={styles.textLabelSupportingNormal} description={displayNameForAuthorizedPayer} onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_PAYER.getRoute(route.params.policyID))} - // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 shouldShowRightIcon wrapperStyle={containerStyle} hoverAndPressStyle={[styles.mr0, styles.br2]} @@ -192,7 +198,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur ), isEndOptionRow: true, - isActive: true, // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 + isActive: policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, }, ]; }, [ From 81d06985f00cf918199f6fa1ff589e64498b3887 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Sat, 2 Mar 2024 04:40:14 +0530 Subject: [PATCH 09/74] adds section list for payerpage --- src/languages/en.ts | 1 + src/languages/es.ts | 1 + .../SetWorkspaceReimbursementParams.ts | 1 - .../workflows/WorkspaceWorkflowsPage.tsx | 100 +++++----- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 181 ++++++++++++++++-- 5 files changed, 216 insertions(+), 68 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index f2822368406d..ca1c2d1f6551 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1045,6 +1045,7 @@ export default { makeOrTrackPaymentsTitle: 'Make or track payments', makeOrTrackPaymentsDescription: 'Add an authorized payer for payments made in Expensify, or simply track payments made elsewhere.', authorizedPayer: 'Authorized payer', + admins: 'Admins', editor: { submissionFrequency: 'Choose how long Expensify should wait before sharing error-free spend.', }, diff --git a/src/languages/es.ts b/src/languages/es.ts index 4d0f74a1fb9c..95cd6e1b9fbc 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1041,6 +1041,7 @@ export default { makeOrTrackPaymentsTitle: 'Realizar o seguir pagos', makeOrTrackPaymentsDescription: 'Añade un pagador autorizado para los pagos realizados en Expensify, o simplemente realiza un seguimiento de los pagos realizados en otro lugar.', authorizedPayer: 'Authorized payer', + admins: 'Administradores', editor: { submissionFrequency: 'Elige cuánto tiempo Expensify debe esperar antes de compartir los gastos sin errores.', }, diff --git a/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts b/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts index 787688b6d64b..dc0aa09e8921 100644 --- a/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts +++ b/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts @@ -1,4 +1,3 @@ - type SetWorkspaceReimbursementParams = { policyID: string; value: string; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 5b8b42b2aa9f..536fab84d264 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,15 +1,15 @@ -import { useIsFocused } from '@react-navigation/native'; -import type { StackScreenProps } from '@react-navigation/stack'; -import React, { useCallback, useEffect, useMemo } from 'react'; -import { View } from 'react-native'; -import type { OnyxEntry } from 'react-native-onyx'; -import { withOnyx } from 'react-native-onyx'; +import {useIsFocused} from '@react-navigation/native'; +import type {StackScreenProps} from '@react-navigation/stack'; +import React, {useCallback, useEffect, useMemo} from 'react'; +import {View} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; import * as Illustrations from '@components/Icon/Illustrations'; import MenuItem from '@components/MenuItem'; import Section from '@components/Section'; import Text from '@components/Text'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; -import type { WithCurrentUserPersonalDetailsProps } from '@components/withCurrentUserPersonalDetails'; +import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import usePrevious from '@hooks/usePrevious'; @@ -23,22 +23,22 @@ import Permissions from '@libs/Permissions'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; import * as ReportUtils from '@libs/ReportUtils'; -import type { CentralPaneNavigatorParamList } from '@navigation/types'; -import type { WithPolicyProps } from '@pages/workspace/withPolicy'; +import type {CentralPaneNavigatorParamList} from '@navigation/types'; +import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicy from '@pages/workspace/withPolicy'; import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections'; import * as BankAccounts from '@userActions/BankAccounts'; import * as Policy from '@userActions/Policy'; -import { navigateToBankAccountRoute } from '@userActions/ReimbursementAccount'; +import {navigateToBankAccountRoute} from '@userActions/ReimbursementAccount'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type { Beta, ReimbursementAccount } from '@src/types/onyx'; +import type {Beta, ReimbursementAccount} from '@src/types/onyx'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; -import type { ToggleSettingOptionRowProps } from './ToggleSettingsOptionRow'; -import { getAutoReportingFrequencyDisplayNames } from './WorkspaceAutoReportingFrequencyPage'; -import type { AutoReportingFrequencyKey } from './WorkspaceAutoReportingFrequencyPage'; +import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; +import {getAutoReportingFrequencyDisplayNames} from './WorkspaceAutoReportingFrequencyPage'; +import type {AutoReportingFrequencyKey} from './WorkspaceAutoReportingFrequencyPage'; type WorkspaceWorkflowsPageOnyxProps = { /** Beta features list */ @@ -51,12 +51,12 @@ type WorkspaceWorkflowsPageProps = WithCurrentUserPersonalDetailsProps & WorkspaceWorkflowsPageOnyxProps & StackScreenProps; -function WorkspaceWorkflowsPage({ policy, betas, route, reimbursementAccount, currentUserPersonalDetails }: WorkspaceWorkflowsPageProps) { - const { translate, preferredLocale } = useLocalize(); +function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, currentUserPersonalDetails}: WorkspaceWorkflowsPageProps) { + const {translate, preferredLocale} = useLocalize(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); - const { isSmallScreenWidth } = useWindowDimensions(); - const { isOffline } = useNetwork(); + const {isSmallScreenWidth} = useWindowDimensions(); + const {isOffline} = useNetwork(); const isFocused = useIsFocused(); const prevIsFocused = usePrevious(isFocused); @@ -93,40 +93,39 @@ function WorkspaceWorkflowsPage({ policy, betas, route, reimbursementAccount, cu const activeRoute = Navigation.getActiveRouteWithoutParams(); const items: ToggleSettingOptionRowProps[] = useMemo(() => { - const { accountNumber, state, bankName } = reimbursementAccount?.achData ?? {}; + const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; const hasVBA = state === BankAccount.STATE.OPEN; const bankDisplayName = bankName ? `${bankName} ${accountNumber ? `${accountNumber.slice(-5)}` : ''}` : ''; - console.log(reimbursementAccount, 'reimbursementAccount---------------->', policy) return [ ...(canUseDelayedSubmission ? [ - { - icon: Illustrations.ReceiptEnvelope, - title: translate('workflowsPage.delaySubmissionTitle'), - subtitle: translate('workflowsPage.delaySubmissionDescription'), - onToggle: (isEnabled: boolean) => { - Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled); - }, - subMenuItems: ( - - ), - isActive: policy?.harvesting?.enabled ?? false, - pendingAction: policy?.pendingFields?.isAutoApprovalEnabled, - }, - ] + { + icon: Illustrations.ReceiptEnvelope, + title: translate('workflowsPage.delaySubmissionTitle'), + subtitle: translate('workflowsPage.delaySubmissionDescription'), + onToggle: (isEnabled: boolean) => { + Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled); + }, + subMenuItems: ( + + ), + isActive: policy?.harvesting?.enabled ?? false, + pendingAction: policy?.pendingFields?.isAutoApprovalEnabled, + }, + ] : []), { icon: Illustrations.Approval, @@ -155,14 +154,9 @@ function WorkspaceWorkflowsPage({ policy, betas, route, reimbursementAccount, cu title: translate('workflowsPage.makeOrTrackPaymentsTitle'), subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), onToggle: () => { - if(!hasVBA) { - navigateToBankAccountRoute(route.params.policyID, activeRoute); - return; - } const isAutoReimbursable = policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; const newReimbursementChoice = isAutoReimbursable ? CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_NO : CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; - const reimburserEmail = newReimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES ? policy?.owner ?? '' : ''; - Policy.setWorkspaceReimbursement(route.params.policyID, reimburserEmail, newReimbursementChoice); + Policy.setWorkspaceReimbursement(route.params.policyID, newReimbursementChoice); }, subMenuItems: ( <> diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 3935f0104f5c..51a3df463500 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -1,28 +1,164 @@ // import { View } from 'react-native'; -import type {StackScreenProps} from '@react-navigation/stack'; -import React from 'react'; -import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import type { StackScreenProps } from '@react-navigation/stack'; +import React, { useCallback, useMemo, useState } from 'react'; // import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import type { SectionListData } from 'react-native'; +import type { OnyxEntry } from 'react-native-onyx'; +import { withOnyx } from 'react-native-onyx'; +import Badge from '@components/Badge'; +import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; +import type { ListItem, Section } from '@components/SelectionList/types'; import useLocalize from '@hooks/useLocalize'; -// import type * as OnyxTypes from '@src/types/onyx'; +import useNetwork from '@hooks/useNetwork'; +import useThemeStyles from '@hooks/useThemeStyles'; +import compose from '@libs/compose'; +import { formatPhoneNumber } from '@libs/LocalePhoneNumber'; +import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; -// import useThemeStyles from '@hooks/useThemeStyles'; -// import * as ErrorUtils from '@libs/ErrorUtils'; -import type {SettingsNavigatorParamList} from '@navigation/types'; +import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; +import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as UserUtils from '@libs/UserUtils'; +import type { SettingsNavigatorParamList } from '@navigation/types'; import AdminPolicyAccessOrNotFoundWrapper from '@pages/workspace/AdminPolicyAccessOrNotFoundWrapper'; import PaidPolicyAccessOrNotFoundWrapper from '@pages/workspace/PaidPolicyAccessOrNotFoundWrapper'; import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading'; -import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading'; -// import ONYXKEYS from '@src/ONYXKEYS'; +import type { WithPolicyAndFullscreenLoadingProps } from '@pages/workspace/withPolicyAndFullscreenLoading'; +import CONST from '@src/CONST'; +import UserListItem from '@components/SelectionList/UserListItem'; +import ONYXKEYS from '@src/ONYXKEYS'; import type SCREENS from '@src/SCREENS'; +import type { PersonalDetailsList, PolicyMember } from '@src/types/onyx'; +import { isEmptyObject } from '@src/types/utils/EmptyObject'; +import useStyleUtils from '@hooks/useStyleUtils'; +import SelectionList from '@components/SelectionList'; + +type WorkspaceWorkflowsPayerPageOnyxProps = { + /** All of the personal details for everyone */ + personalDetails: OnyxEntry; +}; -type WorkspaceWorkflowsPayerPageProps = WithPolicyAndFullscreenLoadingProps & StackScreenProps; +type WorkspaceWorkflowsPayerPageProps = WorkspaceWorkflowsPayerPageOnyxProps & + WithPolicyAndFullscreenLoadingProps & + StackScreenProps; +type MemberOption = Omit & { accountID: number }; +type MembersSection = SectionListData>; -function WorkspaceWorkflowsPayerPage({route, policy}: WorkspaceWorkflowsPayerPageProps) { - const {translate} = useLocalize(); - // const styles = useThemeStyles(); +function WorkspaceWorkflowsPayerPage({ route, policy, policyMembers, personalDetails }: WorkspaceWorkflowsPayerPageProps) { + const { translate } = useLocalize(); + const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const policyName = policy?.name ?? ''; + const { isOffline } = useNetwork(); + + const [searchTerm, setSearchTerm] = useState(''); + + + const isDeletedPolicyMember = useCallback( + (policyMember: PolicyMember) => !isOffline && policyMember.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && isEmptyObject(policyMember.errors), + [isOffline], + ); + + const [formattedPolicyAdmins, formattedAuthorizedPayer] = useMemo(() => { + const policyAdminDetails: MemberOption[] = []; + const authorizedPayerDetails: MemberOption[] = []; + + Object.entries(policyMembers ?? {}).forEach(([accountIDKey, policyMember]) => { + if (isDeletedPolicyMember(policyMember)) { + return; + } + const accountID = Number(accountIDKey); + if (isDeletedPolicyMember(policyMember)) { + return; + } + + const details = personalDetails?.[accountID]; + if (!details) { + Log.hmmm(`[WorkspaceMembersPage] no personal details found for policy member with accountID: ${accountID}`); + } + const isOwner = policy?.owner === details?.login; + const isAdmin = policyMember.role === CONST.POLICY.ROLE.ADMIN; + + if (!isOwner && !isAdmin) { + return; + } + + const roleBadge = ( + + ); + + const formattedMember = { + keyForList: accountIDKey, + accountID, + isSelected: policy?.authorizedPayerAccountID === accountID, + isDisabled: policyMember.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || !isEmptyObject(policyMember.errors), + text: formatPhoneNumber(PersonalDetailsUtils.getDisplayNameOrDefault(details)), + alternateText: formatPhoneNumber(details?.login ?? ''), + rightElement: roleBadge, + icons: [ + { + source: UserUtils.getAvatar(details?.avatar, accountID), + name: formatPhoneNumber(details?.login ?? ''), + type: CONST.ICON_TYPE_AVATAR, + id: accountID, + }, + ], + errors: policyMember.errors, + pendingAction: policyMember.pendingAction, + }; + + if (policy?.authorizedPayerAccountID === accountID) { + authorizedPayerDetails.push(formattedMember); + } else { + policyAdminDetails.push(formattedMember); + } + }); + return [policyAdminDetails, authorizedPayerDetails]; + }, [personalDetails, policyMembers, translate, policy?.authorizedPayerAccountID, isDeletedPolicyMember, policy?.owner, styles, StyleUtils]); + + const sections: MembersSection[] = useMemo(() => { + const sectionsArray: MembersSection[] = []; + + if (searchTerm !== '') { + const filteredOptions = [...formattedPolicyAdmins, ...formattedAuthorizedPayer].filter((option) => { + const searchValue = OptionsListUtils.getSearchValueForPhoneOrEmail(searchTerm); + return !!option.text?.toLowerCase().includes(searchValue) || !!option.login?.toLowerCase().includes(searchValue); + }); + return [ + { + title: undefined, + data: filteredOptions, + shouldShow: true, + }, + ]; + } + + sectionsArray.push({ + title: undefined, + data: formattedAuthorizedPayer, + shouldShow: true, + indexOffset: formattedPolicyAdmins.length, + }); + + sectionsArray.push({ + title: translate('workflowsPage.admins'), + data: formattedPolicyAdmins, + shouldShow: true, + indexOffset: 0, + }); + return sectionsArray; + }, [formattedPolicyAdmins, formattedAuthorizedPayer, translate, searchTerm]); + + const headerMessage = useMemo( + () => (searchTerm && !sections[0].data.length ? translate('common.noResultsFound') : ''), + + // eslint-disable-next-line react-hooks/exhaustive-deps + [translate, sections], + ); return ( @@ -36,6 +172,16 @@ function WorkspaceWorkflowsPayerPage({route, policy}: WorkspaceWorkflowsPayerPag subtitle={policyName} onBackButtonPress={Navigation.goBack} /> + console.log(admin)} + showScrollIndicator + /> @@ -44,4 +190,11 @@ function WorkspaceWorkflowsPayerPage({route, policy}: WorkspaceWorkflowsPayerPag WorkspaceWorkflowsPayerPage.displayName = 'WorkspaceWorkflowsPayerPage'; -export default withPolicyAndFullscreenLoading(WorkspaceWorkflowsPayerPage); +export default compose( + withOnyx({ + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + }, + }), + withPolicyAndFullscreenLoading, +)(WorkspaceWorkflowsPayerPage); From 58ebe8ca33dd12ee8221f7dc77c5fd7ce565540e Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Sat, 2 Mar 2024 04:59:13 +0530 Subject: [PATCH 10/74] fixes crash for ios --- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 41 +++++++++---------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 51a3df463500..a305fd0979f9 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -1,37 +1,37 @@ // import { View } from 'react-native'; -import type { StackScreenProps } from '@react-navigation/stack'; -import React, { useCallback, useMemo, useState } from 'react'; +import type {StackScreenProps} from '@react-navigation/stack'; +import React, {useCallback, useMemo, useState} from 'react'; // import OfflineWithFeedback from '@components/OfflineWithFeedback'; -import type { SectionListData } from 'react-native'; -import type { OnyxEntry } from 'react-native-onyx'; -import { withOnyx } from 'react-native-onyx'; +import type {SectionListData} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; import Badge from '@components/Badge'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; -import type { ListItem, Section } from '@components/SelectionList/types'; +import SelectionList from '@components/SelectionList'; +import type {ListItem, Section} from '@components/SelectionList/types'; +import UserListItem from '@components/SelectionList/UserListItem'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; +import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; -import { formatPhoneNumber } from '@libs/LocalePhoneNumber'; +import {formatPhoneNumber} from '@libs/LocalePhoneNumber'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; -import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as UserUtils from '@libs/UserUtils'; -import type { SettingsNavigatorParamList } from '@navigation/types'; +import type {SettingsNavigatorParamList} from '@navigation/types'; import AdminPolicyAccessOrNotFoundWrapper from '@pages/workspace/AdminPolicyAccessOrNotFoundWrapper'; import PaidPolicyAccessOrNotFoundWrapper from '@pages/workspace/PaidPolicyAccessOrNotFoundWrapper'; import withPolicyAndFullscreenLoading from '@pages/workspace/withPolicyAndFullscreenLoading'; -import type { WithPolicyAndFullscreenLoadingProps } from '@pages/workspace/withPolicyAndFullscreenLoading'; +import type {WithPolicyAndFullscreenLoadingProps} from '@pages/workspace/withPolicyAndFullscreenLoading'; import CONST from '@src/CONST'; -import UserListItem from '@components/SelectionList/UserListItem'; import ONYXKEYS from '@src/ONYXKEYS'; import type SCREENS from '@src/SCREENS'; -import type { PersonalDetailsList, PolicyMember } from '@src/types/onyx'; -import { isEmptyObject } from '@src/types/utils/EmptyObject'; -import useStyleUtils from '@hooks/useStyleUtils'; -import SelectionList from '@components/SelectionList'; +import type {PersonalDetailsList, PolicyMember} from '@src/types/onyx'; +import {isEmptyObject} from '@src/types/utils/EmptyObject'; type WorkspaceWorkflowsPayerPageOnyxProps = { /** All of the personal details for everyone */ @@ -41,19 +41,18 @@ type WorkspaceWorkflowsPayerPageOnyxProps = { type WorkspaceWorkflowsPayerPageProps = WorkspaceWorkflowsPayerPageOnyxProps & WithPolicyAndFullscreenLoadingProps & StackScreenProps; -type MemberOption = Omit & { accountID: number }; +type MemberOption = Omit & {accountID: number}; type MembersSection = SectionListData>; -function WorkspaceWorkflowsPayerPage({ route, policy, policyMembers, personalDetails }: WorkspaceWorkflowsPayerPageProps) { - const { translate } = useLocalize(); +function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDetails}: WorkspaceWorkflowsPayerPageProps) { + const {translate} = useLocalize(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const policyName = policy?.name ?? ''; - const { isOffline } = useNetwork(); + const {isOffline} = useNetwork(); const [searchTerm, setSearchTerm] = useState(''); - const isDeletedPolicyMember = useCallback( (policyMember: PolicyMember) => !isOffline && policyMember.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && isEmptyObject(policyMember.errors), [isOffline], @@ -168,7 +167,7 @@ function WorkspaceWorkflowsPayerPage({ route, policy, policyMembers, personalDet testID={WorkspaceWorkflowsPayerPage.displayName} > From d7a55d587188cfc0b5146e9fc39c7dc82683d1d3 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Sun, 3 Mar 2024 03:09:28 +0530 Subject: [PATCH 11/74] fixes lint issue and add api command --- .../API/parameters/SetWorkspacePayerParams.ts | 6 +++ src/libs/API/parameters/index.ts | 1 + src/libs/API/types.ts | 2 + src/libs/actions/Policy.ts | 42 ++++++++++++++++++- .../workflows/WorkspaceWorkflowsPage.tsx | 40 +++++------------- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 16 ++++++- 6 files changed, 75 insertions(+), 32 deletions(-) create mode 100644 src/libs/API/parameters/SetWorkspacePayerParams.ts diff --git a/src/libs/API/parameters/SetWorkspacePayerParams.ts b/src/libs/API/parameters/SetWorkspacePayerParams.ts new file mode 100644 index 000000000000..59a768275a0a --- /dev/null +++ b/src/libs/API/parameters/SetWorkspacePayerParams.ts @@ -0,0 +1,6 @@ +type SetWorkspaceReimbursementParams = { + policyID: string; + authorizedPayerAccountID: number; +}; + +export default SetWorkspaceReimbursementParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index 3ce07c05f850..5b3fd523cfb8 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -153,4 +153,5 @@ export type {default as SetWorkspaceAutoReportingFrequencyParams} from './SetWor export type {default as SetWorkspaceAutoReportingMonthlyOffsetParams} from './SetWorkspaceAutoReportingMonthlyOffsetParams'; export type {default as SetWorkspaceApprovalModeParams} from './SetWorkspaceApprovalModeParams'; export type {default as SetWorkspaceReimbursementParams} from './SetWorkspaceReimbursementParams'; +export type {default as SetWorkspacePayerParams} from './SetWorkspacePayerParams'; export type {default as SwitchToOldDotParams} from './SwitchToOldDotParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 84a9487ea2b5..242e03dbbcbb 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -13,6 +13,7 @@ const WRITE_COMMANDS = { SET_WORKSPACE_AUTO_REPORTING_MONTHLY_OFFSET: 'UpdatePolicy', SET_WORKSPACE_APPROVAL_MODE: 'SetWorkspaceApprovalMode', SET_WORKSPACE_REIMBURSEMENT: 'SetWorkspaceReimbursement', + SET_WORKSPACE_PAYER: 'SetWorkspacePayer', DISMISS_REFERRAL_BANNER: 'DismissReferralBanner', UPDATE_PREFERRED_LOCALE: 'UpdatePreferredLocale', OPEN_APP: 'OpenApp', @@ -311,6 +312,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING_MONTHLY_OFFSET]: Parameters.SetWorkspaceAutoReportingMonthlyOffsetParams; [WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE]: Parameters.SetWorkspaceApprovalModeParams; [WRITE_COMMANDS.SET_WORKSPACE_REIMBURSEMENT]: Parameters.SetWorkspaceReimbursementParams; + [WRITE_COMMANDS.SET_WORKSPACE_PAYER]: Parameters.SetWorkspacePayerParams; [WRITE_COMMANDS.SWITCH_TO_OLD_DOT]: Parameters.SwitchToOldDotParams; }; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 98bbe7c0511d..f8f89143f300 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -24,6 +24,7 @@ import type { SetWorkspaceAutoReportingFrequencyParams, SetWorkspaceAutoReportingMonthlyOffsetParams, SetWorkspaceAutoReportingParams, + SetWorkspacePayerParams, SetWorkspaceReimbursementParams, UpdateWorkspaceAvatarParams, UpdateWorkspaceCustomUnitAndRateParams, @@ -561,8 +562,8 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo API.write(WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE, params, {optimisticData, failureData, successData}); } -function setWorkspaceReimbursement(policyID: string, reimburserEmail: string, reimbursementChoice: ValueOf) { - const value = {reimburserEmail, reimbursementChoice}; +function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueOf) { + const value = {reimbursementChoice}; const optimisticData: OnyxUpdate[] = [ { @@ -600,6 +601,42 @@ function setWorkspaceReimbursement(policyID: string, reimburserEmail: string, re API.write(WRITE_COMMANDS.SET_WORKSPACE_REIMBURSEMENT, params, {optimisticData, failureData, successData}); } +function setWorkspacePayer(policyID: string, accountID: number) { + const optimisticData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + authorizedPayerAccountID: accountID, + pendingFields: {authorizedPayerAccountID: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, + }, + }, + ]; + + const failureData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + pendingFields: {authorizedPayerAccountID: null}, + }, + }, + ]; + + const successData: OnyxUpdate[] = [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, + value: { + pendingFields: {authorizedPayerAccountID: null}, + }, + }, + ]; + + const params: SetWorkspacePayerParams = {policyID, authorizedPayerAccountID: accountID}; + API.write(WRITE_COMMANDS.SET_WORKSPACE_PAYER, params, {optimisticData, failureData, successData}); +} + /** * Build optimistic data for removing users from the announcement room */ @@ -2577,4 +2614,5 @@ export { setWorkspaceRequiresCategory, clearCategoryErrors, setWorkspaceReimbursement, + setWorkspacePayer, }; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 536fab84d264..40e298b84f47 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -13,21 +13,17 @@ import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentU import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import usePrevious from '@hooks/usePrevious'; -import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import BankAccount from '@libs/models/BankAccount'; import Navigation from '@libs/Navigation/Navigation'; -import * as OptionsListUtils from '@libs/OptionsListUtils'; import Permissions from '@libs/Permissions'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; -import * as ReportUtils from '@libs/ReportUtils'; import type {CentralPaneNavigatorParamList} from '@navigation/types'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicy from '@pages/workspace/withPolicy'; import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections'; -import * as BankAccounts from '@userActions/BankAccounts'; import * as Policy from '@userActions/Policy'; import {navigateToBankAccountRoute} from '@userActions/ReimbursementAccount'; import CONST from '@src/CONST'; @@ -54,15 +50,14 @@ type WorkspaceWorkflowsPageProps = WithCurrentUserPersonalDetailsProps & function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, currentUserPersonalDetails}: WorkspaceWorkflowsPageProps) { const {translate, preferredLocale} = useLocalize(); const styles = useThemeStyles(); - const StyleUtils = useStyleUtils(); const {isSmallScreenWidth} = useWindowDimensions(); const {isOffline} = useNetwork(); const isFocused = useIsFocused(); const prevIsFocused = usePrevious(isFocused); - const ownerPersonalDetails = ReportUtils.getDisplayNamesWithTooltips(OptionsListUtils.getPersonalDetailsForAccountIDs([policy?.ownerAccountID ?? 0], CONST.EMPTY_OBJECT), false); - const policyOwnerDisplayName = ownerPersonalDetails[0]?.displayName; + const policyApproverEmail = policy?.approver; + const policyApproverName = useMemo(() => PersonalDetailsUtils.getPersonalDetailByEmail(policyApproverEmail ?? '')?.displayName ?? policyApproverEmail, [policyApproverEmail]); const containerStyle = useMemo(() => [styles.ph8, styles.mhn8, styles.ml11, styles.pv3, styles.pr0, styles.pl4, styles.mr0, styles.widthAuto, styles.mt4], [styles]); const canUseDelayedSubmission = Permissions.canUseWorkflowsDelayedSubmission(betas); @@ -73,13 +68,9 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur const displayNameForAuthorizedPayer = PersonalDetailsUtils.getPersonalDetailsByIDs([authorizedPayerAccountID], currentUserPersonalDetails.accountID)[0]?.displayName; const fetchData = useCallback(() => { - // Instead of setting the reimbursement account loading within the optimistic data of the API command, use a separate action so that the Onyx value is updated right away. - // openWorkspaceReimburseView uses API.read which will not make the request until all WRITE requests in the sequential queue have finished responding, so there would be a delay in - // updating Onyx with the optimistic data. if (!policy?.id) { return; } - BankAccounts.setReimbursementAccountLoading(true); Policy.openWorkspaceReimburseView(policy?.id); }, [policy]); @@ -88,7 +79,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur return; } fetchData(); - }, [fetchData, isOffline, isFocused, prevIsFocused]); + }, [isFocused, isOffline, prevIsFocused, fetchData]); const activeRoute = Navigation.getActiveRouteWithoutParams(); @@ -139,7 +130,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur title={translate('workflowsPage.approver')} titleStyle={styles.textLabelSupportingNormal} descriptionTextStyle={styles.textNormalThemeText} - description={policyOwnerDisplayName ?? ''} + description={policyApproverName ?? ''} onPress={() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_APPROVER.getRoute(route.params.policyID))} shouldShowRightIcon wrapperStyle={containerStyle} @@ -161,27 +152,20 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur subMenuItems: ( <> navigateToBankAccountRoute(route.params.policyID, activeRoute)} - // TODO will be done in https://github.com/Expensify/Expensify/issues/368335 shouldShowRightIcon wrapperStyle={containerStyle} hoverAndPressStyle={[styles.mr0, styles.br2]} /> {hasVBA && ( Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_PAYER.getRoute(route.params.policyID))} shouldShowRightIcon @@ -193,6 +177,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur ), isEndOptionRow: true, isActive: policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, + pendingAction: policy?.pendingFields?.reimbursementChoice, }, ]; }, [ @@ -200,15 +185,13 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur route.params.policyID, styles, translate, - policyOwnerDisplayName, + policyApproverName, containerStyle, - isOffline, - StyleUtils, onPressAutoReportingFrequency, preferredLocale, canUseDelayedSubmission, activeRoute, - reimbursementAccount, + reimbursementAccount?.achData, displayNameForAuthorizedPayer, ]); @@ -242,7 +225,6 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur shouldShowNotFoundPage={!isPaidGroupPolicy || !isPolicyAdmin} shouldUseScrollView shouldSkipVBBACall - shouldShowLoading={isFocused !== prevIsFocused} >
{ + if (policy?.authorizedPayerAccountID === member.accountID) { + return; + } + + if (policy?.reimbursementChoice !== CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES) { + return; + } + + Policy.setWorkspacePayer(policy?.id, member.accountID); + Navigation.goBack(); + }; + return ( @@ -178,7 +192,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta onChangeText={setSearchTerm} headerMessage={headerMessage} ListItem={UserListItem} - onSelectRow={(admin) => console.log(admin)} + onSelectRow={(admin) => setPolicyAuthorizedPayer(admin)} showScrollIndicator /> From cd837020f127c0b95ffe0d6e7c6b234e5486cfd7 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Sun, 3 Mar 2024 05:27:35 +0530 Subject: [PATCH 12/74] fixes offline behaviour and offline behaviour --- src/languages/en.ts | 4 ++ src/languages/es.ts | 6 ++ .../SetWorkspaceReimbursementParams.ts | 2 +- src/libs/actions/Policy.ts | 25 +++++-- .../workflows/WorkspaceWorkflowsPage.tsx | 67 +++++++++---------- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 19 ++++-- src/types/onyx/Policy.ts | 3 + 7 files changed, 78 insertions(+), 48 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 814b1a6b91fe..08d596bf1da4 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1051,6 +1051,10 @@ export default { editor: { submissionFrequency: 'Choose how long Expensify should wait before sharing error-free spend.', }, + // TODO: confirm copy + genericErrorMessage: { + authorizedPayer: 'The authorized payer could not be updated. Please try again.', + }, frequencies: { weekly: 'Weekly', monthly: 'Monthly', diff --git a/src/languages/es.ts b/src/languages/es.ts index 3bfa83e82014..fc3b938609b0 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1042,11 +1042,17 @@ export default { addApprovalsDescription: 'Requiere una aprobación adicional antes de autorizar un pago.', makeOrTrackPaymentsTitle: 'Realizar o seguir pagos', makeOrTrackPaymentsDescription: 'Añade un pagador autorizado para los pagos realizados en Expensify, o simplemente realiza un seguimiento de los pagos realizados en otro lugar.', + // todo: add translations and cofirm copy authorizedPayer: 'Authorized payer', + // todo: add translations and cofirm copy admins: 'Administradores', editor: { submissionFrequency: 'Elige cuánto tiempo Expensify debe esperar antes de compartir los gastos sin errores.', }, + // todo: add translations and cofirm copy + genericErrorMessage: { + authorizedPayer: 'The authorized payer could not be updated. Please try again.', + }, frequencies: { weekly: 'Semanal', monthly: 'Mensual', diff --git a/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts b/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts index dc0aa09e8921..3f27af07f2f5 100644 --- a/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts +++ b/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts @@ -1,6 +1,6 @@ type SetWorkspaceReimbursementParams = { policyID: string; - value: string; + reimburserEmail: string; }; export default SetWorkspaceReimbursementParams; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index f8f89143f300..a4d79235e826 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -562,16 +562,19 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo API.write(WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE, params, {optimisticData, failureData, successData}); } -function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueOf) { - const value = {reimbursementChoice}; +function setWorkspaceReimbursement(policyID: string, reimburserEmail: string) { + const policy = ReportUtils.getPolicy(policyID); + + const currentPolicyReimburserEmail = policy.reimburserEmail; const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - ...value, - pendingFields: {reimbursementChoice: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, + reimburserEmail, + errorFields: {reimburserEmail: null}, + pendingFields: {reimburserEmail: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, }, }, ]; @@ -581,7 +584,9 @@ function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueO onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - pendingFields: {reimbursementChoice: null}, + reimburserEmail: currentPolicyReimburserEmail, + errorFields: {reimburserEmail: ErrorUtils.getMicroSecondOnyxError('workflowsPage.genericErrorMessage.authorizedPayer')}, + pendingFields: {reimburserEmail: null}, }, }, ]; @@ -591,16 +596,21 @@ function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueO onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - pendingFields: {reimbursementChoice: null}, + errorFields: {reimburserEmail: null}, + pendingFields: {reimburserEmail: null}, }, }, ]; - const params: SetWorkspaceReimbursementParams = {policyID, value: JSON.stringify(value)}; + const params: SetWorkspaceReimbursementParams = {policyID, reimburserEmail}; API.write(WRITE_COMMANDS.SET_WORKSPACE_REIMBURSEMENT, params, {optimisticData, failureData, successData}); } +function clearWorkspaceReimbursementError(policyID: string) { + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {reimburserEmail: null}}); +} + function setWorkspacePayer(policyID: string, accountID: number) { const optimisticData: OnyxUpdate[] = [ { @@ -2614,5 +2624,6 @@ export { setWorkspaceRequiresCategory, clearCategoryErrors, setWorkspaceReimbursement, + clearWorkspaceReimbursementError, setWorkspacePayer, }; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 40e298b84f47..179cb705a852 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -6,10 +6,9 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import * as Illustrations from '@components/Icon/Illustrations'; import MenuItem from '@components/MenuItem'; +import OfflineWithFeedback from '@components/OfflineWithFeedback'; import Section from '@components/Section'; import Text from '@components/Text'; -import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; -import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import usePrevious from '@hooks/usePrevious'; @@ -42,12 +41,9 @@ type WorkspaceWorkflowsPageOnyxProps = { /** Reimbursement account details */ reimbursementAccount: OnyxEntry; }; -type WorkspaceWorkflowsPageProps = WithCurrentUserPersonalDetailsProps & - WithPolicyProps & - WorkspaceWorkflowsPageOnyxProps & - StackScreenProps; +type WorkspaceWorkflowsPageProps = WithPolicyProps & WorkspaceWorkflowsPageOnyxProps & StackScreenProps; -function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, currentUserPersonalDetails}: WorkspaceWorkflowsPageProps) { +function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: WorkspaceWorkflowsPageProps) { const {translate, preferredLocale} = useLocalize(); const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); @@ -63,9 +59,11 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur const onPressAutoReportingFrequency = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY.getRoute(policy?.id ?? '')), [policy?.id]); - const authorizedPayerAccountID = policy?.authorizedPayerAccountID ?? policy?.ownerAccountID ?? 0; - - const displayNameForAuthorizedPayer = PersonalDetailsUtils.getPersonalDetailsByIDs([authorizedPayerAccountID], currentUserPersonalDetails.accountID)[0]?.displayName; + const authorizedPayerEmail = policy?.reimburserEmail; + const displayNameForAuthorizedPayer = useMemo( + () => PersonalDetailsUtils.getPersonalDetailByEmail(authorizedPayerEmail ?? '')?.displayName ?? authorizedPayerEmail, + [authorizedPayerEmail], + ); const fetchData = useCallback(() => { if (!policy?.id) { @@ -145,9 +143,8 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur title: translate('workflowsPage.makeOrTrackPaymentsTitle'), subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), onToggle: () => { - const isAutoReimbursable = policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; - const newReimbursementChoice = isAutoReimbursable ? CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_NO : CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; - Policy.setWorkspaceReimbursement(route.params.policyID, newReimbursementChoice); + // todo: we still need a action to set auto reimburse enable i.e. const.policy.reimbursement_choices.reimbursement_yes + // todo: after enable we need to get VBA owner(?) email and set it to policy.reimburser_email with Policy.setWorkspaceReimbursement }, subMenuItems: ( <> @@ -162,16 +159,18 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur hoverAndPressStyle={[styles.mr0, styles.br2]} /> {hasVBA && ( - Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_PAYER.getRoute(route.params.policyID))} - shouldShowRightIcon - wrapperStyle={containerStyle} - hoverAndPressStyle={[styles.mr0, styles.br2]} - /> + + Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_PAYER.getRoute(route.params.policyID))} + shouldShowRightIcon + wrapperStyle={containerStyle} + hoverAndPressStyle={[styles.mr0, styles.br2]} + /> + )} ), @@ -244,16 +243,14 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, cur WorkspaceWorkflowsPage.displayName = 'WorkspaceWorkflowsPage'; -export default withCurrentUserPersonalDetails( - withPolicy( - withOnyx({ - betas: { - key: ONYXKEYS.BETAS, - }, - // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM - reimbursementAccount: { - key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, - }, - })(WorkspaceWorkflowsPage), - ), +export default withPolicy( + withOnyx({ + betas: { + key: ONYXKEYS.BETAS, + }, + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM + reimbursementAccount: { + key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, + }, + })(WorkspaceWorkflowsPage), ); diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index f5af63306fea..959a2317a3f2 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -7,6 +7,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import Badge from '@components/Badge'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; +import MessagesRow from '@components/MessagesRow'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import type {ListItem, Section} from '@components/SelectionList/types'; @@ -16,6 +17,7 @@ import useNetwork from '@hooks/useNetwork'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; +import * as ErrorUtils from '@libs/ErrorUtils'; import {formatPhoneNumber} from '@libs/LocalePhoneNumber'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; @@ -94,7 +96,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta const formattedMember = { keyForList: accountIDKey, accountID, - isSelected: policy?.authorizedPayerAccountID === accountID, + isSelected: policy?.reimburserEmail === details?.login, isDisabled: policyMember.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || !isEmptyObject(policyMember.errors), text: formatPhoneNumber(PersonalDetailsUtils.getDisplayNameOrDefault(details)), alternateText: formatPhoneNumber(details?.login ?? ''), @@ -111,14 +113,14 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta pendingAction: policyMember.pendingAction, }; - if (policy?.authorizedPayerAccountID === accountID) { + if (policy?.reimburserEmail === details?.login) { authorizedPayerDetails.push(formattedMember); } else { policyAdminDetails.push(formattedMember); } }); return [policyAdminDetails, authorizedPayerDetails]; - }, [personalDetails, policyMembers, translate, policy?.authorizedPayerAccountID, isDeletedPolicyMember, policy?.owner, styles, StyleUtils]); + }, [personalDetails, policyMembers, translate, policy?.reimburserEmail, isDeletedPolicyMember, policy?.owner, styles, StyleUtils]); const sections: MembersSection[] = useMemo(() => { const sectionsArray: MembersSection[] = []; @@ -161,7 +163,8 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta ); const setPolicyAuthorizedPayer = (member: MemberOption) => { - if (policy?.authorizedPayerAccountID === member.accountID) { + const authorizedPayer = personalDetails?.[member.accountID]?.login ?? ''; + if (policy?.reimburserEmail === authorizedPayer) { return; } @@ -169,7 +172,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta return; } - Policy.setWorkspacePayer(policy?.id, member.accountID); + Policy.setWorkspaceReimbursement(policy?.id, authorizedPayer); Navigation.goBack(); }; @@ -185,6 +188,12 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta subtitle={policyName} onBackButtonPress={Navigation.goBack} /> + Policy.clearWorkspaceReimbursementError(route.params.policyID)} + /> ; From 03b63c02b2c11aa6d802073135ab6f880de9bbc7 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 4 Mar 2024 17:23:11 +0530 Subject: [PATCH 13/74] fixes option toggle on/off --- .../SetReimbursementFromChoiceParams.ts | 9 ++++ .../API/parameters/SetWorkspacePayerParams.ts | 6 --- src/libs/API/parameters/index.ts | 2 +- src/libs/API/types.ts | 4 +- src/libs/actions/Policy.ts | 41 +++++++++++++++---- .../workflows/WorkspaceWorkflowsPage.tsx | 6 ++- 6 files changed, 48 insertions(+), 20 deletions(-) create mode 100644 src/libs/API/parameters/SetReimbursementFromChoiceParams.ts delete mode 100644 src/libs/API/parameters/SetWorkspacePayerParams.ts diff --git a/src/libs/API/parameters/SetReimbursementFromChoiceParams.ts b/src/libs/API/parameters/SetReimbursementFromChoiceParams.ts new file mode 100644 index 000000000000..558044c85b81 --- /dev/null +++ b/src/libs/API/parameters/SetReimbursementFromChoiceParams.ts @@ -0,0 +1,9 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type SetReimbursementFromChoiceParams = { + policyID: string; + reimbursementChoice: ValueOf +}; + +export default SetReimbursementFromChoiceParams; diff --git a/src/libs/API/parameters/SetWorkspacePayerParams.ts b/src/libs/API/parameters/SetWorkspacePayerParams.ts deleted file mode 100644 index 59a768275a0a..000000000000 --- a/src/libs/API/parameters/SetWorkspacePayerParams.ts +++ /dev/null @@ -1,6 +0,0 @@ -type SetWorkspaceReimbursementParams = { - policyID: string; - authorizedPayerAccountID: number; -}; - -export default SetWorkspaceReimbursementParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index 5b3fd523cfb8..036257311eb3 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -153,5 +153,5 @@ export type {default as SetWorkspaceAutoReportingFrequencyParams} from './SetWor export type {default as SetWorkspaceAutoReportingMonthlyOffsetParams} from './SetWorkspaceAutoReportingMonthlyOffsetParams'; export type {default as SetWorkspaceApprovalModeParams} from './SetWorkspaceApprovalModeParams'; export type {default as SetWorkspaceReimbursementParams} from './SetWorkspaceReimbursementParams'; -export type {default as SetWorkspacePayerParams} from './SetWorkspacePayerParams'; +export type {default as SetReimbursementFromChoiceParams} from './SetReimbursementFromChoiceParams'; export type {default as SwitchToOldDotParams} from './SwitchToOldDotParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 242e03dbbcbb..8762d4bba902 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -13,7 +13,7 @@ const WRITE_COMMANDS = { SET_WORKSPACE_AUTO_REPORTING_MONTHLY_OFFSET: 'UpdatePolicy', SET_WORKSPACE_APPROVAL_MODE: 'SetWorkspaceApprovalMode', SET_WORKSPACE_REIMBURSEMENT: 'SetWorkspaceReimbursement', - SET_WORKSPACE_PAYER: 'SetWorkspacePayer', + SET_REIMBURSEMENT_FROM_CHOICE: 'Policy_setReimbursementFromChoice', DISMISS_REFERRAL_BANNER: 'DismissReferralBanner', UPDATE_PREFERRED_LOCALE: 'UpdatePreferredLocale', OPEN_APP: 'OpenApp', @@ -312,7 +312,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING_MONTHLY_OFFSET]: Parameters.SetWorkspaceAutoReportingMonthlyOffsetParams; [WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE]: Parameters.SetWorkspaceApprovalModeParams; [WRITE_COMMANDS.SET_WORKSPACE_REIMBURSEMENT]: Parameters.SetWorkspaceReimbursementParams; - [WRITE_COMMANDS.SET_WORKSPACE_PAYER]: Parameters.SetWorkspacePayerParams; + [WRITE_COMMANDS.SET_REIMBURSEMENT_FROM_CHOICE]: Parameters.SetReimbursementFromChoiceParams; [WRITE_COMMANDS.SWITCH_TO_OLD_DOT]: Parameters.SwitchToOldDotParams; }; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index a4d79235e826..d075a15389b3 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -20,11 +20,11 @@ import type { OpenWorkspaceMembersPageParams, OpenWorkspaceParams, OpenWorkspaceReimburseViewParams, + SetReimbursementFromChoiceParams, SetWorkspaceApprovalModeParams, SetWorkspaceAutoReportingFrequencyParams, SetWorkspaceAutoReportingMonthlyOffsetParams, SetWorkspaceAutoReportingParams, - SetWorkspacePayerParams, SetWorkspaceReimbursementParams, UpdateWorkspaceAvatarParams, UpdateWorkspaceCustomUnitAndRateParams, @@ -562,6 +562,11 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo API.write(WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE, params, {optimisticData, failureData, successData}); } +/** + * + * @param policyID + * @param reimburserEmail + */ function setWorkspaceReimbursement(policyID: string, reimburserEmail: string) { const policy = ReportUtils.getPolicy(policyID); @@ -607,18 +612,32 @@ function setWorkspaceReimbursement(policyID: string, reimburserEmail: string) { API.write(WRITE_COMMANDS.SET_WORKSPACE_REIMBURSEMENT, params, {optimisticData, failureData, successData}); } +/** + * clear the workspace reimbursement error while setting the authorized payer + * @param policyID + */ function clearWorkspaceReimbursementError(policyID: string) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {reimburserEmail: null}}); } -function setWorkspacePayer(policyID: string, accountID: number) { +/** + * set the workspace reimbursement choice + * @param policyID + * @param reimbursementChoice + */ +function setReimbursementFromChoice(policyID: string, reimbursementChoice: ValueOf) { + const policy = ReportUtils.getPolicy(policyID); + + const currentPolicyReimbursementChoice = policy.reimbursementChoice; + const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - authorizedPayerAccountID: accountID, - pendingFields: {authorizedPayerAccountID: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, + reimbursementChoice, + errorFields: {reimbursementChoice: null}, + pendingFields: {reimbursementChoice: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, }, }, ]; @@ -628,7 +647,9 @@ function setWorkspacePayer(policyID: string, accountID: number) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - pendingFields: {authorizedPayerAccountID: null}, + reimbursementChoice: currentPolicyReimbursementChoice, + errorFields: {reimbursementChoice: ErrorUtils.getMicroSecondOnyxError('workflowsPage.genericErrorMessage.reimbursementChoice')}, + pendingFields: {reimbursementChoice: null}, }, }, ]; @@ -638,13 +659,15 @@ function setWorkspacePayer(policyID: string, accountID: number) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - pendingFields: {authorizedPayerAccountID: null}, + errorFields: {reimbursementChoice: null}, + pendingFields: {reimbursementChoice: null}, }, }, ]; - const params: SetWorkspacePayerParams = {policyID, authorizedPayerAccountID: accountID}; - API.write(WRITE_COMMANDS.SET_WORKSPACE_PAYER, params, {optimisticData, failureData, successData}); + const params: SetReimbursementFromChoiceParams = {policyID, reimbursementChoice}; + + API.write(WRITE_COMMANDS.SET_REIMBURSEMENT_FROM_CHOICE, params, {optimisticData, failureData, successData}); } /** @@ -2625,5 +2648,5 @@ export { clearCategoryErrors, setWorkspaceReimbursement, clearWorkspaceReimbursementError, - setWorkspacePayer, + setReimbursementFromChoice, }; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 179cb705a852..fd4e24ed1612 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -143,7 +143,9 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo title: translate('workflowsPage.makeOrTrackPaymentsTitle'), subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), onToggle: () => { - // todo: we still need a action to set auto reimburse enable i.e. const.policy.reimbursement_choices.reimbursement_yes + const isActive = policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL; + const newReimbursementChoice = isActive ? CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_NO : CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL; + Policy.setReimbursementFromChoice(route.params.policyID, newReimbursementChoice); // todo: after enable we need to get VBA owner(?) email and set it to policy.reimburser_email with Policy.setWorkspaceReimbursement }, subMenuItems: ( @@ -175,7 +177,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo ), isEndOptionRow: true, - isActive: policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, + isActive: policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL, pendingAction: policy?.pendingFields?.reimbursementChoice, }, ]; From 4c3bd570401af7d4e9288e38e107ce4bd97e97cb Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 4 Mar 2024 18:57:22 +0530 Subject: [PATCH 14/74] fixes bank account fetch logic --- .../SetReimbursementFromChoiceParams.ts | 4 +- .../ReimbursementAccountPage.js | 12 ++- .../workflows/WorkspaceWorkflowsPage.tsx | 15 ++-- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 74 ++++++++++++------- 4 files changed, 64 insertions(+), 41 deletions(-) diff --git a/src/libs/API/parameters/SetReimbursementFromChoiceParams.ts b/src/libs/API/parameters/SetReimbursementFromChoiceParams.ts index 558044c85b81..3bea1c2faaec 100644 --- a/src/libs/API/parameters/SetReimbursementFromChoiceParams.ts +++ b/src/libs/API/parameters/SetReimbursementFromChoiceParams.ts @@ -2,8 +2,8 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; type SetReimbursementFromChoiceParams = { - policyID: string; - reimbursementChoice: ValueOf + policyID: string; + reimbursementChoice: ValueOf; }; export default SetReimbursementFromChoiceParams; diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js index 9855090e70d1..e8464b02aeb1 100644 --- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js +++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js @@ -79,6 +79,7 @@ const propTypes = { /** A step to navigate to if we need to drop the user into a specific point in the flow */ stepToOpen: PropTypes.string, policyID: PropTypes.string, + backTo: PropTypes.string, }), }), }; @@ -252,6 +253,7 @@ function ReimbursementAccountPage({reimbursementAccount, route, onfidoToken, pol const currentStep = achData.currentStep || CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT; const policyName = lodashGet(policy, 'name', ''); const policyID = lodashGet(route.params, 'policyID', ''); + const backTo = lodashGet(route.params, 'backTo'); const styles = useThemeStyles(); const {translate} = useLocalize(); const {isOffline} = useNetwork(); @@ -275,10 +277,17 @@ function ReimbursementAccountPage({reimbursementAccount, route, onfidoToken, pol BankAccounts.openReimbursementAccountPage(stepToOpen, subStep, ignoreLocalCurrentStep ? '' : localCurrentStep, policyID); } + function shouldClearReimbursementAccount() { + return backTo !== ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID) + } + useEffect( () => { fetchData(); return () => { + if (!shouldClearReimbursementAccount()) { + return; + } BankAccounts.clearReimbursementAccount(); }; }, @@ -337,9 +346,10 @@ function ReimbursementAccountPage({reimbursementAccount, route, onfidoToken, pol BankAccounts.hideBankAccountErrors(); } - const backTo = lodashGet(route.params, 'backTo'); // eslint-disable-next-line no-shadow const policyID = lodashGet(route.params, 'policyID'); + // eslint-disable-next-line no-shadow + const backTo = lodashGet(route.params, 'backTo'); Navigation.navigate(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute(getRouteForCurrentStep(currentStep), policyID, backTo)); }, diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index fd4e24ed1612..36d275cfa1e5 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,4 +1,3 @@ -import {useIsFocused} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useEffect, useMemo} from 'react'; import {View} from 'react-native'; @@ -11,7 +10,6 @@ import Section from '@components/Section'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; -import usePrevious from '@hooks/usePrevious'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; import BankAccount from '@libs/models/BankAccount'; @@ -49,9 +47,6 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const {isSmallScreenWidth} = useWindowDimensions(); const {isOffline} = useNetwork(); - const isFocused = useIsFocused(); - const prevIsFocused = usePrevious(isFocused); - const policyApproverEmail = policy?.approver; const policyApproverName = useMemo(() => PersonalDetailsUtils.getPersonalDetailByEmail(policyApproverEmail ?? '')?.displayName ?? policyApproverEmail, [policyApproverEmail]); const containerStyle = useMemo(() => [styles.ph8, styles.mhn8, styles.ml11, styles.pv3, styles.pr0, styles.pl4, styles.mr0, styles.widthAuto, styles.mt4], [styles]); @@ -73,13 +68,13 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo }, [policy]); useEffect(() => { - if (isOffline || !isFocused || prevIsFocused === isFocused) { + if (isOffline) { return; } fetchData(); - }, [isFocused, isOffline, prevIsFocused, fetchData]); + }, [isOffline, fetchData, reimbursementAccount]); - const activeRoute = Navigation.getActiveRouteWithoutParams(); + const activeRoute = Navigation.getActiveRoute(); const items: ToggleSettingOptionRowProps[] = useMemo(() => { const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; @@ -144,7 +139,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), onToggle: () => { const isActive = policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL; - const newReimbursementChoice = isActive ? CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_NO : CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL; + const newReimbursementChoice = isActive ? CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES : CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL; Policy.setReimbursementFromChoice(route.params.policyID, newReimbursementChoice); // todo: after enable we need to get VBA owner(?) email and set it to policy.reimburser_email with Policy.setWorkspaceReimbursement }, @@ -155,7 +150,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo descriptionTextStyle={styles.textNormalThemeText} title={hasVBA ? translate('common.bankAccount') : undefined} description={state !== BankAccount.STATE.OPEN ? translate('workflowsPage.connectBankAccount') : bankDisplayName} - onPress={() => navigateToBankAccountRoute(route.params.policyID, activeRoute)} + onPress={() => navigateToBankAccountRoute(route.params.policyID, ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID))} shouldShowRightIcon wrapperStyle={containerStyle} hoverAndPressStyle={[styles.mr0, styles.br2]} diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 959a2317a3f2..0821cf6f6047 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -6,6 +6,7 @@ import type {SectionListData} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import Badge from '@components/Badge'; +import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import MessagesRow from '@components/MessagesRow'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -23,6 +24,7 @@ import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; +import * as PolicyUtils from '@libs/PolicyUtils'; import * as UserUtils from '@libs/UserUtils'; import type {SettingsNavigatorParamList} from '@navigation/types'; import AdminPolicyAccessOrNotFoundWrapper from '@pages/workspace/AdminPolicyAccessOrNotFoundWrapper'; @@ -47,7 +49,7 @@ type WorkspaceWorkflowsPayerPageProps = WorkspaceWorkflowsPayerPageOnyxProps & type MemberOption = Omit & {accountID: number}; type MembersSection = SectionListData>; -function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDetails}: WorkspaceWorkflowsPayerPageProps) { +function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDetails, isLoadingReportData = true}: WorkspaceWorkflowsPayerPageProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); @@ -168,43 +170,59 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta return; } - if (policy?.reimbursementChoice !== CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES) { + if (policy?.reimbursementChoice !== CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL) { return; } - Policy.setWorkspaceReimbursement(policy?.id, authorizedPayer); + Policy.setWorkspaceReimbursement(policy?.id ?? '', authorizedPayer); Navigation.goBack(); }; + // eslint-disable-next-line rulesdir/no-negated-variables + const shouldShowNotFoundPage = useMemo( + () => + (isEmptyObject(policy) && !isLoadingReportData) || + PolicyUtils.isPendingDeletePolicy(policy) || + policy?.reimbursementChoice !== CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL, + [policy, isLoadingReportData], + ); + return ( - - - Policy.clearWorkspaceReimbursementError(route.params.policyID)} - /> - setPolicyAuthorizedPayer(admin)} - showScrollIndicator - /> - + + + Policy.clearWorkspaceReimbursementError(route.params.policyID)} + /> + + + ); From 6618475d85b9011add16de301a22723cd7ef7ee9 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 4 Mar 2024 19:14:39 +0530 Subject: [PATCH 15/74] resolve lint --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 36d275cfa1e5..18bd963040a0 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -74,8 +74,6 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo fetchData(); }, [isOffline, fetchData, reimbursementAccount]); - const activeRoute = Navigation.getActiveRoute(); - const items: ToggleSettingOptionRowProps[] = useMemo(() => { const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; const hasVBA = state === BankAccount.STATE.OPEN; @@ -186,7 +184,6 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo onPressAutoReportingFrequency, preferredLocale, canUseDelayedSubmission, - activeRoute, reimbursementAccount?.achData, displayNameForAuthorizedPayer, ]); From 99f932cc925ecc5dd925409ef838e0bfb9cf08e0 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 4 Mar 2024 19:16:08 +0530 Subject: [PATCH 16/74] remove unused type --- src/types/onyx/Policy.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index d691b7475f17..551e73ea077a 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -102,9 +102,6 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< /** The accountID of the policy owner */ ownerAccountID?: number; - /** The accountID of the authorized payer */ - authorizedPayerAccountID?: number; - /** The output currency for the policy */ outputCurrency: string; From 0cb874c707a2d5035d0d4107fe4826bcfba8dab2 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 4 Mar 2024 19:34:54 +0530 Subject: [PATCH 17/74] fix error indicator for menu item --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 ++ src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 18bd963040a0..0b0101441c3c 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -78,6 +78,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; const hasVBA = state === BankAccount.STATE.OPEN; const bankDisplayName = bankName ? `${bankName} ${accountNumber ? `${accountNumber.slice(-5)}` : ''}` : ''; + const isFailedToAddAuthorizedPayer = !!policy?.errorFields?.reimburserEmail; return [ ...(canUseDelayedSubmission ? [ @@ -164,6 +165,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo shouldShowRightIcon wrapperStyle={containerStyle} hoverAndPressStyle={[styles.mr0, styles.br2]} + brickRoadIndicator={isFailedToAddAuthorizedPayer ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} /> )} diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 0821cf6f6047..d10f2cb99bdb 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -1,7 +1,5 @@ -// import { View } from 'react-native'; import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useMemo, useState} from 'react'; -// import OfflineWithFeedback from '@components/OfflineWithFeedback'; import type {SectionListData} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; From a5c5ed96f2904dc68f001efed5613a3546212b39 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 4 Mar 2024 19:58:09 +0530 Subject: [PATCH 18/74] prettier diffs --- src/pages/ReimbursementAccount/ReimbursementAccountPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js index e8464b02aeb1..33fb1195a327 100644 --- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js +++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js @@ -278,7 +278,7 @@ function ReimbursementAccountPage({reimbursementAccount, route, onfidoToken, pol } function shouldClearReimbursementAccount() { - return backTo !== ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID) + return backTo !== ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID); } useEffect( From 2356983b3a019e62679283937dabab42d89fc9a6 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 4 Mar 2024 20:13:04 +0530 Subject: [PATCH 19/74] fixes copy for the error --- src/languages/en.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 08d596bf1da4..4a16225d3e7d 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1051,9 +1051,8 @@ export default { editor: { submissionFrequency: 'Choose how long Expensify should wait before sharing error-free spend.', }, - // TODO: confirm copy genericErrorMessage: { - authorizedPayer: 'The authorized payer could not be updated. Please try again.', + authorizedPayer: 'The authorized payer could not be changed. Please try again.', }, frequencies: { weekly: 'Weekly', From af86bf73bf0b3133b644330f3461b4c1a9281214 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 4 Mar 2024 22:02:51 +0530 Subject: [PATCH 20/74] fixes translations and lint --- src/languages/en.ts | 10 +++++----- src/languages/es.ts | 13 +++++-------- .../linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts | 7 ++++++- src/libs/actions/Policy.ts | 2 +- .../workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 4 ++-- 6 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/languages/en.ts b/src/languages/en.ts index 4a16225d3e7d..fc3fcd7ecbb8 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1046,14 +1046,9 @@ export default { addApprovalsDescription: 'Require additional approval before authorizing a payment.', makeOrTrackPaymentsTitle: 'Make or track payments', makeOrTrackPaymentsDescription: 'Add an authorized payer for payments made in Expensify, or simply track payments made elsewhere.', - authorizedPayer: 'Authorized payer', - admins: 'Admins', editor: { submissionFrequency: 'Choose how long Expensify should wait before sharing error-free spend.', }, - genericErrorMessage: { - authorizedPayer: 'The authorized payer could not be changed. Please try again.', - }, frequencies: { weekly: 'Weekly', monthly: 'Monthly', @@ -1071,6 +1066,11 @@ export default { }, }, }, + workflowsPayerPage: { + title: 'Authorized payer', + genericErrorMessage: 'The authorized payer could not be changed. Please try again.', + admins: 'Admins', + }, reportFraudPage: { title: 'Report virtual card fraud', description: 'If your virtual card details have been stolen or compromised, we’ll permanently deactivate your existing card and provide you with a new virtual card and number.', diff --git a/src/languages/es.ts b/src/languages/es.ts index fc3b938609b0..d695fdb0c0d4 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1042,17 +1042,9 @@ export default { addApprovalsDescription: 'Requiere una aprobación adicional antes de autorizar un pago.', makeOrTrackPaymentsTitle: 'Realizar o seguir pagos', makeOrTrackPaymentsDescription: 'Añade un pagador autorizado para los pagos realizados en Expensify, o simplemente realiza un seguimiento de los pagos realizados en otro lugar.', - // todo: add translations and cofirm copy - authorizedPayer: 'Authorized payer', - // todo: add translations and cofirm copy - admins: 'Administradores', editor: { submissionFrequency: 'Elige cuánto tiempo Expensify debe esperar antes de compartir los gastos sin errores.', }, - // todo: add translations and cofirm copy - genericErrorMessage: { - authorizedPayer: 'The authorized payer could not be updated. Please try again.', - }, frequencies: { weekly: 'Semanal', monthly: 'Mensual', @@ -1070,6 +1062,11 @@ export default { }, }, }, + workflowsPayerPage: { + title: 'Pagador autorizado', + genericErrorMessage: 'El pagador autorizado no se pudo cambiar. Por favor, inténtalo mas tarde.', + admins: 'Administradores', + }, reportFraudPage: { title: 'Reportar fraude con la tarjeta virtual', description: diff --git a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts index 33417bdd257b..cc6fe6158c00 100755 --- a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts @@ -5,7 +5,12 @@ const CENTRAL_PANE_TO_RHP_MAPPING: Partial> = [SCREENS.WORKSPACE.PROFILE]: [SCREENS.WORKSPACE.NAME, SCREENS.WORKSPACE.CURRENCY, SCREENS.WORKSPACE.DESCRIPTION, SCREENS.WORKSPACE.SHARE], [SCREENS.WORKSPACE.REIMBURSE]: [SCREENS.WORKSPACE.RATE_AND_UNIT, SCREENS.WORKSPACE.RATE_AND_UNIT_RATE, SCREENS.WORKSPACE.RATE_AND_UNIT_UNIT], [SCREENS.WORKSPACE.MEMBERS]: [SCREENS.WORKSPACE.INVITE, SCREENS.WORKSPACE.INVITE_MESSAGE], - [SCREENS.WORKSPACE.WORKFLOWS]: [SCREENS.WORKSPACE.WORKFLOWS_PAYER, SCREENS.WORKSPACE.WORKFLOWS_APPROVER, SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY, SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET], + [SCREENS.WORKSPACE.WORKFLOWS]: [ + SCREENS.WORKSPACE.WORKFLOWS_PAYER, + SCREENS.WORKSPACE.WORKFLOWS_APPROVER, + SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY, + SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET, + ], [SCREENS.WORKSPACE.CATEGORIES]: [SCREENS.WORKSPACE.CATEGORY_SETTINGS, SCREENS.WORKSPACE.CATEGORIES_SETTINGS], }; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index d075a15389b3..e12ba538231e 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -590,7 +590,7 @@ function setWorkspaceReimbursement(policyID: string, reimburserEmail: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { reimburserEmail: currentPolicyReimburserEmail, - errorFields: {reimburserEmail: ErrorUtils.getMicroSecondOnyxError('workflowsPage.genericErrorMessage.authorizedPayer')}, + errorFields: {reimburserEmail: ErrorUtils.getMicroSecondOnyxError('workflowsPayerPage.genericErrorMessage')}, pendingFields: {reimburserEmail: null}, }, }, diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 0b0101441c3c..2f1266890d03 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -159,7 +159,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_PAYER.getRoute(route.params.policyID))} shouldShowRightIcon diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index d10f2cb99bdb..32b2ea691185 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -147,7 +147,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta }); sectionsArray.push({ - title: translate('workflowsPage.admins'), + title: translate('workflowsPayerPage.admins'), data: formattedPolicyAdmins, shouldShow: true, indexOffset: 0, @@ -199,7 +199,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta testID={WorkspaceWorkflowsPayerPage.displayName} > From eec2653bff3d6a42828ed4d9ed1a7e9dfd572321 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 4 Mar 2024 22:44:55 +0530 Subject: [PATCH 21/74] fixes command name --- .../API/parameters/SetWorkspacePayerParams.ts | 6 ++++ .../SetWorkspaceReimbursementParams.ts | 6 ---- src/libs/API/parameters/index.ts | 2 +- src/libs/API/types.ts | 4 +-- src/libs/actions/Policy.ts | 29 +++++-------------- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 4 +-- 6 files changed, 19 insertions(+), 32 deletions(-) create mode 100644 src/libs/API/parameters/SetWorkspacePayerParams.ts delete mode 100644 src/libs/API/parameters/SetWorkspaceReimbursementParams.ts diff --git a/src/libs/API/parameters/SetWorkspacePayerParams.ts b/src/libs/API/parameters/SetWorkspacePayerParams.ts new file mode 100644 index 000000000000..d1c976c31dd3 --- /dev/null +++ b/src/libs/API/parameters/SetWorkspacePayerParams.ts @@ -0,0 +1,6 @@ +type SetWorkspacePayerParams = { + policyID: string; + reimburserEmail: string; +}; + +export default SetWorkspacePayerParams; diff --git a/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts b/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts deleted file mode 100644 index 3f27af07f2f5..000000000000 --- a/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts +++ /dev/null @@ -1,6 +0,0 @@ -type SetWorkspaceReimbursementParams = { - policyID: string; - reimburserEmail: string; -}; - -export default SetWorkspaceReimbursementParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index 036257311eb3..5dbb3567fdd6 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -152,6 +152,6 @@ export type {default as SetWorkspaceAutoReportingParams} from './SetWorkspaceAut export type {default as SetWorkspaceAutoReportingFrequencyParams} from './SetWorkspaceAutoReportingFrequencyParams'; export type {default as SetWorkspaceAutoReportingMonthlyOffsetParams} from './SetWorkspaceAutoReportingMonthlyOffsetParams'; export type {default as SetWorkspaceApprovalModeParams} from './SetWorkspaceApprovalModeParams'; -export type {default as SetWorkspaceReimbursementParams} from './SetWorkspaceReimbursementParams'; +export type {default as SetWorkspacePayerParams} from './SetWorkspacePayerParams'; export type {default as SetReimbursementFromChoiceParams} from './SetReimbursementFromChoiceParams'; export type {default as SwitchToOldDotParams} from './SwitchToOldDotParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 8762d4bba902..129241516c1c 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -12,7 +12,7 @@ const WRITE_COMMANDS = { SET_WORKSPACE_AUTO_REPORTING_FREQUENCY: 'SetWorkspaceAutoReportingFrequency', SET_WORKSPACE_AUTO_REPORTING_MONTHLY_OFFSET: 'UpdatePolicy', SET_WORKSPACE_APPROVAL_MODE: 'SetWorkspaceApprovalMode', - SET_WORKSPACE_REIMBURSEMENT: 'SetWorkspaceReimbursement', + SET_WORKSPACE_PAYER: 'SetWorkspaceReimbursement', SET_REIMBURSEMENT_FROM_CHOICE: 'Policy_setReimbursementFromChoice', DISMISS_REFERRAL_BANNER: 'DismissReferralBanner', UPDATE_PREFERRED_LOCALE: 'UpdatePreferredLocale', @@ -311,7 +311,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING_FREQUENCY]: Parameters.SetWorkspaceAutoReportingFrequencyParams; [WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING_MONTHLY_OFFSET]: Parameters.SetWorkspaceAutoReportingMonthlyOffsetParams; [WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE]: Parameters.SetWorkspaceApprovalModeParams; - [WRITE_COMMANDS.SET_WORKSPACE_REIMBURSEMENT]: Parameters.SetWorkspaceReimbursementParams; + [WRITE_COMMANDS.SET_WORKSPACE_PAYER]: Parameters.SetWorkspacePayerParams; [WRITE_COMMANDS.SET_REIMBURSEMENT_FROM_CHOICE]: Parameters.SetReimbursementFromChoiceParams; [WRITE_COMMANDS.SWITCH_TO_OLD_DOT]: Parameters.SwitchToOldDotParams; }; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index e12ba538231e..579afbc904f4 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -25,7 +25,7 @@ import type { SetWorkspaceAutoReportingFrequencyParams, SetWorkspaceAutoReportingMonthlyOffsetParams, SetWorkspaceAutoReportingParams, - SetWorkspaceReimbursementParams, + SetWorkspacePayerParams, UpdateWorkspaceAvatarParams, UpdateWorkspaceCustomUnitAndRateParams, UpdateWorkspaceDescriptionParams, @@ -562,12 +562,8 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo API.write(WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE, params, {optimisticData, failureData, successData}); } -/** - * - * @param policyID - * @param reimburserEmail - */ -function setWorkspaceReimbursement(policyID: string, reimburserEmail: string) { + +function setWorkspacePayer(policyID: string, reimburserEmail: string) { const policy = ReportUtils.getPolicy(policyID); const currentPolicyReimburserEmail = policy.reimburserEmail; @@ -607,24 +603,15 @@ function setWorkspaceReimbursement(policyID: string, reimburserEmail: string) { }, ]; - const params: SetWorkspaceReimbursementParams = {policyID, reimburserEmail}; + const params: SetWorkspacePayerParams = {policyID, reimburserEmail}; - API.write(WRITE_COMMANDS.SET_WORKSPACE_REIMBURSEMENT, params, {optimisticData, failureData, successData}); + API.write(WRITE_COMMANDS.SET_WORKSPACE_PAYER, params, {optimisticData, failureData, successData}); } -/** - * clear the workspace reimbursement error while setting the authorized payer - * @param policyID - */ -function clearWorkspaceReimbursementError(policyID: string) { +function clearWorkspaceAuthorizedPayerEmailError(policyID: string) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {reimburserEmail: null}}); } -/** - * set the workspace reimbursement choice - * @param policyID - * @param reimbursementChoice - */ function setReimbursementFromChoice(policyID: string, reimbursementChoice: ValueOf) { const policy = ReportUtils.getPolicy(policyID); @@ -2646,7 +2633,7 @@ export { setWorkspaceCategoryEnabled, setWorkspaceRequiresCategory, clearCategoryErrors, - setWorkspaceReimbursement, - clearWorkspaceReimbursementError, + setWorkspacePayer, + clearWorkspaceAuthorizedPayerEmailError, setReimbursementFromChoice, }; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 32b2ea691185..3797c0069407 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -172,7 +172,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta return; } - Policy.setWorkspaceReimbursement(policy?.id ?? '', authorizedPayer); + Policy.setWorkspacePayer(policy?.id ?? '', authorizedPayer); Navigation.goBack(); }; @@ -207,7 +207,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta type="error" messages={ErrorUtils.getLatestErrorField(policy ?? {}, 'reimburserEmail')} containerStyles={[styles.mh5, styles.mv3]} - onClose={() => Policy.clearWorkspaceReimbursementError(route.params.policyID)} + onClose={() => Policy.clearWorkspaceAuthorizedPayerEmailError(route.params.policyID)} /> Date: Mon, 4 Mar 2024 22:49:45 +0530 Subject: [PATCH 22/74] Update src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx Co-authored-by: Carlos Martins --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 2f1266890d03..af331f6b8c7c 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -78,7 +78,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; const hasVBA = state === BankAccount.STATE.OPEN; const bankDisplayName = bankName ? `${bankName} ${accountNumber ? `${accountNumber.slice(-5)}` : ''}` : ''; - const isFailedToAddAuthorizedPayer = !!policy?.errorFields?.reimburserEmail; + const hasReimburserEmailError = !!policy?.errorFields?.reimburserEmail; return [ ...(canUseDelayedSubmission ? [ From bb9bc3a1b3da01d134786e76d8495cc0f6312d91 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 4 Mar 2024 22:52:45 +0530 Subject: [PATCH 23/74] fixes type error --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index af331f6b8c7c..fe70a469f8aa 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -165,7 +165,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo shouldShowRightIcon wrapperStyle={containerStyle} hoverAndPressStyle={[styles.mr0, styles.br2]} - brickRoadIndicator={isFailedToAddAuthorizedPayer ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} + brickRoadIndicator={hasReimburserEmailError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} /> )} From 7b286130eb60f1d5947d55fb06966694495010a1 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 4 Mar 2024 22:57:18 +0530 Subject: [PATCH 24/74] fixes conditons for toggle --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index fe70a469f8aa..eb0467597075 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -137,8 +137,8 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo title: translate('workflowsPage.makeOrTrackPaymentsTitle'), subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'), onToggle: () => { - const isActive = policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL; - const newReimbursementChoice = isActive ? CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES : CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL; + const isActive = policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; + const newReimbursementChoice = isActive ? CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL : CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; Policy.setReimbursementFromChoice(route.params.policyID, newReimbursementChoice); // todo: after enable we need to get VBA owner(?) email and set it to policy.reimburser_email with Policy.setWorkspaceReimbursement }, @@ -172,7 +172,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo ), isEndOptionRow: true, - isActive: policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL, + isActive: policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, pendingAction: policy?.pendingFields?.reimbursementChoice, }, ]; From 1a1e764a164993a870275965e1c8e686fb177466 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 5 Mar 2024 01:04:59 +0530 Subject: [PATCH 25/74] fixes lint and wrong conditional --- src/libs/actions/Policy.ts | 1 - src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 579afbc904f4..7cb9ea622217 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -562,7 +562,6 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo API.write(WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE, params, {optimisticData, failureData, successData}); } - function setWorkspacePayer(policyID: string, reimburserEmail: string) { const policy = ReportUtils.getPolicy(policyID); diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 3797c0069407..d6fd499cc59e 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -168,7 +168,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta return; } - if (policy?.reimbursementChoice !== CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL) { + if (policy?.reimbursementChoice !== CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES) { return; } @@ -181,7 +181,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta () => (isEmptyObject(policy) && !isLoadingReportData) || PolicyUtils.isPendingDeletePolicy(policy) || - policy?.reimbursementChoice !== CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL, + policy?.reimbursementChoice !== CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, [policy, isLoadingReportData], ); From 10f914beff4121fcc9b45a365bf85ed7f005e439 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 5 Mar 2024 01:40:14 +0530 Subject: [PATCH 26/74] fixes offline behaviour and error handling --- src/components/OfflineWithFeedback.tsx | 31 +++++++++++----- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 36 ++++++++++--------- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/components/OfflineWithFeedback.tsx b/src/components/OfflineWithFeedback.tsx index ba9ce9858d03..21dcc6dc6fd2 100644 --- a/src/components/OfflineWithFeedback.tsx +++ b/src/components/OfflineWithFeedback.tsx @@ -35,6 +35,9 @@ type OfflineWithFeedbackProps = ChildrenProps & { /** Whether we should show the error messages */ shouldShowErrorMessages?: boolean; + /** */ + shouldShowErrorOnTop?: boolean; + /** Whether we should disable opacity */ shouldDisableOpacity?: boolean; @@ -78,6 +81,7 @@ function OfflineWithFeedback({ shouldDisableStrikeThrough = false, shouldHideOnDelete = true, shouldShowErrorMessages = true, + shouldShowErrorOnTop = false, style, ...rest }: OfflineWithFeedbackProps) { @@ -131,8 +135,25 @@ function OfflineWithFeedback({ if (needsStrikeThrough && !hideChildren) { children = applyStrikeThrough(children); } + + const renderErrorMessage = () => { + if (!shouldShowErrorMessages && !hasErrorMessages) { + return null; + } + return ( + + ); + }; + return ( + {shouldShowErrorOnTop && renderErrorMessage()} {!hideChildren && ( )} - {shouldShowErrorMessages && hasErrorMessages && ( - - )} + {!shouldShowErrorOnTop && renderErrorMessage()} ); } diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index d6fd499cc59e..12e9bce4f296 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -6,7 +6,7 @@ import {withOnyx} from 'react-native-onyx'; import Badge from '@components/Badge'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import MessagesRow from '@components/MessagesRow'; +import OfflineWithFeedback from '@components/OfflineWithFeedback'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import type {ListItem, Section} from '@components/SelectionList/types'; @@ -172,7 +172,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta return; } - Policy.setWorkspacePayer(policy?.id ?? '', authorizedPayer); + Policy.setWorkspacePayer(policy?.id ?? '', 'authorizedPayer'); Navigation.goBack(); }; @@ -203,22 +203,24 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta subtitle={policyName} onBackButtonPress={Navigation.goBack} /> - Policy.clearWorkspaceAuthorizedPayerEmailError(route.params.policyID)} - /> - + shouldShowErrorOnTop + > + + From 1d4f4f9b579da1f6ca4f978cbec0fc9e080bc18f Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 02:18:07 +0530 Subject: [PATCH 27/74] resolve conflict --- src/libs/Navigation/linkingConfig/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/Navigation/linkingConfig/config.ts b/src/libs/Navigation/linkingConfig/config.ts index 9722424e2455..5f6faed63754 100644 --- a/src/libs/Navigation/linkingConfig/config.ts +++ b/src/libs/Navigation/linkingConfig/config.ts @@ -282,7 +282,7 @@ const config: LinkingOptions['config'] = { }, [SCREENS.WORKSPACE.WORKFLOWS_PAYER]: { path: ROUTES.WORKSPACE_WORKFLOWS_PAYER.route, - } + }, [SCREENS.WORKSPACE.MEMBER_DETAILS]: { path: ROUTES.WORKSPACE_MEMBER_DETAILS.route, }, From 9bbb535bb0c8953d8317163f1fbacbff6a0105e8 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 02:21:40 +0530 Subject: [PATCH 28/74] fix dupe type in policy --- src/types/onyx/Policy.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 4cd9269b3854..b005a9d2756f 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -176,9 +176,6 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< /** The approver of the policy */ approver?: string; - /** The email of the reimburser */ - reimburserEmail?: string; - /** The approval mode set up on this policy */ approvalMode?: ValueOf; From 3056fd05b2afed43161c197c2a9a790a4eaa1c82 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 04:10:23 +0530 Subject: [PATCH 29/74] changes command as per requirements --- .../OpenPolicyWorkflowsPageParams.ts | 5 ++ ....ts => SetWorkspaceReimbursementParams.ts} | 4 +- src/libs/API/parameters/index.ts | 3 +- src/libs/API/types.ts | 8 ++-- src/libs/actions/Policy.ts | 48 ++++++++++++------- .../workflows/WorkspaceWorkflowsPage.tsx | 13 ++--- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 4 +- 7 files changed, 53 insertions(+), 32 deletions(-) create mode 100644 src/libs/API/parameters/OpenPolicyWorkflowsPageParams.ts rename src/libs/API/parameters/{SetReimbursementFromChoiceParams.ts => SetWorkspaceReimbursementParams.ts} (66%) diff --git a/src/libs/API/parameters/OpenPolicyWorkflowsPageParams.ts b/src/libs/API/parameters/OpenPolicyWorkflowsPageParams.ts new file mode 100644 index 000000000000..3fe1db5feac9 --- /dev/null +++ b/src/libs/API/parameters/OpenPolicyWorkflowsPageParams.ts @@ -0,0 +1,5 @@ +type OpenPolicyWorkflowsPageParams = { + policyID: string; +} + +export default OpenPolicyWorkflowsPageParams; diff --git a/src/libs/API/parameters/SetReimbursementFromChoiceParams.ts b/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts similarity index 66% rename from src/libs/API/parameters/SetReimbursementFromChoiceParams.ts rename to src/libs/API/parameters/SetWorkspaceReimbursementParams.ts index 3bea1c2faaec..f96f6385f541 100644 --- a/src/libs/API/parameters/SetReimbursementFromChoiceParams.ts +++ b/src/libs/API/parameters/SetWorkspaceReimbursementParams.ts @@ -1,9 +1,9 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; -type SetReimbursementFromChoiceParams = { +type SetWorkspaceReimbursementParams = { policyID: string; reimbursementChoice: ValueOf; }; -export default SetReimbursementFromChoiceParams; +export default SetWorkspaceReimbursementParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts index b7acd522b9ce..08443e733e77 100644 --- a/src/libs/API/parameters/index.ts +++ b/src/libs/API/parameters/index.ts @@ -156,5 +156,6 @@ export type {default as SetWorkspaceAutoReportingFrequencyParams} from './SetWor export type {default as SetWorkspaceAutoReportingMonthlyOffsetParams} from './SetWorkspaceAutoReportingMonthlyOffsetParams'; export type {default as SetWorkspaceApprovalModeParams} from './SetWorkspaceApprovalModeParams'; export type {default as SetWorkspacePayerParams} from './SetWorkspacePayerParams'; -export type {default as SetReimbursementFromChoiceParams} from './SetReimbursementFromChoiceParams'; +export type {default as SetWorkspaceReimbursementParams} from './SetWorkspaceReimbursementParams'; export type {default as SwitchToOldDotParams} from './SwitchToOldDotParams'; +export type {default as OpenPolicyWorkflowsPageParams} from './OpenPolicyWorkflowsPageParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 28f6601b8679..a68e5283d7e7 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -12,8 +12,8 @@ const WRITE_COMMANDS = { SET_WORKSPACE_AUTO_REPORTING_FREQUENCY: 'SetWorkspaceAutoReportingFrequency', SET_WORKSPACE_AUTO_REPORTING_MONTHLY_OFFSET: 'UpdatePolicy', SET_WORKSPACE_APPROVAL_MODE: 'SetWorkspaceApprovalMode', - SET_WORKSPACE_PAYER: 'SetWorkspaceReimbursement', - SET_REIMBURSEMENT_FROM_CHOICE: 'Policy_setReimbursementFromChoice', + SET_WORKSPACE_PAYER: 'SetWorkspacePayer', + SET_WORKSPACE_REIMBURSEMENT: 'SetWorkspaceReimbursement', DISMISS_REFERRAL_BANNER: 'DismissReferralBanner', UPDATE_PREFERRED_LOCALE: 'UpdatePreferredLocale', OPEN_APP: 'OpenApp', @@ -314,7 +314,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.SET_WORKSPACE_AUTO_REPORTING_MONTHLY_OFFSET]: Parameters.SetWorkspaceAutoReportingMonthlyOffsetParams; [WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE]: Parameters.SetWorkspaceApprovalModeParams; [WRITE_COMMANDS.SET_WORKSPACE_PAYER]: Parameters.SetWorkspacePayerParams; - [WRITE_COMMANDS.SET_REIMBURSEMENT_FROM_CHOICE]: Parameters.SetReimbursementFromChoiceParams; + [WRITE_COMMANDS.SET_WORKSPACE_REIMBURSEMENT]: Parameters.SetWorkspaceReimbursementParams; [WRITE_COMMANDS.SWITCH_TO_OLD_DOT]: Parameters.SwitchToOldDotParams; }; @@ -349,6 +349,7 @@ const READ_COMMANDS = { OPEN_POLICY_CATEGORIES_PAGE: 'OpenPolicyCategoriesPage', OPEN_WORKSPACE_INVITE_PAGE: 'OpenWorkspaceInvitePage', OPEN_DRAFT_WORKSPACE_REQUEST: 'OpenDraftWorkspaceRequest', + OPEN_POLICY_WORKFLOWS_PAGE: 'OpenPolicyWorkflowsPage', } as const; type ReadCommand = ValueOf; @@ -384,6 +385,7 @@ type ReadCommandParameters = { [READ_COMMANDS.OPEN_POLICY_CATEGORIES_PAGE]: Parameters.OpenPolicyCategoriesPageParams; [READ_COMMANDS.OPEN_WORKSPACE_INVITE_PAGE]: Parameters.OpenWorkspaceInvitePageParams; [READ_COMMANDS.OPEN_DRAFT_WORKSPACE_REQUEST]: Parameters.OpenDraftWorkspaceRequestParams; + [READ_COMMANDS.OPEN_POLICY_WORKFLOWS_PAGE]: Parameters.OpenPolicyWorkflowsPageParams; }; const SIDE_EFFECT_REQUEST_COMMANDS = { diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 311636782520..c6884fed00c5 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -21,17 +21,18 @@ import type { OpenWorkspaceMembersPageParams, OpenWorkspaceParams, OpenWorkspaceReimburseViewParams, - SetReimbursementFromChoiceParams, SetWorkspaceApprovalModeParams, SetWorkspaceAutoReportingFrequencyParams, SetWorkspaceAutoReportingMonthlyOffsetParams, SetWorkspaceAutoReportingParams, SetWorkspacePayerParams, + SetWorkspaceReimbursementParams, UpdateWorkspaceAvatarParams, UpdateWorkspaceCustomUnitAndRateParams, UpdateWorkspaceDescriptionParams, UpdateWorkspaceGeneralSettingsParams, UpdateWorkspaceMembersRoleParams, + OpenPolicyWorkflowsPageParams, } from '@libs/API/parameters'; import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import DateUtils from '@libs/DateUtils'; @@ -567,7 +568,6 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo function setWorkspacePayer(policyID: string, reimburserEmail: string) { const policy = ReportUtils.getPolicy(policyID); - const currentPolicyReimburserEmail = policy.reimburserEmail; const optimisticData: OnyxUpdate[] = [ @@ -582,24 +582,24 @@ function setWorkspacePayer(policyID: string, reimburserEmail: string) { }, ]; - const failureData: OnyxUpdate[] = [ + const successData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - reimburserEmail: currentPolicyReimburserEmail, - errorFields: {reimburserEmail: ErrorUtils.getMicroSecondOnyxError('workflowsPayerPage.genericErrorMessage')}, + errorFields: {reimburserEmail: null}, pendingFields: {reimburserEmail: null}, }, }, ]; - const successData: OnyxUpdate[] = [ + const failureData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - errorFields: {reimburserEmail: null}, + reimburserEmail: currentPolicyReimburserEmail, + errorFields: {reimburserEmail: ErrorUtils.getMicroSecondOnyxError('workflowsPayerPage.genericErrorMessage')}, pendingFields: {reimburserEmail: null}, }, }, @@ -610,11 +610,11 @@ function setWorkspacePayer(policyID: string, reimburserEmail: string) { API.write(WRITE_COMMANDS.SET_WORKSPACE_PAYER, params, {optimisticData, failureData, successData}); } -function clearWorkspaceAuthorizedPayerEmailError(policyID: string) { +function clearWorkspacePayerError(policyID: string) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {reimburserEmail: null}}); } -function setReimbursementFromChoice(policyID: string, reimbursementChoice: ValueOf) { +function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueOf) { const policy = ReportUtils.getPolicy(policyID); const currentPolicyReimbursementChoice = policy.reimbursementChoice; @@ -631,32 +631,32 @@ function setReimbursementFromChoice(policyID: string, reimbursementChoice: Value }, ]; - const failureData: OnyxUpdate[] = [ + const successData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - reimbursementChoice: currentPolicyReimbursementChoice, - errorFields: {reimbursementChoice: ErrorUtils.getMicroSecondOnyxError('workflowsPage.genericErrorMessage.reimbursementChoice')}, + errorFields: {reimbursementChoice: null}, pendingFields: {reimbursementChoice: null}, }, }, ]; - const successData: OnyxUpdate[] = [ + const failureData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - errorFields: {reimbursementChoice: null}, + reimbursementChoice: currentPolicyReimbursementChoice, + errorFields: {reimbursementChoice: ErrorUtils.getMicroSecondOnyxError('workflowsPage.genericErrorMessage.reimbursementChoice')}, pendingFields: {reimbursementChoice: null}, }, }, ]; - const params: SetReimbursementFromChoiceParams = {policyID, reimbursementChoice}; + const params: SetWorkspaceReimbursementParams = {policyID, reimbursementChoice}; - API.write(WRITE_COMMANDS.SET_REIMBURSEMENT_FROM_CHOICE, params, {optimisticData, failureData, successData}); + API.write(WRITE_COMMANDS.SET_WORKSPACE_REIMBURSEMENT, params, {optimisticData, failureData, successData}); } /** @@ -1882,6 +1882,17 @@ function openWorkspaceReimburseView(policyID: string) { API.read(READ_COMMANDS.OPEN_WORKSPACE_REIMBURSE_VIEW, params, {successData, failureData}); } +function openPolicyWorkflowsPage(policyID: string) { + if (!policyID) { + Log.warn('openPolicyWorkflowsPage invalid params', {policyID}); + return; + } + + const params: OpenPolicyWorkflowsPageParams = {policyID}; + + API.read(READ_COMMANDS.OPEN_POLICY_WORKFLOWS_PAGE, params); +} + function setPolicyIDForReimburseView(policyID: string) { Onyx.merge(ONYXKEYS.WORKSPACE_RATE_AND_UNIT, {policyID, rate: null, unit: null}); } @@ -2701,6 +2712,7 @@ export { createPolicyCategory, clearCategoryErrors, setWorkspacePayer, - clearWorkspaceAuthorizedPayerEmailError, - setReimbursementFromChoice, + clearWorkspacePayerError, + setWorkspaceReimbursement, + openPolicyWorkflowsPage, }; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index eb0467597075..9de5e5e704c7 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -54,17 +54,17 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const onPressAutoReportingFrequency = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY.getRoute(policy?.id ?? '')), [policy?.id]); - const authorizedPayerEmail = policy?.reimburserEmail; + const reimburserEmail = policy?.reimburserEmail; const displayNameForAuthorizedPayer = useMemo( - () => PersonalDetailsUtils.getPersonalDetailByEmail(authorizedPayerEmail ?? '')?.displayName ?? authorizedPayerEmail, - [authorizedPayerEmail], + () => PersonalDetailsUtils.getPersonalDetailByEmail(reimburserEmail ?? '')?.displayName ?? reimburserEmail, + [reimburserEmail], ); const fetchData = useCallback(() => { if (!policy?.id) { return; } - Policy.openWorkspaceReimburseView(policy?.id); + Policy.openPolicyWorkflowsPage(policy?.id); }, [policy]); useEffect(() => { @@ -79,6 +79,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const hasVBA = state === BankAccount.STATE.OPEN; const bankDisplayName = bankName ? `${bankName} ${accountNumber ? `${accountNumber.slice(-5)}` : ''}` : ''; const hasReimburserEmailError = !!policy?.errorFields?.reimburserEmail; + return [ ...(canUseDelayedSubmission ? [ @@ -139,8 +140,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo onToggle: () => { const isActive = policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; const newReimbursementChoice = isActive ? CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL : CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; - Policy.setReimbursementFromChoice(route.params.policyID, newReimbursementChoice); - // todo: after enable we need to get VBA owner(?) email and set it to policy.reimburser_email with Policy.setWorkspaceReimbursement + Policy.setWorkspaceReimbursement(route.params.policyID, newReimbursementChoice); }, subMenuItems: ( <> @@ -220,6 +220,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo shouldShowNotFoundPage={!isPaidGroupPolicy || !isPolicyAdmin} shouldUseScrollView shouldSkipVBBACall + shouldShowLoading={false} >
Policy.clearWorkspaceAuthorizedPayerEmailError(route.params.policyID)} + onClose={() => Policy.clearWorkspacePayerError(policy?.id ?? '')} shouldShowErrorOnTop > Date: Fri, 8 Mar 2024 04:21:55 +0530 Subject: [PATCH 30/74] use usenetwork hook for fetch data --- .../workspace/workflows/WorkspaceWorkflowsPage.tsx | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 9de5e5e704c7..23d351afba2e 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -45,7 +45,6 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const {translate, preferredLocale} = useLocalize(); const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); - const {isOffline} = useNetwork(); const policyApproverEmail = policy?.approver; const policyApproverName = useMemo(() => PersonalDetailsUtils.getPersonalDetailByEmail(policyApproverEmail ?? '')?.displayName ?? policyApproverEmail, [policyApproverEmail]); @@ -67,12 +66,9 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo Policy.openPolicyWorkflowsPage(policy?.id); }, [policy]); - useEffect(() => { - if (isOffline) { - return; - } - fetchData(); - }, [isOffline, fetchData, reimbursementAccount]); + useNetwork({onReconnect: fetchData}); + + console.log('WorkspaceWorkflowsPage', {policy}); const items: ToggleSettingOptionRowProps[] = useMemo(() => { const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; From d4bf8fdfd5bebdcfab625d1e4dd9adb257f97698 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 05:10:49 +0530 Subject: [PATCH 31/74] lint and use account instead of email for fetching the reimburser details --- src/ONYXKEYS.ts | 3 +++ .../OpenPolicyWorkflowsPageParams.ts | 4 ++-- src/libs/actions/Policy.ts | 2 +- .../ReimbursementAccountPage.js | 7 ------ .../workflows/WorkspaceWorkflowsPage.tsx | 22 +++++++++++-------- src/types/onyx/Policy.ts | 3 +++ 6 files changed, 22 insertions(+), 19 deletions(-) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 31e22491e2b9..870f23b8d58f 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -323,6 +323,8 @@ const ONYXKEYS = { /** This is deprecated, but needed for a migration, so we still need to include it here so that it will be initialized in Onyx.init */ DEPRECATED_POLICY_MEMBER_LIST: 'policyMemberList_', + + REIMBURSEMENT_ACCOUNT: 'reimbursementAccount_', }, /** List of Form ids */ @@ -489,6 +491,7 @@ type OnyxCollectionValuesMapping = { [ONYXKEYS.COLLECTION.PRIVATE_NOTES_DRAFT]: string; [ONYXKEYS.COLLECTION.NEXT_STEP]: OnyxTypes.ReportNextStep; [ONYXKEYS.COLLECTION.POLICY_JOIN_MEMBER]: OnyxTypes.PolicyJoinMember; + [ONYXKEYS.COLLECTION.REIMBURSEMENT_ACCOUNT]: OnyxTypes.ReimbursementAccount; }; type OnyxValuesMapping = { diff --git a/src/libs/API/parameters/OpenPolicyWorkflowsPageParams.ts b/src/libs/API/parameters/OpenPolicyWorkflowsPageParams.ts index 3fe1db5feac9..eea0788b3927 100644 --- a/src/libs/API/parameters/OpenPolicyWorkflowsPageParams.ts +++ b/src/libs/API/parameters/OpenPolicyWorkflowsPageParams.ts @@ -1,5 +1,5 @@ type OpenPolicyWorkflowsPageParams = { - policyID: string; -} + policyID: string; +}; export default OpenPolicyWorkflowsPageParams; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index e87b69a1679a..1f1875aeb80d 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -17,6 +17,7 @@ import type { DeleteWorkspaceParams, OpenDraftWorkspaceRequestParams, OpenPolicyCategoriesPageParams, + OpenPolicyWorkflowsPageParams, OpenWorkspaceInvitePageParams, OpenWorkspaceMembersPageParams, OpenWorkspaceParams, @@ -32,7 +33,6 @@ import type { UpdateWorkspaceDescriptionParams, UpdateWorkspaceGeneralSettingsParams, UpdateWorkspaceMembersRoleParams, - OpenPolicyWorkflowsPageParams, } from '@libs/API/parameters'; import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import DateUtils from '@libs/DateUtils'; diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js index 33fb1195a327..702f8a637310 100644 --- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js +++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js @@ -277,17 +277,10 @@ function ReimbursementAccountPage({reimbursementAccount, route, onfidoToken, pol BankAccounts.openReimbursementAccountPage(stepToOpen, subStep, ignoreLocalCurrentStep ? '' : localCurrentStep, policyID); } - function shouldClearReimbursementAccount() { - return backTo !== ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID); - } - useEffect( () => { fetchData(); return () => { - if (!shouldClearReimbursementAccount()) { - return; - } BankAccounts.clearReimbursementAccount(); }; }, diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 23d351afba2e..69487086be00 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -53,11 +53,10 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const onPressAutoReportingFrequency = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY.getRoute(policy?.id ?? '')), [policy?.id]); - const reimburserEmail = policy?.reimburserEmail; - const displayNameForAuthorizedPayer = useMemo( - () => PersonalDetailsUtils.getPersonalDetailByEmail(reimburserEmail ?? '')?.displayName ?? reimburserEmail, - [reimburserEmail], - ); + const displayNameForAuthorizedPayer = useMemo(() => { + const personalDetails = PersonalDetailsUtils.getPersonalDetailsByIDs([policy?.reimburserAccountID ?? 0], 0); + return personalDetails[policy?.reimburserAccountID ?? 0]?.displayName ?? policy?.reimburserEmail; + }, [policy?.reimburserEmail]); const fetchData = useCallback(() => { if (!policy?.id) { @@ -68,7 +67,11 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo useNetwork({onReconnect: fetchData}); - console.log('WorkspaceWorkflowsPage', {policy}); + useEffect(() => { + fetchData(); + }, []); + + console.log('WorkspaceWorkflowsPage', {policy, reimbursementAccount}); const items: ToggleSettingOptionRowProps[] = useMemo(() => { const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; @@ -242,8 +245,9 @@ export default withPolicy( key: ONYXKEYS.BETAS, }, // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM - reimbursementAccount: { - key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, - }, + reimbursementAccount: ({policy}) => {{ + console.log('WorkspaceWorkflowsPage', `reimbursementAccount: ${ONYXKEYS.COLLECTION.REIMBURSEMENT_ACCOUNT}${policy?.id}`) + return {key: `${ONYXKEYS.COLLECTION.REIMBURSEMENT_ACCOUNT}${policy?.id}`}; + }} })(WorkspaceWorkflowsPage), ); diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index 61b63106ad8a..7bc49a109b6a 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -232,6 +232,9 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< /** Email of the reimburser when reimbursement is set direct */ reimburserEmail?: string; + /** AccountID of the reimburser when reimbursement is set direct */ + reimburserAccountID?: number; + /** ReportID of the admins room for this workspace */ chatReportIDAdmins?: number; From e1c9f12c6671f83cb5af5ff09d1a01bd6016df02 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 05:54:37 +0530 Subject: [PATCH 32/74] fix type and lint warning --- src/ONYXKEYS.ts | 3 --- .../ReimbursementAccountPage.js | 1 - .../workspace/workflows/WorkspaceWorkflowsPage.tsx | 14 +++++--------- 3 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 870f23b8d58f..31e22491e2b9 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -323,8 +323,6 @@ const ONYXKEYS = { /** This is deprecated, but needed for a migration, so we still need to include it here so that it will be initialized in Onyx.init */ DEPRECATED_POLICY_MEMBER_LIST: 'policyMemberList_', - - REIMBURSEMENT_ACCOUNT: 'reimbursementAccount_', }, /** List of Form ids */ @@ -491,7 +489,6 @@ type OnyxCollectionValuesMapping = { [ONYXKEYS.COLLECTION.PRIVATE_NOTES_DRAFT]: string; [ONYXKEYS.COLLECTION.NEXT_STEP]: OnyxTypes.ReportNextStep; [ONYXKEYS.COLLECTION.POLICY_JOIN_MEMBER]: OnyxTypes.PolicyJoinMember; - [ONYXKEYS.COLLECTION.REIMBURSEMENT_ACCOUNT]: OnyxTypes.ReimbursementAccount; }; type OnyxValuesMapping = { diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js index 702f8a637310..944adc2be85f 100644 --- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js +++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js @@ -79,7 +79,6 @@ const propTypes = { /** A step to navigate to if we need to drop the user into a specific point in the flow */ stepToOpen: PropTypes.string, policyID: PropTypes.string, - backTo: PropTypes.string, }), }), }; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 69487086be00..66feb58dc219 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -56,7 +56,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const displayNameForAuthorizedPayer = useMemo(() => { const personalDetails = PersonalDetailsUtils.getPersonalDetailsByIDs([policy?.reimburserAccountID ?? 0], 0); return personalDetails[policy?.reimburserAccountID ?? 0]?.displayName ?? policy?.reimburserEmail; - }, [policy?.reimburserEmail]); + }, [policy?.reimburserAccountID, policy?.reimburserEmail]); const fetchData = useCallback(() => { if (!policy?.id) { @@ -69,9 +69,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo useEffect(() => { fetchData(); - }, []); - - console.log('WorkspaceWorkflowsPage', {policy, reimbursementAccount}); + }, [fetchData]); const items: ToggleSettingOptionRowProps[] = useMemo(() => { const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; @@ -244,10 +242,8 @@ export default withPolicy( betas: { key: ONYXKEYS.BETAS, }, - // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM - reimbursementAccount: ({policy}) => {{ - console.log('WorkspaceWorkflowsPage', `reimbursementAccount: ${ONYXKEYS.COLLECTION.REIMBURSEMENT_ACCOUNT}${policy?.id}`) - return {key: `${ONYXKEYS.COLLECTION.REIMBURSEMENT_ACCOUNT}${policy?.id}`}; - }} + reimbursementAccount: { + key: ({route}) => `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}${route.params.policyID}`, + }, })(WorkspaceWorkflowsPage), ); From 8931440636f00d390990a8b04cc6330798db9b12 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 06:02:28 +0530 Subject: [PATCH 33/74] remove unused var --- src/pages/ReimbursementAccount/ReimbursementAccountPage.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js index 944adc2be85f..3b6a9340090a 100644 --- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js +++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js @@ -252,7 +252,6 @@ function ReimbursementAccountPage({reimbursementAccount, route, onfidoToken, pol const currentStep = achData.currentStep || CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT; const policyName = lodashGet(policy, 'name', ''); const policyID = lodashGet(route.params, 'policyID', ''); - const backTo = lodashGet(route.params, 'backTo'); const styles = useThemeStyles(); const {translate} = useLocalize(); const {isOffline} = useNetwork(); From b7a8a49d292d039a8f2fdf057a02f9ec181f36e6 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 06:27:49 +0530 Subject: [PATCH 34/74] fix style for connect account page --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 66feb58dc219..6eb17111b61c 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -69,7 +69,8 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo useEffect(() => { fetchData(); - }, [fetchData]); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); const items: ToggleSettingOptionRowProps[] = useMemo(() => { const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; @@ -78,7 +79,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const hasReimburserEmailError = !!policy?.errorFields?.reimburserEmail; return [ - ...(canUseDelayedSubmission + ...(!canUseDelayedSubmission ? [ { icon: Illustrations.ReceiptEnvelope, @@ -144,8 +145,8 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo navigateToBankAccountRoute(route.params.policyID, ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID))} shouldShowRightIcon wrapperStyle={containerStyle} From 980be51a05805bee7bf5971639de5e4c51494c69 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 06:49:20 +0530 Subject: [PATCH 35/74] remove useCallback usage --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 6eb17111b61c..07fc7cb533fc 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -58,12 +58,9 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo return personalDetails[policy?.reimburserAccountID ?? 0]?.displayName ?? policy?.reimburserEmail; }, [policy?.reimburserAccountID, policy?.reimburserEmail]); - const fetchData = useCallback(() => { - if (!policy?.id) { - return; - } - Policy.openPolicyWorkflowsPage(policy?.id); - }, [policy]); + const fetchData = () => { + Policy.openPolicyWorkflowsPage(policy?.id ?? route.params.policyID); + } useNetwork({onReconnect: fetchData}); From ff0c8bd6bbef8d28058892c094db2fb6207840e1 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 07:10:14 +0530 Subject: [PATCH 36/74] prettier diffs --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 07fc7cb533fc..cf7c8fc79119 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -69,6 +69,8 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo // eslint-disable-next-line react-hooks/exhaustive-deps }, []); + console.log('policy', policy); + const items: ToggleSettingOptionRowProps[] = useMemo(() => { const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; const hasVBA = state === BankAccount.STATE.OPEN; From ffd918dd97e25e1b537e6fbd6b1321dd8752c959 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 07:17:15 +0530 Subject: [PATCH 37/74] remove console --- .../workspace/workflows/WorkspaceWorkflowsPage.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index cf7c8fc79119..e8858e2b5f3f 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -60,7 +60,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const fetchData = () => { Policy.openPolicyWorkflowsPage(policy?.id ?? route.params.policyID); - } + }; useNetwork({onReconnect: fetchData}); @@ -69,8 +69,6 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - console.log('policy', policy); - const items: ToggleSettingOptionRowProps[] = useMemo(() => { const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; const hasVBA = state === BankAccount.STATE.OPEN; @@ -78,7 +76,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const hasReimburserEmailError = !!policy?.errorFields?.reimburserEmail; return [ - ...(!canUseDelayedSubmission + ...(canUseDelayedSubmission ? [ { icon: Illustrations.ReceiptEnvelope, @@ -145,7 +143,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo titleStyle={styles.textLabelSupportingNormal} descriptionTextStyle={styles.textNormalThemeText} title={hasVBA ? translate('common.bankAccount') : translate('workflowsPage.connectBankAccount')} - description={state === BankAccount.STATE.OPEN ? bankDisplayName : undefined} + description={state === BankAccount.STATE.OPEN ? bankDisplayName : undefined} onPress={() => navigateToBankAccountRoute(route.params.policyID, ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID))} shouldShowRightIcon wrapperStyle={containerStyle} @@ -243,7 +241,7 @@ export default withPolicy( key: ONYXKEYS.BETAS, }, reimbursementAccount: { - key: ({route}) => `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}${route.params.policyID}`, + key: ({route}) => `${ONYXKEYS.COLLECTION.REIMBURSEMENT_ACCOUNT}${route.params.policyID}`, }, })(WorkspaceWorkflowsPage), ); From ee6e2023a98174e343309f268e698584c44a16e6 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh <104348397+ishpaul777@users.noreply.github.com> Date: Fri, 8 Mar 2024 18:44:46 +0530 Subject: [PATCH 38/74] Update src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx Co-authored-by: Carlos Martins --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index e8858e2b5f3f..822735eb9d57 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -241,7 +241,8 @@ export default withPolicy( key: ONYXKEYS.BETAS, }, reimbursementAccount: { - key: ({route}) => `${ONYXKEYS.COLLECTION.REIMBURSEMENT_ACCOUNT}${route.params.policyID}`, + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM + key: ({route}) => `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}${route.params.policyID}`, }, })(WorkspaceWorkflowsPage), ); From a523144b4429100b84458a8c7c1f1f894446992f Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 20:18:24 +0530 Subject: [PATCH 39/74] fix error handling in payer page --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 9 +++++++-- .../workspace/workflows/WorkspaceWorkflowsPayerPage.tsx | 6 +----- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 822735eb9d57..1f80c845de1a 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -12,6 +12,7 @@ import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import * as ErrorUtils from '@libs/ErrorUtils'; import BankAccount from '@libs/models/BankAccount'; import Navigation from '@libs/Navigation/Navigation'; import Permissions from '@libs/Permissions'; @@ -150,7 +151,11 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo hoverAndPressStyle={[styles.mr0, styles.br2]} /> {hasVBA && ( - + Policy.clearWorkspacePayerError(policy?.id ?? route.params.policyID)} + > `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}${route.params.policyID}`, }, })(WorkspaceWorkflowsPage), diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 4b44f671dce1..f76863963006 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -16,7 +16,6 @@ import useNetwork from '@hooks/useNetwork'; import useStyleUtils from '@hooks/useStyleUtils'; import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; -import * as ErrorUtils from '@libs/ErrorUtils'; import {formatPhoneNumber} from '@libs/LocalePhoneNumber'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; @@ -172,7 +171,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta return; } - Policy.setWorkspacePayer(policy?.id ?? '', authorizedPayer); + Policy.setWorkspacePayer(policy?.id ?? '', "authorizedPayer"); Navigation.goBack(); }; @@ -205,9 +204,6 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta /> Policy.clearWorkspacePayerError(policy?.id ?? '')} shouldShowErrorOnTop > Date: Fri, 8 Mar 2024 20:20:19 +0530 Subject: [PATCH 40/74] remove unneccessary changes in offline with feedback --- src/components/OfflineWithFeedback.tsx | 31 ++++++++------------------ 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/src/components/OfflineWithFeedback.tsx b/src/components/OfflineWithFeedback.tsx index 21dcc6dc6fd2..ba9ce9858d03 100644 --- a/src/components/OfflineWithFeedback.tsx +++ b/src/components/OfflineWithFeedback.tsx @@ -35,9 +35,6 @@ type OfflineWithFeedbackProps = ChildrenProps & { /** Whether we should show the error messages */ shouldShowErrorMessages?: boolean; - /** */ - shouldShowErrorOnTop?: boolean; - /** Whether we should disable opacity */ shouldDisableOpacity?: boolean; @@ -81,7 +78,6 @@ function OfflineWithFeedback({ shouldDisableStrikeThrough = false, shouldHideOnDelete = true, shouldShowErrorMessages = true, - shouldShowErrorOnTop = false, style, ...rest }: OfflineWithFeedbackProps) { @@ -135,25 +131,8 @@ function OfflineWithFeedback({ if (needsStrikeThrough && !hideChildren) { children = applyStrikeThrough(children); } - - const renderErrorMessage = () => { - if (!shouldShowErrorMessages && !hasErrorMessages) { - return null; - } - return ( - - ); - }; - return ( - {shouldShowErrorOnTop && renderErrorMessage()} {!hideChildren && ( )} - {!shouldShowErrorOnTop && renderErrorMessage()} + {shouldShowErrorMessages && hasErrorMessages && ( + + )} ); } From 77a7760836f7aa889f853b285545a46ac185c0c4 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 20:20:52 +0530 Subject: [PATCH 41/74] remove unused prop --- src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index f76863963006..5620c0390917 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -204,7 +204,6 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta /> Date: Fri, 8 Mar 2024 20:46:43 +0530 Subject: [PATCH 42/74] get the errors correctly --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 5 ++--- .../workspace/workflows/WorkspaceWorkflowsPayerPage.tsx | 6 ++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 1f80c845de1a..aaa6c194ab2d 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -12,7 +12,6 @@ import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; -import * as ErrorUtils from '@libs/ErrorUtils'; import BankAccount from '@libs/models/BankAccount'; import Navigation from '@libs/Navigation/Navigation'; import Permissions from '@libs/Permissions'; @@ -68,7 +67,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo useEffect(() => { fetchData(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [policy?.reimbursementChoice]); const items: ToggleSettingOptionRowProps[] = useMemo(() => { const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; @@ -153,7 +152,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo {hasVBA && ( Policy.clearWorkspacePayerError(policy?.id ?? route.params.policyID)} > - + Date: Fri, 8 Mar 2024 20:47:53 +0530 Subject: [PATCH 43/74] remove test data --- src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 8267b777cd7d..d4577cd550c8 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -171,7 +171,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta return; } - Policy.setWorkspacePayer(policy?.id ?? '', 'authorizedPayer'); + Policy.setWorkspacePayer(policy?.id ?? '', authorizedPayer); Navigation.goBack(); }; From 81449445529f936417dc7f9494ba1f5fe796a2d1 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 21:43:47 +0530 Subject: [PATCH 44/74] use the latest error field --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index aaa6c194ab2d..5ab2dacae109 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -17,6 +17,7 @@ import Navigation from '@libs/Navigation/Navigation'; import Permissions from '@libs/Permissions'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; +import * as ErrorUtils from '@libs/ErrorUtils'; import type {CentralPaneNavigatorParamList} from '@navigation/types'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicy from '@pages/workspace/withPolicy'; @@ -152,7 +153,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo {hasVBA && ( Policy.clearWorkspacePayerError(policy?.id ?? route.params.policyID)} > Date: Fri, 8 Mar 2024 22:37:09 +0530 Subject: [PATCH 45/74] fixes prettier diffs --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 5ab2dacae109..dfb4e53c90fe 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -12,12 +12,12 @@ import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useThemeStyles from '@hooks/useThemeStyles'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import * as ErrorUtils from '@libs/ErrorUtils'; import BankAccount from '@libs/models/BankAccount'; import Navigation from '@libs/Navigation/Navigation'; import Permissions from '@libs/Permissions'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; -import * as ErrorUtils from '@libs/ErrorUtils'; import type {CentralPaneNavigatorParamList} from '@navigation/types'; import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicy from '@pages/workspace/withPolicy'; From 67dd74924b9de33591c3ee57ce1ed745864cecbf Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 22:53:25 +0530 Subject: [PATCH 46/74] use accountid for selected member --- .../workspace/workflows/WorkspaceWorkflowsPayerPage.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index d4577cd550c8..2f47d3b99898 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -95,7 +95,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta const formattedMember = { keyForList: accountIDKey, accountID, - isSelected: policy?.reimburserEmail === details?.login, + isSelected: policy?.reimburserEmail === details?.login ?? policy?.reimburserAccountID === accountID, isDisabled: policyMember.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || !isEmptyObject(policyMember.errors), text: formatPhoneNumber(PersonalDetailsUtils.getDisplayNameOrDefault(details)), alternateText: formatPhoneNumber(details?.login ?? ''), @@ -112,14 +112,14 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta pendingAction: policyMember.pendingAction, }; - if (policy?.reimburserEmail === details?.login) { + if (policy?.reimburserEmail === details?.login ?? policy?.reimburserAccountID === accountID) { authorizedPayerDetails.push(formattedMember); } else { policyAdminDetails.push(formattedMember); } }); return [policyAdminDetails, authorizedPayerDetails]; - }, [personalDetails, policyMembers, translate, policy?.reimburserEmail, isDeletedPolicyMember, policy?.owner, styles, StyleUtils]); + }, [personalDetails, policyMembers, translate, policy?.reimburserEmail, isDeletedPolicyMember, policy?.owner, styles, StyleUtils, policy?.reimburserAccountID]); const sections: MembersSection[] = useMemo(() => { const sectionsArray: MembersSection[] = []; From bf8e92b1fb33aefb65a317bfd2839949f0897f3c Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Fri, 8 Mar 2024 22:56:26 +0530 Subject: [PATCH 47/74] remove unused changes --- src/pages/ReimbursementAccount/ReimbursementAccountPage.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js index 3b6a9340090a..473b36571390 100644 --- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js +++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js @@ -339,7 +339,6 @@ function ReimbursementAccountPage({reimbursementAccount, route, onfidoToken, pol // eslint-disable-next-line no-shadow const policyID = lodashGet(route.params, 'policyID'); - // eslint-disable-next-line no-shadow const backTo = lodashGet(route.params, 'backTo'); Navigation.navigate(ROUTES.BANK_ACCOUNT_WITH_STEP_TO_OPEN.getRoute(getRouteForCurrentStep(currentStep), policyID, backTo)); From 31d58cd4395520601f8191f10ff1c49d02523d0a Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Sat, 9 Mar 2024 04:11:46 +0530 Subject: [PATCH 48/74] fix prettier diffs --- src/libs/actions/Policy.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index f20415987f1e..4df22e39e352 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -17,8 +17,8 @@ import type { DeleteWorkspaceParams, OpenDraftWorkspaceRequestParams, OpenPolicyCategoriesPageParams, - OpenPolicyWorkflowsPageParams, OpenPolicyDistanceRatesPageParams, + OpenPolicyWorkflowsPageParams, OpenWorkspaceInvitePageParams, OpenWorkspaceMembersPageParams, OpenWorkspaceParams, From 3d7b851cc0e219a14b1d47fd3d6d7c32fd41b83e Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 11 Mar 2024 16:28:24 +0530 Subject: [PATCH 49/74] fix variable naming --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 51db1e345c11..cc4a4026cd6d 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -70,7 +70,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo // eslint-disable-next-line react-hooks/exhaustive-deps }, [policy?.reimbursementChoice]); - const items: ToggleSettingOptionRowProps[] = useMemo(() => { + const optionItems: ToggleSettingOptionRowProps[] = useMemo(() => { const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; const hasVBA = state === BankAccount.STATE.OPEN; const bankDisplayName = bankName ? `${bankName} ${accountNumber ? `${accountNumber.slice(-5)}` : ''}` : ''; @@ -235,7 +235,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo > {translate('workflowsPage.workflowDescription')} - {items.map((item, index) => renderOptionItem(item, index))} + {optionItems.map((item, index) => renderOptionItem(item, index))}
From ab3ee958b003480d6b0d5c4f61f752fcb08ee246 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 11 Mar 2024 16:40:50 +0530 Subject: [PATCH 50/74] remove chnages to fix 37403 --- .../workflows/WorkspaceWorkflowsPage.tsx | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index cc4a4026cd6d..8da593c9fcf6 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,6 +1,6 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useEffect, useMemo} from 'react'; -import {View} from 'react-native'; +import {View, FlatList} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import * as Illustrations from '@components/Icon/Illustrations'; @@ -195,11 +195,8 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo displayNameForAuthorizedPayer, ]); - const renderOptionItem = (item: ToggleSettingOptionRowProps, index: number) => ( - + const renderOptionItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( + {translate('workflowsPage.workflowDescription')} - {optionItems.map((item, index) => renderOptionItem(item, index))} + item.title} + />
From 4f062876bda877960e64fc55ee2fdd39bb88c765 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 11 Mar 2024 16:55:37 +0530 Subject: [PATCH 51/74] resolves prettier diffs --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 8da593c9fcf6..cfd02cc8b3ff 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,6 +1,6 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useEffect, useMemo} from 'react'; -import {View, FlatList} from 'react-native'; +import {FlatList, View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import * as Illustrations from '@components/Icon/Illustrations'; From efbac7477527117001ed6e4f5ed5ef818b98b31f Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 11 Mar 2024 18:10:48 +0530 Subject: [PATCH 52/74] remove unnecessary offline behavior --- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 25 ++++++++----------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 2f47d3b99898..89a1edda5732 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -6,7 +6,6 @@ import {withOnyx} from 'react-native-onyx'; import Badge from '@components/Badge'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; -import OfflineWithFeedback from '@components/OfflineWithFeedback'; import ScreenWrapper from '@components/ScreenWrapper'; import SelectionList from '@components/SelectionList'; import type {ListItem, Section} from '@components/SelectionList/types'; @@ -139,7 +138,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta } sectionsArray.push({ - title: undefined, + title: 'Authorized Payer', data: formattedAuthorizedPayer, shouldShow: true, indexOffset: formattedPolicyAdmins.length, @@ -202,18 +201,16 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta subtitle={policyName} onBackButtonPress={Navigation.goBack} /> - - - + From 0dc3e0411f178413a2c46ee6f56a9b1b384e127a Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 11 Mar 2024 18:18:22 +0530 Subject: [PATCH 53/74] use correct offline behaviour in payer page --- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 89a1edda5732..384272e4326d 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -91,10 +91,12 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta /> ); + const isAuthorizedPayer = policy?.reimburserEmail === details?.login ?? policy?.reimburserAccountID === accountID; + const formattedMember = { keyForList: accountIDKey, accountID, - isSelected: policy?.reimburserEmail === details?.login ?? policy?.reimburserAccountID === accountID, + isSelected: isAuthorizedPayer, isDisabled: policyMember.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE || !isEmptyObject(policyMember.errors), text: formatPhoneNumber(PersonalDetailsUtils.getDisplayNameOrDefault(details)), alternateText: formatPhoneNumber(details?.login ?? ''), @@ -108,7 +110,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta }, ], errors: policyMember.errors, - pendingAction: policyMember.pendingAction, + pendingAction: policyMember.pendingAction ?? isAuthorizedPayer ? policy?.pendingFields?.reimburserEmail : null, }; if (policy?.reimburserEmail === details?.login ?? policy?.reimburserAccountID === accountID) { @@ -118,7 +120,18 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta } }); return [policyAdminDetails, authorizedPayerDetails]; - }, [personalDetails, policyMembers, translate, policy?.reimburserEmail, isDeletedPolicyMember, policy?.owner, styles, StyleUtils, policy?.reimburserAccountID]); + }, [ + personalDetails, + policyMembers, + translate, + policy?.reimburserEmail, + isDeletedPolicyMember, + policy?.owner, + styles, + StyleUtils, + policy?.reimburserAccountID, + policy?.pendingFields?.reimburserEmail, + ]); const sections: MembersSection[] = useMemo(() => { const sectionsArray: MembersSection[] = []; From bf659a0859636fbed44900f8221eaa2b34948c98 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 11 Mar 2024 18:21:11 +0530 Subject: [PATCH 54/74] use correct translation key --- src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 384272e4326d..e88b2d908dbb 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -151,7 +151,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta } sectionsArray.push({ - title: 'Authorized Payer', + title: translate('workflowsPayerPage.title'), data: formattedAuthorizedPayer, shouldShow: true, indexOffset: formattedPolicyAdmins.length, From 6f7333a0fe5136a4a891aa536cf061f096db353b Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 11 Mar 2024 18:23:14 +0530 Subject: [PATCH 55/74] fix console error for virtualized list --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 1 - src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx | 1 - 2 files changed, 2 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index cfd02cc8b3ff..d892ca9013b2 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -220,7 +220,6 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo guidesCallTaskID={CONST.GUIDES_CALL_TASK_IDS.WORKSPACE_WORKFLOWS} shouldShowOfflineIndicatorInWideScreen shouldShowNotFoundPage={!isPaidGroupPolicy || !isPolicyAdmin} - shouldUseScrollView shouldSkipVBBACall shouldShowLoading={false} > diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index e88b2d908dbb..73e34905f2af 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -151,7 +151,6 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta } sectionsArray.push({ - title: translate('workflowsPayerPage.title'), data: formattedAuthorizedPayer, shouldShow: true, indexOffset: formattedPolicyAdmins.length, From 3d80721c3a9296b2218504aafd4cd20df92945ea Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Mon, 11 Mar 2024 21:10:37 +0530 Subject: [PATCH 56/74] show RBR in workflow menu --- src/pages/workspace/WorkspaceInitialPage.tsx | 1 + src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/WorkspaceInitialPage.tsx b/src/pages/workspace/WorkspaceInitialPage.tsx index 240a148110f7..58738a5c8f1c 100644 --- a/src/pages/workspace/WorkspaceInitialPage.tsx +++ b/src/pages/workspace/WorkspaceInitialPage.tsx @@ -160,6 +160,7 @@ function WorkspaceInitialPage({policyDraft, policy: policyProp, policyMembers, r icon: Expensicons.Workflows, action: singleExecution(waitForNavigate(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS.getRoute(policyID)))), routeName: SCREENS.WORKSPACE.WORKFLOWS, + brickRoadIndicator: !isEmptyObject(policy?.errorFields?.reimburserEmail ?? {}) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined, }); } diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index d892ca9013b2..07b00543895f 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -141,7 +141,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo onToggle: () => { const isActive = policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; const newReimbursementChoice = isActive ? CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL : CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; - Policy.setWorkspaceReimbursement(route.params.policyID, newReimbursementChoice); + Policy.setWorkspaceReimbursement(policy?.id ?? '', newReimbursementChoice); }, subMenuItems: ( <> @@ -159,7 +159,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo Policy.clearWorkspacePayerError(policy?.id ?? route.params.policyID)} + onClose={() => Policy.clearWorkspacePayerError(policy?.id ?? '')} > Date: Mon, 11 Mar 2024 23:56:50 +0530 Subject: [PATCH 57/74] hide expensify team member from the list --- .../workspace/workflows/WorkspaceWorkflowsPayerPage.tsx | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 73e34905f2af..c01d592bf529 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -64,9 +64,6 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta const authorizedPayerDetails: MemberOption[] = []; Object.entries(policyMembers ?? {}).forEach(([accountIDKey, policyMember]) => { - if (isDeletedPolicyMember(policyMember)) { - return; - } const accountID = Number(accountIDKey); if (isDeletedPolicyMember(policyMember)) { return; @@ -79,7 +76,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta const isOwner = policy?.owner === details?.login; const isAdmin = policyMember.role === CONST.POLICY.ROLE.ADMIN; - if (!isOwner && !isAdmin) { + if (PolicyUtils.isExpensifyTeam(details?.login) || (!isOwner && !isAdmin)) { return; } From a4bc90792eb4da4dc743ed5cd424579e06ff7a21 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 00:03:40 +0530 Subject: [PATCH 58/74] use single variable for skipping a member in the list --- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index c01d592bf529..0121bac0c0e9 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -65,18 +65,16 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta Object.entries(policyMembers ?? {}).forEach(([accountIDKey, policyMember]) => { const accountID = Number(accountIDKey); - if (isDeletedPolicyMember(policyMember)) { - return; - } - const details = personalDetails?.[accountID]; - if (!details) { - Log.hmmm(`[WorkspaceMembersPage] no personal details found for policy member with accountID: ${accountID}`); - } const isOwner = policy?.owner === details?.login; const isAdmin = policyMember.role === CONST.POLICY.ROLE.ADMIN; - if (PolicyUtils.isExpensifyTeam(details?.login) || (!isOwner && !isAdmin)) { + const shouldSkipMember = isDeletedPolicyMember(policyMember) || !details || PolicyUtils.isExpensifyTeam(details?.login) || (!isOwner && !isAdmin); + + if (shouldSkipMember) { + if (!details) { + Log.hmmm(`[WorkspaceMembersPage] no personal details found for policy member with accountID: ${accountID}`); + } return; } From bd8004cc1e4a946ae187006911329b13e0cb5173 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 00:05:11 +0530 Subject: [PATCH 59/74] fix console error --- .../workflows/WorkspaceWorkflowsPayerPage.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 0121bac0c0e9..7e48627805d3 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -66,15 +66,16 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta Object.entries(policyMembers ?? {}).forEach(([accountIDKey, policyMember]) => { const accountID = Number(accountIDKey); const details = personalDetails?.[accountID]; + if (!details) { + Log.hmmm(`[WorkspaceMembersPage] no personal details found for policy member with accountID: ${accountID}`); + return; + } + const isOwner = policy?.owner === details?.login; const isAdmin = policyMember.role === CONST.POLICY.ROLE.ADMIN; - - const shouldSkipMember = isDeletedPolicyMember(policyMember) || !details || PolicyUtils.isExpensifyTeam(details?.login) || (!isOwner && !isAdmin); + const shouldSkipMember = isDeletedPolicyMember(policyMember) || PolicyUtils.isExpensifyTeam(details?.login) || (!isOwner && !isAdmin); if (shouldSkipMember) { - if (!details) { - Log.hmmm(`[WorkspaceMembersPage] no personal details found for policy member with accountID: ${accountID}`); - } return; } From 673057ae28218f85b8676c3e7242dfdb4333cd79 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 01:19:55 +0530 Subject: [PATCH 60/74] show laoding indicator while call in progress --- src/libs/actions/Policy.ts | 35 ++++++++++++- .../workflows/WorkspaceWorkflowsPage.tsx | 51 ++++++++++++------- 2 files changed, 67 insertions(+), 19 deletions(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 87f1bef5eab4..b32439ba7a1c 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -1988,9 +1988,42 @@ function openPolicyWorkflowsPage(policyID: string) { return; } + const onyxData: OnyxData = { + optimisticData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM + key: `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}${policyID}`, + value: { + isLoading: true, + }, + }, + ], + successData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM + key: `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}${policyID}`, + value: { + isLoading: false, + }, + }, + ], + failureData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM + key: `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}${policyID}`, + value: { + isLoading: false, + }, + }, + ], + }; + const params: OpenPolicyWorkflowsPageParams = {policyID}; - API.read(READ_COMMANDS.OPEN_POLICY_WORKFLOWS_PAGE, params); + API.read(READ_COMMANDS.OPEN_POLICY_WORKFLOWS_PAGE, params, onyxData); } function setPolicyIDForReimburseView(policyID: string) { diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 07b00543895f..0132d08442cf 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,8 +1,10 @@ +import {useIsFocused} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useCallback, useEffect, useMemo} from 'react'; +import React, {useCallback, useEffect, useMemo, useRef} from 'react'; import {FlatList, View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; +import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import * as Illustrations from '@components/Icon/Illustrations'; import MenuItem from '@components/MenuItem'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; @@ -47,6 +49,9 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); + const firstRender = useRef(true); + const isFocused = useIsFocused(); + const policyApproverEmail = policy?.approver; const policyApproverName = useMemo(() => PersonalDetailsUtils.getPersonalDetailByEmail(policyApproverEmail ?? '')?.displayName ?? policyApproverEmail, [policyApproverEmail]); const containerStyle = useMemo(() => [styles.ph8, styles.mhn8, styles.ml11, styles.pv3, styles.pr0, styles.pl4, styles.mr0, styles.widthAuto, styles.mt4], [styles]); @@ -65,10 +70,15 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo useNetwork({onReconnect: fetchData}); + useEffect(() => { + // Because isLoading is false before merging in Onyx, we need firstRender ref to display loading page as well before isLoading is change to true + firstRender.current = false; + }, []); + useEffect(() => { fetchData(); // eslint-disable-next-line react-hooks/exhaustive-deps - }, [policy?.reimbursementChoice]); + }, []); const optionItems: ToggleSettingOptionRowProps[] = useMemo(() => { const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; @@ -211,6 +221,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const isPaidGroupPolicy = PolicyUtils.isPaidGroupPolicy(policy); const isPolicyAdmin = PolicyUtils.isPolicyAdmin(policy); + const isLoading = reimbursementAccount?.isLoading ?? true; return ( - -
- - {translate('workflowsPage.workflowDescription')} - item.title} - /> - -
-
+ {(isLoading || firstRender.current) && isFocused ? ( + + ) : ( + +
+ + {translate('workflowsPage.workflowDescription')} + item.title} + /> + +
+
+ )}
); } From e43ece914466ff42638cbc2d3e1babfe1bb6f86e Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 02:58:30 +0530 Subject: [PATCH 61/74] fix how we get displayname for the payer --- .../workflows/WorkspaceWorkflowsPage.tsx | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 0132d08442cf..c85c76adf049 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -30,7 +30,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type {Beta, ReimbursementAccount} from '@src/types/onyx'; +import type {Beta, ReimbursementAccount, Session} from '@src/types/onyx'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; import {getAutoReportingFrequencyDisplayNames} from './WorkspaceAutoReportingFrequencyPage'; @@ -41,10 +41,12 @@ type WorkspaceWorkflowsPageOnyxProps = { betas: OnyxEntry; /** Reimbursement account details */ reimbursementAccount: OnyxEntry; + /** Policy details */ + session: OnyxEntry; }; type WorkspaceWorkflowsPageProps = WithPolicyProps & WorkspaceWorkflowsPageOnyxProps & StackScreenProps; -function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: WorkspaceWorkflowsPageProps) { +function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, session}: WorkspaceWorkflowsPageProps) { const {translate, preferredLocale} = useLocalize(); const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); @@ -57,12 +59,13 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo const containerStyle = useMemo(() => [styles.ph8, styles.mhn8, styles.ml11, styles.pv3, styles.pr0, styles.pl4, styles.mr0, styles.widthAuto, styles.mt4], [styles]); const canUseDelayedSubmission = Permissions.canUseWorkflowsDelayedSubmission(betas); - const onPressAutoReportingFrequency = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY.getRoute(policy?.id ?? '')), [policy?.id]); - const displayNameForAuthorizedPayer = useMemo(() => { - const personalDetails = PersonalDetailsUtils.getPersonalDetailsByIDs([policy?.reimburserAccountID ?? 0], 0); - return personalDetails[policy?.reimburserAccountID ?? 0]?.displayName ?? policy?.reimburserEmail; - }, [policy?.reimburserAccountID, policy?.reimburserEmail]); + const personalDetails = PersonalDetailsUtils.getPersonalDetailsByIDs([policy?.reimburserAccountID ?? 0], session?.accountID ?? 0); + const displayNameFromReimburserEmail = PersonalDetailsUtils.getPersonalDetailByEmail(policy?.reimburserEmail ?? '')?.displayName ?? policy?.reimburserEmail; + return personalDetails[0]?.displayName ?? displayNameFromReimburserEmail; + }, [policy?.reimburserAccountID, policy?.reimburserEmail, session?.accountID]); + + const onPressAutoReportingFrequency = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY.getRoute(policy?.id ?? '')), [policy?.id]); const fetchData = () => { Policy.openPolicyWorkflowsPage(policy?.id ?? route.params.policyID); @@ -170,6 +173,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount}: Wo pendingAction={policy?.pendingFields?.reimburserEmail} errors={ErrorUtils.getLatestErrorField(policy ?? {}, 'reimburserEmail')} onClose={() => Policy.clearWorkspacePayerError(policy?.id ?? '')} + errorRowStyles={styles.ml11} > `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}${route.params.policyID}`, }, + session: { + key: ONYXKEYS.SESSION, + }, })(WorkspaceWorkflowsPage), ); From c9f7af91531b3832fd0bf1d34c37800573778950 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 03:28:24 +0530 Subject: [PATCH 62/74] set reimburserAccountID optimistically --- src/libs/actions/Policy.ts | 3 ++- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index b32439ba7a1c..6deaf01e7f55 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -639,7 +639,7 @@ function clearWorkspacePayerError(policyID: string) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {reimburserEmail: null}}); } -function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueOf) { +function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueOf, reimburserAccountID: number) { const policy = ReportUtils.getPolicy(policyID); const currentPolicyReimbursementChoice = policy.reimbursementChoice; @@ -650,6 +650,7 @@ function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueO key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { reimbursementChoice, + reimburserAccountID, errorFields: {reimbursementChoice: null}, pendingFields: {reimbursementChoice: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, }, diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index c85c76adf049..1ed2b2512a88 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -62,7 +62,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses const displayNameForAuthorizedPayer = useMemo(() => { const personalDetails = PersonalDetailsUtils.getPersonalDetailsByIDs([policy?.reimburserAccountID ?? 0], session?.accountID ?? 0); const displayNameFromReimburserEmail = PersonalDetailsUtils.getPersonalDetailByEmail(policy?.reimburserEmail ?? '')?.displayName ?? policy?.reimburserEmail; - return personalDetails[0]?.displayName ?? displayNameFromReimburserEmail; + return displayNameFromReimburserEmail ?? personalDetails?.[0]?.displayName; }, [policy?.reimburserAccountID, policy?.reimburserEmail, session?.accountID]); const onPressAutoReportingFrequency = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_WORKFLOWS_AUTOREPORTING_FREQUENCY.getRoute(policy?.id ?? '')), [policy?.id]); @@ -154,7 +154,9 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses onToggle: () => { const isActive = policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; const newReimbursementChoice = isActive ? CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL : CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; - Policy.setWorkspaceReimbursement(policy?.id ?? '', newReimbursementChoice); + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const newReimburserAccountID = PersonalDetailsUtils.getPersonalDetailByEmail(policy?.reimburserEmail ?? '')?.accountID || policy?.reimburserAccountID || policy?.ownerAccountID + Policy.setWorkspaceReimbursement(policy?.id ?? '', newReimbursementChoice, newReimburserAccountID ?? 0); }, subMenuItems: ( <> From 438e3b1ce14e89c4e04b2270258ec0f898b82a9f Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 03:41:24 +0530 Subject: [PATCH 63/74] fix lint --- .../workflows/WorkspaceWorkflowsPage.tsx | 109 +++++++++--------- 1 file changed, 55 insertions(+), 54 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 1ed2b2512a88..5b1ad35e9652 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,9 +1,9 @@ -import {useIsFocused} from '@react-navigation/native'; -import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useCallback, useEffect, useMemo, useRef} from 'react'; -import {FlatList, View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; -import {withOnyx} from 'react-native-onyx'; +import { useIsFocused } from '@react-navigation/native'; +import type { StackScreenProps } from '@react-navigation/stack'; +import React, { useCallback, useEffect, useMemo, useRef } from 'react'; +import { FlatList, View } from 'react-native'; +import type { OnyxEntry } from 'react-native-onyx'; +import { withOnyx } from 'react-native-onyx'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import * as Illustrations from '@components/Icon/Illustrations'; import MenuItem from '@components/MenuItem'; @@ -20,21 +20,21 @@ import Navigation from '@libs/Navigation/Navigation'; import Permissions from '@libs/Permissions'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; -import type {CentralPaneNavigatorParamList} from '@navigation/types'; -import type {WithPolicyProps} from '@pages/workspace/withPolicy'; +import type { CentralPaneNavigatorParamList } from '@navigation/types'; +import type { WithPolicyProps } from '@pages/workspace/withPolicy'; import withPolicy from '@pages/workspace/withPolicy'; import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections'; import * as Policy from '@userActions/Policy'; -import {navigateToBankAccountRoute} from '@userActions/ReimbursementAccount'; +import { navigateToBankAccountRoute } from '@userActions/ReimbursementAccount'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type {Beta, ReimbursementAccount, Session} from '@src/types/onyx'; +import type { Beta, ReimbursementAccount, Session } from '@src/types/onyx'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; -import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; -import {getAutoReportingFrequencyDisplayNames} from './WorkspaceAutoReportingFrequencyPage'; -import type {AutoReportingFrequencyKey} from './WorkspaceAutoReportingFrequencyPage'; +import type { ToggleSettingOptionRowProps } from './ToggleSettingsOptionRow'; +import { getAutoReportingFrequencyDisplayNames } from './WorkspaceAutoReportingFrequencyPage'; +import type { AutoReportingFrequencyKey } from './WorkspaceAutoReportingFrequencyPage'; type WorkspaceWorkflowsPageOnyxProps = { /** Beta features list */ @@ -46,10 +46,10 @@ type WorkspaceWorkflowsPageOnyxProps = { }; type WorkspaceWorkflowsPageProps = WithPolicyProps & WorkspaceWorkflowsPageOnyxProps & StackScreenProps; -function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, session}: WorkspaceWorkflowsPageProps) { - const {translate, preferredLocale} = useLocalize(); +function WorkspaceWorkflowsPage({ policy, betas, route, reimbursementAccount, session }: WorkspaceWorkflowsPageProps) { + const { translate, preferredLocale } = useLocalize(); const styles = useThemeStyles(); - const {isSmallScreenWidth} = useWindowDimensions(); + const { isSmallScreenWidth } = useWindowDimensions(); const firstRender = useRef(true); const isFocused = useIsFocused(); @@ -71,7 +71,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses Policy.openPolicyWorkflowsPage(policy?.id ?? route.params.policyID); }; - useNetwork({onReconnect: fetchData}); + useNetwork({ onReconnect: fetchData }); useEffect(() => { // Because isLoading is false before merging in Onyx, we need firstRender ref to display loading page as well before isLoading is change to true @@ -84,7 +84,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses }, []); const optionItems: ToggleSettingOptionRowProps[] = useMemo(() => { - const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; + const { accountNumber, state, bankName } = reimbursementAccount?.achData ?? {}; const hasVBA = state === BankAccount.STATE.OPEN; const bankDisplayName = bankName ? `${bankName} ${accountNumber ? `${accountNumber.slice(-5)}` : ''}` : ''; const hasReimburserEmailError = !!policy?.errorFields?.reimburserEmail; @@ -92,38 +92,38 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses return [ ...(canUseDelayedSubmission ? [ - { - icon: Illustrations.ReceiptEnvelope, - title: translate('workflowsPage.delaySubmissionTitle'), - subtitle: translate('workflowsPage.delaySubmissionDescription'), - onToggle: (isEnabled: boolean) => { - const frequency = - policy?.autoReportingFrequency === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT || !policy?.autoReportingFrequency - ? CONST.POLICY.AUTO_REPORTING_FREQUENCIES.WEEKLY - : policy.autoReportingFrequency; - Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled, frequency); - }, - subMenuItems: ( - - ), - isActive: (policy?.harvesting?.enabled && policy.autoReportingFrequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT) ?? false, - pendingAction: policy?.pendingFields?.isAutoApprovalEnabled, - }, - ] + { + icon: Illustrations.ReceiptEnvelope, + title: translate('workflowsPage.delaySubmissionTitle'), + subtitle: translate('workflowsPage.delaySubmissionDescription'), + onToggle: (isEnabled: boolean) => { + const frequency = + policy?.autoReportingFrequency === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT || !policy?.autoReportingFrequency + ? CONST.POLICY.AUTO_REPORTING_FREQUENCIES.WEEKLY + : policy.autoReportingFrequency; + Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled, frequency); + }, + subMenuItems: ( + + ), + isActive: (policy?.harvesting?.enabled && policy.autoReportingFrequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT) ?? false, + pendingAction: policy?.pendingFields?.isAutoApprovalEnabled, + }, + ] : []), { icon: Illustrations.Approval, @@ -154,8 +154,9 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses onToggle: () => { const isActive = policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; const newReimbursementChoice = isActive ? CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL : CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES; - // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - const newReimburserAccountID = PersonalDetailsUtils.getPersonalDetailByEmail(policy?.reimburserEmail ?? '')?.accountID || policy?.reimburserAccountID || policy?.ownerAccountID + const newReimburserAccountID = + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + PersonalDetailsUtils.getPersonalDetailByEmail(policy?.reimburserEmail ?? '')?.accountID || policy?.reimburserAccountID || policy?.ownerAccountID; Policy.setWorkspaceReimbursement(policy?.id ?? '', newReimbursementChoice, newReimburserAccountID ?? 0); }, subMenuItems: ( @@ -211,7 +212,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses displayNameForAuthorizedPayer, ]); - const renderOptionItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( + const renderOptionItem = ({ item }: { item: ToggleSettingOptionRowProps }) => ( `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}${route.params.policyID}`, + key: ({ route }) => `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}${route.params.policyID}`, }, session: { key: ONYXKEYS.SESSION, From b821a4b55175301ef616bba3f1fec69dcc3fe302 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 04:07:32 +0530 Subject: [PATCH 64/74] lint fix and sync reimburseremail and accountid --- src/libs/actions/Policy.ts | 9 +- .../workflows/WorkspaceWorkflowsPage.tsx | 107 +++++++++--------- 2 files changed, 59 insertions(+), 57 deletions(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 6deaf01e7f55..998d818ba47f 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -639,11 +639,9 @@ function clearWorkspacePayerError(policyID: string) { Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {reimburserEmail: null}}); } -function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueOf, reimburserAccountID: number) { +function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueOf, reimburserAccountID: number, reimburserEmail: string) { const policy = ReportUtils.getPolicy(policyID); - const currentPolicyReimbursementChoice = policy.reimbursementChoice; - const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -651,6 +649,7 @@ function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueO value: { reimbursementChoice, reimburserAccountID, + reimburserEmail, errorFields: {reimbursementChoice: null}, pendingFields: {reimbursementChoice: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, }, @@ -673,7 +672,9 @@ function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueO onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - reimbursementChoice: currentPolicyReimbursementChoice, + reimbursementChoice: policy.reimbursementChoice, + reimburserAccountID: policy.reimburserAccountID, + reimburserEmail: policy.reimburserEmail, errorFields: {reimbursementChoice: ErrorUtils.getMicroSecondOnyxError('workflowsPage.genericErrorMessage.reimbursementChoice')}, pendingFields: {reimbursementChoice: null}, }, diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 5b1ad35e9652..2e5aca3452ad 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,9 +1,9 @@ -import { useIsFocused } from '@react-navigation/native'; -import type { StackScreenProps } from '@react-navigation/stack'; -import React, { useCallback, useEffect, useMemo, useRef } from 'react'; -import { FlatList, View } from 'react-native'; -import type { OnyxEntry } from 'react-native-onyx'; -import { withOnyx } from 'react-native-onyx'; +import {useIsFocused} from '@react-navigation/native'; +import type {StackScreenProps} from '@react-navigation/stack'; +import React, {useCallback, useEffect, useMemo, useRef} from 'react'; +import {FlatList, View} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import * as Illustrations from '@components/Icon/Illustrations'; import MenuItem from '@components/MenuItem'; @@ -20,21 +20,21 @@ import Navigation from '@libs/Navigation/Navigation'; import Permissions from '@libs/Permissions'; import * as PersonalDetailsUtils from '@libs/PersonalDetailsUtils'; import * as PolicyUtils from '@libs/PolicyUtils'; -import type { CentralPaneNavigatorParamList } from '@navigation/types'; -import type { WithPolicyProps } from '@pages/workspace/withPolicy'; +import type {CentralPaneNavigatorParamList} from '@navigation/types'; +import type {WithPolicyProps} from '@pages/workspace/withPolicy'; import withPolicy from '@pages/workspace/withPolicy'; import WorkspacePageWithSections from '@pages/workspace/WorkspacePageWithSections'; import * as Policy from '@userActions/Policy'; -import { navigateToBankAccountRoute } from '@userActions/ReimbursementAccount'; +import {navigateToBankAccountRoute} from '@userActions/ReimbursementAccount'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type { Beta, ReimbursementAccount, Session } from '@src/types/onyx'; +import type {Beta, ReimbursementAccount, Session} from '@src/types/onyx'; import ToggleSettingOptionRow from './ToggleSettingsOptionRow'; -import type { ToggleSettingOptionRowProps } from './ToggleSettingsOptionRow'; -import { getAutoReportingFrequencyDisplayNames } from './WorkspaceAutoReportingFrequencyPage'; -import type { AutoReportingFrequencyKey } from './WorkspaceAutoReportingFrequencyPage'; +import type {ToggleSettingOptionRowProps} from './ToggleSettingsOptionRow'; +import {getAutoReportingFrequencyDisplayNames} from './WorkspaceAutoReportingFrequencyPage'; +import type {AutoReportingFrequencyKey} from './WorkspaceAutoReportingFrequencyPage'; type WorkspaceWorkflowsPageOnyxProps = { /** Beta features list */ @@ -46,10 +46,10 @@ type WorkspaceWorkflowsPageOnyxProps = { }; type WorkspaceWorkflowsPageProps = WithPolicyProps & WorkspaceWorkflowsPageOnyxProps & StackScreenProps; -function WorkspaceWorkflowsPage({ policy, betas, route, reimbursementAccount, session }: WorkspaceWorkflowsPageProps) { - const { translate, preferredLocale } = useLocalize(); +function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, session}: WorkspaceWorkflowsPageProps) { + const {translate, preferredLocale} = useLocalize(); const styles = useThemeStyles(); - const { isSmallScreenWidth } = useWindowDimensions(); + const {isSmallScreenWidth} = useWindowDimensions(); const firstRender = useRef(true); const isFocused = useIsFocused(); @@ -71,7 +71,7 @@ function WorkspaceWorkflowsPage({ policy, betas, route, reimbursementAccount, se Policy.openPolicyWorkflowsPage(policy?.id ?? route.params.policyID); }; - useNetwork({ onReconnect: fetchData }); + useNetwork({onReconnect: fetchData}); useEffect(() => { // Because isLoading is false before merging in Onyx, we need firstRender ref to display loading page as well before isLoading is change to true @@ -84,7 +84,7 @@ function WorkspaceWorkflowsPage({ policy, betas, route, reimbursementAccount, se }, []); const optionItems: ToggleSettingOptionRowProps[] = useMemo(() => { - const { accountNumber, state, bankName } = reimbursementAccount?.achData ?? {}; + const {accountNumber, state, bankName} = reimbursementAccount?.achData ?? {}; const hasVBA = state === BankAccount.STATE.OPEN; const bankDisplayName = bankName ? `${bankName} ${accountNumber ? `${accountNumber.slice(-5)}` : ''}` : ''; const hasReimburserEmailError = !!policy?.errorFields?.reimburserEmail; @@ -92,38 +92,38 @@ function WorkspaceWorkflowsPage({ policy, betas, route, reimbursementAccount, se return [ ...(canUseDelayedSubmission ? [ - { - icon: Illustrations.ReceiptEnvelope, - title: translate('workflowsPage.delaySubmissionTitle'), - subtitle: translate('workflowsPage.delaySubmissionDescription'), - onToggle: (isEnabled: boolean) => { - const frequency = - policy?.autoReportingFrequency === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT || !policy?.autoReportingFrequency - ? CONST.POLICY.AUTO_REPORTING_FREQUENCIES.WEEKLY - : policy.autoReportingFrequency; - Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled, frequency); - }, - subMenuItems: ( - - ), - isActive: (policy?.harvesting?.enabled && policy.autoReportingFrequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT) ?? false, - pendingAction: policy?.pendingFields?.isAutoApprovalEnabled, - }, - ] + { + icon: Illustrations.ReceiptEnvelope, + title: translate('workflowsPage.delaySubmissionTitle'), + subtitle: translate('workflowsPage.delaySubmissionDescription'), + onToggle: (isEnabled: boolean) => { + const frequency = + policy?.autoReportingFrequency === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT || !policy?.autoReportingFrequency + ? CONST.POLICY.AUTO_REPORTING_FREQUENCIES.WEEKLY + : policy.autoReportingFrequency; + Policy.setWorkspaceAutoReporting(route.params.policyID, isEnabled, frequency); + }, + subMenuItems: ( + + ), + isActive: (policy?.harvesting?.enabled && policy.autoReportingFrequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT) ?? false, + pendingAction: policy?.pendingFields?.isAutoApprovalEnabled, + }, + ] : []), { icon: Illustrations.Approval, @@ -157,7 +157,8 @@ function WorkspaceWorkflowsPage({ policy, betas, route, reimbursementAccount, se const newReimburserAccountID = // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing PersonalDetailsUtils.getPersonalDetailByEmail(policy?.reimburserEmail ?? '')?.accountID || policy?.reimburserAccountID || policy?.ownerAccountID; - Policy.setWorkspaceReimbursement(policy?.id ?? '', newReimbursementChoice, newReimburserAccountID ?? 0); + const newReimburserEmail = PersonalDetailsUtils.getPersonalDetailsByIDs([newReimburserAccountID ?? 0], session?.accountID ?? 0)?.[0]?.login; + Policy.setWorkspaceReimbursement(policy?.id ?? '', newReimbursementChoice, newReimburserAccountID ?? 0, newReimburserEmail ?? ''); }, subMenuItems: ( <> @@ -212,7 +213,7 @@ function WorkspaceWorkflowsPage({ policy, betas, route, reimbursementAccount, se displayNameForAuthorizedPayer, ]); - const renderOptionItem = ({ item }: { item: ToggleSettingOptionRowProps }) => ( + const renderOptionItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}${route.params.policyID}`, + key: ({route}) => `${ONYXKEYS.REIMBURSEMENT_ACCOUNT}${route.params.policyID}`, }, session: { key: ONYXKEYS.SESSION, From 39937608cb0f4843930812412695daf9a6fd2b26 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 04:19:20 +0530 Subject: [PATCH 65/74] resolve exhaustive deps warning --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 2e5aca3452ad..ca879222d2b3 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -211,6 +211,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses canUseDelayedSubmission, reimbursementAccount?.achData, displayNameForAuthorizedPayer, + session?.accountID ]); const renderOptionItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( From 17e34272d238941d9b049ae9aedac9a4d117ff5c Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 04:59:41 +0530 Subject: [PATCH 66/74] lint fix and sync reimburserEmail and accountid in setWorkspacePayer --- .../linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts | 2 +- src/libs/Navigation/types.ts | 6 +++--- src/libs/actions/Policy.ts | 9 +++++---- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- .../workspace/workflows/WorkspaceWorkflowsPayerPage.tsx | 8 ++++---- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts index 396bb585f308..69c23b2ea07a 100755 --- a/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts +++ b/src/libs/Navigation/linkingConfig/CENTRAL_PANE_TO_RHP_MAPPING.ts @@ -9,7 +9,7 @@ const CENTRAL_PANE_TO_RHP_MAPPING: Partial> = SCREENS.WORKSPACE.WORKFLOWS_APPROVER, SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY, SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_MONTHLY_OFFSET, - SCREENS.WORKSPACE.WORKFLOWS_PAYER + SCREENS.WORKSPACE.WORKFLOWS_PAYER, ], [SCREENS.WORKSPACE.TAGS]: [SCREENS.WORKSPACE.TAGS_SETTINGS, SCREENS.WORKSPACE.TAGS_EDIT], [SCREENS.WORKSPACE.CATEGORIES]: [SCREENS.WORKSPACE.CATEGORY_CREATE, SCREENS.WORKSPACE.CATEGORY_SETTINGS, SCREENS.WORKSPACE.CATEGORIES_SETTINGS], diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 573ad866743d..be0cabf1507e 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -98,6 +98,9 @@ type CentralPaneNavigatorParamList = { [SCREENS.WORKSPACE.DISTANCE_RATES]: { policyID: string; }; + [SCREENS.WORKSPACE.WORKFLOWS_APPROVER]: { + policyID: string; + }; }; type WorkspaceSwitcherNavigatorParamList = { @@ -173,9 +176,6 @@ type SettingsNavigatorParamList = { /** domain passed via route /settings/wallet/card/:domain */ domain: string; }; - [SCREENS.WORKSPACE.WORKFLOWS_APPROVER]: { - policyID: string; - }; [SCREENS.WORKSPACE.WORKFLOWS_PAYER]: { policyID: string; }; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 621166671ca6..5e0635a2e089 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -25,8 +25,8 @@ import type { OpenDraftWorkspaceRequestParams, OpenPolicyCategoriesPageParams, OpenPolicyDistanceRatesPageParams, - OpenPolicyWorkflowsPageParams, OpenPolicyTagsPageParams, + OpenPolicyWorkflowsPageParams, OpenWorkspaceInvitePageParams, OpenWorkspaceMembersPageParams, OpenWorkspaceParams, @@ -592,9 +592,8 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo API.write(WRITE_COMMANDS.SET_WORKSPACE_APPROVAL_MODE, params, {optimisticData, failureData, successData}); } -function setWorkspacePayer(policyID: string, reimburserEmail: string) { +function setWorkspacePayer(policyID: string, reimburserEmail: string, reimburserAccountID: number) { const policy = ReportUtils.getPolicy(policyID); - const currentPolicyReimburserEmail = policy.reimburserEmail; const optimisticData: OnyxUpdate[] = [ { @@ -602,6 +601,7 @@ function setWorkspacePayer(policyID: string, reimburserEmail: string) { key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { reimburserEmail, + reimburserAccountID, errorFields: {reimburserEmail: null}, pendingFields: {reimburserEmail: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE}, }, @@ -624,7 +624,8 @@ function setWorkspacePayer(policyID: string, reimburserEmail: string) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - reimburserEmail: currentPolicyReimburserEmail, + reimburserEmail: policy.reimburserEmail, + reimburserAccountID: policy.reimburserAccountID, errorFields: {reimburserEmail: ErrorUtils.getMicroSecondOnyxError('workflowsPayerPage.genericErrorMessage')}, pendingFields: {reimburserEmail: null}, }, diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index ca879222d2b3..fe2716308e2e 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -211,7 +211,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses canUseDelayedSubmission, reimbursementAccount?.achData, displayNameForAuthorizedPayer, - session?.accountID + session?.accountID, ]); const renderOptionItem = ({item}: {item: ToggleSettingOptionRowProps}) => ( diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 7e48627805d3..9934de95878b 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -169,16 +169,16 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta ); const setPolicyAuthorizedPayer = (member: MemberOption) => { - const authorizedPayer = personalDetails?.[member.accountID]?.login ?? ''; - if (policy?.reimburserEmail === authorizedPayer) { + const authorizedPayerEmail = personalDetails?.[member.accountID]?.login ?? ''; + if (policy?.reimburserEmail === authorizedPayerEmail) { return; } if (policy?.reimbursementChoice !== CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES) { return; } - - Policy.setWorkspacePayer(policy?.id ?? '', authorizedPayer); + const authorizedPayerAccountID = member.accountID; + Policy.setWorkspacePayer(policy?.id ?? '', authorizedPayerEmail, authorizedPayerAccountID); Navigation.goBack(); }; From e3b8564e3fd4e1ba898180f5763320e4826121dd Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 05:04:36 +0530 Subject: [PATCH 67/74] removes unnecessary changes --- src/libs/Navigation/types.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index be0cabf1507e..27f434fe10c1 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -64,6 +64,9 @@ type CentralPaneNavigatorParamList = { [SCREENS.WORKSPACE.WORKFLOWS]: { policyID: string; }; + [SCREENS.WORKSPACE.WORKFLOWS_APPROVER]: { + policyID: string; + }; [SCREENS.WORKSPACE.WORKFLOWS_AUTO_REPORTING_FREQUENCY]: { policyID: string; }; @@ -98,9 +101,6 @@ type CentralPaneNavigatorParamList = { [SCREENS.WORKSPACE.DISTANCE_RATES]: { policyID: string; }; - [SCREENS.WORKSPACE.WORKFLOWS_APPROVER]: { - policyID: string; - }; }; type WorkspaceSwitcherNavigatorParamList = { From 499dafe7f9e888e339805404b3676067d22a23f5 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 19:59:51 +0530 Subject: [PATCH 68/74] adds required styling --- .../workspace/WorkspacePageWithSections.tsx | 7 ++- .../workflows/WorkspaceWorkflowsPage.tsx | 53 +++++++------------ .../workflows/WorkspaceWorkflowsPayerPage.tsx | 2 +- src/styles/utils/spacing.ts | 4 ++ 4 files changed, 31 insertions(+), 35 deletions(-) diff --git a/src/pages/workspace/WorkspacePageWithSections.tsx b/src/pages/workspace/WorkspacePageWithSections.tsx index 32b76ef46202..fb01a858642c 100644 --- a/src/pages/workspace/WorkspacePageWithSections.tsx +++ b/src/pages/workspace/WorkspacePageWithSections.tsx @@ -81,6 +81,9 @@ type WorkspacePageWithSectionsProps = WithPolicyAndFullscreenLoadingProps & * taller header on desktop and different font of the title. * */ icon?: IconAsset; + + /** Whether the page is loading, example any other API call in progres */ + isLoading?: boolean; }; function fetchData(policyID: string, skipVBBACal?: boolean) { @@ -110,12 +113,14 @@ function WorkspacePageWithSections({ shouldShowOfflineIndicatorInWideScreen = false, shouldShowNonAdmin = false, shouldShowNotFoundPage = false, + isLoading: isPageLoading = false, }: WorkspacePageWithSectionsProps) { const styles = useThemeStyles(); const policyID = route.params?.policyID ?? ''; useNetwork({onReconnect: () => fetchData(policyID, shouldSkipVBBACall)}); - const isLoading = reimbursementAccount?.isLoading ?? true; + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing + const isLoading = (reimbursementAccount?.isLoading || isPageLoading) ?? true; const achState = reimbursementAccount?.achData?.state ?? ''; const isUsingECard = user?.isUsingExpensifyCard ?? false; const hasVBA = achState === BankAccount.STATE.OPEN; diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index fe2716308e2e..a1c469d9c672 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -1,10 +1,8 @@ -import {useIsFocused} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; -import React, {useCallback, useEffect, useMemo, useRef} from 'react'; +import React, {useCallback, useEffect, useMemo} from 'react'; import {FlatList, View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; -import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import * as Illustrations from '@components/Icon/Illustrations'; import MenuItem from '@components/MenuItem'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; @@ -51,9 +49,6 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses const styles = useThemeStyles(); const {isSmallScreenWidth} = useWindowDimensions(); - const firstRender = useRef(true); - const isFocused = useIsFocused(); - const policyApproverEmail = policy?.approver; const policyApproverName = useMemo(() => PersonalDetailsUtils.getPersonalDetailByEmail(policyApproverEmail ?? '')?.displayName ?? policyApproverEmail, [policyApproverEmail]); const containerStyle = useMemo(() => [styles.ph8, styles.mhn8, styles.ml11, styles.pv3, styles.pr0, styles.pl4, styles.mr0, styles.widthAuto, styles.mt4], [styles]); @@ -73,11 +68,6 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses useNetwork({onReconnect: fetchData}); - useEffect(() => { - // Because isLoading is false before merging in Onyx, we need firstRender ref to display loading page as well before isLoading is change to true - firstRender.current = false; - }, []); - useEffect(() => { fetchData(); // eslint-disable-next-line react-hooks/exhaustive-deps @@ -177,7 +167,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses pendingAction={policy?.pendingFields?.reimburserEmail} errors={ErrorUtils.getLatestErrorField(policy ?? {}, 'reimburserEmail')} onClose={() => Policy.clearWorkspacePayerError(policy?.id ?? '')} - errorRowStyles={styles.ml11} + errorRowStyles={[styles.ml7]} > - {(isLoading || firstRender.current) && isFocused ? ( - - ) : ( - -
- - {translate('workflowsPage.workflowDescription')} - item.title} - /> - -
-
- )} + +
+ + {translate('workflowsPage.workflowDescription')} + item.title} + /> + +
+
); } diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 9934de95878b..188d978a5ae9 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -178,7 +178,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta return; } const authorizedPayerAccountID = member.accountID; - Policy.setWorkspacePayer(policy?.id ?? '', authorizedPayerEmail, authorizedPayerAccountID); + Policy.setWorkspacePayer(policy?.id ?? '', 'authorizedPayerEmail', authorizedPayerAccountID); Navigation.goBack(); }; diff --git a/src/styles/utils/spacing.ts b/src/styles/utils/spacing.ts index 4f4ea821e794..56000a851e7b 100644 --- a/src/styles/utils/spacing.ts +++ b/src/styles/utils/spacing.ts @@ -167,6 +167,10 @@ export default { marginLeft: 24, }, + ml7: { + marginLeft: 28, + }, + ml8: { marginLeft: 32, }, From ddac89e066f4ce50ade4c29c675c1f158d791b47 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 20:06:36 +0530 Subject: [PATCH 69/74] remove unnecessary changes --- src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx index 188d978a5ae9..9934de95878b 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPayerPage.tsx @@ -178,7 +178,7 @@ function WorkspaceWorkflowsPayerPage({route, policy, policyMembers, personalDeta return; } const authorizedPayerAccountID = member.accountID; - Policy.setWorkspacePayer(policy?.id ?? '', 'authorizedPayerEmail', authorizedPayerAccountID); + Policy.setWorkspacePayer(policy?.id ?? '', authorizedPayerEmail, authorizedPayerAccountID); Navigation.goBack(); }; From 18473897f74281764ec7d2c4d2d92e8af908cab9 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 20:40:38 +0530 Subject: [PATCH 70/74] add failing error for toggle button --- src/libs/actions/Policy.ts | 2 +- .../workspace/workflows/ToggleSettingsOptionRow.tsx | 12 +++++++++--- .../workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 ++ 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 5e0635a2e089..14ddf908729c 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -677,7 +677,7 @@ function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueO reimbursementChoice: policy.reimbursementChoice, reimburserAccountID: policy.reimburserAccountID, reimburserEmail: policy.reimburserEmail, - errorFields: {reimbursementChoice: ErrorUtils.getMicroSecondOnyxError('workflowsPage.genericErrorMessage.reimbursementChoice')}, + errorFields: {reimbursementChoice: ErrorUtils.getMicroSecondOnyxError('common.genericErrorMessage')}, pendingFields: {reimbursementChoice: null}, }, }, diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index c5c4465937b9..7c97ff12537f 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -5,7 +5,7 @@ import OfflineWithFeedback from '@components/OfflineWithFeedback'; import Switch from '@components/Switch'; import Text from '@components/Text'; import useThemeStyles from '@hooks/useThemeStyles'; -import type {PendingAction} from '@src/types/onyx/OnyxCommon'; +import type {Errors, PendingAction} from '@src/types/onyx/OnyxCommon'; import type IconAsset from '@src/types/utils/IconAsset'; type ToggleSettingOptionRowProps = { @@ -23,14 +23,20 @@ type ToggleSettingOptionRowProps = { subMenuItems?: React.ReactNode; /** If there is a pending action, we will grey out the option */ pendingAction?: PendingAction; + /** Any error message to show */ + errors?: Errors; }; const ICON_SIZE = 48; -function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, isActive, pendingAction}: ToggleSettingOptionRowProps) { +function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, isActive, pendingAction, errors}: ToggleSettingOptionRowProps) { const styles = useThemeStyles(); return ( - + diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index a1c469d9c672..f4e6442afaf2 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -187,6 +187,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses isEndOptionRow: true, isActive: policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, pendingAction: policy?.pendingFields?.reimbursementChoice, + errors: ErrorUtils.getLatestErrorField(policy ?? {}, 'reimbursementChoice'), }, ]; }, [ @@ -214,6 +215,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses subMenuItems={item.subMenuItems} isActive={item.isActive} pendingAction={item.pendingAction} + errors={item.errors} /> ); From 2237dfefe6cc9b24bbb5ae676c5fda86d32d8e58 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 20:47:25 +0530 Subject: [PATCH 71/74] added onclose error message callback --- src/libs/actions/Policy.ts | 5 +++++ src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx | 5 ++++- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 ++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index 14ddf908729c..87918d85b636 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -688,6 +688,10 @@ function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueO API.write(WRITE_COMMANDS.SET_WORKSPACE_REIMBURSEMENT, params, {optimisticData, failureData, successData}); } +function clearWorkspaceReimbursementErrors(policyID: string) { + Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {reimbursementChoice: null}}); +} + /** * Build optimistic data for removing users from the announcement room */ @@ -3449,4 +3453,5 @@ export { enablePolicyTaxes, enablePolicyWorkflows, openPolicyDistanceRatesPage, + clearWorkspaceReimbursementErrors, }; diff --git a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx index 7c97ff12537f..da995de1d5d5 100644 --- a/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx +++ b/src/pages/workspace/workflows/ToggleSettingsOptionRow.tsx @@ -25,10 +25,12 @@ type ToggleSettingOptionRowProps = { pendingAction?: PendingAction; /** Any error message to show */ errors?: Errors; + /** Callback to close the error messages */ + onCloseError?: () => void; }; const ICON_SIZE = 48; -function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, isActive, pendingAction, errors}: ToggleSettingOptionRowProps) { +function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, isActive, pendingAction, errors, onCloseError}: ToggleSettingOptionRowProps) { const styles = useThemeStyles(); return ( @@ -36,6 +38,7 @@ function ToggleSettingOptionRow({icon, title, subtitle, onToggle, subMenuItems, pendingAction={pendingAction} errors={errors} errorRowStyles={[styles.mt2]} + onClose={onCloseError} > diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index f4e6442afaf2..ace514537e2d 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -188,6 +188,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses isActive: policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, pendingAction: policy?.pendingFields?.reimbursementChoice, errors: ErrorUtils.getLatestErrorField(policy ?? {}, 'reimbursementChoice'), + onCloseError: () => Policy.clearWorkspaceReimbursementErrors(policy?.id ?? '') }, ]; }, [ @@ -216,6 +217,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses isActive={item.isActive} pendingAction={item.pendingAction} errors={item.errors} + onCloseError={item.onCloseError} /> ); From fe8a1dadf9e16bcd4d41c4214ed37d8a1dcbd6c7 Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 20:47:37 +0530 Subject: [PATCH 72/74] lint fix --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index ace514537e2d..481e6e7e12ce 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -188,7 +188,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses isActive: policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, pendingAction: policy?.pendingFields?.reimbursementChoice, errors: ErrorUtils.getLatestErrorField(policy ?? {}, 'reimbursementChoice'), - onCloseError: () => Policy.clearWorkspaceReimbursementErrors(policy?.id ?? '') + onCloseError: () => Policy.clearWorkspaceReimbursementErrors(policy?.id ?? ''), }, ]; }, [ From 2215017b6cbfcd8846296967fac005b06e35ab9b Mon Sep 17 00:00:00 2001 From: Ishpaul Singh Date: Tue, 12 Mar 2024 21:30:09 +0530 Subject: [PATCH 73/74] remove unnecessary changes --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 481e6e7e12ce..355b493db6ad 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -188,7 +188,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses isActive: policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, pendingAction: policy?.pendingFields?.reimbursementChoice, errors: ErrorUtils.getLatestErrorField(policy ?? {}, 'reimbursementChoice'), - onCloseError: () => Policy.clearWorkspaceReimbursementErrors(policy?.id ?? ''), + onCloseError: () => Policy.clearWorkspaceReimbursementErrors(policy?.id ?? '') }, ]; }, [ @@ -236,7 +236,6 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses shouldShowNotFoundPage={!isPaidGroupPolicy || !isPolicyAdmin} shouldSkipVBBACall isLoading={isLoading} - shouldUseScrollView >
Date: Tue, 12 Mar 2024 21:36:28 +0530 Subject: [PATCH 74/74] lint fix --- src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx index 355b493db6ad..34446fecdaa2 100644 --- a/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx +++ b/src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx @@ -188,7 +188,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses isActive: policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES, pendingAction: policy?.pendingFields?.reimbursementChoice, errors: ErrorUtils.getLatestErrorField(policy ?? {}, 'reimbursementChoice'), - onCloseError: () => Policy.clearWorkspaceReimbursementErrors(policy?.id ?? '') + onCloseError: () => Policy.clearWorkspaceReimbursementErrors(policy?.id ?? ''), }, ]; }, [