Skip to content

Commit 9ac9e98

Browse files
authored
Merge pull request Expensify#85783 from truph01/fix/66381-part-1
Remove Onyx.connect() key ONYXKEYS.COLLECTION.REPORT_ACTIONS in src/libs/OptionsListUtils.ts - part 1
2 parents 675c669 + 65ab43c commit 9ac9e98

14 files changed

Lines changed: 1051 additions & 21 deletions

File tree

src/ONYXKEYS.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,6 +1053,7 @@ const ONYXKEYS = {
10531053
PERSONAL_AND_WORKSPACE_CARD_LIST: 'personalAndWorkspaceCardList',
10541054
CARD_FEED_ERRORS: 'cardFeedErrors',
10551055
TODOS: 'todos',
1056+
SORTED_REPORT_ACTIONS: 'sortedReportActions',
10561057
},
10571058

10581059
/** Stores HybridApp specific state required to interoperate with OldDot */
@@ -1487,6 +1488,7 @@ type OnyxDerivedValuesMapping = {
14871488
[ONYXKEYS.DERIVED.PERSONAL_AND_WORKSPACE_CARD_LIST]: OnyxTypes.PersonalAndWorkspaceCardListDerivedValue;
14881489
[ONYXKEYS.DERIVED.CARD_FEED_ERRORS]: OnyxTypes.CardFeedErrorsDerivedValue;
14891490
[ONYXKEYS.DERIVED.TODOS]: OnyxTypes.TodosDerivedValue;
1491+
[ONYXKEYS.DERIVED.SORTED_REPORT_ACTIONS]: OnyxTypes.SortedReportActionsDerivedValue;
14901492
};
14911493

14921494
type OnyxValues = OnyxValuesMapping & OnyxCollectionValuesMapping & OnyxFormValuesMapping & OnyxFormDraftValuesMapping & OnyxDerivedValuesMapping;

