diff --git a/package-lock.json b/package-lock.json index 60759e507bd3..c2395f385e92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -102,7 +102,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.47", "react-native-pager-view": "6.2.3", "react-native-pdf": "6.7.3", "react-native-performance": "^5.1.0", @@ -31472,17 +31472,17 @@ } }, "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.47", + "resolved": "https://registry.npmjs.org/react-native-onyx/-/react-native-onyx-2.0.47.tgz", + "integrity": "sha512-ZPJ3Be3g/LZQ5hBxytK9+ODdJVuFY6uN/pIPy3KhcXB9LTWnWh/RkphVu9vyEcAAR8gCOYItGgZBGiug9VJNAg==", "dependencies": { "ascii-table": "0.0.9", "fast-equals": "^4.0.3", "underscore": "^1.13.6" }, "engines": { - "node": ">=20.10.0", - "npm": ">=10.2.3" + "node": ">=20.14.0", + "npm": ">=10.7.0" }, "peerDependencies": { "idb-keyval": "^6.2.1", diff --git a/package.json b/package.json index baf110098ac2..913430b21bf5 100644 --- a/package.json +++ b/package.json @@ -154,7 +154,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.47", "react-native-pager-view": "6.2.3", "react-native-pdf": "6.7.3", "react-native-performance": "^5.1.0", diff --git a/src/components/AvatarWithDisplayName.tsx b/src/components/AvatarWithDisplayName.tsx index 61a07a50736b..6b1849c2c77d 100644 --- a/src/components/AvatarWithDisplayName.tsx +++ b/src/components/AvatarWithDisplayName.tsx @@ -34,7 +34,7 @@ type AvatarWithDisplayNameProps = AvatarWithDisplayNamePropsWithOnyx & { report: OnyxEntry; /** The policy which the user has access to and which the report is tied to */ - policy?: OnyxEntry; + policy?: OnyxEntry | null; /** The size of the avatar */ size?: ValueOf; diff --git a/src/components/HeaderWithBackButton/index.tsx b/src/components/HeaderWithBackButton/index.tsx index 78cd92dbc223..b9bf479ab21d 100755 --- a/src/components/HeaderWithBackButton/index.tsx +++ b/src/components/HeaderWithBackButton/index.tsx @@ -30,7 +30,7 @@ function HeaderWithBackButton({ onCloseButtonPress = () => Navigation.dismissModal(), onDownloadButtonPress = () => {}, onThreeDotsButtonPress = () => {}, - report = null, + report, policy, policyAvatar, shouldShowReportAvatarWithDisplay = false, diff --git a/src/components/HeaderWithBackButton/types.ts b/src/components/HeaderWithBackButton/types.ts index 6b08dd74dc8b..1f6b92099e59 100644 --- a/src/components/HeaderWithBackButton/types.ts +++ b/src/components/HeaderWithBackButton/types.ts @@ -102,7 +102,7 @@ type HeaderWithBackButtonProps = Partial & { report?: OnyxEntry; /** The report's policy, if we're showing the details for a report and need info about it for AvatarWithDisplay */ - policy?: OnyxEntry; + policy?: OnyxEntry | null; /** Single execution function to prevent concurrent navigation actions */ singleExecution?: (action: Action) => Action; diff --git a/src/components/KYCWall/BaseKYCWall.tsx b/src/components/KYCWall/BaseKYCWall.tsx index 8c4a131284c8..818b4aff6b00 100644 --- a/src/components/KYCWall/BaseKYCWall.tsx +++ b/src/components/KYCWall/BaseKYCWall.tsx @@ -166,7 +166,7 @@ function KYCWall({ transferBalanceButtonRef.current = targetElement; - const isExpenseReport = ReportUtils.isExpenseReport(iouReport ?? null); + const isExpenseReport = ReportUtils.isExpenseReport(iouReport); const paymentCardList = fundList ?? {}; // Check to see if user has a valid payment method on file and display the add payment popover if they don't diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index 6405e3026b1a..80fca673a346 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -106,13 +106,13 @@ function LHNOptionsList({ */ const renderItem = useCallback( ({item: reportID}: RenderItemProps): ReactElement => { - const itemFullReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] ?? null; - const itemReportActions = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? null; - const itemParentReportActions = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${itemFullReport?.parentReportID}`] ?? null; - const itemParentReportAction = itemParentReportActions?.[itemFullReport?.parentReportActionID ?? ''] ?? null; - const itemPolicy = policy?.[`${ONYXKEYS.COLLECTION.POLICY}${itemFullReport?.policyID}`] ?? null; + const itemFullReport = reports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const itemReportActions = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`]; + const itemParentReportActions = reportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${itemFullReport?.parentReportID}`]; + const itemParentReportAction = itemParentReportActions?.[itemFullReport?.parentReportActionID ?? '']; + const itemPolicy = policy?.[`${ONYXKEYS.COLLECTION.POLICY}${itemFullReport?.policyID}`]; const transactionID = itemParentReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU ? itemParentReportAction.originalMessage.IOUTransactionID ?? '' : ''; - const itemTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] ?? null; + const itemTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; const hasDraftComment = DraftCommentUtils.isValidDraftComment(draftComments?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`]); const sortedReportActions = ReportActionsUtils.getSortedReportActionsForDisplay(itemReportActions); const lastReportAction = sortedReportActions[0]; diff --git a/src/components/LHNOptionsList/OptionRowLHN.tsx b/src/components/LHNOptionsList/OptionRowLHN.tsx index 851e2a9fdd16..daa71ccabdd9 100644 --- a/src/components/LHNOptionsList/OptionRowLHN.tsx +++ b/src/components/LHNOptionsList/OptionRowLHN.tsx @@ -123,7 +123,7 @@ function OptionRowLHN({reportID, isFocused = false, onSelectRow = () => {}, opti const formattedDate = DateUtils.getStatusUntilDate(statusClearAfterDate); const statusContent = formattedDate ? `${statusText ? `${statusText} ` : ''}(${formattedDate})` : statusText; const report = ReportUtils.getReport(optionItem.reportID ?? ''); - const isStatusVisible = !!emojiCode && ReportUtils.isOneOnOneChat(!isEmptyObject(report) ? report : null); + const isStatusVisible = !!emojiCode && ReportUtils.isOneOnOneChat(!isEmptyObject(report) ? report : undefined); const isGroupChat = ReportUtils.isGroupChat(optionItem) || ReportUtils.isDeprecatedGroupDM(optionItem); diff --git a/src/components/LHNOptionsList/OptionRowLHNData.tsx b/src/components/LHNOptionsList/OptionRowLHNData.tsx index c80017c39a3d..a2dd41eab0bd 100644 --- a/src/components/LHNOptionsList/OptionRowLHNData.tsx +++ b/src/components/LHNOptionsList/OptionRowLHNData.tsx @@ -35,7 +35,7 @@ function OptionRowLHNData({ const optionItemRef = useRef(); - const shouldDisplayViolations = canUseViolations && ReportUtils.shouldDisplayTransactionThreadViolations(fullReport, transactionViolations, parentReportAction ?? null); + const shouldDisplayViolations = canUseViolations && ReportUtils.shouldDisplayTransactionThreadViolations(fullReport, transactionViolations, parentReportAction); const optionItem = useMemo(() => { // Note: ideally we'd have this as a dependent selector in onyx! diff --git a/src/components/MoneyReportHeader.tsx b/src/components/MoneyReportHeader.tsx index ec52a6158ad7..538e0454a535 100644 --- a/src/components/MoneyReportHeader.tsx +++ b/src/components/MoneyReportHeader.tsx @@ -35,7 +35,7 @@ type MoneyReportHeaderProps = { report: OnyxTypes.Report; /** The policy tied to the expense report */ - policy: OnyxEntry; + policy: OnyxEntry | null; /** Array of report actions for the report */ reportActions: OnyxTypes.ReportAction[]; diff --git a/src/components/MoneyRequestConfirmationList.tsx b/src/components/MoneyRequestConfirmationList.tsx index e7c799fea3b6..cdb3aa8da1e1 100755 --- a/src/components/MoneyRequestConfirmationList.tsx +++ b/src/components/MoneyRequestConfirmationList.tsx @@ -133,7 +133,7 @@ type MoneyRequestConfirmationListProps = MoneyRequestConfirmationListOnyxProps & selectedParticipants: Participant[]; /** Payee of the expense with login */ - payeePersonalDetails?: OnyxEntry; + payeePersonalDetails?: OnyxEntry | null; /** Should the list be read only, and not editable? */ isReadOnly?: boolean; @@ -184,7 +184,7 @@ type MoneyRequestConfirmationListProps = MoneyRequestConfirmationListOnyxProps & type MoneyRequestConfirmationListItem = Participant | ReportUtils.OptionData; function MoneyRequestConfirmationList({ - transaction = null, + transaction, onSendMoney, onConfirm, iouType = CONST.IOU.TYPE.SUBMIT, @@ -709,7 +709,7 @@ function MoneyRequestConfirmationList({ if (selectedParticipants.length === 0) { return; } - if (!isEditingSplitBill && isMerchantRequired && (isMerchantEmpty || (shouldDisplayFieldError && TransactionUtils.isMerchantMissing(transaction ?? null)))) { + if (!isEditingSplitBill && isMerchantRequired && (isMerchantEmpty || (shouldDisplayFieldError && TransactionUtils.isMerchantMissing(transaction)))) { setFormError('iou.error.invalidMerchant'); return; } @@ -739,7 +739,7 @@ function MoneyRequestConfirmationList({ return; } - if (isEditingSplitBill && TransactionUtils.areRequiredFieldsEmpty(transaction ?? null)) { + if (isEditingSplitBill && TransactionUtils.areRequiredFieldsEmpty(transaction)) { setDidConfirmSplit(true); setFormError('iou.error.genericSmartscanFailureMessage'); return; @@ -861,8 +861,8 @@ function MoneyRequestConfirmationList({ style={[styles.moneyRequestMenuItem, styles.mt2]} titleStyle={styles.moneyRequestConfirmationAmount} disabled={didConfirm} - brickRoadIndicator={shouldDisplayFieldError && TransactionUtils.isAmountMissing(transaction ?? null) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} - errorText={shouldDisplayFieldError && TransactionUtils.isAmountMissing(transaction ?? null) ? translate('common.error.enterAmount') : ''} + brickRoadIndicator={shouldDisplayFieldError && TransactionUtils.isAmountMissing(transaction) ? CONST.BRICK_ROAD_INDICATOR_STATUS.ERROR : undefined} + errorText={shouldDisplayFieldError && TransactionUtils.isAmountMissing(transaction) ? translate('common.error.enterAmount') : ''} /> ), shouldShow: shouldShowSmartScanFields, @@ -1096,7 +1096,7 @@ function MoneyRequestConfirmationList({ isThumbnail, fileExtension, isLocalFile, - } = receiptPath && receiptFilename ? ReceiptUtils.getThumbnailAndImageURIs(transaction ?? null, receiptPath, receiptFilename) : ({} as ReceiptUtils.ThumbnailAndImageURI); + } = receiptPath && receiptFilename ? ReceiptUtils.getThumbnailAndImageURIs(transaction, receiptPath, receiptFilename) : ({} as ReceiptUtils.ThumbnailAndImageURI); const resolvedThumbnail = isLocalFile ? receiptThumbnail : tryResolveUrlFromApiRoot(receiptThumbnail ?? ''); const resolvedReceiptImage = isLocalFile ? receiptImage : tryResolveUrlFromApiRoot(receiptImage ?? ''); diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index e5a61a8fa23c..ff576b34a11d 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -35,10 +35,10 @@ type MoneyRequestHeaderProps = { report: Report; /** The policy which the report is tied to */ - policy: OnyxEntry; + policy: OnyxEntry | null; /** The report action the transaction is tied to from the parent report */ - parentReportAction: OnyxEntry; + parentReportAction: OnyxEntry | null; /** Whether we should display the header as in narrow layout */ shouldUseNarrowLayout?: boolean; diff --git a/src/components/ShowContextMenuContext.ts b/src/components/ShowContextMenuContext.ts index 3a996a8d2c64..7ae3ca4fb825 100644 --- a/src/components/ShowContextMenuContext.ts +++ b/src/components/ShowContextMenuContext.ts @@ -19,9 +19,9 @@ type ShowContextMenuContextProps = { const ShowContextMenuContext = createContext({ anchor: null, - report: null, - action: null, - transactionThreadReport: null, + report: undefined, + action: undefined, + transactionThreadReport: undefined, checkIfContextMenuActive: () => {}, }); diff --git a/src/languages/types.ts b/src/languages/types.ts index 003e9c8fdd10..40b620bff975 100644 --- a/src/languages/types.ts +++ b/src/languages/types.ts @@ -1,5 +1,5 @@ import type {OnyxEntry} from 'react-native-onyx'; -import type {ReportAction} from '@src/types/onyx'; +import type {OnyxInputOrEntry, ReportAction} from '@src/types/onyx'; import type {Unit} from '@src/types/onyx/Policy'; import type en from './en'; @@ -41,15 +41,15 @@ type LocalTimeParams = { }; type EditActionParams = { - action: OnyxEntry; + action: OnyxInputOrEntry; }; type DeleteActionParams = { - action: OnyxEntry; + action: OnyxInputOrEntry; }; type DeleteConfirmationParams = { - action: OnyxEntry; + action: OnyxInputOrEntry; }; type BeginningOfChatHistoryDomainRoomPartOneParams = { diff --git a/src/libs/DistanceRequestUtils.ts b/src/libs/DistanceRequestUtils.ts index cbae1e0d3bfb..e76f368b8f2f 100644 --- a/src/libs/DistanceRequestUtils.ts +++ b/src/libs/DistanceRequestUtils.ts @@ -4,7 +4,7 @@ import type {LocaleContextProps} from '@components/LocaleContextProvider'; import type {RateAndUnit} from '@src/CONST'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {LastSelectedDistanceRates, Report} from '@src/types/onyx'; +import type {LastSelectedDistanceRates, OnyxInputOrEntry, Report} from '@src/types/onyx'; import type {Unit} from '@src/types/onyx/Policy'; import type Policy from '@src/types/onyx/Policy'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; @@ -39,7 +39,7 @@ Onyx.connect({ const METERS_TO_KM = 0.001; // 1 kilometer is 1000 meters const METERS_TO_MILES = 0.000621371; // There are approximately 0.000621371 miles in a meter -function getMileageRates(policy: OnyxEntry, includeDisabledRates = false): Record { +function getMileageRates(policy: OnyxInputOrEntry, includeDisabledRates = false): Record { const mileageRates: Record = {}; if (!policy || !policy?.customUnits) { @@ -78,14 +78,14 @@ function getMileageRates(policy: OnyxEntry, includeDisabledRates = false * @returns [currency] - The currency associated with the rate. * @returns [unit] - The unit of measurement for the distance. */ -function getDefaultMileageRate(policy: OnyxEntry | EmptyObject): MileageRate | null { +function getDefaultMileageRate(policy: OnyxInputOrEntry | EmptyObject): MileageRate | undefined { if (isEmptyObject(policy) || !policy?.customUnits) { - return null; + return undefined; } const distanceUnit = PolicyUtils.getCustomUnit(policy); if (!distanceUnit?.rates) { - return null; + return; } const mileageRates = getMileageRates(policy); @@ -252,8 +252,8 @@ function convertToDistanceInMeters(distance: number, unit: Unit): number { * Returns custom unit rate ID for the distance transaction */ function getCustomUnitRateID(reportID: string) { - const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] ?? null; - const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`] ?? null; + const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; + const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; const policy = PolicyUtils.getPolicy(report?.policyID ?? parentReport?.policyID ?? ''); let customUnitRateID: string = CONST.CUSTOM_UNITS.FAKE_P2P_ID; diff --git a/src/libs/IOUUtils.ts b/src/libs/IOUUtils.ts index 9ff4f5fb8d11..5f6d99332336 100644 --- a/src/libs/IOUUtils.ts +++ b/src/libs/IOUUtils.ts @@ -1,8 +1,7 @@ -import type {OnyxEntry} from 'react-native-onyx'; import type {IOUAction, IOUType} from '@src/CONST'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; -import type {Report, Transaction} from '@src/types/onyx'; +import type {OnyxInputOrEntry, Report, Transaction} from '@src/types/onyx'; import type {IOURequestType} from './actions/IOU'; import * as CurrencyUtils from './CurrencyUtils'; import Navigation from './Navigation/Navigation'; @@ -60,7 +59,7 @@ function calculateAmount(numberOfParticipants: number, total: number, currency: * @param isDeleting - whether the user is deleting the expense * @param isUpdating - whether the user is updating the expense */ -function updateIOUOwnerAndTotal>( +function updateIOUOwnerAndTotal>( iouReport: TReport, actorAccountID: number, amount: number, diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.tsx b/src/libs/Navigation/AppNavigator/AuthScreens.tsx index a160b6765f87..410caf77e3c4 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.tsx +++ b/src/libs/Navigation/AppNavigator/AuthScreens.tsx @@ -127,7 +127,7 @@ Onyx.connect({ Onyx.connect({ key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, - callback: (value: OnyxEntry) => { + callback: (value) => { lastUpdateIDAppliedToClient = value; }, }); diff --git a/src/libs/Network/NetworkStore.ts b/src/libs/Network/NetworkStore.ts index 6b3ea2e82225..d873d52524fb 100644 --- a/src/libs/Network/NetworkStore.ts +++ b/src/libs/Network/NetworkStore.ts @@ -5,8 +5,8 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type Credentials from '@src/types/onyx/Credentials'; -let credentials: Credentials | null = null; -let authToken: string | null = null; +let credentials: Credentials | null | undefined; +let authToken: string | null | undefined; let authTokenType: ValueOf | null; let currentUserEmail: string | null = null; let offline = false; @@ -62,7 +62,7 @@ Onyx.connect({ Onyx.connect({ key: ONYXKEYS.CREDENTIALS, callback: (val) => { - credentials = val; + credentials = val ?? null; checkRequiredData(); }, }); @@ -86,7 +86,7 @@ Onyx.connect({ }); function getCredentials(): Credentials | null { - return credentials; + return credentials ?? null; } function isOffline(): boolean { @@ -94,7 +94,7 @@ function isOffline(): boolean { } function getAuthToken(): string | null { - return authToken; + return authToken ?? null; } function isSupportRequest(command: string): boolean { diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 9840e29ff347..6749ca1f8707 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -15,6 +15,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type { Beta, Login, + OnyxInputOrEntry, PersonalDetails, PersonalDetailsList, Policy, @@ -362,7 +363,7 @@ function getAvatarsForAccountIDs(accountIDs: number[], personalDetails: OnyxEntr * Returns the personal details for an array of accountIDs * @returns keys of the object are emails, values are PersonalDetails objects. */ -function getPersonalDetailsForAccountIDs(accountIDs: number[] | undefined, personalDetails: OnyxEntry): PersonalDetailsList { +function getPersonalDetailsForAccountIDs(accountIDs: number[] | undefined, personalDetails: OnyxInputOrEntry): PersonalDetailsList { const personalDetailsForAccountIDs: PersonalDetailsList = {}; if (!personalDetails) { return personalDetailsForAccountIDs; @@ -372,7 +373,7 @@ function getPersonalDetailsForAccountIDs(accountIDs: number[] | undefined, perso if (!cleanAccountID) { return; } - let personalDetail: OnyxEntry = personalDetails[accountID]; + let personalDetail: OnyxEntry = personalDetails[accountID] ?? undefined; if (!personalDetail) { personalDetail = {} as PersonalDetails; } @@ -479,7 +480,7 @@ function uniqFast(items: string[]): string[] { * Array.prototype.push.apply is faster than using the spread operator. */ function getSearchText( - report: OnyxEntry, + report: OnyxInputOrEntry, reportName: string, personalDetailList: Array>, isChatRoomOrPolicyExpenseChat: boolean, @@ -528,7 +529,7 @@ function getAllReportErrors(report: OnyxEntry, reportActions: OnyxEntry< return Object.assign(prevReportActionErrors, action.errors); }, {}); - const parentReportAction: OnyxEntry = + const parentReportAction: OnyxEntry | null = !report?.parentReportID || !report?.parentReportActionID ? null : allReportActions?.[report.parentReportID ?? '']?.[report.parentReportActionID ?? ''] ?? null; if (ReportActionUtils.wasActionTakenByCurrentUser(parentReportAction) && ReportActionUtils.isTransactionThread(parentReportAction)) { @@ -679,8 +680,8 @@ function getLastMessageTextForReport(report: OnyxEntry, lastActorDetails */ function createOption( accountIDs: number[], - personalDetails: OnyxEntry, - report: OnyxEntry, + personalDetails: OnyxInputOrEntry, + report: OnyxInputOrEntry, reportActions: ReportActions, config?: PreviewConfig, ): ReportUtils.OptionData { @@ -829,7 +830,7 @@ function getReportOption(participant: Participant): ReportUtils.OptionData { const option = createOption( visibleParticipantAccountIDs, allPersonalDetails ?? {}, - !isEmptyObject(report) ? report : null, + !isEmptyObject(report) ? report : undefined, {}, { showChatPreviewLine: false, diff --git a/src/libs/PersonalDetailsUtils.ts b/src/libs/PersonalDetailsUtils.ts index 8cea00a28d94..9a35dfc41b72 100644 --- a/src/libs/PersonalDetailsUtils.ts +++ b/src/libs/PersonalDetailsUtils.ts @@ -4,7 +4,7 @@ import Onyx from 'react-native-onyx'; import type {CurrentUserPersonalDetails} from '@components/withCurrentUserPersonalDetails'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {PersonalDetails, PersonalDetailsList, PrivatePersonalDetails} from '@src/types/onyx'; +import type {OnyxInputOrEntry, PersonalDetails, PersonalDetailsList, PrivatePersonalDetails} from '@src/types/onyx'; import type {OnyxData} from '@src/types/onyx/Request'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import * as LocalePhoneNumber from './LocalePhoneNumber'; @@ -250,7 +250,7 @@ function getEffectiveDisplayName(personalDetail?: PersonalDetails): string | und /** * Creates a new displayName for a user based on passed personal details or login. */ -function createDisplayName(login: string, passedPersonalDetails: Pick | OnyxEntry): string { +function createDisplayName(login: string, passedPersonalDetails: Pick | OnyxInputOrEntry): string { // If we have a number like +15857527441@expensify.sms then let's remove @expensify.sms and format it // so that the option looks cleaner in our UI. const userLogin = LocalePhoneNumber.formatPhoneNumber(login); diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 98db0bdfad20..2c7e37f6d52a 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -6,7 +6,7 @@ import type {SelectorType} from '@components/SelectionScreen'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {Policy, PolicyCategories, PolicyEmployeeList, PolicyTagList, PolicyTags, TaxRate} from '@src/types/onyx'; +import type {OnyxInputOrEntry, Policy, PolicyCategories, PolicyEmployeeList, PolicyTagList, PolicyTags, TaxRate} from '@src/types/onyx'; import type {PolicyFeatureName, Rate, Tenant} from '@src/types/onyx/Policy'; import type PolicyEmployee from '@src/types/onyx/PolicyEmployee'; import type {EmptyObject} from '@src/types/utils/EmptyObject'; @@ -34,7 +34,7 @@ Onyx.connect({ * Filter out the active policies, which will exclude policies with pending deletion * These are policies that we can use to create reports with in NewDot. */ -function getActivePolicies(policies: OnyxCollection): Policy[] { +function getActivePolicies(policies: OnyxCollection | null): Policy[] { return Object.values(policies ?? {}).filter( (policy): policy is Policy => !!policy && policy.pendingAction !== CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE && !!policy.name && !!policy.id, ); @@ -150,7 +150,7 @@ function isExpensifyTeam(email: string | undefined): boolean { /** * Checks if the current user is an admin of the policy. */ -const isPolicyAdmin = (policy: OnyxEntry | EmptyObject, currentUserLogin?: string): boolean => +const isPolicyAdmin = (policy: OnyxInputOrEntry | EmptyObject, currentUserLogin?: string): boolean => (policy?.role ?? (currentUserLogin && policy?.employeeList?.[currentUserLogin]?.role)) === CONST.POLICY.ROLE.ADMIN; /** @@ -163,7 +163,7 @@ const isPolicyEmployee = (policyID: string, policies: OnyxCollection): b /** * Checks if the current user is an owner (creator) of the policy. */ -const isPolicyOwner = (policy: OnyxEntry | EmptyObject, currentUserAccountID: number): boolean => policy?.ownerAccountID === currentUserAccountID; +const isPolicyOwner = (policy: OnyxInputOrEntry | EmptyObject, currentUserAccountID: number): boolean => policy?.ownerAccountID === currentUserAccountID; /** * Create an object mapping member emails to their accountIDs. Filter for members without errors if includeMemberWithErrors is false, and get the login email from the personalDetail object using the accountID. @@ -305,14 +305,14 @@ function isTaxTrackingEnabled(isPolicyExpenseChat: boolean, policy: OnyxEntry | EmptyObject): boolean { +function isInstantSubmitEnabled(policy: OnyxInputOrEntry | EmptyObject): boolean { return policy?.type === CONST.POLICY.TYPE.FREE || (policy?.autoReporting === true && policy?.autoReportingFrequency === CONST.POLICY.AUTO_REPORTING_FREQUENCIES.INSTANT); } /** * Checks if policy's approval mode is "optional", a.k.a. "Submit & Close" */ -function isSubmitAndClose(policy: OnyxEntry | EmptyObject): boolean { +function isSubmitAndClose(policy: OnyxInputOrEntry | EmptyObject): boolean { return policy?.approvalMode === CONST.POLICY.APPROVAL_MODE.OPTIONAL; } @@ -414,13 +414,13 @@ function getPolicy(policyID: string | undefined): Policy | EmptyObject { } /** Return active policies where current user is an admin */ -function getActiveAdminWorkspaces(policies: OnyxCollection): Policy[] { +function getActiveAdminWorkspaces(policies: OnyxCollection | null): Policy[] { const activePolicies = getActivePolicies(policies); return activePolicies.filter((policy) => shouldShowPolicy(policy, NetworkStore.isOffline()) && isPolicyAdmin(policy)); } /** Whether the user can send invoice */ -function canSendInvoice(policies: OnyxCollection): boolean { +function canSendInvoice(policies: OnyxCollection | null): boolean { return getActiveAdminWorkspaces(policies).length > 0; } diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index bb7ea2bced12..021a1d9603cc 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -1,12 +1,13 @@ import {fastMerge} from 'expensify-common'; import _ from 'lodash'; import lodashFindLast from 'lodash/findLast'; -import type {OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; +import type {OnyxCollection, OnyxCollectionInputValue, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; +import type {OnyxInputOrEntry} from '@src/types/onyx'; import type { ActionName, ChangeLog, @@ -100,11 +101,11 @@ Onyx.connect({ let environmentURL: string; Environment.getEnvironmentURL().then((url: string) => (environmentURL = url)); -function isCreatedAction(reportAction: OnyxEntry): boolean { +function isCreatedAction(reportAction: OnyxInputOrEntry): boolean { return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED; } -function isDeletedAction(reportAction: OnyxEntry): boolean { +function isDeletedAction(reportAction: OnyxInputOrEntry): boolean { const message = reportAction?.message ?? []; // A legacy deleted comment has either an empty array or an object with html field with empty string as value @@ -113,34 +114,34 @@ function isDeletedAction(reportAction: OnyxEntry): boolean { +function isDeletedParentAction(reportAction: OnyxInputOrEntry): boolean { return (reportAction?.message?.[0]?.isDeletedParentAction ?? false) && (reportAction?.childVisibleActionCount ?? 0) > 0; } -function isReversedTransaction(reportAction: OnyxEntry) { +function isReversedTransaction(reportAction: OnyxInputOrEntry) { return (reportAction?.message?.[0]?.isReversedTransaction ?? false) && ((reportAction as ReportAction)?.childVisibleActionCount ?? 0) > 0; } -function isPendingRemove(reportAction: OnyxEntry | EmptyObject): boolean { +function isPendingRemove(reportAction: OnyxInputOrEntry | EmptyObject): boolean { if (isEmptyObject(reportAction)) { return false; } return reportAction?.message?.[0]?.moderationDecision?.decision === CONST.MODERATION.MODERATOR_DECISION_PENDING_REMOVE; } -function isMoneyRequestAction(reportAction: OnyxEntry): reportAction is ReportAction & OriginalMessageIOU { +function isMoneyRequestAction(reportAction: OnyxInputOrEntry): reportAction is ReportAction & OriginalMessageIOU { return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU; } -function isReportPreviewAction(reportAction: OnyxEntry): boolean { +function isReportPreviewAction(reportAction: OnyxInputOrEntry): boolean { return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW; } -function isReportActionSubmitted(reportAction: OnyxEntry): boolean { +function isReportActionSubmitted(reportAction: OnyxInputOrEntry): boolean { return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.SUBMITTED; } -function isModifiedExpenseAction(reportAction: OnyxEntry | ReportAction | Record): boolean { +function isModifiedExpenseAction(reportAction: OnyxInputOrEntry | ReportAction | Record): boolean { return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.MODIFIED_EXPENSE; } @@ -148,7 +149,7 @@ function isModifiedExpenseAction(reportAction: OnyxEntry | ReportA * We are in the process of deprecating reportAction.originalMessage and will be setting the db version of "message" to reportAction.message in the future see: https://github.com/Expensify/App/issues/39797 * In the interim, we must check to see if we have an object or array for the reportAction.message, if we have an array we will use the originalMessage as this means we have not yet migrated. */ -function getWhisperedTo(reportAction: OnyxEntry | EmptyObject): number[] { +function getWhisperedTo(reportAction: OnyxInputOrEntry | EmptyObject): number[] { const originalMessage = reportAction?.originalMessage; const message = reportAction?.message; @@ -163,25 +164,25 @@ function getWhisperedTo(reportAction: OnyxEntry | EmptyObject): nu return []; } -function isWhisperAction(reportAction: OnyxEntry | EmptyObject): boolean { +function isWhisperAction(reportAction: OnyxInputOrEntry | EmptyObject): boolean { return getWhisperedTo(reportAction).length > 0; } /** * Checks whether the report action is a whisper targeting someone other than the current user. */ -function isWhisperActionTargetedToOthers(reportAction: OnyxEntry): boolean { +function isWhisperActionTargetedToOthers(reportAction: OnyxInputOrEntry): boolean { if (!isWhisperAction(reportAction)) { return false; } return !getWhisperedTo(reportAction).includes(currentUserAccountID ?? 0); } -function isReimbursementQueuedAction(reportAction: OnyxEntry) { +function isReimbursementQueuedAction(reportAction: OnyxInputOrEntry) { return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.REIMBURSEMENT_QUEUED; } -function isMemberChangeAction(reportAction: OnyxEntry) { +function isMemberChangeAction(reportAction: OnyxInputOrEntry) { return ( reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ROOM_CHANGE_LOG.INVITE_TO_ROOM || reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ROOM_CHANGE_LOG.REMOVE_FROM_ROOM || @@ -216,7 +217,7 @@ function isThreadParentMessage(reportAction: OnyxEntry, reportID: * * @deprecated Use Onyx.connect() or withOnyx() instead */ -function getParentReportAction(report: OnyxEntry | EmptyObject): ReportAction | EmptyObject { +function getParentReportAction(report: OnyxInputOrEntry | EmptyObject): ReportAction | EmptyObject { if (!report?.parentReportID || !report.parentReportActionID) { return {}; } @@ -238,7 +239,7 @@ function isSentMoneyReportAction(reportAction: OnyxEntry | EmptyObject): boolean { +function isTransactionThread(parentReportAction: OnyxInputOrEntry | EmptyObject): boolean { return ( parentReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && (parentReportAction.originalMessage.type === CONST.IOU.REPORT_ACTION_TYPE.CREATE || @@ -419,9 +420,9 @@ function extractLinksFromMessageHtml(reportAction: OnyxEntry): str * @param reportActions - all actions * @param actionIndex - index of the action */ -function findPreviousAction(reportActions: ReportAction[] | null, actionIndex: number): OnyxEntry { +function findPreviousAction(reportActions: ReportAction[] | undefined, actionIndex: number): OnyxEntry { if (!reportActions) { - return null; + return undefined; } for (let i = actionIndex + 1; i < reportActions.length; i++) { @@ -432,7 +433,7 @@ function findPreviousAction(reportActions: ReportAction[] | null, actionIndex: n } } - return null; + return undefined; } /** @@ -441,7 +442,7 @@ function findPreviousAction(reportActions: ReportAction[] | null, actionIndex: n * * @param actionIndex - index of the comment item in state to check */ -function isConsecutiveActionMadeByPreviousActor(reportActions: ReportAction[] | null, actionIndex: number): boolean { +function isConsecutiveActionMadeByPreviousActor(reportActions: ReportAction[] | undefined, actionIndex: number): boolean { const previousAction = findPreviousAction(reportActions, actionIndex); const currentAction = reportActions?.[actionIndex]; @@ -580,7 +581,7 @@ function shouldHideNewMarker(reportAction: OnyxEntry): boolean { * Checks whether an action is actionable track expense. * */ -function isActionableTrackExpense(reportAction: OnyxEntry): reportAction is ReportActionBase & OriginalMessageActionableTrackedExpenseWhisper { +function isActionableTrackExpense(reportAction: OnyxInputOrEntry): reportAction is ReportActionBase & OriginalMessageActionableTrackedExpenseWhisper { return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ACTIONABLE_TRACK_EXPENSE_WHISPER; } @@ -597,7 +598,7 @@ function isResolvedActionTrackExpense(reportAction: OnyxEntry): bo * Checks if a reportAction is fit for display as report last action, meaning that * it satisfies shouldReportActionBeVisible, it's not whisper action and not deleted. */ -function shouldReportActionBeVisibleAsLastAction(reportAction: OnyxEntry): boolean { +function shouldReportActionBeVisibleAsLastAction(reportAction: OnyxInputOrEntry): boolean { if (!reportAction) { return false; } @@ -638,17 +639,21 @@ function replaceBaseURLInPolicyChangeLogAction(reportAction: ReportAction): Repo return updatedReportAction; } -function getLastVisibleAction(reportID: string, actionsToMerge: OnyxCollection = {}): OnyxEntry { - const reportActions = Object.values(fastMerge(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {}, actionsToMerge ?? {}, true)); +function getLastVisibleAction(reportID: string, actionsToMerge: OnyxCollection | OnyxCollectionInputValue = {}): OnyxEntry { + const reportActions = Object.values(fastMerge(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`] ?? {}, actionsToMerge ?? {}, true)) as Array; const visibleReportActions = Object.values(reportActions ?? {}).filter((action): action is ReportAction => shouldReportActionBeVisibleAsLastAction(action)); const sortedReportActions = getSortedReportActions(visibleReportActions, true); if (sortedReportActions.length === 0) { - return null; + return undefined; } return sortedReportActions[0]; } -function getLastVisibleMessage(reportID: string, actionsToMerge: OnyxCollection = {}, reportAction: OnyxEntry | undefined = undefined): LastVisibleMessage { +function getLastVisibleMessage( + reportID: string, + actionsToMerge: OnyxCollection | OnyxCollectionInputValue = {}, + reportAction: OnyxInputOrEntry | undefined = undefined, +): LastVisibleMessage { const lastVisibleAction = reportAction ?? getLastVisibleAction(reportID, actionsToMerge); const message = lastVisibleAction?.message?.[0]; @@ -717,12 +722,12 @@ function getSortedReportActionsForDisplay(reportActions: OnyxEntry): 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; + return undefined; } const filteredReportActions = filterOutDeprecatedReportActions(reportActions); const sortedReportActions = getSortedReportActions(filteredReportActions); - return lodashFindLast(sortedReportActions, (action) => action.actionName === CONST.REPORT.ACTIONS.TYPE.CLOSED) ?? null; + return lodashFindLast(sortedReportActions, (action) => action.actionName === CONST.REPORT.ACTIONS.TYPE.CLOSED); } /** @@ -744,7 +749,7 @@ function getFirstVisibleReportActionID(sortedReportActions: ReportAction[] = [], /** * @returns The latest report action in the `onyxData` or `null` if one couldn't be found */ -function getLatestReportActionFromOnyxData(onyxData: OnyxUpdate[] | null): OnyxEntry { +function getLatestReportActionFromOnyxData(onyxData: OnyxUpdate[] | null): NonNullable> | null { const reportActionUpdate = onyxData?.find((onyxUpdate) => onyxUpdate.key.startsWith(ONYXKEYS.COLLECTION.REPORT_ACTIONS)); if (!reportActionUpdate) { @@ -767,8 +772,8 @@ function getLinkedTransactionID(reportActionOrID: string | OnyxEntry { - return ( - Object.values(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`] ?? {}).find( - (reportAction) => reportAction && reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW && reportAction.originalMessage.linkedReportID === iouReportID, - ) ?? null + return Object.values(allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`] ?? {}).find( + (reportAction) => reportAction && reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW && reportAction.originalMessage.linkedReportID === iouReportID, ); } @@ -835,7 +838,7 @@ function isCreatedTaskReportAction(reportAction: OnyxEntry): boole /** * A helper method to identify if the message is deleted or not. */ -function isMessageDeleted(reportAction: OnyxEntry): boolean { +function isMessageDeleted(reportAction: OnyxInputOrEntry): boolean { return reportAction?.message?.[0]?.isDeletedParentAction ?? false; } @@ -846,7 +849,7 @@ function getNumberOfMoneyRequests(reportPreviewAction: OnyxEntry): return reportPreviewAction?.childMoneyRequestCount ?? 0; } -function isSplitBillAction(reportAction: OnyxEntry): boolean { +function isSplitBillAction(reportAction: OnyxInputOrEntry): boolean { return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && reportAction.originalMessage.type === CONST.IOU.REPORT_ACTION_TYPE.SPLIT; } @@ -854,7 +857,7 @@ function isTrackExpenseAction(reportAction: OnyxEntry): boolean { +function isPayAction(reportAction: OnyxInputOrEntry): boolean { return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && (reportAction.originalMessage as IOUMessage).type === CONST.IOU.REPORT_ACTION_TYPE.PAY; } @@ -950,7 +953,7 @@ function getAllReportActions(reportID: string): ReportActions { * Check whether a report action is an attachment (a file, such as an image or a zip). * */ -function isReportActionAttachment(reportAction: OnyxEntry): boolean { +function isReportActionAttachment(reportAction: OnyxInputOrEntry): boolean { const message = reportAction?.message?.[0]; if (reportAction && ('isAttachment' in reportAction || 'attachmentInfo' in reportAction)) { @@ -1236,7 +1239,7 @@ function isLinkedTransactionHeld(reportActionID: string, reportID: string): bool /** * Check if the current user is the requestor of the action */ -function wasActionTakenByCurrentUser(reportAction: OnyxEntry): boolean { +function wasActionTakenByCurrentUser(reportAction: OnyxInputOrEntry): boolean { return currentUserAccountID === reportAction?.actorAccountID; } diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index aae11a29becf..af41a43aee58 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -21,6 +21,7 @@ import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; import type { Beta, + OnyxInputOrEntry, PersonalDetails, PersonalDetailsList, Policy, @@ -518,7 +519,7 @@ let currentUserPersonalDetails: OnyxEntry; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, callback: (value) => { - currentUserPersonalDetails = value?.[currentUserAccountID ?? -1] ?? null; + currentUserPersonalDetails = value?.[currentUserAccountID ?? -1] ?? undefined; allPersonalDetails = value ?? {}; allPersonalDetailLogins = Object.values(allPersonalDetails).map((personalDetail) => personalDetail?.login ?? ''); }, @@ -600,7 +601,7 @@ function getCurrentUserDisplayNameOrEmail(): string | undefined { return currentUserPersonalDetails?.displayName ?? currentUserEmail; } -function getChatType(report: OnyxEntry | Participant | EmptyObject): ValueOf | undefined { +function getChatType(report: OnyxInputOrEntry | Participant | EmptyObject): ValueOf | undefined { return report?.chatType; } @@ -609,13 +610,13 @@ function getChatType(report: OnyxEntry | Participant | EmptyObject): Val */ function getReport(reportID: string | undefined): OnyxEntry { if (!allReports && !allReportsDraft) { - return null; + return undefined; } const report = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; const draftReport = allReportsDraft?.[`${ONYXKEYS.COLLECTION.REPORT_DRAFT}${reportID}`]; - return report ?? draftReport ?? null; + return report ?? draftReport; } /** @@ -654,7 +655,7 @@ function getRootParentReport(report: OnyxEntry | undefined | EmptyObject const parentReport = getReport(report?.parentReportID); // Runs recursion to iterate a parent report - return getRootParentReport(!isEmptyObject(parentReport) ? parentReport : null); + return getRootParentReport(!isEmptyObject(parentReport) ? parentReport : undefined); } /** @@ -671,14 +672,14 @@ function getPolicy(policyID: string | undefined): Policy | EmptyObject { * Get the policy type from a given report * @param policies must have Onyxkey prefix (i.e 'policy_') for keys */ -function getPolicyType(report: OnyxEntry, policies: OnyxCollection): string { +function getPolicyType(report: OnyxInputOrEntry, policies: OnyxCollection): string { return policies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`]?.type ?? ''; } /** * Get the policy name from a given report */ -function getPolicyName(report: OnyxEntry | undefined | EmptyObject, returnEmptyIfNotFound = false, policy: OnyxEntry | undefined = undefined): string { +function getPolicyName(report: OnyxInputOrEntry | undefined | EmptyObject, returnEmptyIfNotFound = false, policy?: OnyxInputOrEntry): string { const noPolicyFound = returnEmptyIfNotFound ? '' : Localize.translateLocal('workspace.common.unavailable'); if (isEmptyObject(report)) { return noPolicyFound; @@ -714,21 +715,21 @@ function isChatReport(report: OnyxEntry | EmptyObject): boolean { return report?.type === CONST.REPORT.TYPE.CHAT; } -function isInvoiceReport(report: OnyxEntry | EmptyObject): boolean { +function isInvoiceReport(report: OnyxInputOrEntry | EmptyObject): boolean { return report?.type === CONST.REPORT.TYPE.INVOICE; } /** * Checks if a report is an Expense report. */ -function isExpenseReport(report: OnyxEntry | EmptyObject): boolean { +function isExpenseReport(report: OnyxInputOrEntry | EmptyObject): boolean { return report?.type === CONST.REPORT.TYPE.EXPENSE; } /** * Checks if a report is an IOU report using report or reportID */ -function isIOUReport(reportOrID: OnyxEntry | string | EmptyObject): boolean { +function isIOUReport(reportOrID: OnyxInputOrEntry | string | EmptyObject): boolean { const report = typeof reportOrID === 'string' ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? null : reportOrID; return report?.type === CONST.REPORT.TYPE.IOU; } @@ -742,7 +743,7 @@ function isIOUReportUsingReport(report: OnyxEntry | EmptyObject): report /** * Checks if a report is a task report. */ -function isTaskReport(report: OnyxEntry): boolean { +function isTaskReport(report: OnyxInputOrEntry): boolean { return report?.type === CONST.REPORT.TYPE.TASK; } @@ -753,7 +754,7 @@ function isTaskReport(report: OnyxEntry): boolean { * There's another situation where you don't have access to the parentReportAction (because it was created in a chat you don't have access to) * In this case, we have added the key to the report itself */ -function isCanceledTaskReport(report: OnyxEntry | EmptyObject = {}, parentReportAction: OnyxEntry | EmptyObject = {}): boolean { +function isCanceledTaskReport(report: OnyxInputOrEntry | EmptyObject = {}, parentReportAction: OnyxInputOrEntry | EmptyObject = {}): boolean { if (!isEmptyObject(parentReportAction) && (parentReportAction?.message?.[0]?.isDeletedParentAction ?? false)) { return true; } @@ -770,7 +771,7 @@ function isCanceledTaskReport(report: OnyxEntry | EmptyObject = {}, pare * * @param parentReportAction - The parent report action of the report (Used to check if the task has been canceled) */ -function isOpenTaskReport(report: OnyxEntry, parentReportAction: OnyxEntry | EmptyObject = {}): boolean { +function isOpenTaskReport(report: OnyxInputOrEntry, parentReportAction: OnyxInputOrEntry | EmptyObject = {}): boolean { return ( isTaskReport(report) && !isCanceledTaskReport(report, parentReportAction) && report?.stateNum === CONST.REPORT.STATE_NUM.OPEN && report?.statusNum === CONST.REPORT.STATUS_NUM.OPEN ); @@ -793,7 +794,7 @@ function isReportManager(report: OnyxEntry): boolean { /** * Checks if the supplied report has been approved */ -function isReportApproved(reportOrID: OnyxEntry | string | EmptyObject): boolean { +function isReportApproved(reportOrID: OnyxInputOrEntry | string | EmptyObject): boolean { const report = typeof reportOrID === 'string' ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? null : reportOrID; return report?.stateNum === CONST.REPORT.STATE_NUM.APPROVED && report?.statusNum === CONST.REPORT.STATUS_NUM.APPROVED; } @@ -801,7 +802,7 @@ function isReportApproved(reportOrID: OnyxEntry | string | EmptyObject): /** * Checks if the supplied report is an expense report in Open state and status. */ -function isOpenExpenseReport(report: OnyxEntry | EmptyObject): boolean { +function isOpenExpenseReport(report: OnyxInputOrEntry | EmptyObject): boolean { return isExpenseReport(report) && report?.stateNum === CONST.REPORT.STATE_NUM.OPEN && report?.statusNum === CONST.REPORT.STATUS_NUM.OPEN; } @@ -901,7 +902,7 @@ function isUserCreatedPolicyRoom(report: OnyxEntry): boolean { /** * Whether the provided report is a Policy Expense chat. */ -function isPolicyExpenseChat(report: OnyxEntry | Participant | EmptyObject): boolean { +function isPolicyExpenseChat(report: OnyxInputOrEntry | Participant | EmptyObject): boolean { return getChatType(report) === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT || (report?.isPolicyExpenseChat ?? false); } @@ -941,7 +942,7 @@ function isGroupPolicy(policyType: string): boolean { /** * Whether the provided report belongs to a Free, Collect or Control policy */ -function isReportInGroupPolicy(report: OnyxEntry, policy?: OnyxEntry): boolean { +function isReportInGroupPolicy(report: OnyxInputOrEntry, policy?: OnyxInputOrEntry): boolean { const policyType = policy?.type ?? getPolicyType(report, allPolicies); return isGroupPolicy(policyType); } @@ -1025,21 +1026,21 @@ function isWorkspaceTaskReport(report: OnyxEntry): boolean { if (!isTaskReport(report)) { return false; } - const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`] ?? null; + const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; return isPolicyExpenseChat(parentReport); } /** * Returns true if report has a parent */ -function isThread(report: OnyxEntry): boolean { +function isThread(report: OnyxInputOrEntry): boolean { return !!(report?.parentReportID && report?.parentReportActionID); } /** * Returns true if report is of type chat and has a parent and is therefore a Thread. */ -function isChatThread(report: OnyxEntry): boolean { +function isChatThread(report: OnyxInputOrEntry): boolean { return isThread(report) && report?.type === CONST.REPORT.TYPE.CHAT; } @@ -1047,7 +1048,7 @@ function isDM(report: OnyxEntry): boolean { return isChatReport(report) && !getChatType(report) && !isThread(report); } -function isSelfDM(report: OnyxEntry): boolean { +function isSelfDM(report: OnyxInputOrEntry): boolean { return getChatType(report) === CONST.REPORT.CHAT_TYPE.SELF_DM; } @@ -1062,7 +1063,7 @@ function isSystemChat(report: OnyxEntry): boolean { /** * Only returns true if this is our main 1:1 DM report with Concierge */ -function isConciergeChatReport(report: OnyxEntry): boolean { +function isConciergeChatReport(report: OnyxInputOrEntry): boolean { const participantAccountIDs = Object.keys(report?.participants ?? {}) .map(Number) .filter((accountID) => accountID !== currentUserAccountID); @@ -1217,7 +1218,7 @@ function findLastAccessedReport( return sortedReports[0]; } - return adminReport ?? sortedReports.find((report) => !isConciergeChatReport(report)) ?? null; + return adminReport ?? sortedReports.find((report) => !isConciergeChatReport(report)); } // If we only have two reports and one of them is the system chat, filter it out so we don't @@ -1227,7 +1228,7 @@ function findLastAccessedReport( sortedReports = sortedReports.filter((report) => !isSystemChat(report)) ?? []; } - return adminReport ?? sortedReports.at(-1) ?? null; + return adminReport ?? sortedReports.at(-1); } /** @@ -1247,7 +1248,7 @@ function isClosedExpenseReportWithNoExpenses(report: OnyxEntry): boolean /** * Whether the provided report is an archived room */ -function isArchivedRoom(report: OnyxEntry | EmptyObject, reportNameValuePairs?: OnyxEntry | EmptyObject): boolean { +function isArchivedRoom(report: OnyxInputOrEntry | EmptyObject, reportNameValuePairs?: OnyxInputOrEntry | EmptyObject): boolean { if (reportNameValuePairs) { return reportNameValuePairs.isArchived; } @@ -1365,7 +1366,7 @@ function isWorkspaceThread(report: OnyxEntry): boolean { /** * Returns true if reportAction is the first chat preview of a Thread */ -function isThreadFirstChat(reportAction: OnyxEntry, reportID: string): boolean { +function isThreadFirstChat(reportAction: OnyxInputOrEntry, reportID: string): boolean { return reportAction?.childReportID?.toString() === reportID; } @@ -1383,7 +1384,7 @@ function isChildReport(report: OnyxEntry): boolean { function isExpenseRequest(report: OnyxEntry): boolean { if (isThread(report)) { const parentReportAction = ReportActionsUtils.getParentReportAction(report); - const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`] ?? null; + const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; return isExpenseReport(parentReport) && !isEmptyObject(parentReportAction) && ReportActionsUtils.isTransactionThread(parentReportAction); } return false; @@ -1396,7 +1397,7 @@ function isExpenseRequest(report: OnyxEntry): boolean { function isIOURequest(report: OnyxEntry): boolean { if (isThread(report)) { const parentReportAction = ReportActionsUtils.getParentReportAction(report); - const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`] ?? null; + const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; return isIOUReport(parentReport) && !isEmptyObject(parentReportAction) && ReportActionsUtils.isTransactionThread(parentReportAction); } return false; @@ -1406,7 +1407,7 @@ function isIOURequest(report: OnyxEntry): boolean { * A Track Expense Report is a thread where the parent the parentReportAction is a transaction, and * parentReportAction has type of track. */ -function isTrackExpenseReport(report: OnyxEntry): boolean { +function isTrackExpenseReport(report: OnyxInputOrEntry): boolean { if (isThread(report)) { const parentReportAction = ReportActionsUtils.getParentReportAction(report); return !isEmptyObject(parentReportAction) && ReportActionsUtils.isTrackExpenseAction(parentReportAction); @@ -1418,15 +1419,15 @@ function isTrackExpenseReport(report: OnyxEntry): boolean { * Checks if a report is an IOU or expense request. */ function isMoneyRequest(reportOrID: OnyxEntry | string): boolean { - const report = typeof reportOrID === 'string' ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? null : reportOrID; + const report = typeof reportOrID === 'string' ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? undefined : reportOrID; return isIOURequest(report) || isExpenseRequest(report); } /** * Checks if a report is an IOU or expense report. */ -function isMoneyRequestReport(reportOrID: OnyxEntry | EmptyObject | string): boolean { - const report = typeof reportOrID === 'object' ? reportOrID : allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? null; +function isMoneyRequestReport(reportOrID: OnyxInputOrEntry | EmptyObject | string): boolean { + const report = typeof reportOrID === 'object' ? reportOrID : allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? undefined; return isIOUReport(report) || isExpenseReport(report); } @@ -1500,7 +1501,7 @@ function getReportNotificationPreference(report: OnyxEntry): string | nu /** * Checks if the current user is the action's author */ -function isActionCreator(reportAction: OnyxEntry | Partial): boolean { +function isActionCreator(reportAction: OnyxInputOrEntry | Partial): boolean { return reportAction?.actorAccountID === currentUserAccountID; } @@ -1508,7 +1509,7 @@ function isActionCreator(reportAction: OnyxEntry | Partial | Partial): NotificationPreference { +function getChildReportNotificationPreference(reportAction: OnyxInputOrEntry | Partial): NotificationPreference { const childReportNotificationPreference = reportAction?.childReportNotificationPreference ?? ''; if (childReportNotificationPreference) { return childReportNotificationPreference; @@ -1544,7 +1545,7 @@ function canAddOrDeleteTransactions(moneyRequestReport: OnyxEntry): bool * Can only delete if the author is this user and the action is an ADD_COMMENT action or an IOU action in an unsettled report, or if the user is a * policy admin */ -function canDeleteReportAction(reportAction: OnyxEntry, reportID: string): boolean { +function canDeleteReportAction(reportAction: OnyxInputOrEntry, reportID: string): boolean { const report = getReport(reportID); const isActionOwner = reportAction?.actorAccountID === currentUserAccountID; @@ -1632,7 +1633,7 @@ function getReportRecipientAccountIDs(report: OnyxEntry, currentLoginAcc // In 1:1 chat threads, the participants will be the same as parent report. If a report is specifically a 1:1 chat thread then we will // get parent report and use its participants array. if (isThread(report) && !(isTaskReport(report) || isMoneyRequestReport(report))) { - const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`] ?? null; + const parentReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report?.parentReportID}`]; if (isOneOnOneChat(parentReport)) { finalReport = parentReport; } @@ -1753,7 +1754,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: OnyxInputOrEntry): Icon[] { const participantDetails: ParticipantDetails[] = []; const participantsList = participants || []; @@ -1796,7 +1797,7 @@ function getIconsForParticipants(participants: number[], personalDetails: OnyxEn /** * Given a report, return the associated workspace icon. */ -function getWorkspaceIcon(report: OnyxEntry, policy: OnyxEntry = null): Icon { +function getWorkspaceIcon(report: OnyxInputOrEntry, policy?: OnyxInputOrEntry): Icon { const workspaceName = getPolicyName(report, false, policy); const policyExpenseChatAvatarSource = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`]?.avatarURL ? allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`]?.avatarURL @@ -1942,12 +1943,12 @@ function getParticipants(reportID: string) { * The Avatar sources can be URLs or Icon components according to the chat type. */ function getIcons( - report: OnyxEntry, - personalDetails: OnyxEntry, + report: OnyxInputOrEntry, + personalDetails: OnyxInputOrEntry, defaultIcon: AvatarSource | null = null, defaultName = '', defaultAccountID = -1, - policy: OnyxEntry = null, + policy?: OnyxInputOrEntry, ): Icon[] { if (isEmptyObject(report)) { const fallbackIcon: Icon = { @@ -2347,7 +2348,7 @@ function hasNonReimbursableTransactions(iouReportID: string | undefined): boolea return transactions.filter((transaction) => transaction.reimbursable === false).length > 0; } -function getMoneyRequestSpendBreakdown(report: OnyxEntry, allReportsDict: OnyxCollection = null): SpendBreakdown { +function getMoneyRequestSpendBreakdown(report: OnyxInputOrEntry, allReportsDict?: OnyxCollection): SpendBreakdown { const allAvailableReports = allReportsDict ?? allReports; let moneyRequestReport; if (isMoneyRequestReport(report) || isInvoiceReport(report)) { @@ -2387,7 +2388,7 @@ function getMoneyRequestSpendBreakdown(report: OnyxEntry, allReportsDict /** * Get the title for a policy expense chat which depends on the role of the policy member seeing this report */ -function getPolicyExpenseChatName(report: OnyxEntry, policy: OnyxEntry | undefined = undefined): string | undefined { +function getPolicyExpenseChatName(report: OnyxEntry, policy?: OnyxEntry): string | undefined { const ownerAccountID = report?.ownerAccountID; const personalDetails = allPersonalDetails?.[ownerAccountID ?? -1]; const login = personalDetails ? personalDetails.login : null; @@ -2529,7 +2530,7 @@ function getAvailableReportFields(report: Report, policyReportFields: PolicyRepo /** * Get the title for an IOU or expense chat which will be showing the payer and the amount */ -function getMoneyRequestReportName(report: OnyxEntry, policy: OnyxEntry | undefined = undefined): string { +function getMoneyRequestReportName(report: OnyxEntry, policy?: OnyxEntry): string { const isReportSettled = isSettled(report?.reportID ?? ''); const reportFields = isReportSettled ? report?.fieldList : getReportFieldsByPolicyID(report?.policyID ?? ''); const titleReportField = getFormulaTypeReportField(reportFields ?? {}); @@ -2574,7 +2575,7 @@ function getMoneyRequestReportName(report: OnyxEntry, policy: OnyxEntry< * into a flat object. Used for displaying transactions and sending them in API commands */ -function getTransactionDetails(transaction: OnyxEntry, createdDateFormat: string = CONST.DATE.FNS_FORMAT_STRING): TransactionDetails | undefined { +function getTransactionDetails(transaction: OnyxInputOrEntry, createdDateFormat: string = CONST.DATE.FNS_FORMAT_STRING): TransactionDetails | undefined { if (!transaction) { return; } @@ -2618,7 +2619,7 @@ function getTransactionCommentObject(transaction: OnyxEntry): Comme * This is used in conjunction with canEditRestrictedField to control editing of specific fields like amount, currency, created, receipt, and distance. * On its own, it only controls allowing/disallowing navigating to the editing pages or showing/hiding the 'Edit' icon on report actions */ -function canEditMoneyRequest(reportAction: OnyxEntry): boolean { +function canEditMoneyRequest(reportAction: OnyxInputOrEntry): boolean { const isDeleted = ReportActionsUtils.isDeletedAction(reportAction); if (isDeleted) { @@ -2669,7 +2670,7 @@ function canEditMoneyRequest(reportAction: OnyxEntry): boolean { * Checks if the current user can edit the provided property of an expense * */ -function canEditFieldOfMoneyRequest(reportAction: OnyxEntry, fieldToEdit: ValueOf): boolean { +function canEditFieldOfMoneyRequest(reportAction: OnyxInputOrEntry, fieldToEdit: ValueOf): boolean { // A list of fields that cannot be edited by anyone, once an expense has been settled const restrictedFields: string[] = [ CONST.EDIT_REQUEST_FIELD.AMOUNT, @@ -2728,7 +2729,7 @@ function canEditFieldOfMoneyRequest(reportAction: OnyxEntry, field * - It's an expense where conditions for editability are defined in canEditMoneyRequest method * - It's not pending deletion */ -function canEditReportAction(reportAction: OnyxEntry): boolean { +function canEditReportAction(reportAction: OnyxInputOrEntry): boolean { const isCommentOrIOU = reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.ADD_COMMENT || reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU; return !!( @@ -2863,13 +2864,13 @@ function getTransactionReportName(reportAction: OnyxEntry | EmptyObject, - iouReportAction: OnyxEntry | EmptyObject = {}, + report: OnyxInputOrEntry | EmptyObject, + iouReportAction: OnyxInputOrEntry | EmptyObject = {}, shouldConsiderScanningReceiptOrPendingRoute = false, isPreviewMessageForParentChatReport = false, - policy: OnyxEntry = null, + policy?: OnyxInputOrEntry, isForListPreview = false, - originalReportAction: OnyxEntry | EmptyObject = iouReportAction, + originalReportAction: OnyxInputOrEntry | EmptyObject = iouReportAction, ): string { const reportActionMessage = iouReportAction?.message?.[0]?.html ?? ''; @@ -3020,10 +3021,10 @@ function getReportPreviewMessage( * At the moment, we only allow changing one transaction field at a time. */ function getModifiedExpenseOriginalMessage( - oldTransaction: OnyxEntry, + oldTransaction: OnyxInputOrEntry, transactionChanges: TransactionChanges, isFromExpenseReport: boolean, - policy: OnyxEntry, + policy: OnyxInputOrEntry, ): ExpenseOriginalMessage { const originalMessage: ExpenseOriginalMessage = {}; // Remark: Comment field is the only one which has new/old prefixes for the keys (newComment/ oldComment), @@ -3242,7 +3243,7 @@ function getInvoicesChatName(report: OnyxEntry): string { /** * Get the title for a report. */ -function getReportName(report: OnyxEntry, policy: OnyxEntry = null): string { +function getReportName(report: OnyxEntry, policy?: OnyxEntry): string { let formattedName: string | undefined; const parentReportAction = ReportActionsUtils.getParentReportAction(report); if (isChatThread(report)) { @@ -3258,7 +3259,7 @@ function getReportName(report: OnyxEntry, policy: OnyxEntry = nu return Localize.translateLocal('parentReportAction.deletedMessage'); } - const isAttachment = ReportActionsUtils.isReportActionAttachment(!isEmptyObject(parentReportAction) ? parentReportAction : null); + const isAttachment = ReportActionsUtils.isReportActionAttachment(!isEmptyObject(parentReportAction) ? parentReportAction : undefined); const parentReportActionMessage = getReportActionMessage(parentReportAction, report?.parentReportID, report?.reportID ?? '').replace(/(\r\n|\n|\r)/gm, ' '); if (isAttachment && parentReportActionMessage) { return `[${Localize.translateLocal('common.attachment')}]`; @@ -3957,12 +3958,12 @@ function getIOUReportActionMessage(iouReportID: string, type: string, total: num const report = getReport(iouReportID); if (type === CONST.REPORT.ACTIONS.TYPE.SUBMITTED) { - return getIOUSubmittedMessage(!isEmptyObject(report) ? report : null); + return getIOUSubmittedMessage(!isEmptyObject(report) ? report : undefined); } const amount = type === CONST.IOU.REPORT_ACTION_TYPE.PAY - ? CurrencyUtils.convertToDisplayString(getMoneyRequestSpendBreakdown(!isEmptyObject(report) ? report : null).totalDisplaySpend, currency) + ? CurrencyUtils.convertToDisplayString(getMoneyRequestSpendBreakdown(!isEmptyObject(report) ? report : undefined).totalDisplaySpend, currency) : CurrencyUtils.convertToDisplayString(total, currency); let paymentMethodMessage; @@ -4224,7 +4225,13 @@ function buildOptimisticSubmittedReportAction(amount: number, currency: string, * @param [comment] - User comment for the IOU. * @param [transaction] - optimistic first transaction of preview */ -function buildOptimisticReportPreview(chatReport: OnyxEntry, iouReport: Report, comment = '', transaction: OnyxEntry = null, childReportID?: string): ReportAction { +function buildOptimisticReportPreview( + chatReport: OnyxInputOrEntry, + iouReport: Report, + comment = '', + transaction?: OnyxInputOrEntry, + childReportID?: string, +): ReportAction { const hasReceipt = TransactionUtils.hasReceipt(transaction); const isReceiptBeingScanned = hasReceipt && TransactionUtils.isReceiptBeingScanned(transaction); const message = getReportPreviewMessage(iouReport); @@ -4300,11 +4307,11 @@ function buildOptimisticActionableTrackExpenseWhisper(iouAction: OptimisticIOURe * Builds an optimistic modified expense action with a randomly generated reportActionID. */ function buildOptimisticModifiedExpenseReportAction( - transactionThread: OnyxEntry, - oldTransaction: OnyxEntry, + transactionThread: OnyxInputOrEntry, + oldTransaction: OnyxInputOrEntry, transactionChanges: TransactionChanges, isFromExpenseReport: boolean, - policy: OnyxEntry, + policy: OnyxInputOrEntry, ): OptimisticModifiedExpenseReportAction { const originalMessage = getModifiedExpenseOriginalMessage(oldTransaction, transactionChanges, isFromExpenseReport, policy); return { @@ -4387,7 +4394,7 @@ function updateReportPreview( reportPreviewAction: ReportPreviewAction, isPayRequest = false, comment = '', - transaction: OnyxEntry = null, + transaction?: OnyxEntry, ): ReportPreviewAction { const hasReceipt = TransactionUtils.hasReceipt(transaction); const recentReceiptTransactions = reportPreviewAction?.childRecentReceiptTransactionIDs ?? {}; @@ -4478,13 +4485,13 @@ function buildOptimisticTaskReportAction( function buildOptimisticChatReport( participantList: number[], reportName: string = CONST.REPORT.DEFAULT_REPORT_NAME, - chatType: ValueOf | undefined = undefined, + chatType?: ValueOf, policyID: string = CONST.POLICY.OWNER_EMAIL_FAKE, ownerAccountID: number = CONST.REPORT.OWNER_ACCOUNT_ID_FAKE, isOwnPolicyExpenseChat = false, oldPolicyName = '', - visibility: ValueOf | undefined = undefined, - writeCapability: ValueOf | undefined = undefined, + visibility?: ValueOf, + writeCapability?: ValueOf, notificationPreference: NotificationPreference = CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS, parentReportActionID = '', parentReportID = '', @@ -5135,7 +5142,7 @@ function isUnread(report: OnyxEntry): boolean { return lastReadTime < lastVisibleActionCreated || lastReadTime < lastMentionedTime; } -function isIOUOwnedByCurrentUser(report: OnyxEntry, allReportsDict: OnyxCollection = null): boolean { +function isIOUOwnedByCurrentUser(report: OnyxEntry, allReportsDict?: OnyxCollection): boolean { const allAvailableReports = allReportsDict ?? allReports; if (!report || !allAvailableReports) { return false; @@ -5199,7 +5206,7 @@ function canAccessReport(report: OnyxEntry, policies: OnyxCollection, currentReportId: string): boolean { const currentReport = getReport(currentReportId); - const parentReport = getParentReport(!isEmptyObject(currentReport) ? currentReport : null); + const parentReport = getParentReport(!isEmptyObject(currentReport) ? currentReport : undefined); const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report?.reportID}`] ?? {}; const isChildReportHasComment = Object.values(reportActions ?? {})?.some((reportAction) => (reportAction?.childVisibleActionCount ?? 0) > 0); return parentReport?.reportID !== report?.reportID && !isChildReportHasComment; @@ -5208,7 +5215,11 @@ function shouldHideReport(report: OnyxEntry, currentReportId: string): b /** * Checks to see if a report's parentAction is an expense that contains a violation type of either violation or warning */ -function doesTransactionThreadHaveViolations(report: OnyxEntry, transactionViolations: OnyxCollection, parentReportAction: OnyxEntry): boolean { +function doesTransactionThreadHaveViolations( + report: OnyxInputOrEntry, + transactionViolations: OnyxCollection, + parentReportAction: OnyxInputOrEntry, +): boolean { if (parentReportAction?.actionName !== CONST.REPORT.ACTIONS.TYPE.IOU) { return false; } @@ -5391,65 +5402,59 @@ function shouldReportBeInOptionList({ */ function getChatByParticipants(newParticipantList: number[], reports: OnyxCollection = allReports): OnyxEntry { const sortedNewParticipantList = newParticipantList.sort(); - return ( - Object.values(reports ?? {}).find((report) => { - const participantAccountIDs = Object.keys(report?.participants ?? {}); - - // If the report has been deleted, or there are no participants (like an empty #admins room) then skip it - if ( - participantAccountIDs.length === 0 || - isChatThread(report) || - isTaskReport(report) || - isMoneyRequestReport(report) || - isChatRoom(report) || - isPolicyExpenseChat(report) || - isGroupChat(report) - ) { - return false; - } + return Object.values(reports ?? {}).find((report) => { + const participantAccountIDs = Object.keys(report?.participants ?? {}); + + // If the report has been deleted, or there are no participants (like an empty #admins room) then skip it + if ( + participantAccountIDs.length === 0 || + isChatThread(report) || + isTaskReport(report) || + isMoneyRequestReport(report) || + isChatRoom(report) || + isPolicyExpenseChat(report) || + isGroupChat(report) + ) { + return false; + } - const sortedParticipantsAccountIDs = participantAccountIDs.map(Number).sort(); + const sortedParticipantsAccountIDs = participantAccountIDs.map(Number).sort(); - // Only return the chat if it has all the participants - return lodashIsEqual(sortedNewParticipantList, sortedParticipantsAccountIDs); - }) ?? null - ); + // Only return the chat if it has all the participants + return lodashIsEqual(sortedNewParticipantList, sortedParticipantsAccountIDs); + }); } /** * Attempts to find an invoice chat report in onyx with the provided policyID and receiverID. */ function getInvoiceChatByParticipants(policyID: string, receiverID: string | number, reports: OnyxCollection = allReports): OnyxEntry { - return ( - Object.values(reports ?? {}).find((report) => { - if (!report || !isInvoiceRoom(report)) { - return false; - } + return Object.values(reports ?? {}).find((report) => { + if (!report || !isInvoiceRoom(report)) { + return false; + } - const isSameReceiver = - report.invoiceReceiver && - (('accountID' in report.invoiceReceiver && report.invoiceReceiver.accountID === receiverID) || - ('policyID' in report.invoiceReceiver && report.invoiceReceiver.policyID === receiverID)); + const isSameReceiver = + report.invoiceReceiver && + (('accountID' in report.invoiceReceiver && report.invoiceReceiver.accountID === receiverID) || + ('policyID' in report.invoiceReceiver && report.invoiceReceiver.policyID === receiverID)); - return report.policyID === policyID && isSameReceiver; - }) ?? null - ); + return report.policyID === policyID && isSameReceiver; + }); } /** * Attempts to find a policy expense report in onyx that is owned by ownerAccountID in a given policy */ function getPolicyExpenseChat(ownerAccountID: number, policyID: string): OnyxEntry { - return ( - Object.values(allReports ?? {}).find((report: OnyxEntry) => { - // If the report has been deleted, then skip it - if (!report) { - return false; - } + return Object.values(allReports ?? {}).find((report: OnyxEntry) => { + // If the report has been deleted, then skip it + if (!report) { + return false; + } - return report.policyID === policyID && isPolicyExpenseChat(report) && report.ownerAccountID === ownerAccountID; - }) ?? null - ); + return report.policyID === policyID && isPolicyExpenseChat(report) && report.ownerAccountID === ownerAccountID; + }); } function getAllPolicyReports(policyID: string): Array> { @@ -5459,7 +5464,7 @@ function getAllPolicyReports(policyID: string): Array> { /** * Returns true if Chronos is one of the chat participants (1:1) */ -function chatIncludesChronos(report: OnyxEntry | EmptyObject): boolean { +function chatIncludesChronos(report: OnyxInputOrEntry | EmptyObject): boolean { const participantAccountIDs = Object.keys(report?.participants ?? {}).map(Number); return participantAccountIDs.includes(CONST.ACCOUNT_ID.CHRONOS); } @@ -5471,7 +5476,7 @@ function chatIncludesChronos(report: OnyxEntry | EmptyObject): boolean { * - It's a welcome message whisper * - It's an ADD_COMMENT that is not an attachment */ -function canFlagReportAction(reportAction: OnyxEntry, reportID: string | undefined): boolean { +function canFlagReportAction(reportAction: OnyxInputOrEntry, reportID: string | undefined): boolean { let report = getReport(reportID); // If the childReportID exists in reportAction and is equal to the reportID, @@ -5504,7 +5509,7 @@ function canFlagReportAction(reportAction: OnyxEntry, reportID: st /** * Whether flag comment page should show */ -function shouldShowFlagComment(reportAction: OnyxEntry, report: OnyxEntry): boolean { +function shouldShowFlagComment(reportAction: OnyxInputOrEntry, report: OnyxInputOrEntry): boolean { return ( canFlagReportAction(reportAction, report?.reportID) && !isArchivedRoom(report) && @@ -5615,7 +5620,7 @@ function getReportPolicyID(reportID?: string): string | undefined { /** * Check if the chat report is linked to an iou that is waiting for the current user to add a credit bank account. */ -function hasIOUWaitingOnCurrentUserBankAccount(chatReport: OnyxEntry): boolean { +function hasIOUWaitingOnCurrentUserBankAccount(chatReport: OnyxInputOrEntry): boolean { if (chatReport?.iouReportID) { const iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${chatReport?.iouReportID}`]; if (iouReport?.isWaitingOnBankAccount && iouReport?.ownerAccountID === currentUserAccountID) { @@ -5983,7 +5988,7 @@ function canUserPerformWriteAction(report: OnyxEntry, reportNameValuePai /** * Returns ID of the original report from which the given reportAction is first created. */ -function getOriginalReportID(reportID: string, reportAction: OnyxEntry): string | undefined { +function getOriginalReportID(reportID: string, reportAction: OnyxInputOrEntry): string | undefined { const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`]; const currentReportAction = reportActions?.[reportAction?.reportActionID ?? ''] ?? null; const transactionThreadReportID = ReportActionsUtils.getOneTransactionThreadReportID(reportID, reportActions ?? ([] as ReportAction[])); @@ -6227,7 +6232,7 @@ function getIOUReportActionDisplayMessage(reportAction: OnyxEntry, return Localize.translateLocal(translationKey, {amount: formattedAmount, payer: ''}); } - const transactionDetails = getTransactionDetails(!isEmptyObject(transaction) ? transaction : null); + const transactionDetails = getTransactionDetails(!isEmptyObject(transaction) ? transaction : undefined); const formattedAmount = CurrencyUtils.convertToDisplayString(transactionDetails?.amount ?? 0, transactionDetails?.currency); const isRequestSettled = isSettled(originalMessage.IOUReportID); const isApproved = isReportApproved(iouReport); @@ -6434,7 +6439,7 @@ function hasOnlyHeldExpenses(iouReportID: string): boolean { /** * Checks if thread replies should be displayed */ -function shouldDisplayThreadReplies(reportAction: OnyxEntry, reportID: string): boolean { +function shouldDisplayThreadReplies(reportAction: OnyxInputOrEntry, reportID: string): boolean { const hasReplies = (reportAction?.childVisibleActionCount ?? 0) > 0; return hasReplies && !!reportAction?.childCommenterCount && !isThreadFirstChat(reportAction, reportID); } @@ -6442,7 +6447,7 @@ function shouldDisplayThreadReplies(reportAction: OnyxEntry, repor /** * Check if money report has any transactions updated optimistically */ -function hasUpdatedTotal(report: OnyxEntry, policy: OnyxEntry): boolean { +function hasUpdatedTotal(report: OnyxInputOrEntry, policy: OnyxInputOrEntry): boolean { if (!report) { return true; } @@ -6458,7 +6463,7 @@ function hasUpdatedTotal(report: OnyxEntry, policy: OnyxEntry): /** * Return held and full amount formatted with used currency */ -function getNonHeldAndFullAmount(iouReport: OnyxEntry, policy: OnyxEntry): string[] { +function getNonHeldAndFullAmount(iouReport: OnyxInputOrEntry, policy: OnyxInputOrEntry): string[] { const transactions = TransactionUtils.getAllReportTransactions(iouReport?.reportID ?? ''); const hasPendingTransaction = transactions.some((transaction) => !!transaction.pendingAction); @@ -6484,7 +6489,7 @@ function getNonHeldAndFullAmount(iouReport: OnyxEntry, policy: OnyxEntry * - The action is a whisper action and it's neither a report preview nor IOU action * - The action is the thread's first chat */ -function shouldDisableThread(reportAction: OnyxEntry, reportID: string): boolean { +function shouldDisableThread(reportAction: OnyxInputOrEntry, reportID: string): boolean { const isSplitBillAction = ReportActionsUtils.isSplitBillAction(reportAction); const isDeletedAction = ReportActionsUtils.isDeletedAction(reportAction); const isReportPreviewAction = ReportActionsUtils.isReportPreviewAction(reportAction); @@ -6622,7 +6627,7 @@ function getOptimisticDataForParentReportAction(reportID: string, lastVisibleAct }); } -function canBeAutoReimbursed(report: OnyxEntry, policy: OnyxEntry | EmptyObject): boolean { +function canBeAutoReimbursed(report: OnyxInputOrEntry, policy: OnyxInputOrEntry | EmptyObject): boolean { if (isEmptyObject(policy)) { return false; } @@ -6639,7 +6644,7 @@ function canBeAutoReimbursed(report: OnyxEntry, policy: OnyxEntry): boolean { +function isReportOwner(report: OnyxInputOrEntry): boolean { return report?.ownerAccountID === currentUserPersonalDetails?.accountID; } @@ -6690,7 +6695,7 @@ function hasMissingPaymentMethod(userWallet: OnyxEntry, iouReportID: * - we have one, but it's waiting on the payee adding a bank account * - we have one, but we can't add more transactions to it due to: report is approved or settled, or report is processing and policy isn't on Instant submit reporting frequency */ -function shouldCreateNewMoneyRequestReport(existingIOUReport: OnyxEntry | undefined | null, chatReport: OnyxEntry | null): boolean { +function shouldCreateNewMoneyRequestReport(existingIOUReport: OnyxInputOrEntry | undefined, chatReport: OnyxInputOrEntry): boolean { return !existingIOUReport || hasIOUWaitingOnCurrentUserBankAccount(chatReport) || !canAddOrDeleteTransactions(existingIOUReport); } @@ -6709,14 +6714,14 @@ function hasActionsWithErrors(reportID: string): boolean { return Object.values(reportActions).some((action) => !isEmptyObject(action.errors)); } -function isNonAdminOrOwnerOfPolicyExpenseChat(report: OnyxEntry, policy: OnyxEntry): boolean { +function isNonAdminOrOwnerOfPolicyExpenseChat(report: OnyxInputOrEntry, policy: OnyxInputOrEntry): boolean { return isPolicyExpenseChat(report) && !(PolicyUtils.isPolicyAdmin(policy) || PolicyUtils.isPolicyOwner(policy, currentUserAccountID ?? -1) || isReportOwner(report)); } /** * Whether the user can join a report */ -function canJoinChat(report: OnyxEntry, parentReportAction: OnyxEntry, policy: OnyxEntry): boolean { +function canJoinChat(report: OnyxInputOrEntry, parentReportAction: OnyxInputOrEntry, policy: OnyxInputOrEntry): boolean { // We disabled thread functions for whisper action // So we should not show join option for existing thread on whisper message that has already been left, or manually leave it if (ReportActionsUtils.isWhisperAction(parentReportAction)) { @@ -6766,7 +6771,7 @@ function canLeaveChat(report: OnyxEntry, policy: OnyxEntry): boo return (isChatThread(report) && !!report?.notificationPreference?.length) || isUserCreatedPolicyRoom(report) || isNonAdminOrOwnerOfPolicyExpenseChat(report, policy); } -function getReportActionActorAccountID(reportAction: OnyxEntry, iouReport: OnyxEntry | undefined): number | undefined { +function getReportActionActorAccountID(reportAction: OnyxInputOrEntry, iouReport: OnyxInputOrEntry | undefined): number | undefined { switch (reportAction?.actionName) { case CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW: return iouReport ? iouReport.managerID : reportAction?.actorAccountID; @@ -6841,7 +6846,7 @@ function createDraftTransactionAndNavigateToParticipantSelector(transactionID: s /** * @returns the object to update `report.hasOutstandingChildRequest` */ -function getOutstandingChildRequest(iouReport: OnyxEntry | EmptyObject): OutstandingChildRequest { +function getOutstandingChildRequest(iouReport: OnyxInputOrEntry | EmptyObject): OutstandingChildRequest { if (!iouReport || isEmptyObject(iouReport)) { return {}; } diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index 31c015e431c4..43025225d964 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -4,7 +4,7 @@ import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Policy, RecentWaypoint, Report, TaxRate, TaxRates, Transaction, TransactionViolation, TransactionViolations} from '@src/types/onyx'; +import type {OnyxInputOrEntry, Policy, RecentWaypoint, Report, TaxRate, TaxRates, Transaction, TransactionViolation, TransactionViolations} from '@src/types/onyx'; import type {Comment, Receipt, TransactionChanges, TransactionPendingFieldsKey, Waypoint, WaypointCollection} from '@src/types/onyx/Transaction'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {IOURequestType} from './actions/IOU'; @@ -158,7 +158,7 @@ function hasEReceipt(transaction: Transaction | undefined | null): boolean { return !!transaction?.hasEReceipt; } -function hasReceipt(transaction: OnyxEntry | undefined): boolean { +function hasReceipt(transaction: OnyxInputOrEntry | undefined): boolean { return !!transaction?.receipt?.state || hasEReceipt(transaction); } @@ -284,7 +284,7 @@ function getUpdatedTransaction(transaction: Transaction, transactionChanges: Tra * Return the comment field (referred to as description in the App) from the transaction. * The comment does not have its modifiedComment counterpart. */ -function getDescription(transaction: OnyxEntry): string { +function getDescription(transaction: OnyxInputOrEntry): string { // Casting the description to string to avoid wrong data types (e.g. number) being returned from the API return transaction?.comment?.comment?.toString() ?? ''; } @@ -292,7 +292,7 @@ function getDescription(transaction: OnyxEntry): string { /** * Return the amount field from the transaction, return the modifiedAmount if present. */ -function getAmount(transaction: OnyxEntry, isFromExpenseReport = false, isFromTrackedExpense = false): number { +function getAmount(transaction: OnyxInputOrEntry, isFromExpenseReport = false, isFromTrackedExpense = false): number { // IOU requests cannot have negative values, but they can be stored as negative values, let's return absolute value if (!isFromExpenseReport || isFromTrackedExpense) { const amount = transaction?.modifiedAmount ?? 0; @@ -318,7 +318,7 @@ function getAmount(transaction: OnyxEntry, isFromExpenseReport = fa /** * Return the tax amount field from the transaction. */ -function getTaxAmount(transaction: OnyxEntry, isFromExpenseReport: boolean): number { +function getTaxAmount(transaction: OnyxInputOrEntry, isFromExpenseReport: boolean): number { // IOU requests cannot have negative values but they can be stored as negative values, let's return absolute value if (!isFromExpenseReport) { return Math.abs(transaction?.taxAmount ?? 0); @@ -332,14 +332,14 @@ function getTaxAmount(transaction: OnyxEntry, isFromExpenseReport: /** * Return the tax code from the transaction. */ -function getTaxCode(transaction: OnyxEntry): string { +function getTaxCode(transaction: OnyxInputOrEntry): string { return transaction?.taxCode ?? ''; } /** * Return the currency field from the transaction, return the modifiedCurrency if present. */ -function getCurrency(transaction: OnyxEntry): string { +function getCurrency(transaction: OnyxInputOrEntry): string { const currency = transaction?.modifiedCurrency ?? ''; if (currency) { return currency; @@ -372,11 +372,11 @@ function isFetchingWaypointsFromServer(transaction: OnyxEntry): boo /** * Return the merchant field from the transaction, return the modifiedMerchant if present. */ -function getMerchant(transaction: OnyxEntry): string { +function getMerchant(transaction: OnyxInputOrEntry): string { return transaction?.modifiedMerchant ? transaction.modifiedMerchant : transaction?.merchant ?? ''; } -function getDistance(transaction: OnyxEntry): number { +function getDistance(transaction: OnyxInputOrEntry): number { return transaction?.comment?.customUnit?.quantity ?? 0; } @@ -397,7 +397,7 @@ function getWaypoints(transaction: OnyxEntry): WaypointCollection | /** * Return the category from the transaction. This "category" field has no "modified" complement. */ -function getCategory(transaction: OnyxEntry): string { +function getCategory(transaction: OnyxInputOrEntry): string { return transaction?.category ?? ''; } @@ -411,7 +411,7 @@ function getCardID(transaction: Transaction): number { /** * Return the billable field from the transaction. This "billable" field has no "modified" complement. */ -function getBillable(transaction: OnyxEntry): boolean { +function getBillable(transaction: OnyxInputOrEntry): boolean { return transaction?.billable ?? false; } @@ -446,7 +446,7 @@ function getTagArrayFromName(tagName: string): string[] { * Return the tag from the transaction. When the tagIndex is passed, return the tag based on the index. * This "tag" field has no "modified" complement. */ -function getTag(transaction: OnyxEntry, tagIndex?: number): string { +function getTag(transaction: OnyxInputOrEntry, tagIndex?: number): string { if (tagIndex !== undefined) { const tagsArray = getTagArrayFromName(transaction?.tag ?? ''); return tagsArray[tagIndex] ?? ''; @@ -462,7 +462,7 @@ function getTagForDisplay(transaction: OnyxEntry, tagIndex?: number /** * Return the created field from the transaction, return the modifiedCreated if present. */ -function getCreated(transaction: OnyxEntry, dateFormat: string = CONST.DATE.FNS_FORMAT_STRING): string { +function getCreated(transaction: OnyxInputOrEntry, dateFormat: string = CONST.DATE.FNS_FORMAT_STRING): string { // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing const created = transaction?.modifiedCreated ? transaction.modifiedCreated : transaction?.created || ''; @@ -507,7 +507,7 @@ function isPosted(transaction: Transaction): boolean { return transaction.status === CONST.TRANSACTION.STATUS.POSTED; } -function isReceiptBeingScanned(transaction: OnyxEntry): boolean { +function isReceiptBeingScanned(transaction: OnyxInputOrEntry): boolean { return [CONST.IOU.RECEIPT_STATE.SCANREADY, CONST.IOU.RECEIPT_STATE.SCANNING].some((value) => value === transaction?.receipt?.state); } @@ -518,7 +518,7 @@ function didRceiptScanSucceed(transaction: OnyxEntry): boolean { /** * Check if the transaction has a non-smartscanning receipt and is missing required fields */ -function hasMissingSmartscanFields(transaction: OnyxEntry): boolean { +function hasMissingSmartscanFields(transaction: OnyxInputOrEntry): boolean { return !!(transaction && !isDistanceRequest(transaction) && !isReceiptBeingScanned(transaction) && areRequiredFieldsEmpty(transaction)); } @@ -667,7 +667,7 @@ function isOnHoldByTransactionID(transactionID: string): boolean { return false; } - return isOnHold(allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] ?? null); + return isOnHold(allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]); } /** @@ -711,7 +711,7 @@ function getEnabledTaxRateCount(options: TaxRates) { /** * Check if the customUnitRateID has a value default for P2P distance requests */ -function isCustomUnitRateIDForP2P(transaction: OnyxEntry): boolean { +function isCustomUnitRateIDForP2P(transaction: OnyxInputOrEntry): boolean { return transaction?.comment?.customUnit?.customUnitRateID === CONST.CUSTOM_UNITS.FAKE_P2P_ID; } @@ -722,7 +722,7 @@ function hasReservationList(transaction: Transaction | undefined | null): boolea /** * Get rate ID from the transaction object */ -function getRateID(transaction: OnyxEntry): string | undefined { +function getRateID(transaction: OnyxInputOrEntry): string | undefined { return transaction?.comment?.customUnit?.customUnitRateID?.toString(); } diff --git a/src/libs/actions/App.ts b/src/libs/actions/App.ts index ae7fc115ac22..dbe32185b71e 100644 --- a/src/libs/actions/App.ts +++ b/src/libs/actions/App.ts @@ -44,24 +44,24 @@ type PolicyParamsForOpenOrReconnect = { type Locale = ValueOf; -let currentUserAccountID: number | null; +let currentUserAccountID: number | undefined; let currentUserEmail: string; Onyx.connect({ key: ONYXKEYS.SESSION, callback: (val) => { - currentUserAccountID = val?.accountID ?? null; + currentUserAccountID = val?.accountID; currentUserEmail = val?.email ?? ''; }, }); -let isSidebarLoaded: boolean | null; +let isSidebarLoaded: boolean | undefined; Onyx.connect({ key: ONYXKEYS.IS_SIDEBAR_LOADED, callback: (val) => (isSidebarLoaded = val), initWithStoredValues: false, }); -let preferredLocale: string | null = null; +let preferredLocale: string | undefined; Onyx.connect({ key: ONYXKEYS.NVP_PREFERRED_LOCALE, callback: (val) => { @@ -74,7 +74,7 @@ Onyx.connect({ }, }); -let priorityMode: ValueOf | null; +let priorityMode: ValueOf | undefined; Onyx.connect({ key: ONYXKEYS.NVP_PRIORITY_MODE, callback: (nextPriorityMode) => { diff --git a/src/libs/actions/Device/index.ts b/src/libs/actions/Device/index.ts index ed700c06a97f..7ef3a4fd289f 100644 --- a/src/libs/actions/Device/index.ts +++ b/src/libs/actions/Device/index.ts @@ -20,8 +20,8 @@ function getDeviceID(): Promise { key: ONYXKEYS.DEVICE_ID, callback: (id) => { Onyx.disconnect(connectionID); - deviceID = id; - return resolve(id); + deviceID = id ?? null; + return resolve(id ?? null); }, }); }); diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 0957593b3998..969afd90eefa 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -1,6 +1,6 @@ import {format} from 'date-fns'; import {fastMerge, Str} from 'expensify-common'; -import type {OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry, OnyxInputValue, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import ReceiptGeneric from '@assets/images/receipt-generic.png'; @@ -165,11 +165,11 @@ Onyx.connect({ }, }); -let allReports: OnyxCollection = null; +let allReports: OnyxCollection | null = null; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT, waitForCollectionCallback: true, - callback: (value) => (allReports = value), + callback: (value) => (allReports = value ?? null), }); let allTransactions: NonNullable> = {}; @@ -287,7 +287,7 @@ Onyx.connect({ /** * Find the report preview action from given chat report and iou report */ -function getReportPreviewAction(chatReportID: string, iouReportID: string): OnyxEntry { +function getReportPreviewAction(chatReportID: string, iouReportID: string): OnyxInputValue { const reportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReportID}`] ?? {}; // Find the report preview action from the chat report @@ -450,7 +450,7 @@ function getReceiptError(receipt?: Receipt, filename?: string, isScanRequest = t /** Builds the Onyx data for an expense */ function buildOnyxDataForMoneyRequest( - chatReport: OnyxEntry, + chatReport: OnyxTypes.OnyxInputOrEntry, iouReport: OnyxTypes.Report, transaction: OnyxTypes.Transaction, chatCreatedAction: OptimisticCreatedReportAction, @@ -464,9 +464,9 @@ function buildOnyxDataForMoneyRequest( transactionThreadReport: OptimisticChatReport | EmptyObject, transactionThreadCreatedReportAction: OptimisticCreatedReportAction | EmptyObject, shouldCreateNewMoneyRequestReport: boolean, - policy?: OnyxEntry, - policyTagList?: OnyxEntry, - policyCategories?: OnyxEntry, + policy?: OnyxTypes.OnyxInputOrEntry, + policyTagList?: OnyxTypes.OnyxInputOrEntry, + policyCategories?: OnyxTypes.OnyxInputOrEntry, optimisticNextStep?: OnyxTypes.ReportNextStep | null, isOneOnOneSplit = false, existingTransactionThreadReportID?: string, @@ -1152,20 +1152,20 @@ function buildOnyxDataForInvoice( /** Builds the Onyx data for track expense */ function buildOnyxDataForTrackExpense( - chatReport: OnyxEntry, - iouReport: OnyxEntry, + chatReport: OnyxInputValue, + iouReport: OnyxInputValue, transaction: OnyxTypes.Transaction, iouCreatedAction: OptimisticCreatedReportAction, iouAction: OptimisticIOUReportAction, - reportPreviewAction: OnyxEntry, + reportPreviewAction: OnyxInputValue, transactionThreadReport: OptimisticChatReport | EmptyObject, transactionThreadCreatedReportAction: OptimisticCreatedReportAction | EmptyObject, shouldCreateNewMoneyRequestReport: boolean, - policy?: OnyxEntry, - policyTagList?: OnyxEntry, - policyCategories?: OnyxEntry, + policy?: OnyxInputValue, + policyTagList?: OnyxInputValue, + policyCategories?: OnyxInputValue, existingTransactionThreadReportID?: string, - actionableTrackExpenseWhisper?: OnyxEntry, + actionableTrackExpenseWhisper?: OnyxInputValue, ): [OnyxUpdate[], OnyxUpdate[], OnyxUpdate[]] { const isScanRequest = TransactionUtils.isScanRequest(transaction); const isDistanceRequest = TransactionUtils.isDistanceRequest(transaction); @@ -1886,7 +1886,7 @@ function getMoneyRequestInformation( // STEP 2: Get the Expense/IOU report. If the moneyRequestReportID has been provided, we want to add the transaction to this specific report. // If no such reportID has been provided, let's use the chatReport.iouReportID property. In case that is not present, build a new optimistic Expense/IOU report. - let iouReport: OnyxEntry = null; + let iouReport: OnyxInputValue = null; if (moneyRequestReportID) { iouReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${moneyRequestReportID}`] ?? null; } else { @@ -2112,7 +2112,7 @@ function getTrackExpenseInformation( // For this, first use the chatReport.iouReportID property. Build a new optimistic expense report if needed. const shouldUseMoneyReport = !!isPolicyExpenseChat; - let iouReport: OnyxEntry = null; + let iouReport: OnyxInputValue = null; let shouldCreateNewMoneyRequestReport = false; if (shouldUseMoneyReport) { @@ -2202,7 +2202,7 @@ function getTrackExpenseInformation( linkedTrackedExpenseReportAction, ); - let reportPreviewAction: OnyxEntry = null; + let reportPreviewAction: OnyxInputValue = null; if (shouldUseMoneyReport && iouReport) { reportPreviewAction = shouldCreateNewMoneyRequestReport ? null : getReportPreviewAction(chatReport.reportID, iouReport.reportID); @@ -2216,7 +2216,7 @@ function getTrackExpenseInformation( } } - let actionableTrackExpenseWhisper: OnyxEntry = null; + let actionableTrackExpenseWhisper: OnyxInputValue = null; if (!isPolicyExpenseChat) { actionableTrackExpenseWhisper = ReportUtils.buildOptimisticActionableTrackExpenseWhisper(iouAction, optimisticTransaction.transactionID); } @@ -2355,7 +2355,11 @@ function createDistanceRequest( /** * Compute the diff amount when we update the transaction */ -function calculateDiffAmount(iouReport: OnyxEntry, updatedTransaction: OnyxEntry, transaction: OnyxEntry): number { +function calculateDiffAmount( + iouReport: OnyxTypes.OnyxInputOrEntry, + updatedTransaction: OnyxTypes.OnyxInputOrEntry, + transaction: OnyxEntry, +): number { if (!iouReport) { return 0; } @@ -2383,10 +2387,10 @@ function calculateDiffAmount(iouReport: OnyxEntry, updatedTran } function calculateAmountForUpdatedWaypoint( - transaction: OnyxEntry, + transaction: OnyxTypes.OnyxInputOrEntry, transactionChanges: TransactionChanges, - policy: OnyxEntry, - iouReport: OnyxEntry, + policy: OnyxTypes.OnyxInputOrEntry, + iouReport: OnyxTypes.OnyxInputOrEntry, ) { let updatedAmount: number = CONST.IOU.DEFAULT_AMOUNT; let updatedMerchant = Localize.translateLocal('iou.fieldPending'); @@ -2425,9 +2429,9 @@ function getUpdateMoneyRequestParams( transactionID: string, transactionThreadReportID: string, transactionChanges: TransactionChanges, - policy: OnyxEntry, - policyTagList: OnyxEntry, - policyCategories: OnyxEntry, + policy: OnyxTypes.OnyxInputOrEntry, + policyTagList: OnyxTypes.OnyxInputOrEntry, + policyCategories: OnyxTypes.OnyxInputOrEntry, onlyIncludeChangedFields: boolean, ): UpdateMoneyRequestData { const optimisticData: OnyxUpdate[] = []; @@ -2713,7 +2717,7 @@ function getUpdateTrackExpenseParams( transactionThreadReportID: string, transactionChanges: TransactionChanges, onlyIncludeChangedFields: boolean, - policy: OnyxEntry, + policy: OnyxTypes.OnyxInputOrEntry, ): UpdateMoneyRequestData { const optimisticData: OnyxUpdate[] = []; const successData: OnyxUpdate[] = []; @@ -5899,7 +5903,7 @@ function getPayMoneyRequestParams( let currentNextStep = null; let optimisticNextStep = null; if (!isInvoiceReport) { - currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${iouReport.reportID}`]; + currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${iouReport.reportID}`] ?? null; optimisticNextStep = NextStepUtils.buildNextStep(iouReport, CONST.REPORT.STATUS_NUM.REIMBURSED, {isPaidWithExpensify: paymentMethodType === CONST.IOU.PAYMENT_TYPE.VBBA}); } @@ -6059,7 +6063,11 @@ function sendMoneyWithWallet(report: OnyxEntry, amount: number Report.notifyNewAction(params.chatReportID, managerID); } -function canApproveIOU(iouReport: OnyxEntry | EmptyObject, chatReport: OnyxEntry | EmptyObject, policy: OnyxEntry | EmptyObject) { +function canApproveIOU( + iouReport: OnyxTypes.OnyxInputOrEntry | EmptyObject, + chatReport: OnyxTypes.OnyxInputOrEntry | EmptyObject, + policy: OnyxTypes.OnyxInputOrEntry | EmptyObject, +) { if (isEmptyObject(chatReport)) { return false; } @@ -6086,7 +6094,11 @@ function canApproveIOU(iouReport: OnyxEntry | EmptyObject, cha return isCurrentUserManager && !isOpenExpenseReport && !isApproved && !iouSettled && !isArchivedReport; } -function canIOUBePaid(iouReport: OnyxEntry | EmptyObject, chatReport: OnyxEntry | EmptyObject, policy: OnyxEntry | EmptyObject) { +function canIOUBePaid( + iouReport: OnyxTypes.OnyxInputOrEntry | EmptyObject, + chatReport: OnyxTypes.OnyxInputOrEntry | EmptyObject, + policy: OnyxTypes.OnyxInputOrEntry | EmptyObject, +) { const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(chatReport); const isChatReportArchived = ReportUtils.isArchivedRoom(chatReport); const iouSettled = ReportUtils.isSettled(iouReport?.reportID); diff --git a/src/libs/actions/MapboxToken.ts b/src/libs/actions/MapboxToken.ts index 3b98f79698ba..923f5590b2bd 100644 --- a/src/libs/actions/MapboxToken.ts +++ b/src/libs/actions/MapboxToken.ts @@ -9,18 +9,18 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {MapboxAccessToken, Network} from '@src/types/onyx'; -let authToken: string | null; +let authToken: string | undefined; Onyx.connect({ key: ONYXKEYS.SESSION, callback: (value) => { - authToken = value?.authToken ?? null; + authToken = value?.authToken; }, }); let connectionIDForToken: number | null; let connectionIDForNetwork: number | null; let appStateSubscription: NativeEventSubscription | null; -let currentToken: MapboxAccessToken | null; +let currentToken: MapboxAccessToken | undefined; let refreshTimeoutID: NodeJS.Timeout | undefined; let isCurrentlyFetchingToken = false; const REFRESH_INTERVAL = 1000 * 60 * 25; @@ -117,7 +117,7 @@ const init = () => { } if (!connectionIDForNetwork) { - let network: Network | null; + let network: Network | undefined; connectionIDForNetwork = Onyx.connect({ key: ONYXKEYS.NETWORK, callback: (value) => { diff --git a/src/libs/actions/OnyxUpdates.ts b/src/libs/actions/OnyxUpdates.ts index fc651b0599b5..341027f1db65 100644 --- a/src/libs/actions/OnyxUpdates.ts +++ b/src/libs/actions/OnyxUpdates.ts @@ -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: number | undefined = 0; Onyx.connect({ key: ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, callback: (val) => (lastUpdateIDAppliedToClient = val), @@ -102,7 +102,7 @@ function apply({lastUpdateID, type, request, response, updates}: OnyxUpdatesFrom return Promise.resolve(); } - if (lastUpdateID && (lastUpdateIDAppliedToClient === null || Number(lastUpdateID) > lastUpdateIDAppliedToClient)) { + if (lastUpdateID && (lastUpdateIDAppliedToClient === undefined || Number(lastUpdateID) > lastUpdateIDAppliedToClient)) { Onyx.merge(ONYXKEYS.ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT, Number(lastUpdateID)); } if (type === CONST.ONYX_UPDATE_TYPES.HTTPS && request && response) { diff --git a/src/libs/actions/PersonalDetails.ts b/src/libs/actions/PersonalDetails.ts index b9cea5c9447c..daeb4ad58802 100644 --- a/src/libs/actions/PersonalDetails.ts +++ b/src/libs/actions/PersonalDetails.ts @@ -37,7 +37,7 @@ Onyx.connect({ }, }); -let allPersonalDetails: OnyxEntry = null; +let allPersonalDetails: OnyxEntry; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, callback: (val) => (allPersonalDetails = val), diff --git a/src/libs/actions/Policy/Member.ts b/src/libs/actions/Policy/Member.ts index ee2f02b68252..fc28a01b043c 100644 --- a/src/libs/actions/Policy/Member.ts +++ b/src/libs/actions/Policy/Member.ts @@ -1,5 +1,5 @@ import {ExpensiMark} from 'expensify-common'; -import type {NullishDeep, OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; +import type {NullishDeep, OnyxCollection, OnyxCollectionInputValue, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; import type { @@ -232,9 +232,9 @@ function removeMembers(accountIDs: number[], policyID: string) { const announceRoomMembers = removeOptimisticAnnounceRoomMembers(policy.id, policy.name, accountIDs); - const optimisticMembersState: OnyxCollection = {}; - const successMembersState: OnyxCollection = {}; - const failureMembersState: OnyxCollection = {}; + const optimisticMembersState: OnyxCollectionInputValue = {}; + const successMembersState: OnyxCollectionInputValue = {}; + const failureMembersState: OnyxCollectionInputValue = {}; emailList.forEach((email) => { optimisticMembersState[email] = {pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE}; successMembersState[email] = null; @@ -530,9 +530,9 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: InvitedEmailsToAccount // create onyx data for policy expense chats for each new member const membersChats = createPolicyExpenseChats(policyID, invitedEmailsToAccountIDs); - const optimisticMembersState: OnyxCollection = {}; - const successMembersState: OnyxCollection = {}; - const failureMembersState: OnyxCollection = {}; + const optimisticMembersState: OnyxCollectionInputValue = {}; + const successMembersState: OnyxCollectionInputValue = {}; + const failureMembersState: OnyxCollectionInputValue = {}; logins.forEach((email) => { optimisticMembersState[email] = {pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD, role: CONST.POLICY.ROLE.USER}; successMembersState[email] = {pendingAction: null}; diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index d934e217029b..8339b8f92f13 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -120,14 +120,14 @@ Onyx.connect({ }, }); -let allReports: OnyxCollection = null; +let allReports: OnyxCollection; Onyx.connect({ key: ONYXKEYS.COLLECTION.REPORT, waitForCollectionCallback: true, callback: (value) => (allReports = value), }); -let lastAccessedWorkspacePolicyID: OnyxEntry = null; +let lastAccessedWorkspacePolicyID: OnyxEntry; Onyx.connect({ key: ONYXKEYS.LAST_ACCESSED_WORKSPACE_POLICY_ID, callback: (value) => (lastAccessedWorkspacePolicyID = value), @@ -334,7 +334,7 @@ function deleteWorkspace(policyID: string, policyName: string) { // Reset the lastAccessedWorkspacePolicyID if (policyID === lastAccessedWorkspacePolicyID) { - updateLastAccessedWorkspace(null); + updateLastAccessedWorkspace(undefined); } } diff --git a/src/libs/actions/PriorityMode.ts b/src/libs/actions/PriorityMode.ts index 77347967b6cd..3679df575e9c 100644 --- a/src/libs/actions/PriorityMode.ts +++ b/src/libs/actions/PriorityMode.ts @@ -21,7 +21,7 @@ let isReadyPromise = new Promise((resolve) => { resolveIsReadyPromise = resolve; }); -let currentUserAccountID: number | undefined | null; +let currentUserAccountID: number | undefined; Onyx.connect({ key: ONYXKEYS.SESSION, callback: (val) => { @@ -70,11 +70,11 @@ Onyx.connect({ }, }); -let hasTriedFocusMode: boolean | undefined | null; +let hasTriedFocusMode: boolean | null | undefined; Onyx.connect({ key: ONYXKEYS.NVP_TRY_FOCUS_MODE, callback: (val) => { - hasTriedFocusMode = val; + hasTriedFocusMode = val ?? null; // eslint-disable-next-line @typescript-eslint/no-use-before-define checkRequiredData(); diff --git a/src/libs/actions/PushNotification.ts b/src/libs/actions/PushNotification.ts index bc4d4eb05c5a..f1b629f69754 100644 --- a/src/libs/actions/PushNotification.ts +++ b/src/libs/actions/PushNotification.ts @@ -8,7 +8,7 @@ let isUserOptedInToPushNotifications = false; Onyx.connect({ key: ONYXKEYS.PUSH_NOTIFICATIONS_ENABLED, callback: (value) => { - if (value === null) { + if (value === undefined) { return; } isUserOptedInToPushNotifications = value; @@ -35,7 +35,7 @@ function setPushNotificationOptInStatus(isOptingIn: boolean) { value: isUserOptedInToPushNotifications, }, ]; - API.write(commandName, {deviceID}, {optimisticData, failureData}); + API.write(commandName, {deviceID: deviceID}, {optimisticData, failureData}); }); } diff --git a/src/libs/actions/ReimbursementAccount/resetFreePlanBankAccount.ts b/src/libs/actions/ReimbursementAccount/resetFreePlanBankAccount.ts index 3ad8b9ffe599..f8d887fec47a 100644 --- a/src/libs/actions/ReimbursementAccount/resetFreePlanBankAccount.ts +++ b/src/libs/actions/ReimbursementAccount/resetFreePlanBankAccount.ts @@ -76,7 +76,6 @@ function resetFreePlanBankAccount(bankAccountID: number | undefined, session: On key: ONYXKEYS.PLAID_LINK_TOKEN, value: '', }, - // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT { onyxMethod: Onyx.METHOD.SET, key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, diff --git a/src/libs/actions/ReimbursementAccount/store.ts b/src/libs/actions/ReimbursementAccount/store.ts index c82843020f66..644fcbdf4def 100644 --- a/src/libs/actions/ReimbursementAccount/store.ts +++ b/src/libs/actions/ReimbursementAccount/store.ts @@ -4,7 +4,7 @@ import BankAccount from '@libs/models/BankAccount'; import ONYXKEYS from '@src/ONYXKEYS'; import type * as OnyxTypes from '@src/types/onyx'; -let bankAccountList: OnyxEntry = null; +let bankAccountList: OnyxEntry; Onyx.connect({ key: ONYXKEYS.BANK_ACCOUNT_LIST, callback: (val) => { diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 558f4c9e027a..fc6a12bd6fb5 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -92,7 +92,7 @@ Onyx.connect({ let preferredLocale: ValueOf | null = null; Onyx.connect({ key: ONYXKEYS.NVP_PREFERRED_LOCALE, - callback: (val) => (preferredLocale = val), + callback: (val) => (preferredLocale = val ?? null), }); function isSupportAuthToken(): boolean { diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 55d898d3d4f3..32cc2aee1892 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -117,7 +117,7 @@ function createTaskAndNavigate( description: string, assigneeEmail: string, assigneeAccountID = 0, - assigneeChatReport: OnyxEntry = null, + assigneeChatReport?: OnyxEntry, policyID: string = CONST.POLICY.OWNER_EMAIL_FAKE, ) { const optimisticTaskReport = ReportUtils.buildOptimisticTaskReport(currentUserAccountID, assigneeAccountID, parentReportID, title, description, policyID); @@ -508,13 +508,7 @@ function editTask(report: OnyxTypes.Report, {title, description}: OnyxTypes.Task Report.notifyNewAction(report.reportID, currentUserAccountID); } -function editTaskAssignee( - report: OnyxTypes.Report, - ownerAccountID: number, - assigneeEmail: string, - assigneeAccountID: number | null = 0, - assigneeChatReport: OnyxEntry = null, -) { +function editTaskAssignee(report: OnyxTypes.Report, ownerAccountID: number, assigneeEmail: string, assigneeAccountID: number | null = 0, assigneeChatReport?: OnyxEntry) { // Create the EditedReportAction on the task const editTaskReportAction = ReportUtils.buildOptimisticChangedTaskAssigneeReportAction(assigneeAccountID ?? 0); const reportName = report.reportName?.trim(); @@ -770,7 +764,7 @@ function getAssignee(assigneeAccountID: number, personalDetails: OnyxEntry, personalDetails: OnyxEntry): ShareDestination { - const report = reports?.[`report_${reportID}`] ?? null; + const report = reports?.[`report_${reportID}`]; const isOneOnOneChat = ReportUtils.isOneOnOneChat(report); diff --git a/src/libs/actions/TransactionEdit.ts b/src/libs/actions/TransactionEdit.ts index 970b34591103..98423ca48d0a 100644 --- a/src/libs/actions/TransactionEdit.ts +++ b/src/libs/actions/TransactionEdit.ts @@ -33,7 +33,7 @@ function restoreOriginalTransactionFromBackup(transactionID: string, isDraft: bo Onyx.disconnect(connectionID); // Use set to completely overwrite the original transaction - Onyx.set(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, backupTransaction); + Onyx.set(`${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, backupTransaction ?? null); removeBackupTransaction(transactionID); }, }); diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 8c9d4391bb46..5dc1b72b0bee 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -61,7 +61,7 @@ Onyx.connect({ }, }); -let myPersonalDetails: OnyxEntry | EmptyObject = {}; +let myPersonalDetails: OnyxEntry | EmptyObject | null = {}; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, callback: (value) => { diff --git a/src/libs/actions/Welcome.ts b/src/libs/actions/Welcome.ts index 2dbe47608ab9..3f70dc0d962d 100644 --- a/src/libs/actions/Welcome.ts +++ b/src/libs/actions/Welcome.ts @@ -80,7 +80,7 @@ Onyx.connect({ key: ONYXKEYS.NVP_ONBOARDING, initWithStoredValues: false, callback: (value) => { - if (value === null) { + if (value === undefined) { return; } diff --git a/src/libs/migrations/KeyReportActionsDraftByReportActionID.ts b/src/libs/migrations/KeyReportActionsDraftByReportActionID.ts index 193fdfe5f1eb..9ec85cf35745 100644 --- a/src/libs/migrations/KeyReportActionsDraftByReportActionID.ts +++ b/src/libs/migrations/KeyReportActionsDraftByReportActionID.ts @@ -1,4 +1,4 @@ -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxInputValue} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import Log from '@libs/Log'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -27,7 +27,7 @@ export default function () { return resolve(); } - const newReportActionsDrafts: Record> = {}; + const newReportActionsDrafts: Record> = {}; Object.entries(allReportActionsDrafts).forEach(([onyxKey, reportActionDraft]) => { if (typeof reportActionDraft !== 'string') { return; diff --git a/src/libs/migrations/NVPMigration.ts b/src/libs/migrations/NVPMigration.ts index dcab130186d3..7af3bc927c6b 100644 --- a/src/libs/migrations/NVPMigration.ts +++ b/src/libs/migrations/NVPMigration.ts @@ -32,7 +32,7 @@ export default function () { key: oldKey as OnyxKey, callback: (value) => { Onyx.disconnect(connectionID); - if (value === null) { + if (value === undefined) { resolveWhenDone(); return; } diff --git a/src/libs/migrations/PronounsMigration.ts b/src/libs/migrations/PronounsMigration.ts index 5fe911ae7f98..81744fde298c 100644 --- a/src/libs/migrations/PronounsMigration.ts +++ b/src/libs/migrations/PronounsMigration.ts @@ -17,7 +17,7 @@ function getCurrentUserAccountIDFromOnyx(): Promise { }); } -function getCurrentUserPersonalDetailsFromOnyx(currentUserAccountID: number): Promise> { +function getCurrentUserPersonalDetailsFromOnyx(currentUserAccountID: number): Promise> | null> { return new Promise((resolve) => { const connectionID = Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, @@ -35,7 +35,7 @@ function getCurrentUserPersonalDetailsFromOnyx(currentUserAccountID: number): Pr export default function (): Promise { return getCurrentUserAccountIDFromOnyx() .then(getCurrentUserPersonalDetailsFromOnyx) - .then((currentUserPersonalDetails: OnyxEntry) => { + .then((currentUserPersonalDetails) => { if (!currentUserPersonalDetails) { return; } diff --git a/src/libs/migrations/RemoveEmptyReportActionsDrafts.ts b/src/libs/migrations/RemoveEmptyReportActionsDrafts.ts index 48493a82d641..e063bdd67093 100644 --- a/src/libs/migrations/RemoveEmptyReportActionsDrafts.ts +++ b/src/libs/migrations/RemoveEmptyReportActionsDrafts.ts @@ -1,5 +1,5 @@ import _ from 'lodash'; -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxEntry, OnyxInputValue} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import Log from '@libs/Log'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -24,7 +24,7 @@ export default function (): Promise { return resolve(); } - const newReportActionsDrafts: Record> = {}; + const newReportActionsDrafts: Record> = {}; Object.entries(allReportActionsDrafts).forEach(([onyxKey, reportActionDrafts]) => { const newReportActionsDraftsForReport: Record = {}; diff --git a/src/libs/migrations/TransactionBackupsToCollection.ts b/src/libs/migrations/TransactionBackupsToCollection.ts index 8b963d7fa0c2..53fa7e855e72 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, OnyxCollectionInputValue, OnyxEntry} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import Log from '@libs/Log'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -26,7 +26,7 @@ export default function (): Promise { return resolve(); } - const onyxData: OnyxCollection = {}; + const onyxData: OnyxCollectionInputValue = {}; // Find all the transaction backups available Object.keys(transactions).forEach((transactionOnyxKey: string) => { diff --git a/src/pages/EditReportFieldPage.tsx b/src/pages/EditReportFieldPage.tsx index 33502cc357b4..9afa0566af34 100644 --- a/src/pages/EditReportFieldPage.tsx +++ b/src/pages/EditReportFieldPage.tsx @@ -51,7 +51,7 @@ function EditReportFieldPage({route, policy, report}: EditReportFieldPageProps) const styles = useThemeStyles(); const fieldKey = ReportUtils.getReportFieldKey(route.params.fieldID); const reportField = report?.fieldList?.[fieldKey] ?? policy?.fieldList?.[fieldKey]; - const isDisabled = ReportUtils.isReportFieldDisabled(report, reportField ?? null, policy); + const isDisabled = ReportUtils.isReportFieldDisabled(report, reportField, policy); const [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false); const {translate} = useLocalize(); diff --git a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/CompanyOwnersListUBO.tsx b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/CompanyOwnersListUBO.tsx index 542d3d0cf6d0..af92d2626ec0 100644 --- a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/CompanyOwnersListUBO.tsx +++ b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/CompanyOwnersListUBO.tsx @@ -74,7 +74,7 @@ function CompanyOwnersListUBO({ const {isOffline} = useNetwork(); const isLoading = reimbursementAccount?.isLoading ?? false; - const requestorData = getSubstepValues(REQUESTOR_PERSONAL_INFO_KEYS, null, reimbursementAccount); + const requestorData = getSubstepValues(REQUESTOR_PERSONAL_INFO_KEYS, undefined, reimbursementAccount); const error = ErrorUtils.getLatestErrorMessage(reimbursementAccount); const extraBeneficialOwners = diff --git a/src/pages/ReportDetailsPage.tsx b/src/pages/ReportDetailsPage.tsx index 673ddd02f398..704e04b78395 100644 --- a/src/pages/ReportDetailsPage.tsx +++ b/src/pages/ReportDetailsPage.tsx @@ -67,7 +67,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD const styles = useThemeStyles(); const [isLastMemberLeavingGroupModalVisible, setIsLastMemberLeavingGroupModalVisible] = useState(false); const policy = useMemo(() => policies?.[`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID ?? ''}`], [policies, report?.policyID]); - const isPolicyAdmin = useMemo(() => PolicyUtils.isPolicyAdmin(policy ?? null), [policy]); + const isPolicyAdmin = useMemo(() => PolicyUtils.isPolicyAdmin(policy), [policy]); const isPolicyEmployee = useMemo(() => PolicyUtils.isPolicyEmployee(report?.policyID ?? '', policies), [report?.policyID, policies]); const isPolicyExpenseChat = useMemo(() => ReportUtils.isPolicyExpenseChat(report), [report]); const shouldUseFullTitle = useMemo(() => ReportUtils.shouldUseFullTitleToDisplay(report), [report]); @@ -204,7 +204,7 @@ function ReportDetailsPage({policies, report, session, personalDetails}: ReportD }); } - if (isGroupChat || (isChatRoom && ReportUtils.canLeaveChat(report, policy ?? null))) { + if (isGroupChat || (isChatRoom && ReportUtils.canLeaveChat(report, policy))) { items.push({ key: CONST.REPORT_DETAILS_MENU_ITEM.LEAVE_ROOM, translationKey: 'common.leave', diff --git a/src/pages/home/HeaderView.tsx b/src/pages/home/HeaderView.tsx index 41ff0c3e7208..22a104984f2c 100644 --- a/src/pages/home/HeaderView.tsx +++ b/src/pages/home/HeaderView.tsx @@ -62,7 +62,7 @@ type HeaderViewProps = HeaderViewOnyxProps & { report: OnyxTypes.Report; /** The report action the transaction is tied to from the parent report */ - parentReportAction: OnyxEntry; + parentReportAction: OnyxEntry | null; /** The reportID of the current report */ reportID: string; @@ -392,8 +392,7 @@ export default memo( withOnyx({ guideCalendarLink: { key: ONYXKEYS.ACCOUNT, - selector: (account) => account?.guideCalendarLink ?? null, - initialValue: null, + selector: (account) => account?.guideCalendarLink, }, parentReport: { key: ({report}) => `${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID ?? report?.reportID}`, diff --git a/src/pages/home/ReportScreen.tsx b/src/pages/home/ReportScreen.tsx index 5d747a7cfa16..4ea02468e2a8 100644 --- a/src/pages/home/ReportScreen.tsx +++ b/src/pages/home/ReportScreen.tsx @@ -104,7 +104,7 @@ function isEmpty(report: OnyxTypes.Report): boolean { return !Object.values(report).some((value) => value !== undefined && value !== ''); } -function getParentReportAction(parentReportActions: OnyxEntry, parentReportActionID: string | undefined): OnyxEntry { +function getParentReportAction(parentReportActions: OnyxEntry, parentReportActionID: string | undefined): OnyxEntry | null { if (!parentReportActions || !parentReportActionID) { return null; } @@ -293,7 +293,7 @@ function ReportScreen({ const hasHelpfulErrors = Object.keys(report?.errorFields ?? {}).some((key) => key !== 'notFound'); const shouldHideReport = !hasHelpfulErrors && !ReportUtils.canAccessReport(report, policies, betas); - const lastReportAction: OnyxEntry = useMemo( + const lastReportAction: NonNullable> | null = useMemo( () => reportActions.length ? [...reportActions, parentReportAction].find((action) => ReportUtils.canEditReportAction(action) && !ReportActionsUtils.isMoneyRequestAction(action)) ?? null diff --git a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx index 46ebdd751762..1454d7ff1beb 100755 --- a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx +++ b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx @@ -127,7 +127,7 @@ function BaseReportActionContextMenu({ const {isOffline} = useNetwork(); const threedotRef = useRef(null); - const reportAction: OnyxEntry = useMemo(() => { + const reportAction: NonNullable> | null = useMemo(() => { if (isEmptyObject(reportActions) || reportActionID === '0') { return null; } diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index aa7b6aa3bfb5..007497400d72 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -27,13 +27,13 @@ import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ROUTES from '@src/ROUTES'; -import type {Beta, ReportAction, ReportActionReactions, Transaction} from '@src/types/onyx'; +import type {Beta, OnyxInputOrEntry, ReportAction, ReportActionReactions, Transaction} from '@src/types/onyx'; import type IconAsset from '@src/types/utils/IconAsset'; import type {ContextMenuAnchor} from './ReportActionContextMenu'; import {hideContextMenu, showDeleteModal} from './ReportActionContextMenu'; /** Gets the HTML version of the message in an action */ -function getActionHtml(reportAction: OnyxEntry): string { +function getActionHtml(reportAction: OnyxInputOrEntry): string { const message = reportAction?.message?.at(-1) ?? null; return message?.html ?? ''; } @@ -53,9 +53,9 @@ function setClipboardMessage(content: string) { type ShouldShow = ( type: string, - reportAction: OnyxEntry, + reportAction: OnyxInputOrEntry, isArchivedRoom: boolean, - betas: OnyxEntry, + betas: OnyxInputOrEntry, menuTarget: MutableRefObject | undefined, isChronosReport: boolean, reportID: string, diff --git a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx index a0e1d1bc50b9..69e6623746ba 100644 --- a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx +++ b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx @@ -34,7 +34,7 @@ function PopoverReportActionContextMenu(_props: unknown, ref: ForwardedRef(); - const reportActionRef = useRef>(null); + const reportActionRef = useRef> | null>(null); const reportActionIDRef = useRef('0'); const originalReportIDRef = useRef('0'); const selectionRef = useRef(''); @@ -294,7 +294,7 @@ function PopoverReportActionContextMenu(_props: unknown, ref: ForwardedRef; + lastReportAction?: OnyxEntry | null; /** Whether to include chronos */ includeChronos?: boolean; @@ -284,7 +284,7 @@ function ComposerWithSuggestions( const {isSmallScreenWidth} = useWindowDimensions(); const maxComposerLines = isSmallScreenWidth ? CONST.COMPOSER.MAX_LINES_SMALL_SCREEN : CONST.COMPOSER.MAX_LINES; - const parentReportAction = parentReportActions?.[parentReportActionID ?? ''] ?? null; + const parentReportAction = parentReportActions?.[parentReportActionID ?? '']; const shouldAutoFocus = !modal?.isVisible && Modal.areAllModalsHidden() && diff --git a/src/pages/home/report/ReportActionItem.tsx b/src/pages/home/report/ReportActionItem.tsx index a85523593b4c..1cf3d3d68d32 100644 --- a/src/pages/home/report/ReportActionItem.tsx +++ b/src/pages/home/report/ReportActionItem.tsx @@ -110,7 +110,7 @@ type ReportActionItemOnyxProps = { transaction: OnyxEntry; /** The transaction (linked with the report action) route error */ - linkedTransactionRouteError: OnyxEntry; + linkedTransactionRouteError: NonNullable> | null; }; type ReportActionItemProps = { @@ -125,12 +125,12 @@ type ReportActionItemProps = { reportActions: OnyxTypes.ReportAction[]; /** Report action belonging to the report's parent */ - parentReportAction: OnyxEntry; + parentReportAction: OnyxEntry | null; /** The transaction thread report's parentReportAction */ /** It's used by withOnyx HOC */ // eslint-disable-next-line react/no-unused-prop-types - parentReportActionForTransactionThread?: OnyxEntry; + parentReportActionForTransactionThread?: OnyxEntry | null; /** All the data of the action item */ action: OnyxTypes.ReportAction; diff --git a/src/pages/home/report/ReportActionItemMessageEdit.tsx b/src/pages/home/report/ReportActionItemMessageEdit.tsx index d22ef2167c4f..c5545c68c161 100644 --- a/src/pages/home/report/ReportActionItemMessageEdit.tsx +++ b/src/pages/home/report/ReportActionItemMessageEdit.tsx @@ -126,7 +126,7 @@ function ReportActionItemMessageEdit( const unsubscribeOnyxModal = onyxSubscribe({ key: ONYXKEYS.MODAL, callback: (modalArg) => { - if (modalArg === null) { + if (modalArg === undefined) { return; } setModal(modalArg); @@ -136,7 +136,7 @@ function ReportActionItemMessageEdit( const unsubscribeOnyxFocused = onyxSubscribe({ key: ONYXKEYS.INPUT_FOCUSED, callback: (modalArg) => { - if (modalArg === null) { + if (modalArg === undefined) { return; } setOnyxFocused(modalArg); diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index dd4e35510ed9..e0067cda7d07 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -38,7 +38,7 @@ type ReportActionItemParentActionProps = { reportActions: OnyxTypes.ReportAction[]; /** Report actions belonging to the report's parent */ - parentReportAction: OnyxEntry; + parentReportAction: OnyxEntry | null; /** Whether we should display "Replies" divider */ shouldDisplayReplyDivider: boolean; diff --git a/src/pages/home/report/ReportActionItemSingle.tsx b/src/pages/home/report/ReportActionItemSingle.tsx index ce5a27e3f065..94103bb81c8e 100644 --- a/src/pages/home/report/ReportActionItemSingle.tsx +++ b/src/pages/home/report/ReportActionItemSingle.tsx @@ -30,7 +30,7 @@ import ReportActionItemFragment from './ReportActionItemFragment'; type ReportActionItemSingleProps = Partial & { /** All the data of the action */ - action: OnyxEntry; + action: OnyxEntry | null; /** Styles for the outermost View */ wrapperStyle?: StyleProp; diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index c700fea4fb85..7e3835f265f4 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -48,10 +48,10 @@ type ReportActionsListProps = WithCurrentUserPersonalDetailsProps & { reportActions: OnyxTypes.ReportAction[]; /** The report's parentReportAction */ - parentReportAction: OnyxEntry; + parentReportAction: OnyxEntry | null; /** The transaction thread report's parentReportAction */ - parentReportActionForTransactionThread: OnyxEntry; + parentReportActionForTransactionThread: OnyxEntry | null; /** Sorted actions prepared for display */ sortedReportActions: OnyxTypes.ReportAction[]; diff --git a/src/pages/home/report/ReportActionsListItemRenderer.tsx b/src/pages/home/report/ReportActionsListItemRenderer.tsx index 18118e48f7cb..0390536e98a9 100644 --- a/src/pages/home/report/ReportActionsListItemRenderer.tsx +++ b/src/pages/home/report/ReportActionsListItemRenderer.tsx @@ -15,10 +15,10 @@ type ReportActionsListItemRendererProps = { reportActions: ReportAction[]; /** The report's parentReportAction */ - parentReportAction: OnyxEntry; + parentReportAction: OnyxEntry | null; /** The transaction thread report's parentReportAction */ - parentReportActionForTransactionThread: OnyxEntry; + parentReportActionForTransactionThread: OnyxEntry | null; /** Position index of the report action in the overall report FlatList view */ index: number; diff --git a/src/pages/home/report/ReportActionsView.tsx b/src/pages/home/report/ReportActionsView.tsx index 7084434733aa..5f1fa2c1745a 100755 --- a/src/pages/home/report/ReportActionsView.tsx +++ b/src/pages/home/report/ReportActionsView.tsx @@ -53,7 +53,7 @@ type ReportActionsViewProps = ReportActionsViewOnyxProps & { reportActions?: OnyxTypes.ReportAction[]; /** The report's parentReportAction */ - parentReportAction: OnyxEntry; + parentReportAction: OnyxEntry | null; /** The report metadata loading states */ isLoadingInitialReportActions?: boolean; diff --git a/src/pages/home/report/ReportFooter.tsx b/src/pages/home/report/ReportFooter.tsx index aa4139f8ee50..fee64056f6fe 100644 --- a/src/pages/home/report/ReportFooter.tsx +++ b/src/pages/home/report/ReportFooter.tsx @@ -52,7 +52,7 @@ type ReportFooterProps = ReportFooterOnyxProps & { policy: OnyxEntry; /** The last report action */ - lastReportAction?: OnyxEntry; + lastReportAction?: OnyxEntry | null; /** Whether the chat is empty */ isEmptyChat?: boolean; diff --git a/src/pages/home/report/SystemChatReportFooterMessage.tsx b/src/pages/home/report/SystemChatReportFooterMessage.tsx index 449fbb212cf1..6d739762c610 100644 --- a/src/pages/home/report/SystemChatReportFooterMessage.tsx +++ b/src/pages/home/report/SystemChatReportFooterMessage.tsx @@ -36,7 +36,7 @@ function SystemChatReportFooterMessage({choice, policies, activePolicyID}: Syste const adminChatReport = useMemo(() => { const adminPolicy = activePolicyID - ? PolicyUtils.getPolicy(activePolicyID ?? '') + ? PolicyUtils.getPolicy(activePolicyID) : Object.values(policies ?? {}).find((policy) => PolicyUtils.shouldShowPolicy(policy, false) && policy?.role === CONST.POLICY.ROLE.ADMIN && policy?.chatReportIDAdmins); return ReportUtils.getReport(String(adminPolicy?.chatReportIDAdmins)); @@ -86,6 +86,5 @@ export default withOnyx; /** The report's parentReportAction */ - parentReportAction: OnyxEntry; + parentReportAction: NonNullable> | null; /** The policies which the user has access to */ policies: OnyxCollection; @@ -129,7 +129,7 @@ export default function `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report ? report.parentReportID : 0}`, - selector: (parentReportActions: OnyxEntry, props: WithOnyxInstanceState): OnyxEntry => { + selector: (parentReportActions: OnyxEntry, props?: WithOnyxState): NonNullable> | null => { const parentReportActionID = props?.report?.parentReportActionID; if (!parentReportActionID) { return null; diff --git a/src/pages/iou/request/step/IOURequestStepDate.tsx b/src/pages/iou/request/step/IOURequestStepDate.tsx index 3a221b9a56db..d054dad5c11d 100644 --- a/src/pages/iou/request/step/IOURequestStepDate.tsx +++ b/src/pages/iou/request/step/IOURequestStepDate.tsx @@ -74,7 +74,7 @@ function IOURequestStepDate({ const parentReportAction = reportActions?.[(isEditingSplitBill ? reportActionID : report?.parentReportActionID) ?? 0]; const canEditingSplitBill = isEditingSplitBill && session && parentReportAction && session.accountID === parentReportAction.actorAccountID && TransactionUtils.areRequiredFieldsEmpty(transaction); - const canEditMoneyRequest = isEditing && ReportUtils.canEditFieldOfMoneyRequest(parentReportAction ?? null, CONST.EDIT_REQUEST_FIELD.DATE); + const canEditMoneyRequest = isEditing && ReportUtils.canEditFieldOfMoneyRequest(parentReportAction, CONST.EDIT_REQUEST_FIELD.DATE); // eslint-disable-next-line rulesdir/no-negated-variables const shouldShowNotFound = !IOUUtils.isValidMoneyRequestType(iouType) || (isEditing && !canEditMoneyRequest && !canEditingSplitBill); diff --git a/src/pages/settings/Report/ReportSettingsPage.tsx b/src/pages/settings/Report/ReportSettingsPage.tsx index 132ae06d4867..5f98a39263b0 100644 --- a/src/pages/settings/Report/ReportSettingsPage.tsx +++ b/src/pages/settings/Report/ReportSettingsPage.tsx @@ -30,7 +30,7 @@ function ReportSettingsPage({report, policies}: ReportSettingsPageProps) { const isGroupChat = ReportUtils.isGroupChat(report); const {translate} = useLocalize(); // The workspace the report is on, null if the user isn't a member of the workspace - const linkedWorkspace = useMemo(() => Object.values(policies ?? {}).find((policy) => policy && policy.id === report?.policyID) ?? null, [policies, report?.policyID]); + const linkedWorkspace = useMemo(() => Object.values(policies ?? {}).find((policy) => policy && policy.id === report?.policyID), [policies, report?.policyID]); const shouldDisableRename = useMemo(() => ReportUtils.shouldDisableRename(report, linkedWorkspace), [report, linkedWorkspace]); const isMoneyRequestReport = ReportUtils.isMoneyRequestReport(report); @@ -126,7 +126,7 @@ function ReportSettingsPage({report, policies}: ReportSettingsPageProps) { ))} - {linkedWorkspace !== null && ( + {linkedWorkspace != null && ( cardsToShow?.filter((card) => card?.nameValuePairs?.isVirtual), [cardsToShow]); const physicalCards = useMemo(() => cardsToShow?.filter((card) => !card?.nameValuePairs?.isVirtual), [cardsToShow]); - const [cardsDetails, setCardsDetails] = useState>({}); + const [cardsDetails, setCardsDetails] = useState>({}); const [isCardDetailsLoading, setIsCardDetailsLoading] = useState>({}); const [cardsDetailsErrors, setCardsDetailsErrors] = useState>({}); @@ -116,7 +116,7 @@ function ExpensifyCardPage({ // eslint-disable-next-line rulesdir/no-thenable-actions-in-views Card.revealVirtualCardDetails(revealedCardID) .then((value) => { - setCardsDetails((prevState: Record) => ({...prevState, [revealedCardID]: value as TCardDetails})); + setCardsDetails((prevState: Record) => ({...prevState, [revealedCardID]: value as TCardDetails})); setCardsDetailsErrors((prevState) => ({ ...prevState, [revealedCardID]: '', @@ -140,7 +140,7 @@ function ExpensifyCardPage({ const goToGetPhysicalCardFlow = () => { let updatedDraftValues = draftValues; if (!draftValues) { - updatedDraftValues = GetPhysicalCardUtils.getUpdatedDraftValues(null, privatePersonalDetails, loginList); + updatedDraftValues = GetPhysicalCardUtils.getUpdatedDraftValues(undefined, privatePersonalDetails, loginList); // Form draft data needs to be initialized with the private personal details // If no draft data exists FormActions.setDraftValues(ONYXKEYS.FORMS.GET_PHYSICAL_CARD_FORM, updatedDraftValues); diff --git a/src/pages/signin/SignInPage.tsx b/src/pages/signin/SignInPage.tsx index 407ce6304f2b..0b4310cce337 100644 --- a/src/pages/signin/SignInPage.tsx +++ b/src/pages/signin/SignInPage.tsx @@ -141,7 +141,7 @@ function getRenderOptions({ }; } -function SignInPageInner({credentials, account, activeClients = [], preferredLocale, shouldEnableMaxHeight = true}: SignInPageInnerProps) { +function SignInPage({credentials, account, activeClients = [], preferredLocale, shouldEnableMaxHeight = true}: SignInPageInnerProps) { const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const {translate, formatPhoneNumber} = useLocalize(); @@ -267,7 +267,7 @@ function SignInPageInner({credentials, account, activeClients = [], preferredLoc shouldShowOfflineIndicator={false} shouldEnableMaxHeight={shouldEnableMaxHeight} style={[styles.signInPage, StyleUtils.getSafeAreaPadding({...safeAreaInsets, bottom: 0, top: isInNarrowPaneModal ? 0 : safeAreaInsets.top}, 1)]} - testID={SignInPageInner.displayName} + testID={SignInPageThemeWrapper.displayName} > - @@ -326,6 +324,8 @@ function SignInPage(props: SignInPageProps) { ); } +SignInPageThemeWrapper.displayName = 'SignInPage'; + export default withOnyx({ account: {key: ONYXKEYS.ACCOUNT}, credentials: {key: ONYXKEYS.CREDENTIALS}, @@ -340,4 +340,4 @@ export default withOnyx({ preferredLocale: { key: ONYXKEYS.NVP_PREFERRED_LOCALE, }, -})(SignInPage); +})(SignInPageThemeWrapper); diff --git a/src/pages/tasks/NewTaskPage.tsx b/src/pages/tasks/NewTaskPage.tsx index 8f2c1a223db1..b079352aaa6d 100644 --- a/src/pages/tasks/NewTaskPage.tsx +++ b/src/pages/tasks/NewTaskPage.tsx @@ -52,7 +52,7 @@ function NewTaskPage({task, reports, personalDetails}: NewTaskPageProps) { const [title, setTitle] = useState(''); const [description, setDescription] = useState(''); const [errorMessage, setErrorMessage] = useState(''); - const [parentReport, setParentReport] = useState>(null); + const [parentReport, setParentReport] = useState>(); const hasDestinationError = task?.skipConfirmation && !task?.parentReportID; const isAllowedToCreateTask = useMemo(() => isEmptyObject(parentReport) || ReportUtils.isAllowedToComment(parentReport), [parentReport]); @@ -79,7 +79,7 @@ function NewTaskPage({task, reports, personalDetails}: NewTaskPageProps) { // If we have a share destination, we want to set the parent report and // the share destination data if (task?.shareDestination) { - setParentReport(reports?.[`report_${task.shareDestination}`] ?? null); + setParentReport(reports?.[`report_${task.shareDestination}`]); const displayDetails = TaskActions.getShareDestination(task.shareDestination, reports, personalDetails); setShareDestination(displayDetails); } diff --git a/src/pages/tasks/TaskAssigneeSelectorModal.tsx b/src/pages/tasks/TaskAssigneeSelectorModal.tsx index 225da1fbcefe..11a8e3848adc 100644 --- a/src/pages/tasks/TaskAssigneeSelectorModal.tsx +++ b/src/pages/tasks/TaskAssigneeSelectorModal.tsx @@ -103,14 +103,14 @@ function TaskAssigneeSelectorModal({reports, task}: TaskAssigneeSelectorModalPro const report: OnyxEntry = useMemo(() => { if (!route.params?.reportID) { - return null; + return; } if (report && !ReportUtils.isTaskReport(report)) { Navigation.isNavigationReady().then(() => { Navigation.dismissModal(report.reportID); }); } - return reports?.[`${ONYXKEYS.COLLECTION.REPORT}${route.params?.reportID}`] ?? null; + return reports?.[`${ONYXKEYS.COLLECTION.REPORT}${route.params?.reportID}`]; }, [reports, route]); const sections = useMemo(() => { @@ -172,7 +172,7 @@ function TaskAssigneeSelectorModal({reports, task}: TaskAssigneeSelectorModalPro option?.login ?? '', option?.accountID ?? -1, report.reportID, - null, // passing null as report because for editing task the report will be task details report page not the actual report where task was created + undefined, // passing null as report because for editing task the report will be task details report page not the actual report where task was created OptionsListUtils.isCurrentUser({...option, accountID: option?.accountID ?? -1, login: option?.login ?? ''}), ); @@ -186,7 +186,7 @@ function TaskAssigneeSelectorModal({reports, task}: TaskAssigneeSelectorModalPro option?.login ?? '', option.accountID, task?.shareDestination ?? '', - null, // passing null as report is null in this condition + undefined, // passing null as report is null in this condition OptionsListUtils.isCurrentUser({...option, accountID: option?.accountID ?? -1, login: option?.login ?? undefined}), ); Navigation.goBack(ROUTES.NEW_TASK); diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index 4afd3e1b31dd..796a067833c0 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -28,7 +28,7 @@ const ACCESS_VARIANTS = { policy: OnyxEntry, login: string, report: OnyxEntry, - allPolicies: OnyxCollection, + allPolicies: NonNullable> | null, iouType?: IOUType, ) => !!iouType && @@ -36,7 +36,10 @@ const ACCESS_VARIANTS = { // Allow the user to submit the expense if we are submitting the expense in global menu or the report can create the expense (isEmptyObject(report?.reportID) || ReportUtils.canCreateRequest(report, policy, iouType)) && (iouType !== CONST.IOU.TYPE.INVOICE || PolicyUtils.canSendInvoice(allPolicies)), -} as const satisfies Record, iouType?: IOUType) => boolean>; +} as const satisfies Record< + string, + (policy: OnyxTypes.Policy, login: string, report: OnyxTypes.Report, allPolicies: NonNullable> | null, iouType?: IOUType) => boolean +>; type AccessVariant = keyof typeof ACCESS_VARIANTS; type AccessOrNotFoundWrapperOnyxProps = { diff --git a/src/pages/workspace/WorkspaceNewRoomPage.tsx b/src/pages/workspace/WorkspaceNewRoomPage.tsx index 393afcd25eb8..13b3bde2ce4b 100644 --- a/src/pages/workspace/WorkspaceNewRoomPage.tsx +++ b/src/pages/workspace/WorkspaceNewRoomPage.tsx @@ -358,6 +358,5 @@ export default withOnyx = OnyxEntry | OnyxInputValue; + +export default OnyxInputOrEntry; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 85f383aa74ce..5a70ddd48d9e 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -28,6 +28,7 @@ import type MapboxAccessToken from './MapboxAccessToken'; import type Modal from './Modal'; import type Network from './Network'; import type NewGroupChatDraft from './NewGroupChatDraft'; +import type OnyxInputOrEntry from './OnyxInputOrEntry'; import type {OnyxUpdateEvent, OnyxUpdatesFromServer} from './OnyxUpdatesFromServer'; import type {DecisionName, OriginalMessageIOU} from './OriginalMessage'; import type PersonalBankAccount from './PersonalBankAccount'; @@ -111,6 +112,7 @@ export type { MapboxAccessToken, Modal, Network, + OnyxInputOrEntry, OnyxUpdateEvent, OnyxUpdatesFromServer, PersonalBankAccount, diff --git a/src/types/utils/CollectionDataSet.ts b/src/types/utils/CollectionDataSet.ts index b8065cee8f84..c48d1568534e 100644 --- a/src/types/utils/CollectionDataSet.ts +++ b/src/types/utils/CollectionDataSet.ts @@ -1,12 +1,12 @@ -import type {OnyxEntry} from 'react-native-onyx'; +import type {OnyxInputValue} from 'react-native-onyx'; import type {OnyxCollectionKey, OnyxCollectionValuesMapping} from '@src/ONYXKEYS'; /** Helps with typing a collection item update inside Onyx.multiSet call */ -type CollectionDataSet = Record<`${TCollectionKey}${string}`, OnyxEntry>; +type CollectionDataSet = Record<`${TCollectionKey}${string}`, OnyxInputValue>; const toCollectionDataSet = ( collectionKey: TCollectionKey, - collection: Array>, + collection: Array>, idSelector: (collectionValue: OnyxCollectionValuesMapping[TCollectionKey]) => string, ) => { const collectionDataSet = collection.reduce>((result, collectionValue) => { diff --git a/tests/actions/IOUTest.ts b/tests/actions/IOUTest.ts index 4640167c2c60..510e05028f22 100644 --- a/tests/actions/IOUTest.ts +++ b/tests/actions/IOUTest.ts @@ -313,11 +313,10 @@ describe('actions/IOU', () => { callback: (allIOUReportActions) => { Onyx.disconnect(connectionID); - iouCreatedAction = Object.values(allIOUReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ?? null; - iouAction = - Object.values(allIOUReportActions ?? {}).find( - (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU, - ) ?? null; + iouCreatedAction = Object.values(allIOUReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED); + iouAction = Object.values(allIOUReportActions ?? {}).find( + (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU, + ); // The CREATED action should not be created after the IOU action expect(Date.parse(iouCreatedAction?.created ?? '')).toBeLessThan(Date.parse(iouAction?.created ?? '')); @@ -492,8 +491,8 @@ describe('actions/IOU', () => { expect(Object.values(allReports ?? {}).find((report) => report?.reportID === chatReportID)).toBeTruthy(); expect(Object.values(allReports ?? {}).find((report) => report?.reportID === iouReportID)).toBeTruthy(); - chatReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.CHAT) ?? null; - iouReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU) ?? null; + chatReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.CHAT); + iouReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU); // The total on the iou report should be updated expect(iouReport?.total).toBe(11000); @@ -513,11 +512,10 @@ describe('actions/IOU', () => { Onyx.disconnect(connectionID); expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(3); - newIOUAction = - Object.values(reportActionsForIOUReport ?? {}).find( - (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => - reportAction?.reportActionID !== createdAction.reportActionID && reportAction?.reportActionID !== iouAction?.reportActionID, - ) ?? null; + newIOUAction = Object.values(reportActionsForIOUReport ?? {}).find( + (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => + reportAction?.reportActionID !== createdAction.reportActionID && reportAction?.reportActionID !== iouAction?.reportActionID, + ); // The IOUReportID should be correct expect(iouAction.originalMessage.IOUReportID).toBe(iouReportID); @@ -551,7 +549,7 @@ describe('actions/IOU', () => { // There should be two transactions expect(Object.values(allTransactions ?? {}).length).toBe(2); - newTransaction = Object.values(allTransactions ?? {}).find((transaction) => transaction?.transactionID !== existingTransaction.transactionID) ?? null; + newTransaction = Object.values(allTransactions ?? {}).find((transaction) => transaction?.transactionID !== existingTransaction.transactionID); expect(newTransaction?.reportID).toBe(iouReportID); expect(newTransaction?.amount).toBe(amount); @@ -733,7 +731,7 @@ describe('actions/IOU', () => { callback: (reportActionsForIOUReport) => { Onyx.disconnect(connectionID); expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(2); - iouAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + iouAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(iouAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); resolve(); }, @@ -749,10 +747,9 @@ describe('actions/IOU', () => { callback: (reportActionsForTransactionThread) => { Onyx.disconnect(connectionID); expect(Object.values(reportActionsForTransactionThread ?? {}).length).toBe(3); - transactionThreadAction = - Object.values(reportActionsForTransactionThread?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport?.reportID}`] ?? {}).find( - (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED, - ) ?? null; + transactionThreadAction = Object.values( + reportActionsForTransactionThread?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport?.reportID}`] ?? {}, + ).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED); expect(transactionThreadAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); resolve(); }, @@ -794,7 +791,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: false, callback: (reportActionsForReport) => { Onyx.disconnect(connectionID); - iouAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + iouAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(iouAction).toBeFalsy(); resolve(); }, @@ -811,7 +808,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: false, callback: (reportActionsForReport) => { Onyx.disconnect(connectionID); - iouAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + iouAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(iouAction).toBeFalsy(); resolve(); }, @@ -1096,54 +1093,50 @@ describe('actions/IOU', () => { expect(Object.values(allReports ?? {}).length).toBe(10); // 1. The chat report with Rory + Carlos - carlosChatReport = Object.values(allReports ?? {}).find((report) => report?.reportID === carlosChatReport?.reportID) ?? null; + carlosChatReport = Object.values(allReports ?? {}).find((report) => report?.reportID === carlosChatReport?.reportID); expect(isEmptyObject(carlosChatReport)).toBe(false); expect(carlosChatReport?.pendingFields).toBeFalsy(); // 2. The IOU report with Rory + Carlos (new) - carlosIOUReport = - Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU && report.managerID === CARLOS_ACCOUNT_ID) ?? null; + carlosIOUReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU && report.managerID === CARLOS_ACCOUNT_ID); expect(isEmptyObject(carlosIOUReport)).toBe(false); expect(carlosIOUReport?.total).toBe(amount / 4); // 3. The chat report with Rory + Jules - julesChatReport = Object.values(allReports ?? {}).find((report) => report?.reportID === julesChatReport?.reportID) ?? null; + julesChatReport = Object.values(allReports ?? {}).find((report) => report?.reportID === julesChatReport?.reportID); expect(isEmptyObject(julesChatReport)).toBe(false); expect(julesChatReport?.pendingFields).toBeFalsy(); // 4. The IOU report with Rory + Jules - julesIOUReport = Object.values(allReports ?? {}).find((report) => report?.reportID === julesIOUReport?.reportID) ?? null; + julesIOUReport = Object.values(allReports ?? {}).find((report) => report?.reportID === julesIOUReport?.reportID); expect(isEmptyObject(julesIOUReport)).toBe(false); expect(julesChatReport?.pendingFields).toBeFalsy(); expect(julesIOUReport?.total).toBe((julesExistingTransaction?.amount ?? 0) + amount / 4); // 5. The chat report with Rory + Vit (new) - vitChatReport = - Object.values(allReports ?? {}).find( - (report) => - report?.type === CONST.REPORT.TYPE.CHAT && - isEqual(report.participants, {[RORY_ACCOUNT_ID]: RORY_PARTICIPANT, [VIT_ACCOUNT_ID]: VIT_PARTICIPANT}), - ) ?? null; + vitChatReport = Object.values(allReports ?? {}).find( + (report) => + report?.type === CONST.REPORT.TYPE.CHAT && isEqual(report.participants, {[RORY_ACCOUNT_ID]: RORY_PARTICIPANT, [VIT_ACCOUNT_ID]: VIT_PARTICIPANT}), + ); expect(isEmptyObject(vitChatReport)).toBe(false); expect(vitChatReport?.pendingFields).toStrictEqual({createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}); // 6. The IOU report with Rory + Vit (new) - vitIOUReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU && report.managerID === VIT_ACCOUNT_ID) ?? null; + vitIOUReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU && report.managerID === VIT_ACCOUNT_ID); expect(isEmptyObject(vitIOUReport)).toBe(false); expect(vitIOUReport?.total).toBe(amount / 4); // 7. The group chat with everyone - groupChat = - Object.values(allReports ?? {}).find( - (report) => - report?.type === CONST.REPORT.TYPE.CHAT && - isEqual(report.participants, { - [CARLOS_ACCOUNT_ID]: CARLOS_PARTICIPANT, - [JULES_ACCOUNT_ID]: JULES_PARTICIPANT, - [VIT_ACCOUNT_ID]: VIT_PARTICIPANT, - [RORY_ACCOUNT_ID]: RORY_PARTICIPANT, - }), - ) ?? null; + groupChat = Object.values(allReports ?? {}).find( + (report) => + report?.type === CONST.REPORT.TYPE.CHAT && + isEqual(report.participants, { + [CARLOS_ACCOUNT_ID]: CARLOS_PARTICIPANT, + [JULES_ACCOUNT_ID]: JULES_PARTICIPANT, + [VIT_ACCOUNT_ID]: VIT_PARTICIPANT, + [RORY_ACCOUNT_ID]: RORY_PARTICIPANT, + }), + ); expect(isEmptyObject(groupChat)).toBe(false); expect(groupChat?.pendingFields).toStrictEqual({createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}); @@ -1183,14 +1176,12 @@ describe('actions/IOU', () => { // Carlos DM should have two reportActions – the existing CREATED action and a pending IOU action expect(Object.values(carlosReportActions ?? {}).length).toBe(2); - carlosIOUCreatedAction = - Object.values(carlosReportActions ?? {}).find( - (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED, - ) ?? null; - carlosIOUAction = - Object.values(carlosReportActions ?? {}).find( - (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU, - ) ?? null; + carlosIOUCreatedAction = Object.values(carlosReportActions ?? {}).find( + (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED, + ); + carlosIOUAction = Object.values(carlosReportActions ?? {}).find( + (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU, + ); expect(carlosIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); expect(carlosIOUAction?.originalMessage.IOUReportID).toBe(carlosIOUReport?.reportID); expect(carlosIOUAction?.originalMessage.amount).toBe(amount / 4); @@ -1201,15 +1192,13 @@ describe('actions/IOU', () => { // Jules DM should have three reportActions, the existing CREATED action, the existing IOU action, and a new pending IOU action expect(Object.values(julesReportActions ?? {}).length).toBe(3); expect(julesReportActions?.[julesCreatedAction.reportActionID]).toStrictEqual(julesCreatedAction); - julesIOUCreatedAction = - Object.values(julesReportActions ?? {}).find( - (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED, - ) ?? null; - julesIOUAction = - Object.values(julesReportActions ?? {}).find( - (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => - reportAction.reportActionID !== julesCreatedAction.reportActionID && reportAction.reportActionID !== julesExistingIOUAction.reportActionID, - ) ?? null; + julesIOUCreatedAction = Object.values(julesReportActions ?? {}).find( + (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED, + ); + julesIOUAction = Object.values(julesReportActions ?? {}).find( + (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => + reportAction.reportActionID !== julesCreatedAction.reportActionID && reportAction.reportActionID !== julesExistingIOUAction.reportActionID, + ); expect(julesIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); expect(julesIOUAction?.originalMessage.IOUReportID).toBe(julesIOUReport?.reportID); expect(julesIOUAction?.originalMessage.amount).toBe(amount / 4); @@ -1219,14 +1208,12 @@ describe('actions/IOU', () => { // Vit DM should have two reportActions – a pending CREATED action and a pending IOU action expect(Object.values(vitReportActions ?? {}).length).toBe(2); - vitCreatedAction = - Object.values(vitReportActions ?? {}).find( - (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED, - ) ?? null; - vitIOUAction = - Object.values(vitReportActions ?? {}).find( - (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU, - ) ?? null; + vitCreatedAction = Object.values(vitReportActions ?? {}).find( + (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED, + ); + vitIOUAction = Object.values(vitReportActions ?? {}).find( + (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU, + ); expect(vitCreatedAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); expect(vitIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); expect(vitIOUAction?.originalMessage.IOUReportID).toBe(vitIOUReport?.reportID); @@ -1237,12 +1224,10 @@ describe('actions/IOU', () => { // Group chat should have two reportActions – a pending CREATED action and a pending IOU action w/ type SPLIT expect(Object.values(groupReportActions ?? {}).length).toBe(2); - groupCreatedAction = - Object.values(groupReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED) ?? null; - groupIOUAction = - Object.values(groupReportActions ?? {}).find( - (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU, - ) ?? null; + groupCreatedAction = Object.values(groupReportActions ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.CREATED); + groupIOUAction = Object.values(groupReportActions ?? {}).find( + (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU, + ); expect(groupCreatedAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); expect(groupIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); expect(groupIOUAction?.originalMessage).not.toHaveProperty('IOUReportID'); @@ -1271,19 +1256,16 @@ describe('actions/IOU', () => { expect(Object.values(allTransactions ?? {}).length).toBe(5); expect(allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${julesExistingTransaction?.transactionID}`]).toBeTruthy(); - carlosTransaction = - Object.values(allTransactions ?? {}).find( - (transaction) => transaction?.transactionID === (carlosIOUAction?.originalMessage as IOUMessage)?.IOUTransactionID, - ) ?? null; - julesTransaction = - Object.values(allTransactions ?? {}).find( - (transaction) => transaction?.transactionID === (julesIOUAction?.originalMessage as IOUMessage)?.IOUTransactionID, - ) ?? null; - vitTransaction = - Object.values(allTransactions ?? {}).find( - (transaction) => transaction?.transactionID === (vitIOUAction?.originalMessage as IOUMessage)?.IOUTransactionID, - ) ?? null; - groupTransaction = Object.values(allTransactions ?? {}).find((transaction) => transaction?.reportID === CONST.REPORT.SPLIT_REPORTID) ?? null; + carlosTransaction = Object.values(allTransactions ?? {}).find( + (transaction) => transaction?.transactionID === (carlosIOUAction?.originalMessage as IOUMessage)?.IOUTransactionID, + ); + julesTransaction = Object.values(allTransactions ?? {}).find( + (transaction) => transaction?.transactionID === (julesIOUAction?.originalMessage as IOUMessage)?.IOUTransactionID, + ); + vitTransaction = Object.values(allTransactions ?? {}).find( + (transaction) => transaction?.transactionID === (vitIOUAction?.originalMessage as IOUMessage)?.IOUTransactionID, + ); + groupTransaction = Object.values(allTransactions ?? {}).find((transaction) => transaction?.reportID === CONST.REPORT.SPLIT_REPORTID); expect(carlosTransaction?.reportID).toBe(carlosIOUReport?.reportID); expect(julesTransaction?.reportID).toBe(julesIOUReport?.reportID); @@ -1423,7 +1405,7 @@ describe('actions/IOU', () => { expect(chatReport).toHaveProperty('reportID'); expect(chatReport).toHaveProperty('iouReportID'); - iouReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU) ?? null; + iouReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU); expect(iouReport).toBeTruthy(); expect(iouReport).toHaveProperty('reportID'); expect(iouReport).toHaveProperty('chatReportID'); @@ -1450,8 +1432,7 @@ describe('actions/IOU', () => { const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`]; - createIOUAction = - Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(createIOUAction).toBeTruthy(); expect((createIOUAction?.originalMessage as IOUMessage)?.IOUReportID).toBe(iouReport?.reportID); @@ -1469,7 +1450,7 @@ describe('actions/IOU', () => { callback: (allTransactions) => { Onyx.disconnect(connectionID); expect(Object.values(allTransactions ?? {}).length).toBe(1); - transaction = Object.values(allTransactions ?? {}).find((t) => t) ?? null; + transaction = Object.values(allTransactions ?? {}).find((t) => t); expect(transaction).toBeTruthy(); expect(transaction?.amount).toBe(amount); expect(transaction?.reportID).toBe(iouReport?.reportID); @@ -1497,8 +1478,8 @@ describe('actions/IOU', () => { expect(Object.values(allReports ?? {}).length).toBe(3); - chatReport = Object.values(allReports ?? {}).find((r) => r?.type === CONST.REPORT.TYPE.CHAT) ?? null; - iouReport = Object.values(allReports ?? {}).find((r) => r?.type === CONST.REPORT.TYPE.IOU) ?? null; + chatReport = Object.values(allReports ?? {}).find((r) => r?.type === CONST.REPORT.TYPE.CHAT); + iouReport = Object.values(allReports ?? {}).find((r) => r?.type === CONST.REPORT.TYPE.IOU); expect(chatReport?.iouReportID).toBeFalsy(); @@ -1522,11 +1503,10 @@ describe('actions/IOU', () => { const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`]; expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(3); - payIOUAction = - Object.values(reportActionsForIOUReport ?? {}).find( - (reportAction) => - reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && reportAction?.originalMessage?.type === CONST.IOU.REPORT_ACTION_TYPE.PAY, - ) ?? null; + payIOUAction = Object.values(reportActionsForIOUReport ?? {}).find( + (reportAction) => + reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && reportAction?.originalMessage?.type === CONST.IOU.REPORT_ACTION_TYPE.PAY, + ); expect(payIOUAction).toBeTruthy(); expect(payIOUAction?.pendingAction).toBe(CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD); @@ -1547,8 +1527,8 @@ describe('actions/IOU', () => { expect(Object.values(allReports ?? {}).length).toBe(3); - chatReport = Object.values(allReports ?? {}).find((r) => r?.type === CONST.REPORT.TYPE.CHAT) ?? null; - iouReport = Object.values(allReports ?? {}).find((r) => r?.type === CONST.REPORT.TYPE.IOU) ?? null; + chatReport = Object.values(allReports ?? {}).find((r) => r?.type === CONST.REPORT.TYPE.CHAT); + iouReport = Object.values(allReports ?? {}).find((r) => r?.type === CONST.REPORT.TYPE.IOU); expect(chatReport?.iouReportID).toBeFalsy(); @@ -1572,11 +1552,9 @@ describe('actions/IOU', () => { const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport?.reportID}`]; expect(Object.values(reportActionsForIOUReport ?? {}).length).toBe(3); - payIOUAction = - Object.values(reportActionsForIOUReport ?? {}).find( - (reportAction) => - reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && reportAction.originalMessage.type === CONST.IOU.REPORT_ACTION_TYPE.PAY, - ) ?? null; + payIOUAction = Object.values(reportActionsForIOUReport ?? {}).find( + (reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && reportAction.originalMessage.type === CONST.IOU.REPORT_ACTION_TYPE.PAY, + ); expect(payIOUAction).toBeTruthy(); resolve(); @@ -1598,9 +1576,9 @@ describe('actions/IOU', () => { it('updates the IOU request and IOU report when offline', () => { let thread: OptimisticChatReport; - let iouReport: OnyxEntry = null; - let iouAction: OnyxEntry = null; - let transaction: OnyxEntry = null; + let iouReport: OnyxEntry; + let iouAction: OnyxEntry; + let transaction: OnyxEntry; mockFetch?.pause?.(); IOU.requestMoney({reportID: ''}, amount, CONST.CURRENCY.USD, '', merchant, RORY_EMAIL, RORY_ACCOUNT_ID, {login: CARLOS_EMAIL, accountID: CARLOS_ACCOUNT_ID}, comment, {}); @@ -1617,7 +1595,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - iouReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU) ?? null; + iouReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU); resolve(); }, @@ -1648,7 +1626,7 @@ describe('actions/IOU', () => { callback: (allTransactions) => { Onyx.disconnect(connectionID); - transaction = Object.values(allTransactions ?? {}).find((t) => !isEmptyObject(t)) ?? null; + transaction = Object.values(allTransactions ?? {}).find((t) => !isEmptyObject(t)); resolve(); }, }); @@ -1799,7 +1777,7 @@ describe('actions/IOU', () => { callback: (allTransactions) => { Onyx.disconnect(connectionID); - transaction = Object.values(allTransactions ?? {}).find((t) => !isEmptyObject(t)) ?? null; + transaction = Object.values(allTransactions ?? {}).find((t) => !isEmptyObject(t)); resolve(); }, }); @@ -1926,7 +1904,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT) ?? null; + chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT); resolve(); }, @@ -1947,7 +1925,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU) ?? null; + expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU); resolve(); }, @@ -2039,7 +2017,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT) ?? null; + chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT); resolve(); }, @@ -2060,7 +2038,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU) ?? null; + expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU); resolve(); }, @@ -2153,13 +2131,13 @@ describe('actions/IOU', () => { expect(Object.values(allReports ?? {}).length).toBe(3); // Then one of them should be a chat report with relevant properties - chatReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.CHAT) ?? null; + chatReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.CHAT); expect(chatReport).toBeTruthy(); expect(chatReport).toHaveProperty('reportID'); expect(chatReport).toHaveProperty('iouReportID'); // Then one of them should be an IOU report with relevant properties - iouReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU) ?? null; + iouReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.IOU); expect(iouReport).toBeTruthy(); expect(iouReport).toHaveProperty('reportID'); expect(iouReport).toHaveProperty('chatReportID'); @@ -2187,10 +2165,9 @@ describe('actions/IOU', () => { // Then we should find an IOU action with specific properties const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`]; - createIOUAction = - Object.values(reportActionsForIOUReport ?? {}).find( - (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU, - ) ?? null; + createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find( + (reportAction): reportAction is ReportActionBase & OriginalMessageIOU => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU, + ); expect(createIOUAction).toBeTruthy(); expect(createIOUAction?.originalMessage.IOUReportID).toBe(iouReport?.reportID); @@ -2207,7 +2184,7 @@ describe('actions/IOU', () => { }); // Then we should find a specific transaction with relevant properties - transaction = Object.values(allTransactions ?? {}).find((t) => t) ?? null; + transaction = Object.values(allTransactions ?? {}).find((t) => t); expect(transaction).toBeTruthy(); expect(transaction?.amount).toBe(amount); expect(transaction?.reportID).toBe(iouReport?.reportID); @@ -2238,7 +2215,7 @@ describe('actions/IOU', () => { }); }); - createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); // Then the IOU Action should be truthy for offline support. expect(createIOUAction).toBeTruthy(); @@ -2272,7 +2249,7 @@ describe('actions/IOU', () => { }); }); - createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(createIOUAction).toBeFalsy(); // Then we recheck the transaction from the transactions collection @@ -2387,7 +2364,7 @@ describe('actions/IOU', () => { await waitForBatchedUpdates(); - iouReport = Object.values(allReports ?? {}).find((report) => ReportUtils.isIOUReport(report)) ?? null; + iouReport = Object.values(allReports ?? {}).find((report) => ReportUtils.isIOUReport(report)); expect(iouReport).toBeTruthy(); expect(iouReport).toHaveProperty('reportID'); expect(iouReport).toHaveProperty('chatReportID'); @@ -2406,7 +2383,7 @@ describe('actions/IOU', () => { }); }); // Then expect that the IOU report still exists - iouReport = Object.values(allReports ?? {}).find((report) => ReportUtils.isIOUReport(report)) ?? null; + iouReport = Object.values(allReports ?? {}).find((report) => ReportUtils.isIOUReport(report)); expect(iouReport).toBeTruthy(); expect(iouReport).toHaveProperty('reportID'); expect(iouReport).toHaveProperty('chatReportID'); @@ -2451,7 +2428,7 @@ describe('actions/IOU', () => { }); }); const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`]; - createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(createIOUAction?.childReportID).toBe(thread.reportID); await waitForBatchedUpdates(); @@ -2533,7 +2510,7 @@ describe('actions/IOU', () => { }); }); const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`]; - createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(createIOUAction?.childReportID).toBe(thread.reportID); await waitForBatchedUpdates(); @@ -2569,7 +2546,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: false, callback: (reportActionsForReport) => { Onyx.disconnect(connectionID); - createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); resolve(); }, }); @@ -2718,7 +2695,7 @@ describe('actions/IOU', () => { }); const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`]; - createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(createIOUAction?.childReportID).toBe(thread.reportID); await waitForBatchedUpdates(); @@ -2738,7 +2715,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: false, callback: (reportActionsForReport) => { Onyx.disconnect(connectionID); - createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); resolve(); }, }); @@ -2808,7 +2785,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: false, callback: (reportActionsForReport) => { Onyx.disconnect(connectionID); - createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(createIOUAction?.message?.[0]?.isDeletedParentAction).toBeTruthy(); resolve(); }, @@ -2826,7 +2803,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: false, callback: (reportActionsForReport) => { Onyx.disconnect(connectionID); - createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + createIOUAction = Object.values(reportActionsForReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(createIOUAction?.message?.[0]?.isDeletedParentAction).toBeTruthy(); resolve(); }, @@ -2949,7 +2926,7 @@ describe('actions/IOU', () => { }); const reportActionsForIOUReport = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.iouReportID}`]; - createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) ?? null; + createIOUAction = Object.values(reportActionsForIOUReport ?? {}).find((reportAction) => reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU); expect(createIOUAction?.childReportID).toBe(thread.reportID); await waitForBatchedUpdates(); @@ -2976,7 +2953,7 @@ describe('actions/IOU', () => { await waitForBatchedUpdates(); - iouReport = Object.values(allReports ?? {}).find((report) => ReportUtils.isIOUReport(report)) ?? null; + iouReport = Object.values(allReports ?? {}).find((report) => ReportUtils.isIOUReport(report)); expect(iouReport).toBeTruthy(); expect(iouReport).toHaveProperty('reportID'); expect(iouReport).toHaveProperty('chatReportID'); @@ -2994,7 +2971,7 @@ describe('actions/IOU', () => { }); }); - iouReport = Object.values(allReports ?? {}).find((report) => ReportUtils.isIOUReport(report)) ?? null; + iouReport = Object.values(allReports ?? {}).find((report) => ReportUtils.isIOUReport(report)); expect(iouReport).toBeTruthy(); expect(iouReport).toHaveProperty('reportID'); expect(iouReport).toHaveProperty('chatReportID'); @@ -3038,7 +3015,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT) ?? null; + chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT); resolve(); }, @@ -3070,7 +3047,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null; + expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE); Onyx.merge(`report_${expenseReport?.reportID}`, { statusNum: 0, stateNum: 0, @@ -3088,7 +3065,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null; + expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE); // Verify report is a draft expect(expenseReport?.stateNum).toBe(0); @@ -3112,8 +3089,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null; - + expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE); // Report was submitted correctly expect(expenseReport?.stateNum).toBe(1); expect(expenseReport?.statusNum).toBe(1); @@ -3142,7 +3118,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT) ?? null; + chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT); resolve(); }, @@ -3174,7 +3150,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null; + expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE); Onyx.merge(`report_${expenseReport?.reportID}`, { statusNum: 0, stateNum: 0, @@ -3192,7 +3168,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null; + expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE); // Verify report is a draft expect(expenseReport?.stateNum).toBe(0); @@ -3216,7 +3192,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null; + expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE); // Report is closed since the default policy settings is Submit and Close expect(expenseReport?.stateNum).toBe(2); @@ -3246,7 +3222,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT) ?? null; + chatReport = Object.values(allReports ?? {}).find((report) => report?.chatType === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT); resolve(); }, @@ -3278,7 +3254,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null; + expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE); Onyx.merge(`report_${expenseReport?.reportID}`, { statusNum: 0, stateNum: 0, @@ -3296,7 +3272,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null; + expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE); // Verify report is a draft expect(expenseReport?.stateNum).toBe(0); @@ -3321,7 +3297,7 @@ describe('actions/IOU', () => { waitForCollectionCallback: true, callback: (allReports) => { Onyx.disconnect(connectionID); - expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE) ?? null; + expenseReport = Object.values(allReports ?? {}).find((report) => report?.type === CONST.REPORT.TYPE.EXPENSE); // Report was submitted with some fail expect(expenseReport?.stateNum).toBe(0); diff --git a/tests/actions/SessionTest.ts b/tests/actions/SessionTest.ts index f4c4d186ff50..62d6a54b20b5 100644 --- a/tests/actions/SessionTest.ts +++ b/tests/actions/SessionTest.ts @@ -35,13 +35,13 @@ describe('Session', () => { const TEST_INITIAL_AUTH_TOKEN = 'initialAuthToken'; const TEST_REFRESHED_AUTH_TOKEN = 'refreshedAuthToken'; - let credentials: OnyxEntry = null; + let credentials: OnyxEntry; Onyx.connect({ key: ONYXKEYS.CREDENTIALS, callback: (val) => (credentials = val), }); - let session: OnyxEntry = null; + let session: OnyxEntry; Onyx.connect({ key: ONYXKEYS.SESSION, callback: (val) => (session = val), diff --git a/tests/perf-test/ReportActionsList.perf-test.tsx b/tests/perf-test/ReportActionsList.perf-test.tsx index 7d45e3e4b45d..ff284fdd7584 100644 --- a/tests/perf-test/ReportActionsList.perf-test.tsx +++ b/tests/perf-test/ReportActionsList.perf-test.tsx @@ -95,7 +95,7 @@ function ReportActionsListWrapper() { { it('Should move individual draft to a draft collection of report', () => { const setQueries: ReportActionsDraftCollectionDataSet = {}; - setQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}1_1`] = 'a' as unknown as OnyxEntry; - setQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}1_2`] = 'b' as unknown as OnyxEntry; + setQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}1_1`] = 'a' as unknown as OnyxInputValue; + setQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}1_2`] = 'b' as unknown as OnyxInputValue; setQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}2`] = {3: 'c'}; - setQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}2_4`] = 'd' as unknown as OnyxEntry; + setQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}2_4`] = 'd' as unknown as OnyxInputValue; return Onyx.multiSet(setQueries) .then(KeyReportActionsDraftByReportActionID) @@ -320,7 +320,7 @@ describe('Migrations', () => { it("Shouldn't move empty individual draft to a draft collection of report", () => { const setQueries: ReportActionsDraftCollectionDataSet = {}; - setQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}1_1`] = '' as unknown as OnyxEntry; + setQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}1_1`] = '' as unknown as OnyxInputValue; setQueries[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS}1`] = {}; return Onyx.multiSet(setQueries) diff --git a/tests/unit/NetworkTest.ts b/tests/unit/NetworkTest.ts index 9c48de96d1a2..850e7d5c236a 100644 --- a/tests/unit/NetworkTest.ts +++ b/tests/unit/NetworkTest.ts @@ -53,7 +53,7 @@ describe('NetworkTests', () => { const TEST_USER_LOGIN = 'test@testguy.com'; const TEST_USER_ACCOUNT_ID = 1; - let isOffline: boolean | null = null; + let isOffline: boolean | undefined; Onyx.connect({ key: ONYXKEYS.NETWORK, @@ -64,7 +64,7 @@ describe('NetworkTests', () => { // Given a test user login and account ID return TestHelper.signInWithTestUser(TEST_USER_ACCOUNT_ID, TEST_USER_LOGIN).then(() => { - expect(isOffline).toBe(null); + expect(isOffline).toBe(undefined); // Mock fetch() so that it throws a TypeError to simulate a bad network connection global.fetch = jest.fn().mockRejectedValue(new TypeError(CONST.ERROR.FAILED_TO_FETCH)); diff --git a/tests/unit/ReportUtilsTest.ts b/tests/unit/ReportUtilsTest.ts index 81d8bd8357f0..326e020464e0 100644 --- a/tests/unit/ReportUtilsTest.ts +++ b/tests/unit/ReportUtilsTest.ts @@ -267,7 +267,7 @@ describe('ReportUtils', () => { describe('requiresAttentionFromCurrentUser', () => { it('returns false when there is no report', () => { - expect(ReportUtils.requiresAttentionFromCurrentUser(null)).toBe(false); + expect(ReportUtils.requiresAttentionFromCurrentUser(undefined)).toBe(false); }); it('returns false when the matched IOU report does not have an owner accountID', () => { const report = { @@ -358,7 +358,7 @@ describe('ReportUtils', () => { describe('return empty iou options if', () => { it('participants array contains excluded expensify iou emails', () => { const allEmpty = CONST.EXPENSIFY_ACCOUNT_IDS.every((accountID) => { - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(null, null, [currentUserAccountID, accountID]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(undefined, undefined, [currentUserAccountID, accountID]); return moneyRequestOptions.length === 0; }); expect(allEmpty).toBe(true); @@ -369,7 +369,7 @@ describe('ReportUtils', () => { ...LHNTestUtils.getFakeReport(), chatType: CONST.REPORT.CHAT_TYPE.POLICY_ROOM, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID]); expect(moneyRequestOptions.length).toBe(0); }); @@ -379,7 +379,7 @@ describe('ReportUtils', () => { chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, isOwnPolicyExpenseChat: false, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID]); expect(moneyRequestOptions.length).toBe(0); }); @@ -389,7 +389,7 @@ describe('ReportUtils', () => { type: CONST.REPORT.TYPE.IOU, statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID]); expect(moneyRequestOptions.length).toBe(0); }); @@ -400,7 +400,7 @@ describe('ReportUtils', () => { stateNum: CONST.REPORT.STATE_NUM.APPROVED, statusNum: CONST.REPORT.STATUS_NUM.APPROVED, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID]); expect(moneyRequestOptions.length).toBe(0); }); @@ -410,7 +410,7 @@ describe('ReportUtils', () => { type: CONST.REPORT.TYPE.EXPENSE, statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID]); expect(moneyRequestOptions.length).toBe(0); }); @@ -424,7 +424,7 @@ describe('ReportUtils', () => { parentReportID: '100', type: CONST.REPORT.TYPE.EXPENSE, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID]); expect(moneyRequestOptions.length).toBe(0); }); }); @@ -468,7 +468,7 @@ describe('ReportUtils', () => { ...LHNTestUtils.getFakeReport(), chatType, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID, participantsAccountIDs[0]]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID, participantsAccountIDs[0]]); return moneyRequestOptions.length === 1 && moneyRequestOptions.includes(CONST.IOU.TYPE.SPLIT); }); expect(onlyHaveSplitOption).toBe(true); @@ -479,7 +479,7 @@ describe('ReportUtils', () => { ...LHNTestUtils.getFakeReport(), chatType: CONST.REPORT.CHAT_TYPE.POLICY_ROOM, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID, ...participantsAccountIDs]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID, ...participantsAccountIDs]); expect(moneyRequestOptions.length).toBe(1); expect(moneyRequestOptions.includes(CONST.IOU.TYPE.SPLIT)).toBe(true); }); @@ -489,7 +489,7 @@ describe('ReportUtils', () => { ...LHNTestUtils.getFakeReport(), chatType: CONST.REPORT.CHAT_TYPE.POLICY_ROOM, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID, ...participantsAccountIDs]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID, ...participantsAccountIDs]); expect(moneyRequestOptions.length).toBe(1); expect(moneyRequestOptions.includes(CONST.IOU.TYPE.SPLIT)).toBe(true); }); @@ -500,7 +500,7 @@ describe('ReportUtils', () => { type: CONST.REPORT.TYPE.CHAT, participantsAccountIDs: [currentUserAccountID, ...participantsAccountIDs], }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID, ...participantsAccountIDs.map(Number)]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID, ...participantsAccountIDs.map(Number)]); expect(moneyRequestOptions.length).toBe(1); expect(moneyRequestOptions.includes(CONST.IOU.TYPE.SPLIT)).toBe(true); }); @@ -514,7 +514,7 @@ describe('ReportUtils', () => { stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID, participantsAccountIDs[0]]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID, participantsAccountIDs[0]]); expect(moneyRequestOptions.length).toBe(1); expect(moneyRequestOptions.includes(CONST.IOU.TYPE.SUBMIT)).toBe(true); }); @@ -526,7 +526,7 @@ describe('ReportUtils', () => { stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID, participantsAccountIDs[0]]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID, participantsAccountIDs[0]]); expect(moneyRequestOptions.length).toBe(1); expect(moneyRequestOptions.includes(CONST.IOU.TYPE.SUBMIT)).toBe(true); }); @@ -544,7 +544,7 @@ describe('ReportUtils', () => { parentReportID: '102', type: CONST.REPORT.TYPE.EXPENSE, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID]); expect(moneyRequestOptions.length).toBe(2); expect(moneyRequestOptions.includes(CONST.IOU.TYPE.SUBMIT)).toBe(true); expect(moneyRequestOptions.includes(CONST.IOU.TYPE.TRACK)).toBe(true); @@ -587,7 +587,7 @@ describe('ReportUtils', () => { stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID, participantsAccountIDs[0]]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID, participantsAccountIDs[0]]); expect(moneyRequestOptions.length).toBe(1); expect(moneyRequestOptions.includes(CONST.IOU.TYPE.SUBMIT)).toBe(true); }); @@ -599,7 +599,7 @@ describe('ReportUtils', () => { stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID, participantsAccountIDs[0]]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID, participantsAccountIDs[0]]); expect(moneyRequestOptions.length).toBe(1); expect(moneyRequestOptions.includes(CONST.IOU.TYPE.SUBMIT)).toBe(true); }); @@ -646,7 +646,7 @@ describe('ReportUtils', () => { ...LHNTestUtils.getFakeReport(), type: CONST.REPORT.TYPE.CHAT, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID, participantsAccountIDs[0]]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID, participantsAccountIDs[0]]); expect(moneyRequestOptions.length).toBe(3); expect(moneyRequestOptions.includes(CONST.IOU.TYPE.SPLIT)).toBe(true); expect(moneyRequestOptions.includes(CONST.IOU.TYPE.SUBMIT)).toBe(true); @@ -659,7 +659,7 @@ describe('ReportUtils', () => { chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, isOwnPolicyExpenseChat: true, }; - const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, null, [currentUserAccountID, ...participantsAccountIDs]); + const moneyRequestOptions = ReportUtils.temporary_getMoneyRequestOptions(report, undefined, [currentUserAccountID, ...participantsAccountIDs]); expect(moneyRequestOptions.length).toBe(3); expect(moneyRequestOptions.includes(CONST.IOU.TYPE.SUBMIT)).toBe(true); expect(moneyRequestOptions.includes(CONST.IOU.TYPE.SPLIT)).toBe(true); @@ -693,14 +693,14 @@ describe('ReportUtils', () => { {reportID: '4', lastReadTime: '2023-07-07 07:15:44.030', type: CONST.REPORT.TYPE.IOU}, {lastReadTime: '2023-07-09 07:15:44.030'} as Report, {reportID: '6'}, - null, + undefined, ]; const sortedReports: Array> = [ {reportID: '3', lastReadTime: '2023-07-06 07:15:44.030'}, {reportID: '4', lastReadTime: '2023-07-07 07:15:44.030', type: CONST.REPORT.TYPE.IOU}, {reportID: '1', lastReadTime: '2023-07-08 07:15:44.030'}, ]; - expect(ReportUtils.sortReportsByLastRead(reports, null)).toEqual(sortedReports); + expect(ReportUtils.sortReportsByLastRead(reports, undefined)).toEqual(sortedReports); }); });