-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Add confirmation prompt when approving held request via report preview #42896
Changes from 14 commits
2974def
68aa796
4c67715
21b35f7
b34f9da
ac8b499
fca320f
78f8f52
99eebd8
0091e82
5866cb9
7392bd5
fd6d0f7
2897d7f
e7969de
7ccb8ff
28220dd
3df8d03
dfad444
083823d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,5 @@ | ||
import truncate from 'lodash/truncate'; | ||
import React, {useMemo} from 'react'; | ||
import React, {useMemo, useState} from 'react'; | ||
import type {StyleProp, ViewStyle} from 'react-native'; | ||
import {View} from 'react-native'; | ||
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; | ||
|
@@ -9,13 +9,15 @@ import Icon from '@components/Icon'; | |
import * as Expensicons from '@components/Icon/Expensicons'; | ||
import OfflineWithFeedback from '@components/OfflineWithFeedback'; | ||
import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; | ||
import ProcessMoneyReportHoldMenu from '@components/ProcessMoneyReportHoldMenu'; | ||
import SettlementButton from '@components/SettlementButton'; | ||
import {showContextMenuForReport} from '@components/ShowContextMenuContext'; | ||
import Text from '@components/Text'; | ||
import useLocalize from '@hooks/useLocalize'; | ||
import usePermissions from '@hooks/usePermissions'; | ||
import useTheme from '@hooks/useTheme'; | ||
import useThemeStyles from '@hooks/useThemeStyles'; | ||
import useWindowDimensions from '@hooks/useWindowDimensions'; | ||
import ControlSelection from '@libs/ControlSelection'; | ||
import * as CurrencyUtils from '@libs/CurrencyUtils'; | ||
import * as DeviceCapabilities from '@libs/DeviceCapabilities'; | ||
|
@@ -33,6 +35,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; | |
import ROUTES from '@src/ROUTES'; | ||
import type {Policy, Report, ReportAction, Transaction, TransactionViolations, UserWallet} from '@src/types/onyx'; | ||
import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; | ||
import type DeepValueOf from '@src/types/utils/DeepValueOf'; | ||
import type {PendingMessageProps} from './MoneyRequestPreview/types'; | ||
import ReportActionItemImages from './ReportActionItemImages'; | ||
|
||
|
@@ -119,6 +122,12 @@ function ReportPreview({ | |
[transactions, iouReportID, action], | ||
); | ||
|
||
const [isHoldMenuVisible, setIsHoldMenuVisible] = useState(false); | ||
const [requestType, setRequestType] = useState<DeepValueOf<typeof CONST.IOU.ACTION_TYPE>>(); | ||
const [nonHeldAmount, fullAmount] = ReportUtils.getNonHeldAndFullAmount(iouReport, policy); | ||
const {isSmallScreenWidth} = useWindowDimensions(); | ||
const [paymentType, setPaymentType] = useState<PaymentMethodType>(); | ||
|
||
const managerID = iouReport?.managerID ?? 0; | ||
const {totalDisplaySpend, reimbursableSpend} = ReportUtils.getMoneyRequestSpendBreakdown(iouReport); | ||
|
||
|
@@ -162,6 +171,28 @@ function ReportPreview({ | |
[chatReport?.isOwnPolicyExpenseChat, policy?.harvesting?.enabled], | ||
); | ||
|
||
const confirmPayment = (type: PaymentMethodType | undefined) => { | ||
if (!type) { | ||
return; | ||
} | ||
setPaymentType(type); | ||
setRequestType(CONST.IOU.ACTION_TYPE.PAY); | ||
if (ReportUtils.hasHeldExpenses(iouReport?.reportID)) { | ||
setIsHoldMenuVisible(true); | ||
} else if (chatReport && iouReport) { | ||
IOU.payMoneyRequest(type, chatReport, iouReport, false); | ||
} | ||
}; | ||
|
||
const confirmApproval = () => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we create a utility function to avoid code repetition? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In this these function, we also have logic to set state of the component so we shouldn't create a util for this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Do you mean we shouldn't pass setIsHoldMenuVisible,... to the util function? Could you explain more why we shouldn't do that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mean we shouldn't create a util function for this case since this function also controls the state of a component. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And Since we only use this logic for report preview and |
||
setRequestType(CONST.IOU.ACTION_TYPE.APPROVE); | ||
if (ReportUtils.hasHeldExpenses(iouReport?.reportID)) { | ||
setIsHoldMenuVisible(true); | ||
} else { | ||
IOU.approveMoneyRequest(iouReport ?? {}, true); | ||
} | ||
}; | ||
|
||
const getDisplayAmount = (): string => { | ||
if (totalDisplaySpend) { | ||
return CurrencyUtils.convertToDisplayString(totalDisplaySpend, iouReport?.currency); | ||
|
@@ -368,7 +399,8 @@ function ReportPreview({ | |
policyID={policyID} | ||
chatReportID={chatReportID} | ||
iouReport={iouReport} | ||
onPress={(paymentType?: PaymentMethodType) => chatReport && iouReport && paymentType && IOU.payMoneyRequest(paymentType, chatReport, iouReport)} | ||
onPress={confirmPayment} | ||
confirmApproval={confirmApproval} | ||
enablePaymentsRoute={ROUTES.ENABLE_PAYMENTS} | ||
addBankAccountRoute={bankAccountRoute} | ||
shouldHidePaymentOptions={!shouldShowPayButton} | ||
|
@@ -399,6 +431,19 @@ function ReportPreview({ | |
</View> | ||
</PressableWithoutFeedback> | ||
</View> | ||
{isHoldMenuVisible && iouReport && requestType !== undefined && ( | ||
<ProcessMoneyReportHoldMenu | ||
nonHeldAmount={!ReportUtils.hasOnlyHeldExpenses(iouReport?.reportID ?? '') ? nonHeldAmount : undefined} | ||
requestType={requestType} | ||
fullAmount={fullAmount} | ||
isSmallScreenWidth={isSmallScreenWidth} | ||
onClose={() => setIsHoldMenuVisible(false)} | ||
isVisible={isHoldMenuVisible} | ||
paymentType={paymentType} | ||
chatReport={chatReport} | ||
moneyRequestReport={iouReport} | ||
/> | ||
)} | ||
</OfflineWithFeedback> | ||
); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@nkdengineer IMO, we don't need to create a new type here. Let's reuse REPORT_ACTION_TYPE and create a new type PreviewPaymentMethodType like this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@DylanDylann I updated.