src/hooks/useSearchSelector.base.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import {sortedActionsSelector} from '@selectors/SortedReportActions';
12
import {useCallback, useMemo, useState} from 'react';
23
import type {PermissionStatus} from 'react-native-permissions';
34
import {usePersonalDetails} from '@components/OnyxListItemProvider';
@@ -7,7 +8,7 @@ import {getEmptyOptions, getPersonalDetailSearchTerms, getSearchOptions, getSear
78
import type {OptionData} from '@libs/ReportUtils';
89
import CONST from '@src/CONST';
910
import ONYXKEYS from '@src/ONYXKEYS';
10-
import type {PersonalDetails} from '@src/types/onyx';
11+
import type * as OnyxTypes from '@src/types/onyx';
1112
import useCurrentUserPersonalDetails from './useCurrentUserPersonalDetails';
1213
import useDebounce from './useDebounce';
1314
import useDebouncedState from './useDebouncedState';
@@ -69,7 +70,7 @@ type UseSearchSelectorConfig = {
6970
shouldInitialize?: boolean;
7071

7172
/** Additional contact options to merge (used by platform-specific implementations) */
72-
contactOptions?: Array<SearchOption<PersonalDetails>>;
73+
contactOptions?: Array<SearchOption<OnyxTypes.PersonalDetails>>;
7374

7475
/** Whether to filter with recent attendees */
7576
recentAttendees?: Array<Partial<OptionData>>;
@@ -83,7 +84,7 @@ type ContactState = {
8384
permissionStatus: PermissionStatus;
8485

8586
/** Contact options from device */
86-
contactOptions: Array<SearchOption<PersonalDetails>>;
87+
contactOptions: Array<SearchOption<OnyxTypes.PersonalDetails>>;
8788

8889
/** Whether to show import UI */
8990
showImportUI: boolean;
@@ -193,6 +194,7 @@ function useSearchSelectorBase({
193194
const [draftComments] = useOnyx(ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT);
194195
const [nvpDismissedProductTraining] = useOnyx(ONYXKEYS.NVP_DISMISSED_PRODUCT_TRAINING);
195196
const [visibleReportActionsData] = useOnyx(ONYXKEYS.DERIVED.VISIBLE_REPORT_ACTIONS);
197+
const [sortedActions] = useOnyx(ONYXKEYS.DERIVED.SORTED_REPORT_ACTIONS, {selector: sortedActionsSelector});
196198
const currentUserPersonalDetails = useCurrentUserPersonalDetails();
197199
const currentUserAccountID = currentUserPersonalDetails.accountID;
198200
const currentUserEmail = currentUserPersonalDetails.email ?? '';
@@ -255,6 +257,7 @@ function useSearchSelectorBase({
255257
countryCode,
256258
reportAttributesDerived: reportAttributesDerived?.reports,
257259
allPolicyTags,
260+
sortedActions,
258261
});
259262
case CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_GENERAL:
260263
return getValidOptions(optionsWithContacts, allPolicies, draftComments, nvpDismissedProductTraining, loginList, currentUserAccountID, currentUserEmail, {
@@ -276,6 +279,7 @@ function useSearchSelectorBase({
276279
countryCode,
277280
reportAttributesDerived: reportAttributesDerived?.reports,
278281
allPolicyTags,
282+
sortedActions,
279283
...getValidOptionsConfig,
280284
});
281285
case CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_SHARE_DESTINATION:
@@ -300,6 +304,7 @@ function useSearchSelectorBase({
300304
countryCode,
301305
reportAttributesDerived: reportAttributesDerived?.reports,
302306
allPolicyTags,
307+
sortedActions,
303308
});
304309
case CONST.SEARCH_SELECTOR.SEARCH_CONTEXT_ATTENDEES:
305310
return getValidOptions(optionsWithContacts, allPolicies, draftComments, nvpDismissedProductTraining, loginList, currentUserAccountID, currentUserEmail, {
@@ -321,6 +326,7 @@ function useSearchSelectorBase({
321326
countryCode,
322327
reportAttributesDerived: reportAttributesDerived?.reports,
323328
allPolicyTags,
329+
sortedActions,
324330
...getValidOptionsConfig,
325331
});
326332
default:
@@ -356,6 +362,7 @@ function useSearchSelectorBase({
356362
selectedOptions,
357363
visibleReportActionsData,
358364
allPolicyTags,
365+
sortedActions,
359366
]);
360367

361368
const isOptionSelected = useMemo(() => {

src/libs/OptionsListUtils/index.ts

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -215,38 +215,45 @@ Onyx.connect({
215215
},
216216
});
217217

218-
const lastReportActions: ReportActions = {};
219-
const allSortedReportActions: Record<string, ReportAction[]> = {};
220-
const cachedOneTransactionThreadReportIDs: Record<string, string | undefined> = {};
221-
let allReportActions: OnyxCollection<ReportActions>;
218+
/** @deprecated Use sortedReportActionsData from ONYXKEYS.DERIVED.SORTED_REPORT_ACTIONS instead. Will be removed once all flows are migrated. */
219+
const deprecatedLastReportActions: ReportActions = {};
220+
/** @deprecated Use sortedReportActionsData from ONYXKEYS.DERIVED.SORTED_REPORT_ACTIONS instead. Will be removed once all flows are migrated. */
221+
const deprecatedAllSortedReportActions: Record<string, ReportAction[]> = {};
222+
/** @deprecated Use sortedReportActionsData from ONYXKEYS.DERIVED.SORTED_REPORT_ACTIONS instead. Will be removed once all flows are migrated. */
223+
const deprecatedCachedOneTransactionThreadReportIDs: Record<string, string | undefined> = {};
224+
/** @deprecated Use sortedReportActionsData from ONYXKEYS.DERIVED.SORTED_REPORT_ACTIONS instead. Will be removed once all flows are migrated. */
225+
let deprecatedAllReportActions: OnyxCollection<ReportActions>;
222226
Onyx.connect({
223227
key: ONYXKEYS.COLLECTION.REPORT_ACTIONS,
224228
waitForCollectionCallback: true,
225229
callback: (actions) => {
226230
if (!actions) {
227231
return;
228232
}
229-
230-
allReportActions = actions ?? {};
233+
// eslint-disable-next-line @typescript-eslint/no-deprecated
234+
deprecatedAllReportActions = actions ?? {};
231235

232236
// Iterate over the report actions to build the sorted report actions objects
233-
for (const reportActions of Object.entries(allReportActions)) {
237+
// eslint-disable-next-line @typescript-eslint/no-deprecated
238+
for (const reportActions of Object.entries(deprecatedAllReportActions)) {
234239
const reportID = reportActions[0].split('_').at(1);
235240
if (!reportID) {
236241
continue;
237242
}
238243

239244
const reportActionsArray = Object.values(reportActions[1] ?? {});
240245
let sortedReportActions = getSortedReportActions(withDEWRoutedActionsArray(reportActionsArray), true);
241-
allSortedReportActions[reportID] = sortedReportActions;
246+
// eslint-disable-next-line @typescript-eslint/no-deprecated
247+
deprecatedAllSortedReportActions[reportID] = sortedReportActions;
242248
const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`];
243249
const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.chatReportID}`];
244250

245251
// If the report is a one-transaction report, we need to return the combined reportActions so that the LHN can display modifications
246252
// to the transaction thread or the report itself.
247253
// Cache the result for O(1) lookup in renderItem.
248254
const transactionThreadReportID = getOneTransactionThreadReportID(report, chatReport, actions[reportActions[0]]);
249-
cachedOneTransactionThreadReportIDs[reportID] = transactionThreadReportID;
255+
// eslint-disable-next-line @typescript-eslint/no-deprecated
256+
deprecatedCachedOneTransactionThreadReportIDs[reportID] = transactionThreadReportID;
250257

251258
if (transactionThreadReportID) {
252259
const transactionThreadReportActionsArray = Object.values(actions[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReportID}`] ?? {});
@@ -255,9 +262,11 @@ Onyx.connect({
255262

256263
const firstReportAction = sortedReportActions.at(0);
257264
if (!firstReportAction) {
258-
delete lastReportActions[reportID];
265+
// eslint-disable-next-line @typescript-eslint/no-deprecated
266+
delete deprecatedLastReportActions[reportID];
259267
} else {
260-
lastReportActions[reportID] = firstReportAction;
268+
// eslint-disable-next-line @typescript-eslint/no-deprecated
269+
deprecatedLastReportActions[reportID] = firstReportAction;
261270
}
262271
}
263272
},
@@ -618,7 +627,8 @@ function getLastMessageTextForReport({
618627
const canUserPerformWrite = canUserPerformWriteAction(report, isReportArchived);
619628
let lastReportAction = lastAction ?? getLastVisibleAction(reportID, canUserPerformWrite, {}, undefined, visibleReportActionsDataParam);
620629

621-
const transactionThreadReportID = reportID ? cachedOneTransactionThreadReportIDs[reportID] : undefined;
630+
// eslint-disable-next-line @typescript-eslint/no-deprecated
631+
const transactionThreadReportID = reportID ? deprecatedCachedOneTransactionThreadReportIDs[reportID] : undefined;
622632

623633
if (reportID && !lastAction && transactionThreadReportID) {
624634
lastReportAction =
@@ -648,7 +658,8 @@ function getLastMessageTextForReport({
648658
}
649659

650660
// some types of actions are filtered out for lastReportAction, in some cases we need to check the actual last action
651-
const lastOriginalReportAction = reportID ? lastReportActions[reportID] : undefined;
661+
// eslint-disable-next-line @typescript-eslint/no-deprecated
662+
const lastOriginalReportAction = reportID ? deprecatedLastReportActions[reportID] : undefined;
652663
let lastMessageTextFromReport = '';
653664

654665
if (isArchivedNonExpenseReport(report, isReportArchived)) {
@@ -681,7 +692,8 @@ function getLastMessageTextForReport({
681692
const iouReportID = iouReport?.reportID;
682693
const reportCache = iouReportID ? visibleReportActionsDataParam?.[iouReportID] : undefined;
683694
const visibleReportActionsForIOUReport = reportCache && Object.keys(reportCache).length > 0 ? visibleReportActionsDataParam : undefined;
684-
const iouReportActions = iouReportID ? allSortedReportActions[iouReportID] : undefined;
695+
// eslint-disable-next-line @typescript-eslint/no-deprecated
696+
const iouReportActions = iouReportID ? deprecatedAllSortedReportActions[iouReportID] : undefined;
685697
const canPerformWrite = canUserPerformWriteAction(report, isReportArchived);
686698
const lastIOUMoneyReportAction =
687699
iouReportID && iouReportActions
@@ -2253,6 +2265,8 @@ function prepareReportOptionsForDisplay(
22532265
config: GetValidReportsConfig,
22542266
visibleReportActionsData: VisibleReportActionsDerivedValue = {},
22552267
reportAttributesDerived?: ReportAttributesDerivedValue['reports'],
2268+
// eslint-disable-next-line @typescript-eslint/no-deprecated
2269+
sortedActions: Record<string, ReportAction[]> = deprecatedAllSortedReportActions,
22562270
policyTags?: OnyxCollection<PolicyTagLists>,
22572271
): Array<SearchOption<Report>> {
22582272
const {
@@ -2305,7 +2319,7 @@ function prepareReportOptionsForDisplay(
23052319
const chatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.chatReportID}`];
23062320
const oneTransactionThreadReportID =
23072321
report.type === CONST.REPORT.TYPE.IOU || report.type === CONST.REPORT.TYPE.EXPENSE || report.type === CONST.REPORT.TYPE.INVOICE
2308-
? getOneTransactionThreadReportID(report, chatReport, allSortedReportActions[report.reportID])
2322+
? getOneTransactionThreadReportID(report, chatReport, sortedActions[report.reportID])
23092323
: undefined;
23102324
const oneTransactionThreadReport = oneTransactionThreadReportID ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${oneTransactionThreadReportID}`] : undefined;
23112325

@@ -2315,11 +2329,11 @@ function prepareReportOptionsForDisplay(
23152329
let lastIOUCreationDate;
23162330
// Add a field to sort the recent reports by the time of last IOU request for create actions
23172331
if (preferRecentExpenseReports) {
2318-
const reportPreviewAction = allSortedReportActions[option.reportID]?.find((reportAction) => isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW));
2332+
const reportPreviewAction = sortedActions[option.reportID]?.find((reportAction) => isActionOfType(reportAction, CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW));
23192333

23202334
if (reportPreviewAction) {
23212335
const iouReportID = getIOUReportIDFromReportActionPreview(reportPreviewAction);
2322-
const iouReportActions = iouReportID ? (allSortedReportActions[iouReportID] ?? []) : [];
2336+
const iouReportActions = iouReportID ? (sortedActions[iouReportID] ?? []) : [];
23232337
const lastIOUAction = iouReportActions.find((iouAction) => iouAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU);
23242338
if (lastIOUAction) {
23252339
lastIOUCreationDate = lastIOUAction.lastModified;
@@ -2440,6 +2454,7 @@ function getValidOptions(
24402454
countryCode = CONST.DEFAULT_COUNTRY_CODE,
24412455
visibleReportActionsData = {},
24422456
reportAttributesDerived,
2457+
sortedActions,
24432458
...config
24442459
}: GetOptionsConfig = {},
24452460
): Options {
@@ -2545,6 +2560,7 @@ function getValidOptions(
25452560
},
25462561
visibleReportActionsData,
25472562
reportAttributesDerived,
2563+
sortedActions,
25482564
allPolicyTags,
25492565
).at(0);
25502566
}
@@ -2567,6 +2583,7 @@ function getValidOptions(
25672583
},
25682584
visibleReportActionsData,
25692585
reportAttributesDerived,
2586+
sortedActions,
25702587
allPolicyTags,
25712588
);
25722589

@@ -2585,6 +2602,7 @@ function getValidOptions(
25852602
},
25862603
visibleReportActionsData,
25872604
reportAttributesDerived,
2605+
sortedActions,
25882606
allPolicyTags,
25892607
);
25902608
} else if (recentAttendees && recentAttendees?.length > 0) {

src/libs/OptionsListUtils/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type {
1010
PersonalDetailsList,
1111
PolicyTagLists,
1212
Report,
13+
ReportAction,
1314
ReportActions,
1415
ReportAttributesDerivedValue,
1516
TransactionViolation,
@@ -221,6 +222,8 @@ type GetOptionsConfig = {
221222
countryCode?: number;
222223
visibleReportActionsData?: VisibleReportActionsDerivedValue;
223224
reportAttributesDerived?: ReportAttributesDerivedValue['reports'];
225+
// TODO: Remove the optional operator once all call sites pass sortedActions (https://github.com/Expensify/App/issues/66381)
226+
sortedActions?: Record<string, ReportAction[]>;
224227
} & GetValidReportsConfig;
225228

226229
type GetUserToInviteConfig = {

src/libs/actions/OnyxDerived/ONYX_DERIVED_VALUES.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import outstandingReportsByPolicyIDConfig from './configs/outstandingReportsByPo
66
import personalAndWorkspaceCardListConfig from './configs/personalAndWorkspaceCardList';
77
import reportAttributesConfig from './configs/reportAttributes';
88
import reportTransactionsAndViolationsConfig from './configs/reportTransactionsAndViolations';
9+
import sortedReportActionsConfig from './configs/sortedReportActions';
910
import todosConfig from './configs/todos';
1011
import visibleReportActionsConfig from './configs/visibleReportActions';
1112
import type {OnyxDerivedValueConfig} from './types';
@@ -23,6 +24,7 @@ const ONYX_DERIVED_VALUES = {
2324
[ONYXKEYS.DERIVED.PERSONAL_AND_WORKSPACE_CARD_LIST]: personalAndWorkspaceCardListConfig,
2425
[ONYXKEYS.DERIVED.CARD_FEED_ERRORS]: cardFeedErrorsConfig,
2526
[ONYXKEYS.DERIVED.TODOS]: todosConfig,
27+
[ONYXKEYS.DERIVED.SORTED_REPORT_ACTIONS]: sortedReportActionsConfig,
2628
} as const satisfies {
2729
// eslint-disable-next-line @typescript-eslint/no-explicit-any
2830
[Key in ValueOf<typeof ONYXKEYS.DERIVED>]: OnyxDerivedValueConfig<Key, any>;

0 commit comments

Comments
 (0)