Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Wave Collect] [Workflows] Display meaningful message when currency is not available for Direct Reimbursement #38318

Merged
merged 36 commits into from
Mar 20, 2024
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
16cae1b
handle errors
lakchote Mar 14, 2024
cff3658
add translations for workflows errors
lakchote Mar 14, 2024
47c3c74
handle workflows errors
lakchote Mar 14, 2024
e515c8e
add errors for failure data
lakchote Mar 14, 2024
a280421
create method to check valid currency for reimbursement
lakchote Mar 14, 2024
ef1d156
handle errors for workspace name and description
lakchote Mar 14, 2024
3aa3925
make method more specific
lakchote Mar 18, 2024
a7d48f2
show currency modal switcher if vbba not set and fix default reimburs…
lakchote Mar 18, 2024
b3d9939
fix style
lakchote Mar 18, 2024
20af98e
remove unneeded translation key
lakchote Mar 18, 2024
be8fd34
remove old logic for edge case when default reimbursement choice was …
lakchote Mar 18, 2024
e053abc
Merge branch 'main' into lucien/fix-worklows-error-messages
lakchote Mar 18, 2024
c1c65f6
fix typo
lakchote Mar 18, 2024
f385e85
add consts for policy collection fields
lakchote Mar 19, 2024
7cc1c1a
add generic method to clear policy error fields
lakchote Mar 19, 2024
9f0a1fe
use const for policy collection fields
lakchote Mar 19, 2024
7343b48
remove currency not available as direct reimbursement
lakchote Mar 19, 2024
b7b2a07
improved logic for hasValidCurrencyForDirectReimbursement()
lakchote Mar 19, 2024
84a1c83
improved naming
lakchote Mar 19, 2024
7c95b21
Merge branch 'main' into lucien/fix-worklows-error-messages
lakchote Mar 19, 2024
a2a788e
rename method and filter EUR currency for direct reimbursement as it'…
lakchote Mar 19, 2024
428bbe6
fix reimbursement choice
lakchote Mar 19, 2024
39f9161
fix lint
lakchote Mar 19, 2024
cf6a4bd
fix style
lakchote Mar 19, 2024
c2a82ca
fix edge case
lakchote Mar 19, 2024
14a7018
Merge branch 'main' into lucien/fix-worklows-error-messages
lakchote Mar 19, 2024
801c6ae
fix currency supported
lakchote Mar 20, 2024
086c310
Merge branch 'main' into lucien/fix-worklows-error-messages
lakchote Mar 20, 2024
fc71b6d
improved naming
lakchote Mar 20, 2024
45c7923
use new naming for const collection keys
lakchote Mar 20, 2024
c1d1aa6
fix toggle logic
lakchote Mar 20, 2024
172c8b3
improved toggle logic
lakchote Mar 20, 2024
1140772
Merge branch 'main' into lucien/fix-worklows-error-messages
lakchote Mar 20, 2024
a932d16
fix style
lakchote Mar 20, 2024
256049f
Merge branch 'main' into lucien/fix-worklows-error-messages
lakchote Mar 20, 2024
adb5d5e
fix toggle logic
lakchote Mar 20, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/languages/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1072,6 +1072,14 @@ export default {
},
},
},
workflowsDelayedSubmissionPage: {
autoReportingErrorMessage: 'The delayed submission parameter could not be changed. Please try again or contact support.',
autoReportingFrequencyErrorMessage: 'The submission frequency could not be changed. Please try again or contact support.',
monthlyOffsetErrorMessage: 'The monthly frequency could not be changed. Please try again or contact support.',
},
workflowsApprovalPage: {
genericErrorMessage: 'The approver could not be changed. Please try again or contact support.',
Comment on lines +1075 to +1080
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has marketing reviewed these copies?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Asked about it here

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lakchote This is usually done using Marketing label autoassigner on the linked issue so we get one dedicated person for this

},
workflowsPayerPage: {
title: 'Authorized payer',
genericErrorMessage: 'The authorized payer could not be changed. Please try again.',
Expand Down
8 changes: 8 additions & 0 deletions src/languages/es.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1068,6 +1068,14 @@ export default {
},
},
},
workflowsDelayedSubmissionPage: {
autoReportingErrorMessage: 'El parámetro de envío retrasado no pudo ser cambiado. Por favor, inténtelo de nuevo o contacte al soporte.',
autoReportingFrequencyErrorMessage: 'La frecuencia de envío no pudo ser cambiada. Por favor, inténtelo de nuevo o contacte al soporte.',
monthlyOffsetErrorMessage: 'La frecuencia mensual no pudo ser cambiada. Por favor, inténtelo de nuevo o contacte al soporte.',
},
workflowsApprovalPage: {
genericErrorMessage: 'El aprobador no pudo ser cambiado. Por favor, inténtelo de nuevo o contacte al soporte.',
},
workflowsPayerPage: {
title: 'Pagador autorizado',
genericErrorMessage: 'El pagador autorizado no se pudo cambiar. Por favor, inténtalo mas tarde.',
Expand Down
42 changes: 42 additions & 0 deletions src/libs/actions/Policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ type WorkspaceMembersRoleData = {
role: typeof CONST.POLICY.ROLE.ADMIN | typeof CONST.POLICY.ROLE.USER;
};

const CURRENCY_AU = 'AUD';
const CURRENCY_CA = 'CAD';
const CURRENCY_GB = 'GBP';
const CURRENCY_US = 'USD';
const CURRENCY_EUR = 'EUR';

const DIRECT_REIMBURSEMENT_CURRENCIES: string[] = [CURRENCY_AU, CURRENCY_CA, CURRENCY_EUR, CURRENCY_GB, CURRENCY_US];

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have these defined here, it also seems like we support NZD, which is missing in your list above

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 definitely lets reuse this from Const or add there what is missing there

Copy link
Contributor Author

@lakchote lakchote Mar 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We already have these defined here, it also seems like we support NZD, which is missing in your list above

NZD is not supported for direct reimbursement it seems?

See here.

I'm going to remove it in order to be ISO with PHP-Libs.

const allPolicies: OnyxCollection<Policy> = {};
Onyx.connect({
key: ONYXKEYS.COLLECTION.POLICY,
Expand Down Expand Up @@ -249,6 +257,9 @@ function updateLastAccessedWorkspace(policyID: OnyxEntry<string>) {
Onyx.set(ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID, policyID);
}

function hasValidCurrencyForDirectReimbursement(currency: string) {
lakchote marked this conversation as resolved.
Show resolved Hide resolved
return DIRECT_REIMBURSEMENT_CURRENCIES.includes(currency);
}
/**
* Check if the user has any active free policies (aka workspaces)
*/
Expand Down Expand Up @@ -466,6 +477,7 @@ function setWorkspaceAutoReporting(policyID: string, enabled: boolean, frequency
},
autoReportingFrequency: policy.autoReportingFrequency ?? null,
pendingFields: {isAutoApprovalEnabled: null, harvesting: null},
errorFields: {autoReporting: ErrorUtils.getMicroSecondOnyxError('workflowsDelayedSubmissionPage.autoReportingErrorMessage')},
},
},
];
Expand Down Expand Up @@ -506,6 +518,7 @@ function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf
value: {
autoReportingFrequency: policy.autoReportingFrequency ?? null,
pendingFields: {autoReportingFrequency: null},
errorFields: {autoReportingFrequency: ErrorUtils.getMicroSecondOnyxError('workflowsDelayedSubmissionPage.autoReportingFrequencyErrorMessage')},
},
},
];
Expand Down Expand Up @@ -546,6 +559,7 @@ function setWorkspaceAutoReportingMonthlyOffset(policyID: string, autoReportingO
value: {
autoReportingOffset: policy.autoReportingOffset ?? null,
pendingFields: {autoReportingOffset: null},
errorFields: {autoReportingOffset: ErrorUtils.getMicroSecondOnyxError('workflowsDelayedSubmissionPage.monthlyOffsetErrorMessage')},
},
},
];
Expand Down Expand Up @@ -594,6 +608,7 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo
approvalMode: policy.approvalMode ?? null,
isAutoApprovalEnabled: policy.isAutoApprovalEnabled ?? null,
pendingFields: {approvalMode: null},
errorFields: {approvalMode: ErrorUtils.getMicroSecondOnyxError('workflowsApprovalPage.genericErrorMessage')},
},
},
];
Expand Down Expand Up @@ -657,6 +672,26 @@ function setWorkspacePayer(policyID: string, reimburserEmail: string, reimburser
API.write(WRITE_COMMANDS.SET_WORKSPACE_PAYER, params, {optimisticData, failureData, successData});
}

