Skip to content

Commit

Permalink
Merge pull request Expensify#54793 from FitseTLT/fix-hold-unhold-scro…
Browse files Browse the repository at this point in the history
…ll-to-bottom-bug

Fix - Page not scroll down when hold and unhold expense
  • Loading branch information
techievivek authored Jan 7, 2025
2 parents e933f4a + fb49ac2 commit 2e2fd1c
Show file tree
Hide file tree
Showing 2 changed files with 179 additions and 1 deletion.
45 changes: 45 additions & 0 deletions src/libs/actions/IOU.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8393,6 +8393,7 @@ function putOnHold(transactionID: string, comment: string, reportID: string, sea
const parentReportActionOptimistic = ReportUtils.getOptimisticDataForParentReportAction(reportID, createdReportActionComment.created, CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD);
const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`];
const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`];
const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];

const optimisticData: OnyxUpdate[] = [
{
Expand All @@ -8418,6 +8419,13 @@ function putOnHold(transactionID: string, comment: string, reportID: string, sea
key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`,
value: updatedViolations,
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {
lastVisibleActionCreated: createdReportActionComment.created,
},
},
];

if (iouReport && iouReport.currency === transaction?.currency) {
Expand Down Expand Up @@ -8463,6 +8471,21 @@ function putOnHold(transactionID: string, comment: string, reportID: string, sea
errors: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('iou.error.genericHoldExpenseFailureMessage'),
},
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`,
value: {
[createdReportAction.reportActionID]: null,
[createdReportActionComment.reportActionID]: null,
},
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {
lastVisibleActionCreated: report?.lastVisibleActionCreated,
},
},
];

// If we are holding from the search page, we optimistically update the snapshot data that search uses so that it is kept in sync
Expand Down Expand Up @@ -8516,6 +8539,7 @@ function unholdRequest(transactionID: string, reportID: string, searchHash?: num
const transactionViolations = allTransactionViolations[`${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`];
const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`];
const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${transaction?.reportID}`];
const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];

