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

IOU Details Modal #2394

Merged
merged 153 commits into from
May 18, 2021
Merged
Show file tree
Hide file tree
Changes from 130 commits
Commits
Show all changes
153 commits
Select commit Hold shift + click to select a range
d0190cd
create dynamic IOU Details route and empty Modal
Julesssss Apr 7, 2021
113825f
replace preview HTML with a React View, to simplify 'view details' ca…
Julesssss Apr 8, 2021
73640e3
retrieve IOU report dynamically
Julesssss Apr 9, 2021
bbd260f
add basic button
Julesssss Apr 9, 2021
fdb1338
start using originalMessage json data, now that API returns it
Julesssss Apr 12, 2021
6707a31
refactor transaction Views to own component
Julesssss Apr 14, 2021
a5bc309
rename IOUDetailPage to IOUDetailsModal
Julesssss Apr 14, 2021
e7084b1
attempt to depend on two onyx subscriptions
Julesssss Apr 15, 2021
3e5dc11
formatting
Julesssss Apr 15, 2021
8e2dc07
use user email to determine whether payment is possible
Julesssss Apr 15, 2021
7f07909
add isLoading to state
Julesssss Apr 15, 2021
32e00f4
add padding to IOU Detail Modal
Julesssss Apr 15, 2021
867bd47
use email const
Julesssss Apr 15, 2021
3ced807
add PayIOU request/action
Julesssss Apr 15, 2021
a03e474
open IOUReport dynamically, by retrieving ID from transaction
Julesssss Apr 15, 2021
d755943
fix double Onyx subscription
Julesssss Apr 16, 2021
0c76ef1
update TransactionItem component to take action
Julesssss Apr 16, 2021
57c4789
find action and pass to TransactionItem
Julesssss Apr 16, 2021
80d373f
post rebase formatting fixes
Julesssss Apr 20, 2021
d5bec43
prep and comments for post Preview UI work
Julesssss Apr 20, 2021
b063b9c
display temp button to unblock removeTransaction functionality
Julesssss Apr 20, 2021
f15262e
add rejectTransaction API call and IOU Action function
Julesssss Apr 20, 2021
5de6dc9
rename ...IOUPreview Component to ...IOUAction
Julesssss Apr 26, 2021
74a0d53
refactor IOUAction, splitting out IOUPreview to reusable Component
Julesssss Apr 26, 2021
68c0041
format IOU Action
Julesssss Apr 26, 2021
0c4a01b
Merge branch 'main' into jules-iouDetailsModal
Julesssss Apr 27, 2021
4021260
add shouldHidePayButton prop to PreviewComponent
Julesssss Apr 27, 2021
ee830c3
order IOU transactions by creation date
Julesssss Apr 27, 2021
151f45b
refactor launch IOUModal func, call when IOU Preview pay button is pr…
Julesssss Apr 27, 2021
dd08992
display loading icon in button during IOU settlement
Julesssss Apr 27, 2021
a8aa309
Merge branch 'main' into jules-iouDetailsModal
Julesssss Apr 28, 2021
178bb00
display transaction in same style as chat comment
Julesssss Apr 28, 2021
c5448e9
reuse ReportActionItemSingle Component
Julesssss Apr 29, 2021
0c0d8ff
rename TransactionItem to ReportTransaction
Julesssss Apr 29, 2021
3398b20
reject specific transaction when button is pressed
Julesssss Apr 29, 2021
967db30
fix issue where IOU was undefined when accessed
Julesssss Apr 29, 2021
2f712c8
ensure the report is updated after local settlement
Julesssss Apr 30, 2021
ea30ecc
separate IOU Detail transactions to Component, to fix compose bug
Julesssss Apr 30, 2021
f658907
Merge branch 'main' into jules-iouDetailsModal
Julesssss Apr 30, 2021
6d5c1e4
format and fix lint errors
Julesssss Apr 30, 2021
7fd307d
refactor IOUTransactions name and file location
Julesssss May 4, 2021
e43f51c
fix bad View import
Julesssss May 4, 2021
5de2094
use the updated IOUAction data
Julesssss May 5, 2021
718c712
display loading indicator while IOU Report is fetched
Julesssss May 5, 2021
baabe70
hide View Details link for group splits
Julesssss May 6, 2021
59be4be
modify IOU Details route to take chatReportID and IOUReportID
Julesssss May 6, 2021
470b8e2
pass dynamic chatReportID to IOU Details Modal route
Julesssss May 6, 2021
5fa7b2d
simplify launching of IOU Details Modal, thanks to new prop availability
Julesssss May 6, 2021
d7ec83b
retrieve and persist settled IOU reports to Onyx when viewed
Julesssss May 6, 2021
f1499b8
get IOUReportID from action to launch the details Modal
Julesssss May 6, 2021
885212d
refactor and vastly simplify Report logic for updating IOU Reports
Julesssss May 6, 2021
827eb35
hide settlement button for settled IOUs
Julesssss May 7, 2021
5bab22b
show 'userA paid userB' in Preview if IOU is settled
Julesssss May 7, 2021
959d3e7
remove divider from IOUModal
Julesssss May 7, 2021
c3ef642
IOUPreview formatting
Julesssss May 7, 2021
c33a2bd
update the IOU report after settling it
Julesssss May 7, 2021
297f905
implement basic logic for preventing rejection of settled report tran…
Julesssss May 7, 2021
7796cae
simplify IOU Detail transactions
Julesssss May 7, 2021
c70a2f9
ensure reportIDs props are passed as Number
Julesssss May 7, 2021
005c34f
clear IOU state on app restart
Julesssss May 7, 2021
5efb7d4
formatting improvements and fixes
Julesssss May 7, 2021
360ccfd
remove comments
Julesssss May 7, 2021
ae72d44
replace error with debug log
Julesssss May 10, 2021
6f9cb9a
active IOuReportID was passed, should instead be retrieved from the I…
Julesssss May 10, 2021
d2a4c24
simplify isDMChat logic
Julesssss May 10, 2021
93dc2e5
remove rejectTransaction logic for next PR
Julesssss May 10, 2021
0b5fd65
Merge branch 'main' into jules-iouDetailsModal
Julesssss May 10, 2021
f523ba5
fix IOU prop default
Julesssss May 10, 2021
5d28272
allow IOU transactions to scroll, fix padding
Julesssss May 10, 2021
6b674ad
replace error with log
Julesssss May 10, 2021
544246d
proptype fixes
Julesssss May 10, 2021
ebe94d3
update podfile
Julesssss May 10, 2021
55501d6
pass unique key to transaction Components
Julesssss May 10, 2021
5a5a69f
fix issue where reportID was passed outside of array
Julesssss May 10, 2021
900ff6c
remove useless comment
Julesssss May 10, 2021
ec0e19c
ensure a null IOU report will not be rendered
Julesssss May 10, 2021
84d1c9f
remove useless style
Julesssss May 10, 2021
2a6a661
re-enables flipper, I'll leave a note in the PR instead
Julesssss May 10, 2021
4e92ed0
remove useless console log
Julesssss May 10, 2021
fdec47e
fix bug where incorrect import is used
Julesssss May 10, 2021
e8e9f4e
change iouReportID default
Julesssss May 10, 2021
d5057de
format podfile, to avoid any change
Julesssss May 10, 2021
643e768
reverse podfile commit
Julesssss May 10, 2021
d0a5329
add additional comments
Julesssss May 10, 2021
8634f3d
revert pod changes, to exclude Flipper workaround
Julesssss May 10, 2021
d0ce923
Merge branch 'main' into jules-iouDetailsModal
Julesssss May 11, 2021
c74cf3f
iou error is now of type string
Julesssss May 11, 2021
73d7e87
improve prop name
Julesssss May 11, 2021
01403b8
invert hasMultipleParticipants logic to simplify
Julesssss May 11, 2021
e1920fa
move IOUPreview session subscription out of parent
Julesssss May 11, 2021
adfa4b3
remove useless outer style for Preview comp
Julesssss May 11, 2021
2841e9a
various prop improvements
Julesssss May 11, 2021
8ee1595
improvements to IOUDetailModal
Julesssss May 11, 2021
d14fff9
replace IOUTransaction PureComponent with Component
Julesssss May 11, 2021
96471cd
refactor style name
Julesssss May 11, 2021
6368d7f
document getSimplifiedIOUReport function
Julesssss May 11, 2021
aead72e
add explanation for removing the IOU Report empty error message
Julesssss May 11, 2021
7d33d18
improve comments
Julesssss May 11, 2021
a0d49a4
Merge branch 'main' into jules-iouDetailsModal
Julesssss May 11, 2021
6973227
further formatting and code review adjustments
Julesssss May 11, 2021
e3575d8
throw error instead of just printing an error message
Julesssss May 11, 2021
2e57b60
improve and simplify logic for updating reports, with better document…
Julesssss May 11, 2021
bf76b01
additional formatting
Julesssss May 11, 2021
427283d
Merge branch 'main' into jules-iouDetailsModal
Julesssss May 11, 2021
762d452
minor formatting fix
Julesssss May 11, 2021
a3906dc
rename iouTransactionProp to camelCase
Julesssss May 12, 2021
b12022a
make ReportActionItemIOUAction a stateless function
Julesssss May 12, 2021
158bd98
Merge branch 'main' into jules-iouDetailsModal
Julesssss May 12, 2021
4ae8b85
clarify transaction/action matching logic
Julesssss May 12, 2021
ed2a838
replace null check with undefined check
Julesssss May 12, 2021
eb80f91
remove iouTransaction props
Julesssss May 12, 2021
95d1758
replace prop-type file with camelCase (case change wasn't recognised …
Julesssss May 12, 2021
6256019
Merge branch 'main' into jules-iouDetailsModal
Julesssss May 12, 2021
124a547
modify pPromise chain to take function
Julesssss May 12, 2021
cc3c2ea
Merge branch 'main' into jules-iouDetailsModal
Julesssss May 13, 2021
fc637b8
locallize hardcoded strings
Julesssss May 13, 2021
50f8dbb
further document the logic behind linking chat and iou reports
Julesssss May 13, 2021
d780c1b
further function documentation
Julesssss May 13, 2021
cc6a450
add back blockquote for web override
Julesssss May 13, 2021
918b7b6
fix lint warning
Julesssss May 13, 2021
db86f85
refactor ReportActionItem IOU Components and rename
Julesssss May 13, 2021
bdbc65e
define const for launch modal callback
Julesssss May 13, 2021
4c3ccf9
replace reference to settled with paid, improve other comments
Julesssss May 13, 2021
1984da1
remove unnecessary use of View, reorder defaultProps, remove function
Julesssss May 13, 2021
61e0446
style improvements, based on review feedback
Julesssss May 13, 2021
d17e8bd
further review feedback applied
Julesssss May 13, 2021
5840b66
move follow up functions out of the Promise chain
Julesssss May 14, 2021
cd0bf1a
revert IOU error back to boolean, remove unnecessary updates
Julesssss May 14, 2021
8719dd3
improve error handling
Julesssss May 14, 2021
b120209
improve fetchIOUReportByIDAndUpdateChatReport usage comment
Julesssss May 14, 2021
a990a54
refactor IOU components back to original location and name for now
Julesssss May 17, 2021
9f85df1
update prop type to fix type warning
Julesssss May 17, 2021
4fa35c2
Merge branch 'main' into jules-iouDetailsModal
Julesssss May 17, 2021
260aca9
reuse the translate function
Julesssss May 17, 2021
8fbe49d
rewrite the fetchIOUReportByID... function docs to make clearer
Julesssss May 17, 2021
c10d6ac
improved comment formatting
Julesssss May 17, 2021
d7f213c
update fetchIOUReportID... param docs too
Julesssss May 17, 2021
c1c5c2e
migrate to new latest propType style
Julesssss May 17, 2021
bfaef8e
apply code review feedback fixes and improvements
Julesssss May 17, 2021
e548db2
switch transactionID type to String, to prevent conversion bug
Julesssss May 17, 2021
129dded
further improve comments based upon review feedback
Julesssss May 17, 2021
f43bbf0
reverse accidental removal of image
Julesssss May 17, 2021
9054afc
additional usage of sync
Julesssss May 17, 2021
3fdc230
Merge branch 'main' into jules-iouDetailsModal
Julesssss May 17, 2021
b403daa
prevents .toString from being called on undefined
Julesssss May 17, 2021
d173c81
simplify fetchIOUReportByIDAndUpdateChatReport function name, reuse '…
Julesssss May 17, 2021
92e2263
fixed exception that was recently introduced, to ensure that the PR i…
Julesssss May 17, 2021
5a7a25a
additional comment improvements
Julesssss May 18, 2021
eeb1a7a
Merge branch 'main' into jules-iouDetailsModal
Julesssss May 18, 2021
49b3787
Merge branch 'main' into jules-iouDetailsModal
Julesssss May 18, 2021
a1ef2b9
ensure that activityIndicator displays when loading paid reports
Julesssss May 18, 2021
3f6fafd
remove iouReport isRequired, as this is no longer true
Julesssss May 18, 2021
2edf67d
reverse user 'paid' user message
Julesssss May 18, 2021
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
2 changes: 1 addition & 1 deletion src/Expensify.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Onyx.init({
[ONYXKEYS.SESSION]: {loading: false, shouldShowComposeInput: true},
[ONYXKEYS.ACCOUNT]: CONST.DEFAULT_ACCOUNT_DATA,
[ONYXKEYS.NETWORK]: {isOffline: false},
[ONYXKEYS.IOU]: {loading: false},
[ONYXKEYS.IOU]: {loading: false, error: false, creatingIOUTransaction: false},
Julesssss marked this conversation as resolved.
Show resolved Hide resolved
},
registerStorageEventListener: (onStorageEvent) => {
listenToStorageEvents(onStorageEvent);
Expand Down
3 changes: 3 additions & 0 deletions src/ROUTES.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ export default {
getIouRequestRoute: reportID => `iou/request/${reportID}`,
IOU_BILL: 'iou/split/:reportID',
getIouSplitRoute: reportID => `iou/split/${reportID}`,
IOU_DETAILS: 'iou/details',
IOU_DETAILS_WITH_IOU_REPORT_ID: 'iou/details/:chatReportID/:iouReportID/',
marcaaron marked this conversation as resolved.
Show resolved Hide resolved
getIouDetailsRoute: (chatReportID, iouReportID) => `iou/details/${chatReportID}/${iouReportID}`,
SEARCH: 'search',
SET_PASSWORD_WITH_VALIDATE_CODE: 'setpassword/:accountID/:validateCode',
DETAILS: 'details',
Expand Down
144 changes: 144 additions & 0 deletions src/components/ReportActionItem/IOUPreview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import React from 'react';
import {View, TouchableOpacity, Text} from 'react-native';
import PropTypes from 'prop-types';
import Str from 'expensify-common/lib/str';
import {withOnyx} from 'react-native-onyx';
import lodashGet from 'lodash/get';
import compose from '../../libs/compose';
import styles from '../../styles/styles';
import ONYXKEYS from '../../ONYXKEYS';
import MultipleAvatars from '../MultipleAvatars';
import withLocalize, {withLocalizePropTypes} from '../withLocalize';

const propTypes = {
// Additional logic for displaying the pay button
shouldHidePayButton: PropTypes.bool,

// Callback for the Pay/Settle button
onPayButtonPressed: PropTypes.func,

// The active IOUReport, used for Onyx subscription
// eslint-disable-next-line react/no-unused-prop-types
iouReportID: PropTypes.number,

/* --- Onyx Props --- */
// Active IOU Report for current report
iou: PropTypes.shape({
// Email address of the manager in this iou report
managerEmail: PropTypes.string,

// Email address of the creator of this iou report
ownerEmail: PropTypes.string,

// Outstanding amount of this transaction
cachedTotal: PropTypes.string,

// Does the report have an outstanding IOU that needs to be paid?
hasOutstandingIOU: PropTypes.bool,
}),

// All of the personal details for everyone
personalDetails: PropTypes.objectOf(PropTypes.shape({

// This is either the user's full name, or their login if full name is an empty string
displayName: PropTypes.string.isRequired,
})).isRequired,

// Session info for the currently logged in user.
session: PropTypes.shape({
// Currently logged in user email
email: PropTypes.string,
}).isRequired,

...withLocalizePropTypes,
};

const defaultProps = {
iou: {},
iouReportID: undefined,
shouldHidePayButton: false,
onPayButtonPressed: null,
};

const ReportActionItemIOUPreview = ({
iou,
personalDetails,
session,
shouldHidePayButton,
onPayButtonPressed,
translate,
}) => {
const sessionEmail = lodashGet(session, 'email', null);

// Pay button should only be visible to the manager of the report.
const isCurrentUserManager = iou.managerEmail === sessionEmail;

const managerName = lodashGet(
personalDetails,
[iou.managerEmail, 'displayName'],
iou.managerEmail ? Str.removeSMSDomain(iou.managerEmail) : '',
);
const ownerName = lodashGet(
personalDetails,
[iou.ownerEmail, 'displayName'],
iou.ownerEmail ? Str.removeSMSDomain(iou.ownerEmail) : '',
);
const managerAvatar = lodashGet(personalDetails, [iou.managerEmail, 'avatar'], '');
const ownerAvatar = lodashGet(personalDetails, [iou.ownerEmail, 'avatar'], '');
const cachedTotal = iou.cachedTotal ? iou.cachedTotal.replace(/[()]/g, '') : '';

return (
<View style={styles.iouPreviewBox}>
<View style={styles.flexRow}>
<View style={styles.flex1}>
<Text style={styles.h1}>{cachedTotal}</Text>
<Text style={styles.mt2}>
{iou.hasOutstandingIOU
? translate('iou.owes', {manager: managerName, owner: ownerName})
: translate('iou.paid', {manager: managerName, owner: ownerName})}
</Text>
</View>
<View style={styles.iouPreviewBoxAvatar}>
<MultipleAvatars
avatarImageURLs={[managerAvatar, ownerAvatar]}
secondAvatarStyle={[styles.secondAvatarInline]}
/>
</View>
</View>
{isCurrentUserManager && !shouldHidePayButton && (
<TouchableOpacity
style={[styles.buttonSmall, styles.buttonSuccess, styles.mt4]}
onPress={onPayButtonPressed}
>
<Text
style={[
styles.buttonSmallText,
styles.buttonSuccessText,
]}
>
{translate('iou.pay')}
</Text>
</TouchableOpacity>
)}
</View>
);
};

ReportActionItemIOUPreview.propTypes = propTypes;
ReportActionItemIOUPreview.defaultProps = defaultProps;
ReportActionItemIOUPreview.displayName = 'ReportActionItemIOUPreview';

export default compose(
withLocalize,
withOnyx({
personalDetails: {
key: ONYXKEYS.PERSONAL_DETAILS,
},
iou: {
key: ({iouReportID}) => `${ONYXKEYS.COLLECTION.REPORT_IOUS}${iouReportID}`,
},
session: {
key: ONYXKEYS.SESSION,
},
}),
)(ReportActionItemIOUPreview);
58 changes: 58 additions & 0 deletions src/components/ReportActionItem/IOUQuote.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react';
import {View, Text} from 'react-native';
import PropTypes from 'prop-types';
import _ from 'underscore';
import styles from '../../styles/styles';
import ReportActionPropTypes from '../../pages/home/report/ReportActionPropTypes';
import withLocalize, {withLocalizePropTypes} from '../withLocalize';

const propTypes = {
// All the data of the action
action: PropTypes.shape(ReportActionPropTypes).isRequired,

// Should the View Details link be displayed?
shouldShowViewDetailsLink: PropTypes.bool,

// Callback invoked when View Details is pressed
onViewDetailsPressed: PropTypes.func,

...withLocalizePropTypes,
};

const defaultProps = {
shouldShowViewDetailsLink: false,
onViewDetailsPressed: null,
};

const ReportActionItemIOUQuote = ({
action,
shouldShowViewDetailsLink,
onViewDetailsPressed,
translate,
}) => (
<View style={[styles.chatItemMessage]}>
{_.map(action.message, (fragment, index) => (
<View key={`iouQuote-${action.sequenceNumber}-${index}`}>
<View style={[styles.blockquote]}>
<Text style={[styles.chatItemMessage]}>
{fragment.text}
</Text>
{shouldShowViewDetailsLink && (
<Text
style={[styles.chatItemMessageLink]}
onPress={onViewDetailsPressed}
>
{translate('iou.viewDetails')}
</Text>
)}
</View>
</View>
))}
</View>
);

ReportActionItemIOUQuote.propTypes = propTypes;
ReportActionItemIOUQuote.defaultProps = defaultProps;
ReportActionItemIOUQuote.displayName = 'ReportActionItemIOUQuote';

export default withLocalize(ReportActionItemIOUQuote);
68 changes: 68 additions & 0 deletions src/components/ReportActionItem/IOUReportAction.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import React from 'react';
import PropTypes from 'prop-types';
import {withOnyx} from 'react-native-onyx';
import ONYXKEYS from '../../ONYXKEYS';
import ReportActionItemIOUQuote from './IOUQuote';
import ReportActionPropTypes from '../../pages/home/report/ReportActionPropTypes';
import ReportActionItemIOUPreview from './IOUPreview';
import Navigation from '../../libs/Navigation/Navigation';
import ROUTES from '../../ROUTES';

const propTypes = {
// All the data of the action
action: PropTypes.shape(ReportActionPropTypes).isRequired,

// The associated chatReport
chatReportID: PropTypes.number.isRequired,

// Should render the preview Component?
shouldDisplayPreview: PropTypes.bool.isRequired,

/* --- Onyx Props --- */
// ChatReport associated with iouReport
chatReport: PropTypes.shape({
// The participants of this report
participants: PropTypes.arrayOf(PropTypes.string),
}),
};

const defaultProps = {
chatReport: {},
};

const ReportActionItemIOUAction = ({
action,
chatReportID,
shouldDisplayPreview,
chatReport,
}) => {
const launchDetailsModal = () => {
Navigation.navigate(ROUTES.getIouDetailsRoute(chatReportID, action.originalMessage.IOUReportID));
};
const hasMultipleParticipants = chatReport.participants.length >= 2;
return (
<>
<ReportActionItemIOUQuote
action={action}
shouldShowViewDetailsLink={!hasMultipleParticipants}
onViewDetailsPressed={launchDetailsModal}
/>
{shouldDisplayPreview && (
<ReportActionItemIOUPreview
iouReportID={action.originalMessage.IOUReportID}
onPayButtonPressed={launchDetailsModal}
/>
)}
</>
);
};

ReportActionItemIOUAction.propTypes = propTypes;
ReportActionItemIOUAction.defaultProps = defaultProps;
ReportActionItemIOUAction.displayName = 'ReportActionItemIOUAction';

export default withOnyx({
chatReport: {
key: ({chatReportID}) => `${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`,
},
})(ReportActionItemIOUAction);
Loading