From 575541a70c49ca799edc65ab32f3b7fd43f072f5 Mon Sep 17 00:00:00 2001
From: OSBotify <76178356+OSBotify@users.noreply.github.com>
Date: Wed, 17 May 2023 07:31:57 -0400
Subject: [PATCH 1/2] Merge pull request #19111 from
Expensify/version-BUILD-3E18B8A0-F3BA-497D-A27B-52B695EC488E
Update version to 1.3.15-1 on main
(cherry picked from commit 098228b668591ab95569d60db3fc5bebde5e6dc7)
---
android/app/build.gradle | 4 ++--
ios/NewExpensify/Info.plist | 2 +-
ios/NewExpensifyTests/Info.plist | 2 +-
package-lock.json | 4 ++--
package.json | 2 +-
5 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 60039a852cce..5670d132f6be 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -106,8 +106,8 @@ android {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
multiDexEnabled rootProject.ext.multiDexEnabled
- versionCode 1001031500
- versionName "1.3.15-0"
+ versionCode 1001031501
+ versionName "1.3.15-1"
}
splits {
diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist
index 31984a8b4aba..75d2bd6580b6 100644
--- a/ios/NewExpensify/Info.plist
+++ b/ios/NewExpensify/Info.plist
@@ -30,7 +30,7 @@
CFBundleVersion
- 1.3.15.0
+ 1.3.15.1
ITSAppUsesNonExemptEncryption
LSApplicationQueriesSchemes
diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist
index 3dfd9dda34d1..fe589eb776a9 100644
--- a/ios/NewExpensifyTests/Info.plist
+++ b/ios/NewExpensifyTests/Info.plist
@@ -19,6 +19,6 @@
CFBundleSignature
????
CFBundleVersion
- 1.3.15.0
+ 1.3.15.1
diff --git a/package-lock.json b/package-lock.json
index 426844cf8e51..dead2a14dda9 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "new.expensify",
- "version": "1.3.15-0",
+ "version": "1.3.15-1",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "new.expensify",
- "version": "1.3.15-0",
+ "version": "1.3.15-1",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
diff --git a/package.json b/package.json
index 92da55701256..c65610f73df9 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "new.expensify",
- "version": "1.3.15-0",
+ "version": "1.3.15-1",
"author": "Expensify, Inc.",
"homepage": "https://new.expensify.com",
"description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",
From 71fea06f36d3685e3c9edc384e98433df925d2df Mon Sep 17 00:00:00 2001
From: Vit Horacek <36083550+mountiny@users.noreply.github.com>
Date: Wed, 17 May 2023 12:24:01 +0100
Subject: [PATCH 2/2] Merge pull request #18423 from
Expensify/cristi_display-report-preview
Display report preview using new reportAction data source
(cherry picked from commit 8d650c62fc0f14995f32eb87f9b78c9616c2455c)
---
src/CONST.js | 1 +
src/components/ReportActionItem/IOUPreview.js | 1 -
.../ReportActionItem/MoneyRequestAction.js | 12 -
.../ReportActionItem/ReportPreview.js | 15 +-
src/libs/ReportActionsUtils.js | 17 +
src/libs/ReportUtils.js | 24 ++
src/libs/actions/IOU.js | 368 ++++++------------
src/pages/home/report/ReportActionItem.js | 12 +
.../home/report/ReportActionItemSingle.js | 3 +-
src/pages/iou/IOUTransactions.js | 6 +-
tests/actions/IOUTest.js | 2 +-
11 files changed, 186 insertions(+), 275 deletions(-)
diff --git a/src/CONST.js b/src/CONST.js
index f06b00422834..47fb10ec576a 100755
--- a/src/CONST.js
+++ b/src/CONST.js
@@ -469,6 +469,7 @@ const CONST = {
CHRONOSOOOLIST: 'CHRONOSOOOLIST',
TASKCOMPLETED: 'TASKCOMPLETED',
TASKREOPENED: 'TASKREOPENED',
+ REPORTPREVIEW: 'REPORTPREVIEW',
POLICYCHANGELOG: {
ADD_APPROVER_RULE: 'POLICYCHANGELOG_ADD_APPROVER_RULE',
ADD_CATEGORY: 'POLICYCHANGELOG_ADD_CATEGORY',
diff --git a/src/components/ReportActionItem/IOUPreview.js b/src/components/ReportActionItem/IOUPreview.js
index 0f538b74326a..813d7da22928 100644
--- a/src/components/ReportActionItem/IOUPreview.js
+++ b/src/components/ReportActionItem/IOUPreview.js
@@ -224,7 +224,6 @@ const IOUPreview = (props) => {
)}
-
{!isCurrentUserManager && props.shouldShowPendingConversionMessage && (
diff --git a/src/components/ReportActionItem/MoneyRequestAction.js b/src/components/ReportActionItem/MoneyRequestAction.js
index b6f9cd88d5bb..3eb35063d116 100644
--- a/src/components/ReportActionItem/MoneyRequestAction.js
+++ b/src/components/ReportActionItem/MoneyRequestAction.js
@@ -7,7 +7,6 @@ import ONYXKEYS from '../../ONYXKEYS';
import CONST from '../../CONST';
import {withNetwork} from '../OnyxProvider';
import compose from '../../libs/compose';
-import ReportPreview from './ReportPreview';
import reportActionPropTypes from '../../pages/home/report/reportActionPropTypes';
import networkPropTypes from '../networkPropTypes';
import iouReportPropTypes from '../../pages/iouReportPropTypes';
@@ -149,17 +148,6 @@ const MoneyRequestAction = (props) => {
containerStyles={[styles.cursorPointer, props.isHovered ? styles.iouPreviewBoxHover : undefined]}
isHovered={props.isHovered}
/>
- {props.isMostRecentIOUReportAction && !hasMultipleParticipants && (
-
- )}
>
);
};
diff --git a/src/components/ReportActionItem/ReportPreview.js b/src/components/ReportActionItem/ReportPreview.js
index add769e2cc50..030f3f4fbc3e 100644
--- a/src/components/ReportActionItem/ReportPreview.js
+++ b/src/components/ReportActionItem/ReportPreview.js
@@ -12,7 +12,6 @@ import styles from '../../styles/styles';
import reportActionPropTypes from '../../pages/home/report/reportActionPropTypes';
import withLocalize, {withLocalizePropTypes} from '../withLocalize';
import compose from '../../libs/compose';
-import ONYXKEYS from '../../ONYXKEYS';
import ControlSelection from '../../libs/ControlSelection';
import * as DeviceCapabilities from '../../libs/DeviceCapabilities';
import {showContextMenuForReport} from '../ShowContextMenuContext';
@@ -20,10 +19,11 @@ import * as StyleUtils from '../../styles/StyleUtils';
import * as CurrencyUtils from '../../libs/CurrencyUtils';
import * as ReportUtils from '../../libs/ReportUtils';
import Button from '../Button';
-import Navigation from '../../libs/Navigation/Navigation';
-import ROUTES from '../../ROUTES';
import themeColors from '../../styles/themes/default';
import getButtonState from '../../libs/getButtonState';
+import Navigation from '../../libs/Navigation/Navigation';
+import ROUTES from '../../ROUTES';
+import ONYXKEYS from '../../ONYXKEYS';
const propTypes = {
/** All the data of the action */
@@ -36,6 +36,7 @@ const propTypes = {
// eslint-disable-next-line react/no-unused-prop-types
iouReportID: PropTypes.string.isRequired,
+ /* Onyx Props */
/** chatReport associated with iouReport */
chatReport: PropTypes.shape({
/** The participants of this report */
@@ -72,9 +73,6 @@ const propTypes = {
/** Popover context menu anchor, used for showing context menu */
contextMenuAnchor: PropTypes.shape({current: PropTypes.elementType}),
- /** Callback invoked when View Details is pressed */
- onViewDetailsPressed: PropTypes.func,
-
/** Callback for updating context menu active state, used for showing context menu */
checkIfContextMenuActive: PropTypes.func,
@@ -89,7 +87,6 @@ const defaultProps = {
isHovered: false,
chatReport: {},
iouReport: {},
- onViewDetailsPressed: () => {},
checkIfContextMenuActive: () => {},
session: {
email: null,
@@ -106,7 +103,9 @@ const ReportPreview = (props) => {
{_.map(props.action.message, (index) => (
{
+ Navigation.navigate(ROUTES.getReportRoute(props.iouReportID));
+ }}
onPressIn={() => DeviceCapabilities.canUseTouchScreen() && ControlSelection.block()}
onPressOut={() => ControlSelection.unblock()}
onLongPress={(event) => showContextMenuForReport(event, props.contextMenuAnchor, props.chatReportID, props.action, props.checkIfContextMenuActive)}
diff --git a/src/libs/ReportActionsUtils.js b/src/libs/ReportActionsUtils.js
index 20062514675c..a37a5ba79432 100644
--- a/src/libs/ReportActionsUtils.js
+++ b/src/libs/ReportActionsUtils.js
@@ -100,6 +100,10 @@ function getSortedReportActions(reportActions, shouldSortInDescendingOrder = fal
if ((first.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED || second.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) && first.actionName !== second.actionName) {
return (first.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED ? -1 : 1) * invertedMultiplier;
}
+ // Ensure that `REPORTPREVIEW` actions always come after if they have the same timestamp as another action type
+ if ((first.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW || second.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW) && first.actionName !== second.actionName) {
+ return (first.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW ? 1 : -1) * invertedMultiplier;
+ }
// Then fallback on reportActionID as the final sorting criteria. It is a random number,
// but using this will ensure that the order of reportActions with the same created time and action type
@@ -333,6 +337,18 @@ function getLinkedTransactionID(reportID, reportActionID) {
return reportAction.originalMessage.IOUTransactionID;
}
+/**
+ * @param {*} chatReportID
+ * @param {*} iouReportID
+ * @returns {Object} The report preview action or `null` if one couldn't be found
+ */
+function getReportPreviewAction(chatReportID, iouReportID) {
+ return _.find(
+ allReportActions[chatReportID],
+ (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW && lodashGet(reportAction, 'originalMessage.linkedReportID') === iouReportID,
+ );
+}
+
function isCreatedTaskReportAction(reportAction) {
return reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT && _.has(reportAction.originalMessage, 'taskReportID');
}
@@ -351,6 +367,7 @@ export {
getLatestReportActionFromOnyxData,
isMoneyRequestAction,
getLinkedTransactionID,
+ getReportPreviewAction,
isCreatedTaskReportAction,
getParentReportAction,
isTransactionThread,
diff --git a/src/libs/ReportUtils.js b/src/libs/ReportUtils.js
index c8942a72b450..b01ab88749be 100644
--- a/src/libs/ReportUtils.js
+++ b/src/libs/ReportUtils.js
@@ -1427,6 +1427,29 @@ function buildOptimisticIOUReportAction(type, amount, currency, comment, partici
};
}
+function buildOptimisticReportPreview(reportID, iouReportID, payeeAccountID) {
+ return {
+ reportActionID: NumberUtils.rand64(),
+ reportID,
+ created: DateUtils.getDBTime(),
+ actionName: CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW,
+ pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD,
+ accountID: payeeAccountID,
+ message: [
+ {
+ html: '',
+ text: '',
+ isEdited: false,
+ type: CONST.REPORT.MESSAGE.TYPE.COMMENT,
+ },
+ ],
+ originalMessage: {
+ linkedReportID: iouReportID,
+ },
+ actorEmail: currentUserEmail,
+ };
+}
+
function buildOptimisticTaskReportAction(taskReportID, actionName, message = '') {
const originalMessage = {
taskReportID,
@@ -2219,6 +2242,7 @@ export {
buildOptimisticIOUReport,
buildOptimisticExpenseReport,
buildOptimisticIOUReportAction,
+ buildOptimisticReportPreview,
buildOptimisticTaskReportAction,
buildOptimisticAddCommentReportAction,
buildOptimisticTaskCommentReportAction,
diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js
index 46e2573bc6a8..0b429a6d098b 100644
--- a/src/libs/actions/IOU.js
+++ b/src/libs/actions/IOU.js
@@ -10,6 +10,7 @@ import * as Localize from '../Localize';
import asyncOpenURL from '../asyncOpenURL';
import * as API from '../API';
import * as ReportUtils from '../ReportUtils';
+import * as ReportActionsUtils from '../ReportActionsUtils';
import * as IOUUtils from '../IOUUtils';
import * as OptionsListUtils from '../OptionsListUtils';
import DateUtils from '../DateUtils';
@@ -43,7 +44,18 @@ Onyx.connect({
},
});
-function buildOnyxDataForMoneyRequest(chatReport, iouReport, transaction, chatCreatedAction, iouCreatedAction, iouAction, isNewChatReport, isNewIOUReport) {
+function buildOnyxDataForMoneyRequest(
+ chatReport,
+ iouReport,
+ transaction,
+ chatCreatedAction,
+ iouCreatedAction,
+ iouAction,
+ reportPreviewAction,
+ isNewChatReport,
+ isNewIOUReport,
+ isNewReportPreviewAction,
+) {
const optimisticData = [
{
// Use SET for new reports because it doesn't exist yet, is faster and we need the data to be available when we navigate to the chat page
@@ -72,17 +84,16 @@ function buildOnyxDataForMoneyRequest(chatReport, iouReport, transaction, chatCr
key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`,
value: transaction,
},
- ...(isNewChatReport
- ? [
- {
- onyxMethod: Onyx.METHOD.SET,
- key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`,
- value: {
- [chatCreatedAction.reportActionID]: chatCreatedAction,
- },
- },
- ]
- : []),
+ {
+ onyxMethod: isNewChatReport ? Onyx.METHOD.SET : Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`,
+ value: {
+ ...(isNewChatReport ? {[chatCreatedAction.reportActionID]: chatCreatedAction} : {}),
+ [reportPreviewAction.reportActionID]: {
+ ...(isNewReportPreviewAction ? reportPreviewAction : {created: DateUtils.getDBTime()}),
+ },
+ },
+ },
{
onyxMethod: isNewIOUReport ? Onyx.METHOD.SET : Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
@@ -104,16 +115,6 @@ function buildOnyxDataForMoneyRequest(chatReport, iouReport, transaction, chatCr
errorFields: null,
},
},
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`,
- value: {
- [chatCreatedAction.reportActionID]: {
- pendingAction: null,
- errors: null,
- },
- },
- },
]
: []),
...(isNewIOUReport
@@ -133,6 +134,27 @@ function buildOnyxDataForMoneyRequest(chatReport, iouReport, transaction, chatCr
key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`,
value: {pendingAction: null},
},
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`,
+ value: {
+ ...(isNewChatReport
+ ? {
+ [chatCreatedAction.reportActionID]: {
+ pendingAction: null,
+ errors: null,
+ },
+ }
+ : {}),
+ ...(isNewReportPreviewAction
+ ? {
+ [reportPreviewAction.reportActionID]: {
+ pendingAction: null,
+ },
+ }
+ : {}),
+ },
+ },
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
@@ -196,21 +218,24 @@ function buildOnyxDataForMoneyRequest(chatReport, iouReport, transaction, chatCr
},
},
},
- ...(isNewChatReport
- ? [
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`,
- value: {
+ {
+ onyxMethod: Onyx.METHOD.MERGE,
+ key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport.reportID}`,
+ value: {
+ ...(isNewChatReport
+ ? {
[chatCreatedAction.reportActionID]: {
errors: {
[DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'),
},
},
- },
- },
- ]
- : []),
+ }
+ : {}),
+ [reportPreviewAction.reportActionID]: {
+ created: reportPreviewAction.created,
+ },
+ },
+ },
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`,
@@ -293,7 +318,11 @@ function requestMoney(report, amount, currency, payeeEmail, participant, comment
// STEP 3: Build optimistic transaction
const optimisticTransaction = TransactionUtils.buildOptimisticTransaction(amount, currency, iouReport.reportID, comment);
- // STEP 4: Build optimistic reportActions. We need a CREATED action for each report and an IOU action for the IOU report
+ // STEP 4: Build optimistic reportActions. We need:
+ // 1. CREATED action for the chatReport
+ // 2. CREATED action for the iouReport
+ // 3. IOU action for the iouReport
+ // 4. REPORTPREVIEW action for the chatReport
// Note: The CREATED action for the IOU report must be optimistically generated before the IOU action so there's no chance that it appears after the IOU action in the chat
const optimisticCreatedActionForChat = ReportUtils.buildOptimisticCreatedReportAction(payeeEmail);
const optimisticCreatedActionForIOU = ReportUtils.buildOptimisticCreatedReportAction(payeeEmail);
@@ -308,6 +337,13 @@ function requestMoney(report, amount, currency, payeeEmail, participant, comment
iouReport.reportID,
);
+ let isNewReportPreviewAction = false;
+ let reportPreviewAction = ReportActionsUtils.getReportPreviewAction(chatReport.reportID, iouReport.reportID);
+ if (!reportPreviewAction) {
+ isNewReportPreviewAction = true;
+ reportPreviewAction = ReportUtils.buildOptimisticReportPreview(chatReport.reportID, iouReport.reportID);
+ }
+
// STEP 5: Build Onyx Data
const [optimisticData, successData, failureData] = buildOnyxDataForMoneyRequest(
chatReport,
@@ -316,8 +352,10 @@ function requestMoney(report, amount, currency, payeeEmail, participant, comment
optimisticCreatedActionForChat,
optimisticCreatedActionForIOU,
optimisticIOUAction,
+ reportPreviewAction,
isNewChatReport,
isNewIOUReport,
+ isNewReportPreviewAction,
);
// STEP 6: Make the request
@@ -335,6 +373,7 @@ function requestMoney(report, amount, currency, payeeEmail, participant, comment
reportActionID: optimisticIOUAction.reportActionID,
createdChatReportActionID: isNewChatReport ? optimisticCreatedActionForChat.reportActionID : 0,
createdIOUReportActionID: isNewIOUReport ? optimisticCreatedActionForIOU.reportActionID : 0,
+ reportPreviewReportActionID: reportPreviewAction.reportActionID,
},
{optimisticData, successData, failureData},
);
@@ -491,21 +530,27 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment
return;
}
+ // STEP 1: Get existing chat report OR build a new optimistic one
// If we only have one participant and the request was initiated from the global create menu, i.e. !existingGroupChatReportID, the oneOnOneChatReport is the groupChatReport
- const existingOneOnOneChatReport = !hasMultipleParticipants && !existingGroupChatReportID ? groupChatReport : ReportUtils.getChatByParticipants([email]);
- const oneOnOneChatReport = existingOneOnOneChatReport || ReportUtils.buildOptimisticChatReport([email]);
+ let oneOnOneChatReport;
+ let isNewOneOnOneChatReport = false;
+ oneOnOneChatReport = !hasMultipleParticipants && !existingGroupChatReportID ? groupChatReport : ReportUtils.getChatByParticipants([email]);
+
+ if (!oneOnOneChatReport) {
+ isNewOneOnOneChatReport = true;
+ oneOnOneChatReport = ReportUtils.buildOptimisticChatReport([email]);
+ }
+
+ // STEP 2: Get existing IOU report and update its total OR build a new optimistic one
+ const isNewOneOnOneIOUReport = !oneOnOneChatReport.iouReportID;
let oneOnOneIOUReport;
- let existingOneOnOneIOUReport = null;
- if (oneOnOneChatReport.iouReportID) {
- existingOneOnOneIOUReport = iouReports[`${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.iouReportID}`];
- oneOnOneIOUReport = IOUUtils.updateIOUOwnerAndTotal(existingOneOnOneIOUReport, currentUserEmail, splitAmount, currency);
- oneOnOneChatReport.hasOutstandingIOU = oneOnOneIOUReport.total !== 0;
+ if (!isNewOneOnOneIOUReport) {
+ oneOnOneIOUReport = IOUUtils.updateIOUOwnerAndTotal(iouReports[`${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.iouReportID}`], currentUserEmail, splitAmount, currency);
} else {
oneOnOneIOUReport = ReportUtils.buildOptimisticIOUReport(currentUserEmail, email, splitAmount, oneOnOneChatReport.reportID, currency);
- oneOnOneChatReport.hasOutstandingIOU = true;
- oneOnOneChatReport.iouReportID = oneOnOneIOUReport.reportID;
}
+ // STEP 3: Build optimistic transaction
const oneOnOneTransaction = TransactionUtils.buildOptimisticTransaction(
splitAmount,
currency,
@@ -515,7 +560,12 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment
groupTransaction.transactionID,
);
- // Note: The created action must be optimistically generated before the IOU action so there's no chance that the created action appears after the IOU action in the chat
+ // STEP 4: Build optimistic reportActions. We need:
+ // 1. CREATED action for the chatReport
+ // 2. CREATED action for the iouReport
+ // 3. IOU action for the iouReport
+ // 4. REPORTPREVIEW action for the chatReport
+ // Note: The CREATED action for the IOU report must be optimistically generated before the IOU action so there's no chance that it appears after the IOU action in the chat
const oneOnOneCreatedActionForChat = ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail);
const oneOnOneCreatedActionForIOU = ReportUtils.buildOptimisticCreatedReportAction(currentUserEmail);
const oneOnOneIOUAction = ReportUtils.buildOptimisticIOUReportAction(
@@ -529,227 +579,43 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment
oneOnOneIOUReport.reportID,
);
- optimisticData.push(
- {
- onyxMethod: existingOneOnOneChatReport ? Onyx.METHOD.MERGE : Onyx.METHOD.SET,
- key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`,
- value: {
- ...oneOnOneChatReport,
- lastReadTime: DateUtils.getDBTime(),
- hasOutstandingIOU: oneOnOneIOUReport.total !== 0,
- iouReportID: oneOnOneIOUReport.reportID,
- ...(existingOneOnOneChatReport ? {} : {pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}}),
- },
- },
- {
- onyxMethod: existingOneOnOneIOUReport ? Onyx.METHOD.MERGE : Onyx.METHOD.SET,
- key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneIOUReport.reportID}`,
- value: {
- ...oneOnOneIOUReport,
- lastMessageText: oneOnOneIOUAction.message[0].text,
- lastMessageHtml: oneOnOneIOUAction.message[0].html,
- ...(existingOneOnOneIOUReport ? {} : {pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}}),
- },
- },
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.TRANSACTION}${oneOnOneTransaction.transactionID}`,
- value: oneOnOneTransaction,
- },
- ...(existingOneOnOneChatReport
- ? []
- : [
- {
- onyxMethod: existingOneOnOneChatReport ? Onyx.METHOD.MERGE : Onyx.METHOD.SET,
- key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`,
- value: {
- [oneOnOneCreatedActionForChat.reportActionID]: oneOnOneCreatedActionForChat,
- },
- },
- ]),
- {
- onyxMethod: existingOneOnOneIOUReport ? Onyx.METHOD.MERGE : Onyx.METHOD.SET,
- key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneIOUReport.reportID}`,
- value: {
- ...(existingOneOnOneIOUReport ? {} : {[oneOnOneCreatedActionForIOU.reportActionID]: oneOnOneCreatedActionForIOU}),
- [oneOnOneIOUAction.reportActionID]: oneOnOneIOUAction,
- },
- },
- );
-
- successData.push(
- ...(existingOneOnOneChatReport
- ? []
- : [
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`,
- value: {
- pendingFields: null,
- errorFields: null,
- },
- },
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`,
- value: {
- [oneOnOneCreatedActionForChat.reportActionID]: {
- pendingAction: null,
- errors: null,
- },
- },
- },
- ]),
- ...(existingOneOnOneIOUReport
- ? []
- : [
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneIOUReport.reportID}`,
- value: {
- pendingFields: null,
- errorFields: null,
- },
- },
- ]),
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.TRANSACTION}${oneOnOneTransaction.transactionID}`,
- value: {pendingAction: null},
- },
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneIOUReport.reportID}`,
- value: {
- ...(existingOneOnOneIOUReport
- ? {}
- : {
- [oneOnOneCreatedActionForIOU.reportActionID]: {
- pendingAction: null,
- errors: null,
- },
- }),
- [oneOnOneIOUAction.reportActionID]: {
- pendingAction: null,
- errors: null,
- },
- },
- },
- );
+ let isNewOneOnOneReportPreviewAction = false;
+ let oneOnOneReportPreviewAction = ReportActionsUtils.getReportPreviewAction(oneOnOneChatReport.reportID, oneOnOneIOUReport.reportID);
+ if (!oneOnOneReportPreviewAction) {
+ isNewOneOnOneReportPreviewAction = true;
+ oneOnOneReportPreviewAction = ReportUtils.buildOptimisticReportPreview(oneOnOneChatReport.reportID, oneOnOneIOUReport.reportID);
+ }
- failureData.push(
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneChatReport.reportID}`,
- value: {
- hasOutstandingIOU: oneOnOneChatReport.hasOutstandingIOU,
- lastReadTime: oneOnOneChatReport.lastReadTime,
- iouReportID: oneOnOneChatReport.iouReportID,
- ...(existingOneOnOneChatReport
- ? {}
- : {
- errorFields: {
- createChat: {
- [DateUtils.getMicroseconds()]: Localize.translateLocal('report.genericCreateReportFailureMessage'),
- },
- },
- }),
- },
- },
- ...(existingOneOnOneIOUReport
- ? []
- : [
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneIOUReport.reportID}`,
- value: {
- errorFields: {
- createChat: {
- [DateUtils.getMicroseconds()]: Localize.translateLocal('report.genericCreateReportFailureMessage'),
- },
- },
- },
- },
- ]),
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.TRANSACTION}${oneOnOneTransaction.transactionID}`,
- value: {
- errors: {
- [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'),
- },
- },
- },
- ...(existingOneOnOneChatReport
- ? []
- : [
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneChatReport.reportID}`,
- value: {
- [oneOnOneCreatedActionForChat.reportActionID]: {
- errors: {
- [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'),
- },
- },
- },
- },
- ]),
- {
- onyxMethod: Onyx.METHOD.MERGE,
- key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oneOnOneIOUReport.reportID}`,
- value: {
- ...(existingOneOnOneIOUReport
- ? {
- [oneOnOneIOUAction.reportActionID]: {
- errors: {
- [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'),
- },
- },
- }
- : {
- [oneOnOneCreatedActionForIOU.reportActionID]: {
- errors: {
- [DateUtils.getMicroseconds()]: Localize.translateLocal('iou.error.genericCreateFailureMessage'),
- },
- },
- }),
- },
- },
+ // STEP 5: Build Onyx Data
+ const [oneOnOneOptimisticData, oneOnOneSuccessData, oneOnOneFailureData] = buildOnyxDataForMoneyRequest(
+ oneOnOneChatReport,
+ oneOnOneIOUReport,
+ oneOnOneTransaction,
+ oneOnOneCreatedActionForChat,
+ oneOnOneCreatedActionForIOU,
+ oneOnOneIOUAction,
+ oneOnOneReportPreviewAction,
+ isNewOneOnOneChatReport,
+ isNewOneOnOneIOUReport,
+ isNewOneOnOneReportPreviewAction,
);
- // Regardless of the number of participants, we always want to push the iouReport update to onyxData
- optimisticData.push({
- // We want to use set in case we are creating the the optimistic chat.
- // If we have multiple participants selected, we need to check if the 1:1 chat between the users already exists
- // If we have only one other participant, the group chat is the 1:1 chat and we need to check if that already exists
- onyxMethod: (hasMultipleParticipants && existingOneOnOneChatReport) || (!hasMultipleParticipants && existingGroupChatReport) ? Onyx.METHOD.MERGE : Onyx.METHOD.SET,
- key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneIOUReport.reportID}`,
- value: oneOnOneIOUReport,
- });
-
- failureData.push({
- onyxMethod: Onyx.METHOD.SET,
- key: `${ONYXKEYS.COLLECTION.REPORT}${oneOnOneIOUReport.reportID}`,
- value: existingOneOnOneIOUReport || oneOnOneIOUReport,
- });
-
const splitData = {
email,
amount: splitAmount,
iouReportID: oneOnOneIOUReport.reportID,
chatReportID: oneOnOneChatReport.reportID,
transactionID: oneOnOneTransaction.transactionID,
+ reportActionID: oneOnOneIOUAction.reportActionID,
createdChatReportActionID: oneOnOneCreatedActionForChat.reportActionID,
createdIOUReportActionID: oneOnOneCreatedActionForIOU.reportActionID,
- reportActionID: oneOnOneIOUAction.reportActionID,
+ reportPreviewReportActionID: oneOnOneReportPreviewAction.reportActionID,
};
- if (!_.isEmpty(oneOnOneCreatedActionForChat)) {
- splitData.createdReportActionID = oneOnOneCreatedActionForChat.reportActionID;
- }
-
splits.push(splitData);
+ optimisticData.push(...oneOnOneOptimisticData);
+ successData.push(...oneOnOneSuccessData);
+ failureData.push(...oneOnOneFailureData);
});
const groupData = {
@@ -758,7 +624,7 @@ function createSplitsAndOnyxData(participants, currentUserLogin, amount, comment
reportActionID: groupIOUReportAction.reportActionID,
};
- if (!_.isEmpty(groupCreatedReportAction)) {
+ if (_.isEmpty(existingGroupChatReport)) {
groupData.createdReportActionID = groupCreatedReportAction.reportActionID;
}
diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js
index 5c0140e1b3de..6ecbcc33f2a3 100644
--- a/src/pages/home/report/ReportActionItem.js
+++ b/src/pages/home/report/ReportActionItem.js
@@ -47,6 +47,7 @@ import * as Expensicons from '../../../components/Icon/Expensicons';
import Text from '../../../components/Text';
import DisplayNames from '../../../components/DisplayNames';
import personalDetailsPropType from '../../personalDetailsPropType';
+import ReportPreview from '../../../components/ReportActionItem/ReportPreview';
import ReportActionItemDraft from './ReportActionItemDraft';
import TaskPreview from '../../../components/ReportActionItem/TaskPreview';
import TaskAction from '../../../components/ReportActionItem/TaskAction';
@@ -204,6 +205,17 @@ class ReportActionItem extends Component {
checkIfContextMenuActive={this.checkIfContextMenuActive}
/>
);
+ } else if (this.props.action.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW) {
+ children = (
+
+ );
} else if (
this.props.action.actionName === CONST.REPORT.ACTIONS.TYPE.TASKCOMPLETED ||
this.props.action.actionName === CONST.REPORT.ACTIONS.TYPE.TASKCANCELED ||
diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js
index 37fc0b8b3fe2..f388faf1b5a4 100644
--- a/src/pages/home/report/ReportActionItemSingle.js
+++ b/src/pages/home/report/ReportActionItemSingle.js
@@ -37,7 +37,7 @@ const propTypes = {
children: PropTypes.node.isRequired,
/** Report for this action */
- report: reportPropTypes.isRequired,
+ report: reportPropTypes,
/** Show header for action */
showHeader: PropTypes.bool,
@@ -53,6 +53,7 @@ const defaultProps = {
wrapperStyles: [styles.chatItem],
showHeader: true,
shouldShowSubscriptAvatar: false,
+ report: undefined,
};
const showUserDetails = (email) => {
diff --git a/src/pages/iou/IOUTransactions.js b/src/pages/iou/IOUTransactions.js
index ecb00e99ef15..b8a0998e492d 100644
--- a/src/pages/iou/IOUTransactions.js
+++ b/src/pages/iou/IOUTransactions.js
@@ -79,7 +79,11 @@ class IOUTransactions extends Component {
{_.map(sortedReportActions, (reportAction) => {
// iouReportIDs should be strings, but we still have places that send them as ints so we convert them both to Numbers for comparison
- if (!reportAction.originalMessage || Number(reportAction.originalMessage.IOUReportID) !== Number(this.props.iouReportID)) {
+ if (
+ !reportAction.originalMessage ||
+ reportAction.actionName !== CONST.REPORT.ACTIONS.TYPE.IOU ||
+ Number(reportAction.originalMessage.IOUReportID) !== Number(this.props.iouReportID)
+ ) {
return;
}
diff --git a/tests/actions/IOUTest.js b/tests/actions/IOUTest.js
index aee969e865a1..ade3f9617edd 100644
--- a/tests/actions/IOUTest.js
+++ b/tests/actions/IOUTest.js
@@ -1178,7 +1178,7 @@ describe('actions/IOU', () => {
expect(iouReport.chatReportID).toBe(chatReport.reportID);
expect(chatReport.pendingFields).toBeFalsy();
- expect(chatReport.pendingFields).toBeFalsy();
+ expect(iouReport.pendingFields).toBeFalsy();
// expect(iouReport.status).toBe(CONST.REPORT.STATUS.SUBMITTED);
// expect(iouReport.stateNum).toBe(CONST.REPORT.STATE_NUM.SUBMITTED);