const optimisticData: OnyxUpdate[] = [
{
Expand All @@ -8540,6 +8564,13 @@ function unholdRequest(transactionID: string, reportID: string, searchHash?: num
key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`,
value: transactionViolations?.filter((violation) => violation.name !== CONST.VIOLATIONS.HOLD) ?? [],
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {
lastVisibleActionCreated: createdReportAction.created,
},
},
];

if (iouReport && iouReport.currency === transaction?.currency) {
Expand Down Expand Up @@ -8570,6 +8601,13 @@ function unholdRequest(transactionID: string, reportID: string, searchHash?: num
];

const failureData: OnyxUpdate[] = [
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`,
value: {
[createdReportAction.reportActionID]: null,
},
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`,
Expand All @@ -8583,6 +8621,13 @@ function unholdRequest(transactionID: string, reportID: string, searchHash?: num
key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`,
value: transactionViolations ?? null,
},
{
onyxMethod: Onyx.METHOD.MERGE,
key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`,
value: {
lastVisibleActionCreated: report?.lastVisibleActionCreated,
},
},
];

// If we are unholding from the search page, we optimistically update the snapshot data that search uses so that it is kept in sync
Expand Down
135 changes: 134 additions & 1 deletion tests/actions/IOUTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import * as ReportUtils from '@src/libs/ReportUtils';
import ONYXKEYS from '@src/ONYXKEYS';
import ROUTES from '@src/ROUTES';
import type * as OnyxTypes from '@src/types/onyx';
import type {Participant} from '@src/types/onyx/Report';
import type {Participant, ReportCollectionDataSet} from '@src/types/onyx/Report';
import type {ReportActionsCollectionDataSet} from '@src/types/onyx/ReportAction';
import type {TransactionCollectionDataSet} from '@src/types/onyx/Transaction';
import {toCollectionDataSet} from '@src/types/utils/CollectionDataSet';
Expand Down Expand Up @@ -3683,6 +3683,139 @@ describe('actions/IOU', () => {
});
});

describe('putOnHold', () => {
test("should update the transaction thread report's lastVisibleActionCreated to the optimistically added hold comment report action created timestamp", () => {
const iouReport = ReportUtils.buildOptimisticIOUReport(1, 2, 100, '1', 'USD');
const transaction = TransactionUtils.buildOptimisticTransaction({
transactionParams: {
amount: 100,
currency: 'USD',
reportID: iouReport.reportID,
},
});

const transactionCollectionDataSet: TransactionCollectionDataSet = {
[`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`]: transaction,
};
const iouAction: OnyxTypes.ReportAction = ReportUtils.buildOptimisticIOUReportAction(
CONST.IOU.REPORT_ACTION_TYPE.CREATE,
transaction.amount,
transaction.currency,
'',
[],
transaction.transactionID,
);
const transactionThread = ReportUtils.buildTransactionThread(iouAction, iouReport);

const actions: OnyxInputValue<OnyxTypes.ReportActions> = {[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouAction.reportActionID}`]: iouAction};
const reportCollectionDataSet: ReportCollectionDataSet = {
[`${ONYXKEYS.COLLECTION.REPORT}${transactionThread.reportID}`]: transactionThread,
[`${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`]: iouReport,
};
const actionCollectionDataSet: ReportActionsCollectionDataSet = {[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`]: actions};
const comment = 'hold reason';

return waitForBatchedUpdates()
.then(() => Onyx.multiSet({...reportCollectionDataSet, ...transactionCollectionDataSet, ...actionCollectionDataSet}))
.then(() => {
// When an expense is put on hold
IOU.putOnHold(transaction.transactionID, comment, transactionThread.reportID);
return waitForBatchedUpdates();
})
.then(() => {
return new Promise<void>((resolve) => {
const connection = Onyx.connect({
key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThread.reportID}`,
callback: (report) => {
Onyx.disconnect(connection);
const lastVisibleActionCreated = report?.lastVisibleActionCreated;
const connection2 = Onyx.connect({
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThread.reportID}`,
callback: (reportActions) => {
Onyx.disconnect(connection2);
resolve();
const lastAction = ReportActionsUtils.getSortedReportActions(Object.values(reportActions ?? {}), true).at(0);
const message = ReportActionsUtils.getReportActionMessage(lastAction);
// Then the transaction thread report lastVisibleActionCreated should equal the hold comment action created timestamp.
expect(message?.text).toBe(comment);
expect(lastVisibleActionCreated).toBe(lastAction?.created);
},
});
},
});
});
});
});
});

describe('unHoldRequest', () => {
test("should update the transaction thread report's lastVisibleActionCreated to the optimistically added unhold report action created timestamp", () => {
const iouReport = ReportUtils.buildOptimisticIOUReport(1, 2, 100, '1', 'USD');
const transaction = TransactionUtils.buildOptimisticTransaction({
transactionParams: {
amount: 100,
currency: 'USD',
reportID: iouReport.reportID,
},
});

const transactionCollectionDataSet: TransactionCollectionDataSet = {
[`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`]: transaction,
};
const iouAction: OnyxTypes.ReportAction = ReportUtils.buildOptimisticIOUReportAction(
CONST.IOU.REPORT_ACTION_TYPE.CREATE,
transaction.amount,
transaction.currency,
'',
[],
transaction.transactionID,
);
const transactionThread = ReportUtils.buildTransactionThread(iouAction, iouReport);

const actions: OnyxInputValue<OnyxTypes.ReportActions> = {[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouAction.reportActionID}`]: iouAction};
const reportCollectionDataSet: ReportCollectionDataSet = {
[`${ONYXKEYS.COLLECTION.REPORT}${transactionThread.reportID}`]: transactionThread,
[`${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`]: iouReport,
};
const actionCollectionDataSet: ReportActionsCollectionDataSet = {[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`]: actions};
const comment = 'hold reason';

return waitForBatchedUpdates()
.then(() => Onyx.multiSet({...reportCollectionDataSet, ...transactionCollectionDataSet, ...actionCollectionDataSet}))
.then(() => {
IOU.putOnHold(transaction.transactionID, comment, transactionThread.reportID);
return waitForBatchedUpdates();
})
.then(() => {
// When an expense is unhold
IOU.unholdRequest(transaction.transactionID, transactionThread.reportID);
return waitForBatchedUpdates();
})
.then(() => {
return new Promise<void>((resolve) => {
const connection = Onyx.connect({
key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThread.reportID}`,
callback: (report) => {
Onyx.disconnect(connection);
const lastVisibleActionCreated = report?.lastVisibleActionCreated;
const connection2 = Onyx.connect({
key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThread.reportID}`,
callback: (reportActions) => {
Onyx.disconnect(connection2);
resolve();
const lastAction = ReportActionsUtils.getSortedReportActions(Object.values(reportActions ?? {}), true).at(0);
// Then the transaction thread report lastVisibleActionCreated should equal the unhold action created timestamp.
expect(lastAction?.actionName).toBe(CONST.REPORT.ACTIONS.TYPE.UNHOLD);
expect(lastVisibleActionCreated).toBe(lastAction?.created);
},
});
},
});
});
});
});
});

describe('sendInvoice', () => {
it('creates a new invoice chat when one has been converted from individual to business', async () => {
// Mock API.write for this test
Expand Down

0 comments on commit 2e2fd1c

Please sign in to comment.