function clearWorkspaceAutoReportingError(policyID: string) {
Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {autoReporting: null}});
}

function clearWorkspaceAutoReportingFrequencyError(policyID: string) {
Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {autoReportingFrequency: null}});
}

function clearWorkspaceGeneralSettingError(policyID: string) {
Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {generalSettings: null}});
}

function clearWorkspaceAutoReportingOffsetError(policyID: string) {
Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {autoReportingOffset: null}});
}

function clearWorkspaceApprovalError(policyID: string) {
Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {approvalMode: null}});
}

lakchote marked this conversation as resolved.
Show resolved Hide resolved
function clearWorkspacePayerError(policyID: string) {
Onyx.merge(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`, {errorFields: {reimburserEmail: null}});
}
Expand Down Expand Up @@ -1358,6 +1393,7 @@ function updateGeneralSettings(policyID: string, name: string, currency: string)
},
},
];

const failureData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
Expand Down Expand Up @@ -3908,4 +3944,10 @@ export {
clearWorkspaceReimbursementErrors,
deleteWorkspaceCategories,
setWorkspaceTagEnabled,
clearWorkspaceApprovalError,
clearWorkspaceAutoReportingError,
clearWorkspaceAutoReportingFrequencyError,
clearWorkspaceAutoReportingOffsetError,
clearWorkspaceGeneralSettingError,
hasValidCurrencyForDirectReimbursement,
};
14 changes: 12 additions & 2 deletions src/pages/workspace/WorkspaceProfilePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import useLocalize from '@hooks/useLocalize';
import useThemeIllustrations from '@hooks/useThemeIllustrations';
import useThemeStyles from '@hooks/useThemeStyles';
import useWindowDimensions from '@hooks/useWindowDimensions';
import * as ErrorUtils from '@libs/ErrorUtils';
import Navigation from '@libs/Navigation/Navigation';
import * as PolicyUtils from '@libs/PolicyUtils';
import * as ReportUtils from '@libs/ReportUtils';
Expand Down Expand Up @@ -162,7 +163,11 @@ function WorkspaceProfilePage({policy, currencyList = {}, route}: WorkSpaceProfi
/>
</OfflineWithFeedback>
{(!StringUtils.isEmptyString(policy?.description ?? '') || !readOnly) && (
<OfflineWithFeedback pendingAction={policy?.pendingFields?.description}>
<OfflineWithFeedback
pendingAction={policy?.pendingFields?.description}
errors={ErrorUtils.getLatestErrorField(policy ?? {}, 'description')}
lakchote marked this conversation as resolved.
Show resolved Hide resolved
onClose={() => Policy.clearWorkspaceGeneralSettingError(policy?.id ?? '')}
>
<MenuItemWithTopDescription
title={policyDescription}
description={translate('workspace.editor.descriptionInputLabel')}
Expand All @@ -176,7 +181,12 @@ function WorkspaceProfilePage({policy, currencyList = {}, route}: WorkSpaceProfi
/>
</OfflineWithFeedback>
)}
<OfflineWithFeedback pendingAction={policy?.pendingFields?.generalSettings}>
<OfflineWithFeedback
pendingAction={policy?.pendingFields?.generalSettings}
errors={ErrorUtils.getLatestErrorField(policy ?? {}, 'generalSettings')}
lakchote marked this conversation as resolved.
Show resolved Hide resolved
onClose={() => Policy.clearWorkspaceGeneralSettingError(policy?.id ?? '')}
errorRowStyles={[styles.mt2]}
>
<View>
<MenuItemWithTopDescription
title={formattedCurrency}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import ScreenWrapper from '@components/ScreenWrapper';
import RadioListItem from '@components/SelectionList/RadioListItem';
import useLocalize from '@hooks/useLocalize';
import useThemeStyles from '@hooks/useThemeStyles';
import * as ErrorUtils from '@libs/ErrorUtils';
import * as Localize from '@libs/Localize';
import Navigation from '@libs/Navigation/Navigation';
import * as PolicyUtils from '@libs/PolicyUtils';
Expand Down Expand Up @@ -80,7 +81,12 @@ function WorkspaceAutoReportingFrequencyPage({policy}: WorkspaceAutoReportingFre
};

const monthlyFrequencyDetails = () => (
<OfflineWithFeedback pendingAction={policy?.pendingFields?.autoReportingOffset}>
<OfflineWithFeedback
pendingAction={policy?.pendingFields?.autoReportingOffset}
errors={ErrorUtils.getLatestErrorField(policy ?? {}, 'autoReportingOffset')}
lakchote marked this conversation as resolved.
Show resolved Hide resolved
onClose={() => Policy.clearWorkspaceAutoReportingOffsetError(policy?.id ?? '')}
errorRowStyles={[styles.ml7]}
>
<MenuItem
title={translate('workflowsPage.submissionFrequencyDateOfMonth')}
titleStyle={styles.textLabelSupportingNormal}
Expand Down Expand Up @@ -119,12 +125,17 @@ function WorkspaceAutoReportingFrequencyPage({policy}: WorkspaceAutoReportingFre
title={translate('workflowsPage.submissionFrequency')}
onBackButtonPress={Navigation.goBack}
/>

<FlatList
data={autoReportingFrequencyItems}
renderItem={renderItem}
keyExtractor={(item: WorkspaceAutoReportingFrequencyPageItem) => item.text}
/>
<OfflineWithFeedback
pendingAction={policy?.pendingFields?.autoReportingFrequency}
errors={ErrorUtils.getLatestErrorField(policy ?? {}, 'autoReportingFrequency')}
lakchote marked this conversation as resolved.
Show resolved Hide resolved
onClose={() => Policy.clearWorkspaceAutoReportingFrequencyError(policy?.id ?? '')}
>
<FlatList
data={autoReportingFrequencyItems}
renderItem={renderItem}
keyExtractor={(item: WorkspaceAutoReportingFrequencyPageItem) => item.text}
/>
</OfflineWithFeedback>
</FullPageNotFoundView>
</ScreenWrapper>
);
Expand Down
46 changes: 40 additions & 6 deletions src/pages/workspace/workflows/WorkspaceWorkflowsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type {StackScreenProps} from '@react-navigation/stack';
import React, {useCallback, useEffect, useMemo} from 'react';
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {FlatList, View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {withOnyx} from 'react-native-onyx';
import ConfirmModal from '@components/ConfirmModal';
import * as Illustrations from '@components/Icon/Illustrations';
import MenuItem from '@components/MenuItem';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
Expand Down Expand Up @@ -53,6 +54,7 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses
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);
const [isCurrencyModalOpen, setIsCurrencyModalOpen] = useState(false);

const displayNameForAuthorizedPayer = useMemo(() => {
const personalDetails = PersonalDetailsUtils.getPersonalDetailsByIDs([policy?.reimburserAccountID ?? 0], session?.accountID ?? 0);
Expand All @@ -66,6 +68,15 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses
Policy.openPolicyWorkflowsPage(policy?.id ?? route.params.policyID);
};

const confirmCurrencyChangeAndHideModal = useCallback(() => {
if (!policy) {
return;
}
Policy.updateGeneralSettings(policy.id, policy.name, CONST.CURRENCY.USD);
setIsCurrencyModalOpen(false);
navigateToBankAccountRoute(route.params.policyID, ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID));
}, [policy, route.params.policyID]);

useNetwork({onReconnect: fetchData});

useEffect(() => {
Expand All @@ -78,6 +89,8 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses
const hasVBA = state === BankAccount.STATE.OPEN;
const bankDisplayName = bankName ? `${bankName} ${accountNumber ? `${accountNumber.slice(-5)}` : ''}` : '';
const hasReimburserEmailError = !!policy?.errorFields?.reimburserEmail;
const hasApprovalError = !!policy?.errorFields?.approvalMode;
const hasDelayedSubmissionError = !!policy?.errorFields?.autoReporting;

return [
...(canUseDelayedSubmission
Expand Down Expand Up @@ -108,10 +121,13 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses
shouldShowRightIcon
wrapperStyle={containerStyle}
hoverAndPressStyle={[styles.mr0, styles.br2]}
brickRoadIndicator={hasDelayedSubmissionError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
/>
),
isActive: (policy?.harvesting?.enabled && policy.autoReportingFrequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT) ?? false,
isActive: (policy?.harvesting?.enabled && policy.autoReportingFrequency !== CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT && !hasDelayedSubmissionError) ?? false,
pendingAction: policy?.pendingFields?.isAutoApprovalEnabled,
errors: ErrorUtils.getLatestErrorField(policy ?? {}, 'autoReporting'),
lakchote marked this conversation as resolved.
Show resolved Hide resolved
onCloseError: () => Policy.clearWorkspaceAutoReportingError(policy?.id ?? ''),
},
]
: []),
Expand All @@ -132,18 +148,20 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses
shouldShowRightIcon
wrapperStyle={containerStyle}
hoverAndPressStyle={[styles.mr0, styles.br2]}
brickRoadIndicator={hasApprovalError ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined}
/>
),
isActive: policy?.isAutoApprovalEnabled ?? false,
isActive: (policy?.isAutoApprovalEnabled && !hasApprovalError) ?? false,
pendingAction: policy?.pendingFields?.approvalMode,
errors: ErrorUtils.getLatestErrorField(policy ?? {}, 'approvalMode'),
lakchote marked this conversation as resolved.
Show resolved Hide resolved
onCloseError: () => Policy.clearWorkspaceApprovalError(policy?.id ?? ''),
},
{
icon: Illustrations.WalletAlt,
title: translate('workflowsPage.makeOrTrackPaymentsTitle'),
subtitle: translate('workflowsPage.makeOrTrackPaymentsDescription'),
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;
const newReimbursementChoice = !hasVBA ? CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL : CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will never toggle on from a clean state with no VBA, as we will set to REIMBURSEMENT_MANUAL initially, whereas we consider only REIMBURSEMENT_YES as the active state here:

isActive: policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_YES,

It also won't toggle off as we don't set REIMBURSEMENT_NO.

const newReimburserAccountID =
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
PersonalDetailsUtils.getPersonalDetailByEmail(policy?.reimburserEmail ?? '')?.accountID || policy?.reimburserAccountID || policy?.ownerAccountID;
Expand All @@ -157,7 +175,13 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses
descriptionTextStyle={styles.textNormalThemeText}
title={hasVBA ? translate('common.bankAccount') : translate('workflowsPage.connectBankAccount')}
description={state === BankAccount.STATE.OPEN ? bankDisplayName : undefined}
onPress={() => navigateToBankAccountRoute(route.params.policyID, ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID))}
onPress={() => {
if (!Policy.hasValidCurrencyForDirectReimbursement(policy?.outputCurrency ?? '')) {
setIsCurrencyModalOpen(true);
return;
}
navigateToBankAccountRoute(route.params.policyID, ROUTES.WORKSPACE_WORKFLOWS.getRoute(route.params.policyID));
}}
shouldShowRightIcon
wrapperStyle={containerStyle}
hoverAndPressStyle={[styles.mr0, styles.br2]}
Expand Down Expand Up @@ -250,6 +274,16 @@ function WorkspaceWorkflowsPage({policy, betas, route, reimbursementAccount, ses
renderItem={renderOptionItem}
keyExtractor={(item: ToggleSettingOptionRowProps) => item.title}
/>
<ConfirmModal
title={translate('workspace.bankAccount.workspaceCurrency')}
isVisible={isCurrencyModalOpen}
onConfirm={confirmCurrencyChangeAndHideModal}
onCancel={() => setIsCurrencyModalOpen(false)}
prompt={translate('workspace.bankAccount.updateCurrencyPrompt')}
confirmText={translate('workspace.bankAccount.updateToUSD')}
cancelText={translate('common.cancel')}
danger
/>
</View>
</Section>
</View>
Expand Down
Loading