Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
46 changes: 41 additions & 5 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,35 @@ const ROUTES = {
SEARCH_ADVANCED_FILTERS_POSTED: 'search/filters/posted',
SEARCH_REPORT: {
route: 'search/view/:reportID/:reportActionID?',
getRoute: ({reportID, reportActionID, backTo}: {reportID: string | undefined; reportActionID?: string; backTo?: string}) => {
getRoute: ({
reportID,
reportActionID,
backTo,
moneyRequestReportActionID,
transactionID,
}: {
reportID: string | undefined;
reportActionID?: string;
backTo?: string;
moneyRequestReportActionID?: string;
transactionID?: string;
}) => {
if (!reportID) {
Log.warn('Invalid reportID is used to build the SEARCH_REPORT route');
}
const baseRoute = reportActionID ? (`search/view/${reportID}/${reportActionID}` as const) : (`search/view/${reportID}` as const);
return getUrlWithBackToParam(baseRoute, backTo);

const queryParams = [];

// When we are opening a transaction thread but don't have the transaction report created yet we need to pass the moneyRequestReportActionID and transactionID so we can send those to the OpenReport call and create the transaction report
if (moneyRequestReportActionID && transactionID) {
queryParams.push(`moneyRequestReportActionID=${moneyRequestReportActionID}`);
queryParams.push(`transactionID=${transactionID}`);
}

const queryString = queryParams.length > 0 ? (`${baseRoute}?${queryParams.join('&')}` as const) : baseRoute;

return getUrlWithBackToParam(queryString, backTo);
},
},
SEARCH_MONEY_REQUEST_REPORT: {
Expand Down Expand Up @@ -320,13 +343,26 @@ const ROUTES = {
REPORT: 'r',
REPORT_WITH_ID: {
route: 'r/:reportID?/:reportActionID?',
getRoute: (reportID: string | undefined, reportActionID?: string, referrer?: string) => {
getRoute: (reportID: string | undefined, reportActionID?: string, referrer?: string, moneyRequestReportActionID?: string, transactionID?: string) => {
if (!reportID) {
Log.warn('Invalid reportID is used to build the REPORT_WITH_ID route');
}
const baseRoute = reportActionID ? (`r/${reportID}/${reportActionID}` as const) : (`r/${reportID}` as const);
const referrerParam = referrer ? `?referrer=${encodeURIComponent(referrer)}` : '';
return `${baseRoute}${referrerParam}` as const;

const queryParams: string[] = [];
if (referrer) {
queryParams.push(`referrer=${encodeURIComponent(referrer)}`);
}

// When we are opening a transaction thread but don't have the transaction report created yet we need to pass the moneyRequestReportActionID and transactionID so we can send those to the OpenReport call and create the transaction report
if (moneyRequestReportActionID && transactionID) {
queryParams.push(`moneyRequestReportActionID=${moneyRequestReportActionID}`);
queryParams.push(`transactionID=${transactionID}`);
}

const queryString = queryParams.length > 0 ? `?${queryParams.join('&')}` : '';

return `${baseRoute}${queryString}` as const;
},
},
REPORT_AVATAR: {
Expand Down
14 changes: 13 additions & 1 deletion src/components/ReportActionItem/MoneyRequestAction.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ import useThemeStyles from '@hooks/useThemeStyles';
import {isIOUReportPendingCurrencyConversion} from '@libs/IOUUtils';
import Navigation from '@libs/Navigation/Navigation';
import {
getOriginalMessage,
isDeletedParentAction as isDeletedParentActionReportActionsUtils,
isMoneyRequestAction,
isReversedTransaction as isReversedTransactionReportActionsUtils,
isSplitBillAction as isSplitBillActionReportActionsUtils,
isTrackExpenseAction as isTrackExpenseActionReportActionsUtils,
} from '@libs/ReportActionsUtils';
import {contextMenuRef} from '@pages/home/report/ContextMenu/ReportActionContextMenu';
import {generateReportID} from '@libs/ReportUtils';
import type {ContextMenuAnchor} from '@pages/home/report/ContextMenu/ReportActionContextMenu';
import {contextMenuRef} from '@pages/home/report/ContextMenu/ReportActionContextMenu';
import CONST from '@src/CONST';
import type {TranslationPaths} from '@src/languages/types';
import ONYXKEYS from '@src/ONYXKEYS';
Expand Down Expand Up @@ -90,6 +93,15 @@ function MoneyRequestAction({
return;
}

// In case the childReportID is not present it probably means the transaction thread was not created yet,
// so we need to send the parentReportActionID and the transactionID to the route so we can call OpenReport correctly
const transactionID = isMoneyRequestAction(action) ? getOriginalMessage(action)?.IOUTransactionID : CONST.DEFAULT_NUMBER_ID;
if (!action?.childReportID && transactionID && action.reportActionID) {
const optimisticReportID = generateReportID();
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(optimisticReportID, undefined, undefined, action.reportActionID, transactionID));
return;
}

Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(action?.childReportID));
};

Expand Down
17 changes: 13 additions & 4 deletions src/components/Search/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useSearchHighlightAndScroll from '@hooks/useSearchHighlightAndScroll';
import useThemeStyles from '@hooks/useThemeStyles';
import {turnOffMobileSelectionMode, turnOnMobileSelectionMode} from '@libs/actions/MobileSelectionMode';
import {createTransactionThread, search} from '@libs/actions/Search';
import {search, updateSearchResultsWithTransactionThreadReportID} from '@libs/actions/Search';
import {canUseTouchScreen} from '@libs/DeviceCapabilities';
import Log from '@libs/Log';
import isSearchTopmostFullScreenRoute from '@libs/Navigation/helpers/isSearchTopmostFullScreenRoute';
Expand Down Expand Up @@ -298,14 +298,23 @@ function Search({queryJSON, currentSearchResults, lastNonEmptySearchResults, onS
return;
}

const backTo = Navigation.getActiveRoute();

// If we're trying to open a legacy transaction without a transaction thread, let's create the thread and navigate the user
if (isTransactionListItemType(item) && reportID === '0' && item.moneyRequestReportActionID) {
reportID = generateReportID();
createTransactionThread(hash, item.transactionID, reportID, item.moneyRequestReportActionID);
updateSearchResultsWithTransactionThreadReportID(hash, item.transactionID, reportID);
Navigation.navigate(
ROUTES.SEARCH_REPORT.getRoute({
reportID,
backTo,
moneyRequestReportActionID: item.moneyRequestReportActionID,
transactionID: item.transactionID,
}),
);
return;
}

const backTo = Navigation.getActiveRoute();

if (canUseTableReportView && isReportListItemType(item)) {
Navigation.navigate(ROUTES.SEARCH_MONEY_REQUEST_REPORT.getRoute({reportID, backTo}));
return;
Expand Down
2 changes: 2 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1616,6 +1616,8 @@ type ReportsSplitNavigatorParamList = {
reportID: string;
openOnAdminRoom?: boolean;
referrer?: string;
moneyRequestReportActionID?: string;
transactionID?: string;
};
};

Expand Down
15 changes: 2 additions & 13 deletions src/libs/actions/Search.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,6 @@ import ONYXKEYS from '@src/ONYXKEYS';
import FILTER_KEYS from '@src/types/form/SearchAdvancedFiltersForm';
import type {LastPaymentMethod, LastPaymentMethodType, SearchResults} from '@src/types/onyx';
import type {SearchPolicy, SearchReport, SearchTransaction} from '@src/types/onyx/SearchResults';
import {openReport} from './Report';

let currentUserEmail: string;
Onyx.connect({
key: ONYXKEYS.SESSION,
callback: (val) => {
currentUserEmail = val?.email ?? '';
},
});

let lastPaymentMethod: OnyxEntry<LastPaymentMethod>;
Onyx.connect({
Expand Down Expand Up @@ -262,9 +253,7 @@ function search({queryJSON, offset}: {queryJSON: SearchQueryJSON; offset?: numbe
* It's possible that we return legacy transactions that don't have a transaction thread created yet.
* In that case, when users select the search result row, we need to create the transaction thread on the fly and update the search result with the new transactionThreadReport
*/
function createTransactionThread(hash: number, transactionID: string, reportID: string, moneyRequestReportActionID: string) {
openReport(reportID, '', [currentUserEmail], undefined, moneyRequestReportActionID);

function updateSearchResultsWithTransactionThreadReportID(hash: number, transactionID: string, reportID: string) {
const onyxUpdate: Record<string, Record<string, Partial<SearchTransaction>>> = {
data: {
[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]: {
Expand Down Expand Up @@ -422,7 +411,7 @@ function clearAdvancedFilters() {
export {
saveSearch,
search,
createTransactionThread,
updateSearchResultsWithTransactionThreadReportID,
deleteMoneyRequestOnSearch,
holdMoneyRequestOnSearch,
unholdMoneyRequestOnSearch,
Expand Down
12 changes: 11 additions & 1 deletion src/pages/home/ReportScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ function ReportScreen({route, navigation}: ReportScreenProps) {
const [isLinkingToMessage, setIsLinkingToMessage] = useState(!!reportActionIDFromRoute);

const [currentUserAccountID = -1] = useOnyx(ONYXKEYS.SESSION, {selector: (value) => value?.accountID});
const [currentUserEmail] = useOnyx(ONYXKEYS.SESSION, {selector: (value) => value?.email});
const [isLoadingApp] = useOnyx(ONYXKEYS.IS_LOADING_APP);
const {reportActions, linkedAction, sortedAllReportActions, hasNewerActions, hasOlderActions} = usePaginatedReportActions(reportID, reportActionIDFromRoute);

Expand Down Expand Up @@ -427,8 +428,17 @@ function ReportScreen({route, navigation}: ReportScreenProps) {
);

const fetchReport = useCallback(() => {
const moneyRequestReportActionID: string | undefined = route.params?.moneyRequestReportActionID;
const transactionID: string | undefined = route.params?.transactionID;

// When we get here with a moneyRequestReportActionID and a transactionID from the route it means we don't have the trasaction thread created yet
// so we have to call OpenReport in a way that the transaction thread will be created and attached to the parentReportAction
if (moneyRequestReportActionID && transactionID && currentUserEmail) {
openReport(reportIDFromRoute, '', [currentUserEmail], undefined, moneyRequestReportActionID);
return;
}
openReport(reportIDFromRoute, reportActionIDFromRoute);
}, [reportIDFromRoute, reportActionIDFromRoute]);
}, [route.params?.moneyRequestReportActionID, route.params?.transactionID, reportIDFromRoute, reportActionIDFromRoute, currentUserEmail]);

useEffect(() => {
if (!reportID || !isFocused) {
Expand Down