Skip to content

Commit 12ff528

Browse files
committed
88960 correctly find search navigator and fallback to default query if it was not mounted yet
1 parent f8263d4 commit 12ff528

2 files changed

Lines changed: 113 additions & 101 deletions

File tree

src/libs/SearchQueryUtils.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,14 +1856,18 @@ function getQueryWithUpdatedValues(query: string, shouldSkipAmountConversion = f
18561856

18571857
function getCurrentSearchQueryJSON() {
18581858
const rootState = navigationRef.getRootState();
1859-
const lastSearchNavigator = rootState?.routes?.findLast((route) => route.name === NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR);
1860-
1859+
const lastTabNavigator = rootState?.routes?.findLast((route) => route.name === NAVIGATORS.TAB_NAVIGATOR);
1860+
const lastSearchNavigator = lastTabNavigator?.state?.routes?.findLast((route) => route.name === NAVIGATORS.SEARCH_FULLSCREEN_NAVIGATOR);
18611861
let lastSearchNavigatorState = lastSearchNavigator?.state;
18621862
if (!lastSearchNavigatorState) {
18631863
lastSearchNavigatorState = lastSearchNavigator?.key ? getPreservedNavigatorState(lastSearchNavigator?.key) : undefined;
18641864
}
1865+
1866+
// When the SearchFullscreenNavigator has never been mounted (e.g. lazy tab not yet visited),
1867+
// neither .state nor the preserved state map will have an entry. Fall back to the default
1868+
// query that the navigator would use as its initialParams.
18651869
if (!lastSearchNavigatorState) {
1866-
return;
1870+
return buildSearchQueryJSON(buildSearchQueryString());
18671871
}
18681872

18691873
const lastSearchRoute = lastSearchNavigatorState.routes.findLast((route) => route.name === SCREENS.SEARCH.ROOT);

src/libs/actions/IOU/index.ts

Lines changed: 106 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -2575,17 +2575,23 @@ function shouldOptimisticallyUpdateSearch(
25752575
(isInvoice && currentSearchQueryJSON.type === CONST.SEARCH.DATA_TYPES.INVOICE) ||
25762576
(iouReport?.type === CONST.REPORT.TYPE.EXPENSE && currentSearchQueryJSON.type === CONST.SEARCH.DATA_TYPES.EXPENSE_REPORT);
25772577

2578-
return (
2579-
shouldOptimisticallyUpdateByStatus &&
2580-
validSearchTypes &&
2581-
(currentSearchQueryJSON.flatFilters.length === 0 ||
2582-
(submitQueryJSON?.similarSearchHash === currentSearchQueryJSON.similarSearchHash && expenseReportStatusFilterMapping[CONST.SEARCH.STATUS.EXPENSE.DRAFTS](iouReport)) ||
2583-
(approveQueryJSON?.similarSearchHash === currentSearchQueryJSON.similarSearchHash && expenseReportStatusFilterMapping[CONST.SEARCH.STATUS.EXPENSE.OUTSTANDING](iouReport)) ||
2584-
(unapprovedCashSimilarSearchHash === currentSearchQueryJSON.similarSearchHash &&
2585-
isExpenseReport(iouReport) &&
2586-
(expenseReportStatusFilterMapping[CONST.SEARCH.STATUS.EXPENSE.DRAFTS](iouReport) || expenseReportStatusFilterMapping[CONST.SEARCH.STATUS.EXPENSE.OUTSTANDING](iouReport)) &&
2587-
transaction?.reimbursable))
2588-
);
2578+
const hasNoFlatFilters = currentSearchQueryJSON.flatFilters.length === 0;
2579+
2580+
const matchesSubmitQuery =
2581+
submitQueryJSON?.similarSearchHash === currentSearchQueryJSON.similarSearchHash && expenseReportStatusFilterMapping[CONST.SEARCH.STATUS.EXPENSE.DRAFTS](iouReport);
2582+
2583+
const matchesApproveQuery =
2584+
approveQueryJSON?.similarSearchHash === currentSearchQueryJSON.similarSearchHash && expenseReportStatusFilterMapping[CONST.SEARCH.STATUS.EXPENSE.OUTSTANDING](iouReport);
2585+
2586+
const matchesUnapprovedCashQuery =
2587+
unapprovedCashSimilarSearchHash === currentSearchQueryJSON.similarSearchHash &&
2588+
isExpenseReport(iouReport) &&
2589+
(expenseReportStatusFilterMapping[CONST.SEARCH.STATUS.EXPENSE.DRAFTS](iouReport) || expenseReportStatusFilterMapping[CONST.SEARCH.STATUS.EXPENSE.OUTSTANDING](iouReport)) &&
2590+
transaction?.reimbursable;
2591+
2592+
const matchesFilterQuery = hasNoFlatFilters || matchesSubmitQuery || matchesApproveQuery || matchesUnapprovedCashQuery;
2593+
2594+
return shouldOptimisticallyUpdateByStatus && validSearchTypes && matchesFilterQuery;
25892595
}
25902596

25912597
function getSearchOnyxUpdate({
@@ -2602,108 +2608,110 @@ function getSearchOnyxUpdate({
26022608
const fromAccountID = deprecatedCurrentUserPersonalDetails?.accountID;
26032609
const currentSearchQueryJSON = getCurrentSearchQueryJSON();
26042610

2605-
if (currentSearchQueryJSON && toAccountID != null && fromAccountID != null) {
2606-
if (shouldOptimisticallyUpdateSearch(currentSearchQueryJSON, iouReport, isInvoice, transaction)) {
2607-
const isOptimisticToAccountData = isOptimisticPersonalDetail(toAccountID);
2608-
const successData = [];
2609-
if (isOptimisticToAccountData) {
2610-
// The optimistic personal detail is removed on the API's success data but we can't change the managerID of the transaction in the snapshot.
2611-
// So we need to add the optimistic personal detail back to the snapshot in success data to prevent the flickering.
2612-
// After that, it will be cleared via Search API.
2613-
// See https://github.com/Expensify/App/issues/61310 for more information.
2614-
successData.push({
2615-
onyxMethod: Onyx.METHOD.MERGE,
2616-
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${currentSearchQueryJSON.hash}` as const,
2617-
value: {
2618-
data: {
2619-
[ONYXKEYS.PERSONAL_DETAILS_LIST]: {
2620-
[toAccountID]: {
2621-
accountID: toAccountID,
2622-
displayName: participant?.displayName,
2623-
login: participant?.login,
2624-
},
2611+
if (!currentSearchQueryJSON || toAccountID === undefined || fromAccountID === undefined) {
2612+
return;
2613+
}
2614+
2615+
if (shouldOptimisticallyUpdateSearch(currentSearchQueryJSON, iouReport, isInvoice, transaction)) {
2616+
const isOptimisticToAccountData = isOptimisticPersonalDetail(toAccountID);
2617+
const successData = [];
2618+
if (isOptimisticToAccountData) {
2619+
// The optimistic personal detail is removed on the API's success data but we can't change the managerID of the transaction in the snapshot.
2620+
// So we need to add the optimistic personal detail back to the snapshot in success data to prevent the flickering.
2621+
// After that, it will be cleared via Search API.
2622+
// See https://github.com/Expensify/App/issues/61310 for more information.
2623+
successData.push({
2624+
onyxMethod: Onyx.METHOD.MERGE,
2625+
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${currentSearchQueryJSON.hash}` as const,
2626+
value: {
2627+
data: {
2628+
[ONYXKEYS.PERSONAL_DETAILS_LIST]: {
2629+
[toAccountID]: {
2630+
accountID: toAccountID,
2631+
displayName: participant?.displayName,
2632+
login: participant?.login,
26252633
},
26262634
},
26272635
},
2628-
});
2629-
}
2630-
const snapshotData = {
2631-
[ONYXKEYS.PERSONAL_DETAILS_LIST]: {
2632-
[toAccountID]: {
2633-
accountID: toAccountID,
2634-
displayName: participant?.displayName,
2635-
login: participant?.login,
2636-
},
2637-
[fromAccountID]: {
2638-
accountID: fromAccountID,
2639-
avatar: deprecatedCurrentUserPersonalDetails?.avatar,
2640-
displayName: deprecatedCurrentUserPersonalDetails?.displayName,
2641-
login: deprecatedCurrentUserPersonalDetails?.login,
2642-
},
26432636
},
2644-
[`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`]: {
2637+
});
2638+
}
2639+
const snapshotData = {
2640+
[ONYXKEYS.PERSONAL_DETAILS_LIST]: {
2641+
[toAccountID]: {
2642+
accountID: toAccountID,
2643+
displayName: participant?.displayName,
2644+
login: participant?.login,
2645+
},
2646+
[fromAccountID]: {
26452647
accountID: fromAccountID,
2646-
managerID: toAccountID,
2647-
...(transactionThreadReportID && {transactionThreadReportID}),
2648-
...(isFromOneTransactionReport && {isFromOneTransactionReport}),
2649-
...transaction,
2648+
avatar: deprecatedCurrentUserPersonalDetails?.avatar,
2649+
displayName: deprecatedCurrentUserPersonalDetails?.displayName,
2650+
login: deprecatedCurrentUserPersonalDetails?.login,
26502651
},
2651-
...(policy && {[`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`]: policy}),
2652-
...(iouReport && {[`${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`]: iouReport}),
2653-
...(iouReport && iouAction && {[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`]: {[iouAction.reportActionID]: iouAction}}),
2654-
};
2652+
},
2653+
[`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`]: {
2654+
accountID: fromAccountID,
2655+
managerID: toAccountID,
2656+
...(transactionThreadReportID && {transactionThreadReportID}),
2657+
...(isFromOneTransactionReport && {isFromOneTransactionReport}),
2658+
...transaction,
2659+
},
2660+
...(policy && {[`${ONYXKEYS.COLLECTION.POLICY}${policy.id}`]: policy}),
2661+
...(iouReport && {[`${ONYXKEYS.COLLECTION.REPORT}${iouReport.reportID}`]: iouReport}),
2662+
...(iouReport && iouAction && {[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`]: {[iouAction.reportActionID]: iouAction}}),
2663+
};
26552664

2656-
const optimisticData: Array<OnyxUpdate<typeof ONYXKEYS.COLLECTION.SNAPSHOT>> = [
2657-
{
2665+
const optimisticData: Array<OnyxUpdate<typeof ONYXKEYS.COLLECTION.SNAPSHOT>> = [
2666+
{
2667+
onyxMethod: Onyx.METHOD.MERGE,
2668+
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${currentSearchQueryJSON.hash}` as const,
2669+
value: {
2670+
// @ts-expect-error - will be solved in https://github.com/Expensify/App/issues/73830
2671+
data: snapshotData,
2672+
},
2673+
},
2674+
];
2675+
2676+
if (currentSearchQueryJSON.groupBy === CONST.SEARCH.GROUP_BY.FROM) {
2677+
const newFlatFilters = currentSearchQueryJSON.flatFilters.filter((filter) => filter.key !== CONST.SEARCH.SYNTAX_FILTER_KEYS.FROM);
2678+
newFlatFilters.push({
2679+
key: CONST.SEARCH.SYNTAX_FILTER_KEYS.FROM,
2680+
filters: [{operator: CONST.SEARCH.SYNTAX_OPERATORS.EQUAL_TO, value: fromAccountID}],
2681+
});
2682+
2683+
const groupTransactionsQueryJSON = buildSearchQueryJSON(
2684+
buildSearchQueryString({
2685+
...currentSearchQueryJSON,
2686+
groupBy: undefined,
2687+
flatFilters: newFlatFilters,
2688+
}),
2689+
);
2690+
2691+
if (groupTransactionsQueryJSON?.hash) {
2692+
optimisticData.push({
26582693
onyxMethod: Onyx.METHOD.MERGE,
2659-
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${currentSearchQueryJSON.hash}` as const,
2694+
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${groupTransactionsQueryJSON.hash}` as const,
26602695
value: {
2696+
search: {
2697+
type: groupTransactionsQueryJSON.type,
2698+
status: groupTransactionsQueryJSON.status,
2699+
offset: 0,
2700+
hasMoreResults: false,
2701+
hasResults: true,
2702+
isLoading: false,
2703+
},
26612704
// @ts-expect-error - will be solved in https://github.com/Expensify/App/issues/73830
26622705
data: snapshotData,
26632706
},
2664-
},
2665-
];
2666-
2667-
if (currentSearchQueryJSON.groupBy === CONST.SEARCH.GROUP_BY.FROM) {
2668-
const newFlatFilters = currentSearchQueryJSON.flatFilters.filter((filter) => filter.key !== CONST.SEARCH.SYNTAX_FILTER_KEYS.FROM);
2669-
newFlatFilters.push({
2670-
key: CONST.SEARCH.SYNTAX_FILTER_KEYS.FROM,
2671-
filters: [{operator: CONST.SEARCH.SYNTAX_OPERATORS.EQUAL_TO, value: fromAccountID}],
26722707
});
2673-
2674-
const groupTransactionsQueryJSON = buildSearchQueryJSON(
2675-
buildSearchQueryString({
2676-
...currentSearchQueryJSON,
2677-
groupBy: undefined,
2678-
flatFilters: newFlatFilters,
2679-
}),
2680-
);
2681-
2682-
if (groupTransactionsQueryJSON?.hash) {
2683-
optimisticData.push({
2684-
onyxMethod: Onyx.METHOD.MERGE,
2685-
key: `${ONYXKEYS.COLLECTION.SNAPSHOT}${groupTransactionsQueryJSON.hash}` as const,
2686-
value: {
2687-
search: {
2688-
type: groupTransactionsQueryJSON.type,
2689-
status: groupTransactionsQueryJSON.status,
2690-
offset: 0,
2691-
hasMoreResults: false,
2692-
hasResults: true,
2693-
isLoading: false,
2694-
},
2695-
// @ts-expect-error - will be solved in https://github.com/Expensify/App/issues/73830
2696-
data: snapshotData,
2697-
},
2698-
});
2699-
}
27002708
}
2701-
2702-
return {
2703-
optimisticData,
2704-
successData,
2705-
};
27062709
}
2710+
2711+
return {
2712+
optimisticData,
2713+
successData,
2714+
};
27072715
}
27082716
}
27092717

0 commit comments

Comments
 (0)