-
Notifications
You must be signed in to change notification settings - Fork 2.9k
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 #18148 from Expensify/yuwen-moneyRequestHeader
[No QA] Create Money Request Header component
- Loading branch information
Showing
8 changed files
with
357 additions
and
29 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
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,117 @@ | ||
import React from 'react'; | ||
import {View} from 'react-native'; | ||
import _ from 'underscore'; | ||
import PropTypes from 'prop-types'; | ||
import CONST from '../CONST'; | ||
import reportPropTypes from '../pages/reportPropTypes'; | ||
import participantPropTypes from './participantPropTypes'; | ||
import withWindowDimensions, {windowDimensionsPropTypes} from './withWindowDimensions'; | ||
import withLocalize, {withLocalizePropTypes} from './withLocalize'; | ||
import styles from '../styles/styles'; | ||
import SubscriptAvatar from './SubscriptAvatar'; | ||
import * as ReportUtils from '../libs/ReportUtils'; | ||
import Avatar from './Avatar'; | ||
import DisplayNames from './DisplayNames'; | ||
import compose from '../libs/compose'; | ||
import * as OptionsListUtils from '../libs/OptionsListUtils'; | ||
import Text from './Text'; | ||
|
||
const propTypes = { | ||
/** The report currently being looked at */ | ||
report: reportPropTypes, | ||
|
||
/** The policies which the user has access to and which the report could be tied to */ | ||
policies: PropTypes.shape({ | ||
/** Name of the policy */ | ||
name: PropTypes.string, | ||
}), | ||
|
||
/** The size of the avatar */ | ||
size: PropTypes.oneOf(_.values(CONST.AVATAR_SIZE)), | ||
|
||
/** Personal details of all the users */ | ||
personalDetails: PropTypes.objectOf(participantPropTypes), | ||
|
||
...windowDimensionsPropTypes, | ||
...withLocalizePropTypes, | ||
}; | ||
|
||
const defaultProps = { | ||
personalDetails: {}, | ||
policies: {}, | ||
report: null, | ||
size: CONST.AVATAR_SIZE.DEFAULT, | ||
}; | ||
|
||
const AvatarWithDisplayName = (props) => { | ||
const title = ReportUtils.getDisplayNameForParticipant(props.report.ownerEmail, true); | ||
const subtitle = ReportUtils.getChatRoomSubtitle(props.report, props.policies); | ||
const isExpenseReport = ReportUtils.isExpenseReport(props.report); | ||
const icons = ReportUtils.getIcons(props.report, props.personalDetails, props.policies); | ||
const ownerPersonalDetails = OptionsListUtils.getPersonalDetailsForLogins([props.report.ownerEmail], props.personalDetails); | ||
const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(ownerPersonalDetails, false); | ||
return ( | ||
<View> | ||
<View style={[styles.appContentHeaderTitle]}> | ||
{Boolean(props.report && title) && ( | ||
<View | ||
style={[ | ||
styles.flexRow, | ||
styles.alignItemsCenter, | ||
styles.justifyContentBetween, | ||
]} | ||
> | ||
{isExpenseReport ? ( | ||
<SubscriptAvatar | ||
mainAvatar={icons[0]} | ||
secondaryAvatar={icons[1]} | ||
mainTooltip={props.report.ownerEmail} | ||
secondaryTooltip={subtitle} | ||
size={props.size} | ||
/> | ||
) : ( | ||
<Avatar | ||
size={props.size} | ||
source={icons[0].source} | ||
type={icons[0].type} | ||
name={icons[0].name} | ||
containerStyles={props.size === CONST.AVATAR_SIZE.SMALL ? styles.emptyAvatarSmall : styles.emptyAvatar} | ||
/> | ||
)} | ||
<View style={[styles.flex1, styles.flexColumn]}> | ||
<DisplayNames | ||
fullTitle={title} | ||
displayNamesWithTooltips={displayNamesWithTooltips} | ||
tooltipEnabled | ||
numberOfLines={1} | ||
textStyles={[styles.headerText, styles.pre]} | ||
shouldUseFullTitle={isExpenseReport} | ||
/> | ||
{!_.isEmpty(subtitle) && ( | ||
<Text | ||
style={[ | ||
styles.sidebarLinkText, | ||
styles.optionAlternateText, | ||
styles.textLabelSupporting, | ||
styles.pre, | ||
]} | ||
numberOfLines={1} | ||
> | ||
{subtitle} | ||
</Text> | ||
)} | ||
</View> | ||
</View> | ||
)} | ||
</View> | ||
</View> | ||
); | ||
}; | ||
AvatarWithDisplayName.propTypes = propTypes; | ||
AvatarWithDisplayName.displayName = 'AvatarWithDisplayName'; | ||
AvatarWithDisplayName.defaultProps = defaultProps; | ||
|
||
export default compose( | ||
withWindowDimensions, | ||
withLocalize, | ||
)(AvatarWithDisplayName); |
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,142 @@ | ||
import React from 'react'; | ||
import {View} from 'react-native'; | ||
import PropTypes from 'prop-types'; | ||
import lodashGet from 'lodash/get'; | ||
import HeaderWithCloseButton from './HeaderWithCloseButton'; | ||
import iouReportPropTypes from '../pages/iouReportPropTypes'; | ||
import withLocalize, {withLocalizePropTypes} from './withLocalize'; | ||
import * as ReportUtils from '../libs/ReportUtils'; | ||
import * as Expensicons from './Icon/Expensicons'; | ||
import Text from './Text'; | ||
import participantPropTypes from './participantPropTypes'; | ||
import Avatar from './Avatar'; | ||
import styles from '../styles/styles'; | ||
import themeColors from '../styles/themes/default'; | ||
import CONST from '../CONST'; | ||
import withWindowDimensions from './withWindowDimensions'; | ||
import compose from '../libs/compose'; | ||
import Navigation from '../libs/Navigation/Navigation'; | ||
import ROUTES from '../ROUTES'; | ||
import Icon from './Icon'; | ||
|
||
const propTypes = { | ||
/** The report currently being looked at */ | ||
report: iouReportPropTypes.isRequired, | ||
|
||
/** The policies which the user has access to and which the report could be tied to */ | ||
policies: PropTypes.shape({ | ||
/** Name of the policy */ | ||
name: PropTypes.string, | ||
}).isRequired, | ||
|
||
/** Personal details so we can get the ones for the report participants */ | ||
personalDetails: PropTypes.objectOf(participantPropTypes).isRequired, | ||
|
||
/** Whether we're viewing a report with a single transaction in it */ | ||
isSingleTransactionView: PropTypes.bool, | ||
|
||
...withLocalizePropTypes, | ||
}; | ||
|
||
const defaultProps = { | ||
isSingleTransactionView: false, | ||
}; | ||
|
||
const MoneyRequestHeader = (props) => { | ||
const formattedAmount = props.numberFormat(props.report.total / 100, { | ||
style: 'currency', | ||
currency: props.report.currency, | ||
}); | ||
const isSettled = false; // TODO: use ReportUtils.isSettled(props.report.reportID) once that method is added | ||
const isExpenseReport = ReportUtils.isExpenseReport(props.report); | ||
const payeeName = isExpenseReport | ||
? ReportUtils.getPolicyName(props.report, props.policies) | ||
: ReportUtils.getDisplayNameForParticipant(props.report.managerEmail); | ||
const payeeAvatar = isExpenseReport | ||
? ReportUtils.getWorkspaceAvatar(props.report) | ||
: ReportUtils.getAvatar(lodashGet(props.personalDetails, [props.report.managerEmail, 'avatar']), props.personalDetails); | ||
return ( | ||
<View style={[ | ||
{backgroundColor: themeColors.highlightBG}, | ||
styles.pl0, | ||
]} | ||
> | ||
<HeaderWithCloseButton | ||
shouldShowAvatarWithDisplay | ||
shouldShowThreeDotsButton={!isSettled} | ||
threeDotsMenuItems={[{ | ||
icon: Expensicons.Trashcan, | ||
text: props.translate('common.delete'), | ||
onSelected: () => {}, | ||
}]} | ||
threeDotsAnchorPosition={styles.threeDotsPopoverOffsetNoCloseButton} | ||
report={props.report} | ||
policies={props.policies} | ||
personalDetails={props.personalDetails} | ||
containerStyles={[styles.pt5, styles.pb3, styles.pr1]} | ||
shouldShowCloseButton={false} | ||
shouldShowBackButton={props.isSmallScreenWidth} | ||
onBackButtonPress={() => Navigation.navigate(ROUTES.HOME)} | ||
/> | ||
<View style={[styles.ph5, styles.pb5]}> | ||
<Text style={[styles.textLabelSupporting, styles.lh16]}>{props.translate('common.to')}</Text> | ||
<View style={[ | ||
styles.flexRow, | ||
styles.alignItemsCenter, | ||
styles.justifyContentBetween, | ||
styles.pv3, | ||
]} | ||
> | ||
<View style={[ | ||
styles.flexRow, | ||
styles.alignItemsCenter, | ||
styles.justifyContentBetween, | ||
]} | ||
> | ||
<Avatar | ||
source={payeeAvatar} | ||
type={isExpenseReport ? CONST.ICON_TYPE_WORKSPACE : CONST.ICON_TYPE_AVATAR} | ||
name={payeeName} | ||
size={CONST.AVATAR_SIZE.HEADER} | ||
/> | ||
<View style={[styles.flexColumn, styles.ml3]}> | ||
<Text | ||
style={[styles.headerText, styles.pre]} | ||
numberOfLines={1} | ||
> | ||
{payeeName} | ||
</Text> | ||
{isExpenseReport && ( | ||
<Text | ||
style={[styles.textLabelSupporting, styles.lh16, styles.pre]} | ||
numberOfLines={1} | ||
> | ||
{props.translate('workspace.common.workspace')} | ||
</Text> | ||
)} | ||
</View> | ||
</View> | ||
<View style={[styles.flexRow]}> | ||
{!props.isSingleTransactionView && ( | ||
<Text style={[styles.newKansasLarge]}>{formattedAmount}</Text> | ||
)} | ||
{isSettled && ( | ||
<View style={styles.moneyRequestHeaderCheckmark}> | ||
<Icon src={Expensicons.Checkmark} fill={themeColors.iconSuccessFill} /> | ||
</View> | ||
)} | ||
</View> | ||
</View> | ||
</View> | ||
</View> | ||
); | ||
}; | ||
|
||
MoneyRequestHeader.displayName = 'MoneyRequestHeader'; | ||
MoneyRequestHeader.propTypes = propTypes; | ||
MoneyRequestHeader.defaultProps = defaultProps; | ||
|
||
export default compose( | ||
withWindowDimensions, | ||
withLocalize, | ||
)(MoneyRequestHeader); |
Oops, something went wrong.