diff --git a/package-lock.json b/package-lock.json index fb1d180847c6..9074b1b8dc58 100644 --- a/package-lock.json +++ b/package-lock.json @@ -103,7 +103,7 @@ "react-native-linear-gradient": "^2.8.1", "react-native-localize": "^2.2.6", "react-native-modal": "^13.0.0", - "react-native-onyx": "2.0.41", + "react-native-onyx": "2.0.32", "react-native-pager-view": "6.2.3", "react-native-pdf": "6.7.3", "react-native-performance": "^5.1.0", @@ -241,7 +241,7 @@ "ts-jest": "^29.1.2", "ts-node": "^10.9.2", "type-fest": "^4.10.2", - "typescript": "^5.4.5", + "typescript": "^5.3.2", "wait-port": "^0.2.9", "webpack": "^5.76.0", "webpack-bundle-analyzer": "^4.5.0", @@ -31485,9 +31485,9 @@ } }, "node_modules/react-native-onyx": { - "version": "2.0.41", - "resolved": "https://registry.npmjs.org/react-native-onyx/-/react-native-onyx-2.0.41.tgz", - "integrity": "sha512-33r0sVBq7MV/GZwRneRt81uxgW8x3YG75VNJvThycB/dkCnGCfbxoVkZADVH3ET3jzfFXy9wnS06sZnZp78zMQ==", + "version": "2.0.32", + "resolved": "https://registry.npmjs.org/react-native-onyx/-/react-native-onyx-2.0.32.tgz", + "integrity": "sha512-tB9wqMJGTLOYfrfplRP+9aq5JdD8w/hV/OZsMAVH+ewbE1zLY8OymUsAsIFdF1v+cB8HhehP569JVLZmhm6bsg==", "dependencies": { "ascii-table": "0.0.9", "fast-equals": "^4.0.3", @@ -36088,10 +36088,9 @@ } }, "node_modules/typescript": { - "version": "5.4.5", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", - "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "version": "5.3.3", "devOptional": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 88b47e803558..42dcce0713e0 100644 --- a/package.json +++ b/package.json @@ -155,7 +155,7 @@ "react-native-linear-gradient": "^2.8.1", "react-native-localize": "^2.2.6", "react-native-modal": "^13.0.0", - "react-native-onyx": "2.0.41", + "react-native-onyx": "2.0.32", "react-native-pager-view": "6.2.3", "react-native-pdf": "6.7.3", "react-native-performance": "^5.1.0", @@ -293,7 +293,7 @@ "ts-jest": "^29.1.2", "ts-node": "^10.9.2", "type-fest": "^4.10.2", - "typescript": "^5.4.5", + "typescript": "^5.3.2", "wait-port": "^0.2.9", "webpack": "^5.76.0", "webpack-bundle-analyzer": "^4.5.0", diff --git a/src/components/AddressForm.tsx b/src/components/AddressForm.tsx index 296ecce7d092..9ad4643e834a 100644 --- a/src/components/AddressForm.tsx +++ b/src/components/AddressForm.tsx @@ -4,6 +4,7 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ErrorUtils from '@libs/ErrorUtils'; import type {MaybePhraseKey} from '@libs/Localize'; +import Navigation from '@libs/Navigation/Navigation'; import * as ValidationUtils from '@libs/ValidationUtils'; import CONST from '@src/CONST'; import type {Country} from '@src/CONST'; @@ -148,6 +149,8 @@ function AddressForm({ label={translate('common.addressLine', {lineNumber: 1})} onValueChange={(data: unknown, key: unknown) => { onAddressChanged(data, key); + // This enforces the country selector to use the country from address instead of the country from URL + Navigation.setParams({country: undefined}); }} defaultValue={street1} renamedInputKeys={{ diff --git a/src/components/AttachmentModal.tsx b/src/components/AttachmentModal.tsx index de98ba79d23c..fb6a8e911e87 100644 --- a/src/components/AttachmentModal.tsx +++ b/src/components/AttachmentModal.tsx @@ -607,6 +607,7 @@ export default withOnyx({ const transactionID = parentReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU ? parentReportAction?.originalMessage.IOUTransactionID ?? '0' : '0'; return `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`; }, + initWithStoredValues: false, }, })(memo(AttachmentModal)); diff --git a/src/components/AvatarWithDisplayName.tsx b/src/components/AvatarWithDisplayName.tsx index 156c27abbc9d..8942bf97a7dd 100644 --- a/src/components/AvatarWithDisplayName.tsx +++ b/src/components/AvatarWithDisplayName.tsx @@ -1,6 +1,6 @@ import React, {useCallback, useEffect, useRef} from 'react'; import {View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import useStyleUtils from '@hooks/useStyleUtils'; @@ -12,7 +12,7 @@ import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {PersonalDetails, PersonalDetailsList, Policy, Report, ReportActions} from '@src/types/onyx'; +import type {PersonalDetails, Policy, Report, ReportActions} from '@src/types/onyx'; import DisplayNames from './DisplayNames'; import MultipleAvatars from './MultipleAvatars'; import ParentNavigationSubtitle from './ParentNavigationSubtitle'; @@ -25,7 +25,7 @@ type AvatarWithDisplayNamePropsWithOnyx = { parentReportActions: OnyxEntry; /** Personal details of all users */ - personalDetails: OnyxEntry; + personalDetails: OnyxCollection; }; type AvatarWithDisplayNameProps = AvatarWithDisplayNamePropsWithOnyx & { diff --git a/src/components/KeyboardAvoidingView/index.ios.tsx b/src/components/KeyboardAvoidingView/index.ios.tsx index 171210eab7ac..a7cd767377ef 100644 --- a/src/components/KeyboardAvoidingView/index.ios.tsx +++ b/src/components/KeyboardAvoidingView/index.ios.tsx @@ -3,7 +3,7 @@ */ import React from 'react'; import {KeyboardAvoidingView as KeyboardAvoidingViewComponent} from 'react-native'; -import type {KeyboardAvoidingViewProps} from './types'; +import type KeyboardAvoidingViewProps from './types'; function KeyboardAvoidingView(props: KeyboardAvoidingViewProps) { // eslint-disable-next-line react/jsx-props-no-spreading diff --git a/src/components/KeyboardAvoidingView/index.tsx b/src/components/KeyboardAvoidingView/index.tsx index c0882ae1e9cc..09ec21e5b219 100644 --- a/src/components/KeyboardAvoidingView/index.tsx +++ b/src/components/KeyboardAvoidingView/index.tsx @@ -3,7 +3,7 @@ */ import React from 'react'; import {View} from 'react-native'; -import type {KeyboardAvoidingViewProps} from './types'; +import type KeyboardAvoidingViewProps from './types'; function KeyboardAvoidingView(props: KeyboardAvoidingViewProps) { const {behavior, contentContainerStyle, enabled, keyboardVerticalOffset, ...rest} = props; diff --git a/src/components/KeyboardAvoidingView/types.ts b/src/components/KeyboardAvoidingView/types.ts index 2c1ef64ced8f..48d354e8b53f 100644 --- a/src/components/KeyboardAvoidingView/types.ts +++ b/src/components/KeyboardAvoidingView/types.ts @@ -1,4 +1,3 @@ -import type {KeyboardAvoidingViewProps} from 'react-native'; +import {KeyboardAvoidingViewProps} from 'react-native'; -// eslint-disable-next-line import/prefer-default-export -export type {KeyboardAvoidingViewProps}; +export default KeyboardAvoidingViewProps; diff --git a/src/languages/types.ts b/src/languages/types.ts index ef984b9e640a..e2e7e26e696b 100644 --- a/src/languages/types.ts +++ b/src/languages/types.ts @@ -1,4 +1,3 @@ -import type {OnyxEntry} from 'react-native-onyx'; import type {ReportAction} from '@src/types/onyx'; import type {Unit} from '@src/types/onyx/Policy'; import type en from './en'; @@ -41,15 +40,15 @@ type LocalTimeParams = { }; type EditActionParams = { - action: OnyxEntry; + action: ReportAction | null; }; type DeleteActionParams = { - action: OnyxEntry; + action: ReportAction | null; }; type DeleteConfirmationParams = { - action: OnyxEntry; + action: ReportAction | null; }; type BeginningOfChatHistoryDomainRoomPartOneParams = { @@ -300,10 +299,11 @@ type DistanceRateOperationsParams = {count: number}; type ReimbursementRateParams = {unit: Unit}; export type { - AddressLineParams, AdminCanceledRequestParams, - AlreadySignedInParams, ApprovedAmountParams, + AddressLineParams, + AlreadySignedInParams, + UserSplitParams, BeginningOfChatHistoryAdminRoomPartOneParams, BeginningOfChatHistoryAnnounceRoomPartOneParams, BeginningOfChatHistoryAnnounceRoomPartTwo, @@ -324,10 +324,8 @@ export type { FormattedMaxLengthParams, GoBackMessageParams, GoToRoomParams, - HeldRequestParams, InstantSummaryParams, LocalTimeParams, - LogSizeParams, LoggedInAsParams, ManagerApprovedAmountParams, ManagerApprovedParams, @@ -341,13 +339,11 @@ export type { PaidElsewhereWithAmountParams, PaidWithExpensifyWithAmountParams, ParentNavigationSummaryParams, - PaySomeoneParams, PayerOwesAmountParams, PayerOwesParams, PayerPaidAmountParams, PayerPaidParams, PayerSettledParams, - ReimbursementRateParams, RemovedTheRequestParams, RenamedRoomActionParams, ReportArchiveReasonsClosedParams, @@ -379,9 +375,7 @@ export type { UntilTimeParams, UpdatedTheDistanceParams, UpdatedTheRequestParams, - UsePlusButtonParams, UserIsAlreadyMemberParams, - UserSplitParams, ViolationsAutoReportedRejectedExpenseParams, ViolationsCashExpenseWithNoReceiptParams, ViolationsConversionSurchargeParams, @@ -398,9 +392,14 @@ export type { ViolationsTaxOutOfPolicyParams, WaitingOnBankAccountParams, WalletProgramParams, + UsePlusButtonParams, WeSentYouMagicSignInLinkParams, WelcomeEnterMagicCodeParams, WelcomeNoteParams, WelcomeToRoomParams, ZipCodeExampleFormatParams, + LogSizeParams, + HeldRequestParams, + PaySomeoneParams, + ReimbursementRateParams, }; diff --git a/src/libs/EmojiUtils.ts b/src/libs/EmojiUtils.ts index 9d82cefe831c..0be7e76a0aa9 100644 --- a/src/libs/EmojiUtils.ts +++ b/src/libs/EmojiUtils.ts @@ -433,7 +433,7 @@ function suggestEmojis(text: string, lang: Locale, limit: number = CONST.AUTO_CO /** * Retrieve preferredSkinTone as Number to prevent legacy 'default' String value */ -const getPreferredSkinToneIndex = (value: OnyxEntry): number => { +const getPreferredSkinToneIndex = (value: string | number | null): number => { if (value !== null && Number.isInteger(Number(value))) { return Number(value); } diff --git a/src/libs/ErrorUtils.ts b/src/libs/ErrorUtils.ts index ecaf563d59d1..3487f05b9c05 100644 --- a/src/libs/ErrorUtils.ts +++ b/src/libs/ErrorUtils.ts @@ -1,5 +1,4 @@ import mapValues from 'lodash/mapValues'; -import type {OnyxEntry} from 'react-native-onyx'; import CONST from '@src/CONST'; import type {TranslationFlatObject, TranslationPaths} from '@src/languages/types'; import type {ErrorFields, Errors} from '@src/types/onyx/OnyxCommon'; @@ -62,7 +61,7 @@ type OnyxDataWithErrors = { errors?: Errors | null; }; -function getLatestErrorMessage(onyxData: OnyxEntry): Localize.MaybePhraseKey { +function getLatestErrorMessage(onyxData: TOnyxData | null): Localize.MaybePhraseKey { const errors = onyxData?.errors ?? {}; if (Object.keys(errors).length === 0) { @@ -73,8 +72,8 @@ function getLatestErrorMessage(onyxData: O return getErrorMessageWithTranslationData(errors[key]); } -function getLatestErrorMessageField(onyxData: OnyxEntry): Errors { - const errors = onyxData?.errors ?? {}; +function getLatestErrorMessageField(onyxData: TOnyxData): Errors { + const errors = onyxData.errors ?? {}; if (Object.keys(errors).length === 0) { return {}; @@ -89,8 +88,8 @@ type OnyxDataWithErrorFields = { errorFields?: ErrorFields; }; -function getLatestErrorField(onyxData: OnyxEntry, fieldName: string): Errors { - const errorsForField = onyxData?.errorFields?.[fieldName] ?? {}; +function getLatestErrorField(onyxData: TOnyxData, fieldName: string): Errors { + const errorsForField = onyxData.errorFields?.[fieldName] ?? {}; if (Object.keys(errorsForField).length === 0) { return {}; @@ -100,8 +99,8 @@ function getLatestErrorField(onyxData return {[key]: getErrorMessageWithTranslationData(errorsForField[key])}; } -function getEarliestErrorField(onyxData: OnyxEntry, fieldName: string): Errors { - const errorsForField = onyxData?.errorFields?.[fieldName] ?? {}; +function getEarliestErrorField(onyxData: TOnyxData, fieldName: string): Errors { + const errorsForField = onyxData.errorFields?.[fieldName] ?? {}; if (Object.keys(errorsForField).length === 0) { return {}; @@ -114,8 +113,8 @@ function getEarliestErrorField(onyxDa /** * Method used to get the latest error field for any field */ -function getLatestErrorFieldForAnyField(onyxData: OnyxEntry): Errors { - const errorFields = onyxData?.errorFields ?? {}; +function getLatestErrorFieldForAnyField(onyxData: TOnyxData): Errors { + const errorFields = onyxData.errorFields ?? {}; if (Object.keys(errorFields).length === 0) { return {}; @@ -190,9 +189,9 @@ export { getErrorMessageWithTranslationData, getErrorsWithTranslationData, getLatestErrorField, - getLatestErrorFieldForAnyField, getLatestErrorMessage, getLatestErrorMessageField, + getLatestErrorFieldForAnyField, getMicroSecondOnyxError, getMicroSecondOnyxErrorObject, isReceiptError, diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 0343fa0b2c56..6a26b1a6cfc2 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -30,7 +30,7 @@ Onyx.connect({ */ function getActivePolicies(policies: OnyxCollection): Policy[] { return Object.values(policies ?? {}).filter( - (policy): policy is Policy => !!policy && policy.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && !!policy.name && !!policy.id, + (policy): policy is Policy => policy !== null && policy && policy.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && !!policy.name && !!policy.id, ); } diff --git a/src/libs/Pusher/pusher.ts b/src/libs/Pusher/pusher.ts index 2c5dda801359..d35d6122aff7 100644 --- a/src/libs/Pusher/pusher.ts +++ b/src/libs/Pusher/pusher.ts @@ -170,7 +170,7 @@ function bindEventToChannel(channel: Channel let data: EventData; try { - data = isObject(eventData) ? eventData : JSON.parse(eventData as string); + data = isObject(eventData) ? eventData : JSON.parse(eventData); } catch (err) { Log.alert('[Pusher] Unable to parse single JSON event data from Pusher', {error: err, eventData}); return; diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 07bfbf559030..bde91a510798 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -644,7 +644,7 @@ function getLastVisibleMessage(reportID: string, actionsToMerge: OnyxCollection< /** * A helper method to filter out report actions keyed by sequenceNumbers. */ -function filterOutDeprecatedReportActions(reportActions: OnyxEntry): ReportAction[] { +function filterOutDeprecatedReportActions(reportActions: ReportActions | null): ReportAction[] { return Object.entries(reportActions ?? {}) .filter(([key, reportAction]) => !isReportActionDeprecated(reportAction, key)) .map((entry) => entry[1]); @@ -656,7 +656,7 @@ function filterOutDeprecatedReportActions(reportActions: OnyxEntry | ReportAction[], shouldIncludeInvisibleActions = false): ReportAction[] { +function getSortedReportActionsForDisplay(reportActions: ReportActions | null | ReportAction[], shouldIncludeInvisibleActions = false): ReportAction[] { let filteredReportActions: ReportAction[] = []; if (!reportActions) { return []; @@ -680,7 +680,7 @@ function getSortedReportActionsForDisplay(reportActions: OnyxEntry): OnyxEntry { +function getLastClosedReportAction(reportActions: ReportActions | null): OnyxEntry { // If closed report action is not present, return early if (!Object.values(reportActions ?? {}).some((action) => action.actionName === CONST.REPORT.ACTIONS.TYPE.CLOSED)) { return null; @@ -733,7 +733,7 @@ function getLinkedTransactionID(reportActionOrID: string | OnyxEntry { return allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`]?.[reportActionID] ?? null; } diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index ef59f1c19f97..75c97c01e988 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -507,7 +507,7 @@ Onyx.connect({ }, }); -let allPersonalDetails: OnyxEntry; +let allPersonalDetails: OnyxCollection; let allPersonalDetailLogins: string[]; let currentUserPersonalDetails: OnyxEntry; Onyx.connect({ @@ -1644,7 +1644,7 @@ function getReportRecipientAccountIDs(report: OnyxEntry, currentLoginAcc /** * Whether the time row should be shown for a report. */ -function canShowReportRecipientLocalTime(personalDetails: OnyxEntry, report: OnyxEntry, accountID: number): boolean { +function canShowReportRecipientLocalTime(personalDetails: OnyxCollection, report: OnyxEntry, accountID: number): boolean { const reportRecipientAccountIDs = getReportRecipientAccountIDs(report, accountID); const hasMultipleParticipants = reportRecipientAccountIDs.length > 1; const reportRecipient = personalDetails?.[reportRecipientAccountIDs[0]]; @@ -1728,7 +1728,7 @@ function getDefaultGroupAvatar(reportID?: string): IconAsset { * Returns the appropriate icons for the given chat report using the stored personalDetails. * The Avatar sources can be URLs or Icon components according to the chat type. */ -function getIconsForParticipants(participants: number[], personalDetails: OnyxEntry): Icon[] { +function getIconsForParticipants(participants: number[], personalDetails: OnyxCollection): Icon[] { const participantDetails: ParticipantDetails[] = []; const participantsList = participants || []; @@ -1913,7 +1913,7 @@ function getParticipants(reportID: string) { */ function getIcons( report: OnyxEntry, - personalDetails: OnyxEntry, + personalDetails: OnyxCollection, defaultIcon: UserUtils.AvatarSource | null = null, defaultName = '', defaultAccountID = -1, diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index 46d37c54f087..79e73f1585d2 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -366,7 +366,7 @@ function getMerchant(transaction: OnyxEntry): string { return transaction?.modifiedMerchant ? transaction.modifiedMerchant : transaction?.merchant ?? ''; } -function getDistance(transaction: OnyxEntry): number { +function getDistance(transaction: Transaction | null): number { return transaction?.comment?.customUnit?.quantity ?? 0; } diff --git a/src/libs/actions/BankAccounts.ts b/src/libs/actions/BankAccounts.ts index fdb21eedbf84..cddb2c371a60 100644 --- a/src/libs/actions/BankAccounts.ts +++ b/src/libs/actions/BankAccounts.ts @@ -1,3 +1,4 @@ +import type {OnyxEntry} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import type {OnfidoDataWithApplicantID} from '@components/Onfido/types'; @@ -69,7 +70,7 @@ function openPlaidView() { clearPlaid().then(() => ReimbursementAccount.setBankAccountSubStep(CONST.BANK_ACCOUNT.SETUP_TYPE.PLAID)); } -function setPlaidEvent(eventName: string | null) { +function setPlaidEvent(eventName: OnyxEntry) { Onyx.set(ONYXKEYS.PLAID_CURRENT_EVENT, eventName); } diff --git a/src/libs/actions/FormActions.ts b/src/libs/actions/FormActions.ts index 5fe1705d8db3..1fcf9bed6a55 100644 --- a/src/libs/actions/FormActions.ts +++ b/src/libs/actions/FormActions.ts @@ -24,7 +24,7 @@ function clearErrorFields(formID: OnyxFormKey) { } function setDraftValues(formID: OnyxFormKey, draftValues: NullishDeep>) { - Onyx.merge(`${formID}Draft`, draftValues ?? null); + Onyx.merge(`${formID}Draft`, draftValues); } function clearDraftValues(formID: OnyxFormKey) { diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 568b9dfecf25..0dd6eb53fcfe 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1356,7 +1356,7 @@ function buildOnyxDataForTrackExpense( failureData.push({ onyxMethod: Onyx.METHOD.SET, key: ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE, - value: quickAction ?? null, + value: quickAction, }); if (iouReport) { @@ -1590,7 +1590,7 @@ function getDeleteTrackExpenseInformation( failureData.push({ onyxMethod: Onyx.METHOD.SET, key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, - value: transaction ?? null, + value: transaction, }); } @@ -1598,7 +1598,7 @@ function getDeleteTrackExpenseInformation( failureData.push({ onyxMethod: Onyx.METHOD.SET, key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, - value: transactionViolations ?? null, + value: transactionViolations, }); } @@ -1660,7 +1660,7 @@ function getSendInvoiceInformation( let chatReport = !isEmptyObject(invoiceChatReport) && invoiceChatReport?.reportID ? invoiceChatReport : null; if (!chatReport) { - chatReport = ReportUtils.getInvoiceChatByParticipants(senderWorkspaceID, receiverAccountID) ?? null; + chatReport = ReportUtils.getInvoiceChatByParticipants(senderWorkspaceID, receiverAccountID); } if (!chatReport) { @@ -1813,7 +1813,7 @@ function getMoneyRequestInformation( } if (!chatReport) { - chatReport = ReportUtils.getChatByParticipants([payerAccountID, payeeAccountID]) ?? null; + chatReport = ReportUtils.getChatByParticipants([payerAccountID, payeeAccountID]); } // If we still don't have a report, it likely doens't exist and we need to build an optimistic one @@ -5325,7 +5325,7 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor { onyxMethod: Onyx.METHOD.SET, key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, - value: transaction ?? null, + value: transaction, }, ]; @@ -5333,7 +5333,7 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor failureData.push({ onyxMethod: Onyx.METHOD.SET, key: `${ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS}${transactionID}`, - value: transactionViolations ?? null, + value: transactionViolations, }); } @@ -6429,7 +6429,7 @@ function detachReceipt(transactionID: string) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, value: { - ...(transaction ?? null), + ...transaction, errors: ErrorUtils.getMicroSecondOnyxError('iou.error.receiptDeleteFailureError'), }, }, diff --git a/src/libs/actions/OnyxUpdates.ts b/src/libs/actions/OnyxUpdates.ts index fc651b0599b5..04656f1adfec 100644 --- a/src/libs/actions/OnyxUpdates.ts +++ b/src/libs/actions/OnyxUpdates.ts @@ -1,4 +1,4 @@ -import type {OnyxUpdate} from 'react-native-onyx'; +import type {OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {Merge} from 'type-fest'; import Log from '@libs/Log'; @@ -13,7 +13,7 @@ import * as QueuedOnyxUpdates from './QueuedOnyxUpdates'; // This key needs to be separate from ONYXKEYS.ONYX_UPDATES_FROM_SERVER so that it can be updated without triggering the callback when the server IDs are updated. If that // callback were triggered it would lead to duplicate processing of server updates. -let lastUpdateIDAppliedToClient: number | null = 0; +let lastUpdateIDAppliedToClient: OnyxEntry = 0; Onyx.connect({ key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, callback: (val) => (lastUpdateIDAppliedToClient = val), @@ -151,4 +151,4 @@ function doesClientNeedToBeUpdated(previousUpdateID = 0, clientLastUpdateID = 0) } // eslint-disable-next-line import/prefer-default-export -export {apply, doesClientNeedToBeUpdated, saveUpdateInformation}; +export {saveUpdateInformation, doesClientNeedToBeUpdated, apply}; diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index b796f684b63a..d3630dcd6b3a 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -235,7 +235,7 @@ Onyx.connect({ * Stores in Onyx the policy ID of the last workspace that was accessed by the user */ function updateLastAccessedWorkspace(policyID: OnyxEntry) { - Onyx.set(ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID, policyID ?? null); + Onyx.set(ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID, policyID); } /** diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 11f1122be38a..3df92a2f3190 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -83,6 +83,7 @@ import INPUT_IDS from '@src/types/form/NewRoomForm'; import type { InvitedEmailsToAccountIDs, NewGroupChatDraft, + PersonalDetails, PersonalDetailsList, PolicyReportField, QuickAction, @@ -840,8 +841,8 @@ function openReport( }); // Add optimistic personal details for new participants - const optimisticPersonalDetails: OnyxEntry = {}; - const settledPersonalDetails: OnyxEntry = {}; + const optimisticPersonalDetails: OnyxCollection = {}; + const settledPersonalDetails: OnyxCollection = {}; const redundantParticipants: Record = {}; const participantAccountIDs = PersonalDetailsUtils.getAccountIDsByLogins(participantLoginList); participantLoginList.forEach((login, index) => { diff --git a/src/libs/actions/ReportActions.ts b/src/libs/actions/ReportActions.ts index 4fc72bae1e7d..217dd0b12100 100644 --- a/src/libs/actions/ReportActions.ts +++ b/src/libs/actions/ReportActions.ts @@ -71,11 +71,11 @@ Onyx.connect({ }); /** - * + * ignore: `undefined` means we want to check both parent and children report actions ignore: `parent` or `child` means we want to ignore checking parent or child report actions because they've been previously checked */ -function clearAllRelatedReportActionErrors(reportID: string, reportAction: ReportAction | null | undefined, ignore?: IgnoreDirection, keys?: string[]) { +function clearAllRelatedReportActionErrors(reportID: string, reportAction: ReportAction | null, ignore?: IgnoreDirection, keys?: string[]) { const errorKeys = keys ?? Object.keys(reportAction?.errors ?? {}); if (!reportAction || errorKeys.length === 0) { return; diff --git a/src/libs/migrations/RenameReceiptFilename.ts b/src/libs/migrations/RenameReceiptFilename.ts index 100b279c950f..b867024fc74e 100644 --- a/src/libs/migrations/RenameReceiptFilename.ts +++ b/src/libs/migrations/RenameReceiptFilename.ts @@ -1,5 +1,5 @@ import Onyx from 'react-native-onyx'; -import type {NullishDeep, OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import type {NullishDeep, OnyxCollection} from 'react-native-onyx'; import Log from '@libs/Log'; import ONYXKEYS from '@src/ONYXKEYS'; import type Transaction from '@src/types/onyx/Transaction'; @@ -24,7 +24,7 @@ export default function () { return resolve(); } - const transactionsWithReceipt: Array> = Object.values(transactions).filter((transaction) => transaction?.receiptFilename); + const transactionsWithReceipt: Array = Object.values(transactions).filter((transaction) => transaction?.receiptFilename); if (!transactionsWithReceipt?.length) { Log.info('[Migrate Onyx] Skipped migration RenameReceiptFilename because there were no transactions with the receiptFilename property'); return resolve(); diff --git a/src/libs/migrations/TransactionBackupsToCollection.ts b/src/libs/migrations/TransactionBackupsToCollection.ts index 8b963d7fa0c2..a7167492007a 100644 --- a/src/libs/migrations/TransactionBackupsToCollection.ts +++ b/src/libs/migrations/TransactionBackupsToCollection.ts @@ -1,4 +1,4 @@ -import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import Log from '@libs/Log'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -30,7 +30,7 @@ export default function (): Promise { // Find all the transaction backups available Object.keys(transactions).forEach((transactionOnyxKey: string) => { - const transaction: OnyxEntry = transactions[transactionOnyxKey]; + const transaction: Transaction | null = transactions[transactionOnyxKey]; // Determine whether or not the transaction is a backup if (transactionOnyxKey.endsWith('-backup') && transaction) { diff --git a/src/pages/GroupChatNameEditPage.tsx b/src/pages/GroupChatNameEditPage.tsx index cb604a1e1722..87218fbb89cd 100644 --- a/src/pages/GroupChatNameEditPage.tsx +++ b/src/pages/GroupChatNameEditPage.tsx @@ -1,6 +1,5 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback, useMemo} from 'react'; -import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; @@ -25,7 +24,7 @@ import type NewGroupChatDraft from '@src/types/onyx/NewGroupChatDraft'; import type {Errors} from '@src/types/onyx/OnyxCommon'; type GroupChatNameEditPageOnyxProps = { - groupChatDraft: OnyxEntry; + groupChatDraft: NewGroupChatDraft | null; }; type GroupChatNameEditPageProps = StackScreenProps & GroupChatNameEditPageOnyxProps; diff --git a/src/pages/NewChatPage.tsx b/src/pages/NewChatPage.tsx index a70320444dc9..555a7c855d42 100755 --- a/src/pages/NewChatPage.tsx +++ b/src/pages/NewChatPage.tsx @@ -1,7 +1,6 @@ import isEmpty from 'lodash/isEmpty'; import reject from 'lodash/reject'; import React, {useCallback, useEffect, useMemo, useState} from 'react'; -import type {OnyxEntry} from 'react-native-onyx'; import {useOnyx} from 'react-native-onyx'; import Button from '@components/Button'; import KeyboardAvoidingView from '@components/KeyboardAvoidingView'; @@ -32,7 +31,6 @@ import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {Beta} from '@src/types/onyx'; import type {SelectedParticipant} from '@src/types/onyx/NewGroupChatDraft'; type NewChatPageProps = { @@ -56,7 +54,7 @@ function useOptions({isGroupChat}: NewChatPageProps) { const filteredOptions = OptionsListUtils.getFilteredOptions( listOptions.reports ?? [], listOptions.personalDetails ?? [], - (betas ?? []) as OnyxEntry, + betas ?? [], debouncedSearchTerm, selectedOptions, isGroupChat ? excludedGroupEmails : [], diff --git a/src/pages/PrivateNotes/PrivateNotesEditPage.tsx b/src/pages/PrivateNotes/PrivateNotesEditPage.tsx index c3d8239bdf99..19cbe0bbea42 100644 --- a/src/pages/PrivateNotes/PrivateNotesEditPage.tsx +++ b/src/pages/PrivateNotes/PrivateNotesEditPage.tsx @@ -5,7 +5,7 @@ import Str from 'expensify-common/lib/str'; import lodashDebounce from 'lodash/debounce'; import React, {useCallback, useMemo, useRef, useState} from 'react'; import {Keyboard} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; @@ -31,12 +31,12 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import INPUT_IDS from '@src/types/form/PrivateNotesForm'; -import type {PersonalDetailsList, Report} from '@src/types/onyx'; +import type {PersonalDetails, Report} from '@src/types/onyx'; import type {Note} from '@src/types/onyx/Report'; type PrivateNotesEditPageOnyxProps = { /** All of the personal details for everyone */ - personalDetailsList: OnyxEntry; + personalDetailsList: OnyxCollection; }; type PrivateNotesEditPageProps = WithReportAndPrivateNotesOrNotFoundProps & diff --git a/src/pages/PrivateNotes/PrivateNotesListPage.tsx b/src/pages/PrivateNotes/PrivateNotesListPage.tsx index cf3ce4c36b53..1893f81da2fe 100644 --- a/src/pages/PrivateNotes/PrivateNotesListPage.tsx +++ b/src/pages/PrivateNotes/PrivateNotesListPage.tsx @@ -1,6 +1,6 @@ import React, {useMemo} from 'react'; -import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; +import type {OnyxCollection} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; @@ -15,11 +15,11 @@ import withReportAndPrivateNotesOrNotFound from '@pages/home/report/withReportAn import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {PersonalDetailsList, Report} from '@src/types/onyx'; +import type {PersonalDetails, Report} from '@src/types/onyx'; type PrivateNotesListPageOnyxProps = { /** All of the personal details for everyone */ - personalDetailsList: OnyxEntry; + personalDetailsList: OnyxCollection; }; type PrivateNotesListPageProps = WithReportAndPrivateNotesOrNotFoundProps & diff --git a/src/pages/ReimbursementAccount/ConnectBankAccount/components/BankAccountValidationForm.tsx b/src/pages/ReimbursementAccount/ConnectBankAccount/components/BankAccountValidationForm.tsx index 97a8caaef692..a83e18d119c9 100644 --- a/src/pages/ReimbursementAccount/ConnectBankAccount/components/BankAccountValidationForm.tsx +++ b/src/pages/ReimbursementAccount/ConnectBankAccount/components/BankAccountValidationForm.tsx @@ -1,7 +1,6 @@ import Str from 'expensify-common/lib/str'; import React, {useCallback} from 'react'; import {View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; @@ -27,7 +26,7 @@ type BankAccountValidationFormProps = { requiresTwoFactorAuth: boolean; /** The policy which the user has access to and which the report is tied to */ - policy: OnyxEntry; + policy: Policy | null; }; type AmountValues = { diff --git a/src/pages/ReimbursementAccount/utils/getValuesForBeneficialOwner.ts b/src/pages/ReimbursementAccount/utils/getValuesForBeneficialOwner.ts index b564b8f325ee..3733a6727c54 100644 --- a/src/pages/ReimbursementAccount/utils/getValuesForBeneficialOwner.ts +++ b/src/pages/ReimbursementAccount/utils/getValuesForBeneficialOwner.ts @@ -1,4 +1,3 @@ -import type {OnyxEntry} from 'react-native-onyx'; import CONST from '@src/CONST'; import type {ReimbursementAccountForm} from '@src/types/form'; @@ -13,7 +12,7 @@ type BeneficialOwnerValues = { zipCode: string; }; -function getValuesForBeneficialOwner(beneficialOwnerBeingModifiedID: string, reimbursementAccountDraft: OnyxEntry): BeneficialOwnerValues { +function getValuesForBeneficialOwner(beneficialOwnerBeingModifiedID: string, reimbursementAccountDraft: ReimbursementAccountForm | null): BeneficialOwnerValues { if (!reimbursementAccountDraft) { return { firstName: '', diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index adb1daa1e82f..96c242ca1869 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -2,7 +2,7 @@ import {useRoute} from '@react-navigation/native'; import type {StackScreenProps} from '@react-navigation/stack'; import React, {useEffect, useMemo} from 'react'; import {View} from 'react-native'; -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import AvatarWithImagePicker from '@components/AvatarWithImagePicker'; @@ -53,7 +53,7 @@ type ReportDetailsPageMenuItem = { type ReportDetailsPageOnyxProps = { /** Personal details of all the users */ - personalDetails: OnyxEntry; + personalDetails: OnyxCollection; /** Session info for the currently logged in user. */ session: OnyxEntry; diff --git a/src/pages/home/sidebar/ProfileAvatarWithIndicator.tsx b/src/pages/home/sidebar/ProfileAvatarWithIndicator.tsx index b29506ea8e8f..b0287efb8990 100644 --- a/src/pages/home/sidebar/ProfileAvatarWithIndicator.tsx +++ b/src/pages/home/sidebar/ProfileAvatarWithIndicator.tsx @@ -15,7 +15,8 @@ type ProfileAvatarWithIndicatorProps = { function ProfileAvatarWithIndicator({isSelected = false}: ProfileAvatarWithIndicatorProps) { const styles = useThemeStyles(); const currentUserPersonalDetails = useCurrentUserPersonalDetails(); - const [isLoading = true] = useOnyx(ONYXKEYS.IS_LOADING_APP); + const [isLoadingOnyxValue] = useOnyx(ONYXKEYS.IS_LOADING_APP); + const isLoading = isLoadingOnyxValue ?? true; return ( diff --git a/src/pages/settings/Profile/PersonalDetails/AddressPage.tsx b/src/pages/settings/Profile/PersonalDetails/AddressPage.tsx index 91a8b94537ab..fcb018348b72 100644 --- a/src/pages/settings/Profile/PersonalDetails/AddressPage.tsx +++ b/src/pages/settings/Profile/PersonalDetails/AddressPage.tsx @@ -70,31 +70,31 @@ function AddressPage({privatePersonalDetails, route, isLoadingApp = true}: Addre }, [address]); const handleAddressChange = useCallback((value: unknown, key: unknown) => { - const addressPart = value as string; - const addressPartKey = key as keyof Address; + const countryValue = value as Country | ''; + const addressKey = key as keyof Address; - if (addressPartKey !== 'country' && addressPartKey !== 'state' && addressPartKey !== 'city' && addressPartKey !== 'zipPostCode') { + if (addressKey !== 'country' && addressKey !== 'state' && addressKey !== 'city' && addressKey !== 'zipPostCode') { return; } - if (addressPartKey === 'country') { - setCurrentCountry(addressPart as Country | ''); + if (addressKey === 'country') { + setCurrentCountry(countryValue); setState(''); setCity(''); setZipcode(''); return; } - if (addressPartKey === 'state') { - setState(addressPart); + if (addressKey === 'state') { + setState(countryValue); setCity(''); setZipcode(''); return; } - if (addressPartKey === 'city') { - setCity(addressPart); + if (addressKey === 'city') { + setCity(countryValue); setZipcode(''); return; } - setZipcode(addressPart); + setZipcode(countryValue); }, []); useEffect(() => { diff --git a/src/types/utils/isLoadingOnyxValue.ts b/src/types/utils/isLoadingOnyxValue.ts index 7d5bfa88ba2e..052c97ad40ef 100644 --- a/src/types/utils/isLoadingOnyxValue.ts +++ b/src/types/utils/isLoadingOnyxValue.ts @@ -1,6 +1,6 @@ -import type {ResultMetadata} from 'react-native-onyx'; +import type {OnyxKey, UseOnyxResult} from 'react-native-onyx'; -function isLoadingOnyxValue(...results: ResultMetadata[]): boolean { +function isLoadingOnyxValue(...results: Array[1]>): boolean { return results.some((result) => result.status === 'loading'); } diff --git a/src/utils/arraysEqual.ts b/src/utils/arraysEqual.ts deleted file mode 100644 index 3a8111cc7bb7..000000000000 --- a/src/utils/arraysEqual.ts +++ /dev/null @@ -1,25 +0,0 @@ -function arraysEqual(a: T[], b: T[]): boolean { - if (a === b) { - return true; - } - if (a == null || b == null) { - return false; - } - if (a.length !== b.length) { - return false; - } - - // If you don't care about the order of the elements inside - // the array, you should sort both arrays here. - // Please note that calling sort on an array will modify that array. - // you might want to clone your array first. - - for (let i = 0; i < a.length; ++i) { - if (a[i] !== b[i]) { - return false; - } - } - return true; -} - -export default arraysEqual; diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 4640167c2c60..940d533b9d2b 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -464,7 +464,7 @@ describe('actions/IOU', () => { let newTransaction: OnyxEntry; mockFetch?.pause?.(); return Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${chatReportID}`, chatReport) - .then(() => Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`, iouReport ?? null)) + .then(() => Onyx.set(`${ONYXKEYS.COLLECTION.REPORT}${iouReportID}`, iouReport)) .then(() => Onyx.set(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReportID}`, { [createdAction.reportActionID]: createdAction, @@ -780,7 +780,7 @@ describe('actions/IOU', () => { .then( () => new Promise((resolve) => { - ReportActions.clearAllRelatedReportActionErrors(iouReportID ?? '', iouAction ?? null); + ReportActions.clearAllRelatedReportActionErrors(iouReportID ?? '', iouAction); resolve(); }), )