-
Notifications
You must be signed in to change notification settings - Fork 3.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #33124 from software-mansion-labs/hold-requests/mo…
…ney-request-page [WAVE7] Hold Requests: Approving/Paying expense reports with held requests
- Loading branch information
Showing
12 changed files
with
375 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import React from 'react'; | ||
import {View} from 'react-native'; | ||
import useLocalize from '@hooks/useLocalize'; | ||
import useTheme from '@hooks/useTheme'; | ||
import useThemeStyles from '@hooks/useThemeStyles'; | ||
import CONST from '@src/CONST'; | ||
import Button from './Button'; | ||
import Header from './Header'; | ||
import Icon from './Icon'; | ||
import * as Expensicons from './Icon/Expensicons'; | ||
import Modal from './Modal'; | ||
import PressableWithoutFeedback from './Pressable/PressableWithoutFeedback'; | ||
import Text from './Text'; | ||
import Tooltip from './Tooltip'; | ||
|
||
type DecisionModalProps = { | ||
/** Title describing purpose of modal */ | ||
title: string; | ||
|
||
/** Modal subtitle/description */ | ||
prompt?: string; | ||
|
||
/** Text content used in first button */ | ||
firstOptionText?: string; | ||
|
||
/** Text content used in second button */ | ||
secondOptionText: string; | ||
|
||
/** onSubmit callback fired after clicking on first button */ | ||
onFirstOptionSubmit: () => void; | ||
|
||
/** onSubmit callback fired after clicking on second button */ | ||
onSecondOptionSubmit: () => void; | ||
|
||
/** Is the window width narrow, like on a mobile device? */ | ||
isSmallScreenWidth: boolean; | ||
|
||
/** Callback for closing modal */ | ||
onClose: () => void; | ||
|
||
/** Whether modal is visible */ | ||
isVisible: boolean; | ||
}; | ||
|
||
function DecisionModal({title, prompt = '', firstOptionText, secondOptionText, onFirstOptionSubmit, onSecondOptionSubmit, isSmallScreenWidth, onClose, isVisible}: DecisionModalProps) { | ||
const {translate} = useLocalize(); | ||
const theme = useTheme(); | ||
const styles = useThemeStyles(); | ||
|
||
return ( | ||
<Modal | ||
onClose={onClose} | ||
isVisible={isVisible} | ||
type={isSmallScreenWidth ? CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED : CONST.MODAL.MODAL_TYPE.CONFIRM} | ||
> | ||
<View style={[styles.m5]}> | ||
<View> | ||
<View style={[styles.flexRow, styles.mb4]}> | ||
<Header | ||
title={title} | ||
containerStyles={[styles.alignItemsCenter]} | ||
/> | ||
<Tooltip text={translate('common.close')}> | ||
<PressableWithoutFeedback | ||
onPress={onClose} | ||
style={[styles.touchableButtonImage]} | ||
accessibilityRole={CONST.ACCESSIBILITY_ROLE.BUTTON} | ||
accessibilityLabel={translate('common.close')} | ||
> | ||
<Icon | ||
src={Expensicons.Close} | ||
fill={theme.icon} | ||
/> | ||
</PressableWithoutFeedback> | ||
</Tooltip> | ||
</View> | ||
|
||
<Text>{prompt}</Text> | ||
</View> | ||
{firstOptionText && ( | ||
<Button | ||
success | ||
style={[styles.mt4]} | ||
onPress={onFirstOptionSubmit} | ||
pressOnEnter | ||
text={firstOptionText} | ||
/> | ||
)} | ||
<Button | ||
style={[styles.mt3, styles.noSelect]} | ||
onPress={onSecondOptionSubmit} | ||
text={secondOptionText} | ||
/> | ||
</View> | ||
</Modal> | ||
); | ||
} | ||
|
||
DecisionModal.displayName = 'DecisionModal'; | ||
|
||
export default DecisionModal; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
import React from 'react'; | ||
import type {OnyxEntry} from 'react-native-onyx'; | ||
import useLocalize from '@hooks/useLocalize'; | ||
import * as IOU from '@userActions/IOU'; | ||
import type * as OnyxTypes from '@src/types/onyx'; | ||
import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; | ||
import DecisionModal from './DecisionModal'; | ||
|
||
type ProcessMoneyReportHoldMenuProps = { | ||
/** The chat report this report is linked to */ | ||
chatReport: OnyxEntry<OnyxTypes.Report>; | ||
|
||
/** Full amount of expense report to pay */ | ||
fullAmount: string; | ||
|
||
/** Is the window width narrow, like on a mobile device? */ | ||
isSmallScreenWidth: boolean; | ||
|
||
/** Whether modal is visible */ | ||
isVisible: boolean; | ||
|
||
/** The report currently being looked at */ | ||
moneyRequestReport: OnyxTypes.Report; | ||
|
||
/** Not held amount of expense report */ | ||
nonHeldAmount?: string; | ||
|
||
/** Callback for closing modal */ | ||
onClose: () => void; | ||
|
||
/** Type of payment */ | ||
paymentType?: PaymentMethodType; | ||
|
||
/** Type of action handled */ | ||
requestType?: 'pay' | 'approve'; | ||
}; | ||
|
||
function ProcessMoneyReportHoldMenu({ | ||
requestType, | ||
nonHeldAmount, | ||
fullAmount, | ||
isSmallScreenWidth = false, | ||
onClose, | ||
isVisible, | ||
paymentType, | ||
chatReport, | ||
moneyRequestReport, | ||
}: ProcessMoneyReportHoldMenuProps) { | ||
const {translate} = useLocalize(); | ||
const isApprove = requestType === 'approve'; | ||
|
||
const onSubmit = (full: boolean) => { | ||
if (isApprove) { | ||
IOU.approveMoneyRequest(moneyRequestReport, full); | ||
} else if (chatReport && paymentType) { | ||
IOU.payMoneyRequest(paymentType, chatReport, moneyRequestReport, full); | ||
} | ||
onClose(); | ||
}; | ||
|
||
return ( | ||
<DecisionModal | ||
title={translate(isApprove ? 'iou.confirmApprove' : 'iou.confirmPay')} | ||
onClose={onClose} | ||
isVisible={isVisible} | ||
prompt={translate(isApprove ? 'iou.confirmApprovalAmount' : 'iou.confirmPayAmount')} | ||
firstOptionText={nonHeldAmount ? `${translate(isApprove ? 'iou.approveOnly' : 'iou.payOnly')} ${nonHeldAmount}` : undefined} | ||
secondOptionText={`${translate(isApprove ? 'iou.approve' : 'iou.pay')} ${fullAmount}`} | ||
onFirstOptionSubmit={() => onSubmit(false)} | ||
onSecondOptionSubmit={() => onSubmit(true)} | ||
isSmallScreenWidth={isSmallScreenWidth} | ||
/> | ||
); | ||
} | ||
|
||
ProcessMoneyReportHoldMenu.displayName = 'ProcessMoneyReportHoldMenu'; | ||
|
||
export default ProcessMoneyReportHoldMenu; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.