From 061ba9de5fc6293af543d92780a81cfb0ae341a5 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 31 May 2024 00:07:15 +0700 Subject: [PATCH 01/21] remove empty object --- src/components/AddPaymentMethodMenu.tsx | 7 ++-- src/components/AttachmentModal.tsx | 3 +- .../HTMLRenderers/MentionReportRenderer.tsx | 3 +- src/components/KYCWall/types.ts | 3 +- .../LHNOptionsList/LHNOptionsList.tsx | 2 +- .../LHNOptionsList/OptionRowLHNData.tsx | 2 +- src/components/LHNOptionsList/types.ts | 3 +- src/components/LocaleContextProvider.tsx | 2 +- .../Reactions/ReactionTooltipContent.tsx | 2 +- .../MoneyRequestPreviewContent.tsx | 8 ++-- src/components/SettlementButton.tsx | 9 ++-- .../withCurrentUserPersonalDetails.tsx | 6 +-- src/hooks/useCurrentUserPersonalDetails.ts | 10 +---- src/libs/DistanceRequestUtils.ts | 3 +- src/libs/NextStepUtils.ts | 13 ++---- src/libs/OptionsListUtils.ts | 17 ++++---- src/libs/PersonalDetailsUtils.ts | 3 +- src/libs/PolicyUtils.ts | 6 +-- src/libs/ReportUtils.ts | 2 +- src/libs/actions/IOU.ts | 42 +++++++++---------- src/libs/getReportPolicyID.ts | 7 ++-- .../ReportActionCompose.tsx | 2 +- 22 files changed, 65 insertions(+), 90 deletions(-) diff --git a/src/components/AddPaymentMethodMenu.tsx b/src/components/AddPaymentMethodMenu.tsx index ac965769450..93786cd9c43 100644 --- a/src/components/AddPaymentMethodMenu.tsx +++ b/src/components/AddPaymentMethodMenu.tsx @@ -11,7 +11,6 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {AnchorPosition} from '@src/styles'; import type {Report, Session} from '@src/types/onyx'; import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import * as Expensicons from './Icon/Expensicons'; import type {PaymentMethod} from './KYCWall/types'; import PopoverMenu from './PopoverMenu'; @@ -32,7 +31,7 @@ type AddPaymentMethodMenuProps = AddPaymentMethodMenuOnyxProps & { onItemSelected: (paymentMethod: PaymentMethod) => void; /** The IOU/Expense report we are paying */ - iouReport?: OnyxEntry | EmptyObject; + iouReport?: OnyxEntry; /** Anchor position for the AddPaymentMenu. */ anchorPosition: AnchorPosition; @@ -65,9 +64,9 @@ function AddPaymentMethodMenu({ // Users can choose to pay with business bank account in case of Expense reports or in case of P2P IOU report // which then starts a bottom up flow and creates a Collect workspace where the payer is an admin and payee is an employee. - const isIOUReport = ReportUtils.isIOUReport(iouReport ?? {}); + const isIOUReport = ReportUtils.isIOUReport(iouReport ?? null); const canUseBusinessBankAccount = - ReportUtils.isExpenseReport(iouReport ?? {}) || (isIOUReport && !ReportActionsUtils.hasRequestFromCurrentAccount(iouReport?.reportID ?? '', session?.accountID ?? 0)); + ReportUtils.isExpenseReport(iouReport ?? null) || (isIOUReport && !ReportActionsUtils.hasRequestFromCurrentAccount(iouReport?.reportID ?? '', session?.accountID ?? 0)); const canUsePersonalBankAccount = shouldShowPersonalBankAccountOption || isIOUReport; diff --git a/src/components/AttachmentModal.tsx b/src/components/AttachmentModal.tsx index af7f482198b..8943262d3a5 100644 --- a/src/components/AttachmentModal.tsx +++ b/src/components/AttachmentModal.tsx @@ -26,7 +26,6 @@ import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type ModalType from '@src/types/utils/ModalType'; import AttachmentCarousel from './Attachments/AttachmentCarousel'; @@ -99,7 +98,7 @@ type AttachmentModalProps = AttachmentModalOnyxProps & { headerTitle?: string; /** The report that has this attachment */ - report?: OnyxEntry | EmptyObject; + report?: OnyxEntry; /** Optional callback to fire when we want to do something after modal show. */ onModalShow?: () => void; diff --git a/src/components/HTMLEngineProvider/HTMLRenderers/MentionReportRenderer.tsx b/src/components/HTMLEngineProvider/HTMLRenderers/MentionReportRenderer.tsx index 345bd338f36..261e01af422 100644 --- a/src/components/HTMLEngineProvider/HTMLRenderers/MentionReportRenderer.tsx +++ b/src/components/HTMLEngineProvider/HTMLRenderers/MentionReportRenderer.tsx @@ -16,7 +16,6 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Report} from '@src/types/onyx'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; type MentionReportOnyxProps = { @@ -28,7 +27,7 @@ type MentionReportRendererProps = MentionReportOnyxProps & CustomRendererProps value.replace(CONST.UNICODE.LTR, '').replace('#', ''); -const getMentionDetails = (htmlAttributeReportID: string, currentReport: OnyxEntry | EmptyObject, reports: OnyxCollection, tnode: TText | TPhrasing) => { +const getMentionDetails = (htmlAttributeReportID: string, currentReport: OnyxEntry, reports: OnyxCollection, tnode: TText | TPhrasing) => { let reportID: string | undefined; let mentionDisplayText: string; diff --git a/src/components/KYCWall/types.ts b/src/components/KYCWall/types.ts index 53ed00e0414..568f2a15903 100644 --- a/src/components/KYCWall/types.ts +++ b/src/components/KYCWall/types.ts @@ -7,7 +7,6 @@ import type {Route} from '@src/ROUTES'; import type {Report} from '@src/types/onyx'; import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; type Source = ValueOf; @@ -45,7 +44,7 @@ type KYCWallProps = { chatReportID?: string; /** The IOU/Expense report we are paying */ - iouReport?: OnyxEntry | EmptyObject; + iouReport?: OnyxEntry; /** Where the popover should be positioned relative to the anchor points. */ anchorAlignment?: AnchorAlignment; diff --git a/src/components/LHNOptionsList/LHNOptionsList.tsx b/src/components/LHNOptionsList/LHNOptionsList.tsx index 6405e3026b1..5ae35b7adb3 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.tsx +++ b/src/components/LHNOptionsList/LHNOptionsList.tsx @@ -123,7 +123,7 @@ function LHNOptionsList({ if (lastReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) { lastReportActionTransactionID = lastReportAction.originalMessage?.IOUTransactionID ?? ''; } - const lastReportActionTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${lastReportActionTransactionID}`] ?? {}; + const lastReportActionTransaction = transactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${lastReportActionTransactionID}`]; return ( ; @@ -84,7 +83,7 @@ type OptionRowLHNDataProps = { transaction: OnyxEntry; /** The transaction linked to the report's last action */ - lastReportActionTransaction?: OnyxEntry; + lastReportActionTransaction?: OnyxEntry; /** Whether a report contains a draft */ hasDraftComment: boolean; diff --git a/src/components/LocaleContextProvider.tsx b/src/components/LocaleContextProvider.tsx index eb7d9324d2a..22c5a763124 100644 --- a/src/components/LocaleContextProvider.tsx +++ b/src/components/LocaleContextProvider.tsx @@ -73,7 +73,7 @@ const LocaleContext = createContext({ preferredLocale: CONST.LOCALES.DEFAULT, }); -function LocaleContextProvider({preferredLocale, currentUserPersonalDetails = {}, children}: LocaleContextProviderProps) { +function LocaleContextProvider({preferredLocale, currentUserPersonalDetails, children}: LocaleContextProviderProps) { const locale = preferredLocale ?? CONST.LOCALES.DEFAULT; const selectedTimezone = useMemo(() => currentUserPersonalDetails?.timezone?.selected, [currentUserPersonalDetails]); diff --git a/src/components/Reactions/ReactionTooltipContent.tsx b/src/components/Reactions/ReactionTooltipContent.tsx index 198eba1f969..8f469b01272 100644 --- a/src/components/Reactions/ReactionTooltipContent.tsx +++ b/src/components/Reactions/ReactionTooltipContent.tsx @@ -23,7 +23,7 @@ type ReactionTooltipContentProps = Pick PersonalDetailsUtils.getPersonalDetailsByIDs(accountIDs, currentUserPersonalDetails.accountID, true), [currentUserPersonalDetails.accountID, accountIDs]); diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index 8a3cf039a32..d0ae956246b 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -3,6 +3,7 @@ import truncate from 'lodash/truncate'; import React, {useMemo} from 'react'; import {View} from 'react-native'; import type {GestureResponderEvent} from 'react-native'; +import type {OnyxEntry} from 'react-native-onyx'; import ConfirmedRoute from '@components/ConfirmedRoute'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -36,7 +37,6 @@ import * as PaymentMethods from '@userActions/PaymentMethods'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import type {IOUMessage} from '@src/types/onyx/OriginalMessage'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type {MoneyRequestPreviewProps, PendingMessageProps} from './types'; @@ -214,10 +214,8 @@ function MoneyRequestPreviewContent({ }; const getDisplayDeleteAmountText = (): string => { - const iouOriginalMessage: IOUMessage | EmptyObject = action?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU ? action.originalMessage : {}; - const {amount = 0, currency = CONST.CURRENCY.USD} = iouOriginalMessage; - - return CurrencyUtils.convertToDisplayString(amount, currency); + const iouOriginalMessage: OnyxEntry = action?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU ? action.originalMessage : null; + return CurrencyUtils.convertToDisplayString(iouOriginalMessage?.amount, iouOriginalMessage?.currency); }; const displayAmount = isDeleted ? getDisplayDeleteAmountText() : getDisplayAmountText(); diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index f56c4dd1a86..f0a5224220d 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -17,7 +17,6 @@ import type {ButtonSizeValue} from '@src/styles/utils/types'; import type {LastPaymentMethod, Policy, Report} from '@src/types/onyx'; import type {PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import type AnchorAlignment from '@src/types/utils/AnchorAlignment'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import ButtonWithDropdownMenu from './ButtonWithDropdownMenu'; import type {PaymentType} from './ButtonWithDropdownMenu/types'; import * as Expensicons from './Icon/Expensicons'; @@ -55,7 +54,7 @@ type SettlementButtonProps = SettlementButtonOnyxProps & { chatReportID?: string; /** The IOU/Expense report we are paying */ - iouReport?: OnyxEntry | EmptyObject; + iouReport?: OnyxEntry; /** Should we show the payment options? */ shouldHidePaymentOptions?: boolean; @@ -123,7 +122,7 @@ function SettlementButton({ enablePaymentsRoute, // The "iouReport" and "nvpLastPaymentMethod" objects needs to be stable to prevent the "useMemo" // hook from being recreated unnecessarily, hence the use of CONST.EMPTY_ARRAY and CONST.EMPTY_OBJECT - iouReport = CONST.EMPTY_OBJECT, + iouReport = null, nvpLastPaymentMethod = CONST.EMPTY_OBJECT, isDisabled = false, isLoading = false, @@ -150,7 +149,7 @@ function SettlementButton({ const session = useSession(); const chatReport = ReportUtils.getReport(chatReportID); const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicyExpenseChat(chatReport); - const shouldShowPaywithExpensifyOption = !isPaidGroupPolicy || (!shouldHidePaymentOptions && ReportUtils.isPayer(session, iouReport as OnyxEntry)); + const shouldShowPaywithExpensifyOption = !isPaidGroupPolicy || (!shouldHidePaymentOptions && ReportUtils.isPayer(session, iouReport)); const shouldShowPayElsewhereOption = !isPaidGroupPolicy || policy?.reimbursementChoice === CONST.POLICY.REIMBURSEMENT_CHOICES.REIMBURSEMENT_MANUAL; const paymentButtonOptions = useMemo(() => { const buttonOptions = []; @@ -222,7 +221,7 @@ function SettlementButton({ if (confirmApproval) { confirmApproval(); } else { - IOU.approveMoneyRequest(iouReport ?? {}); + IOU.approveMoneyRequest(iouReport); } return; } diff --git a/src/components/withCurrentUserPersonalDetails.tsx b/src/components/withCurrentUserPersonalDetails.tsx index 8bbaf1c9305..91fd388eabf 100644 --- a/src/components/withCurrentUserPersonalDetails.tsx +++ b/src/components/withCurrentUserPersonalDetails.tsx @@ -4,10 +4,8 @@ import useCurrentUserPersonalDetails from '@hooks/useCurrentUserPersonalDetails' import getComponentDisplayName from '@libs/getComponentDisplayName'; import type {PersonalDetails} from '@src/types/onyx'; -type CurrentUserPersonalDetails = PersonalDetails | Record; - type HOCProps = { - currentUserPersonalDetails: CurrentUserPersonalDetails; + currentUserPersonalDetails: PersonalDetails; }; type WithCurrentUserPersonalDetailsProps = HOCProps; @@ -32,4 +30,4 @@ export default function ; - function useCurrentUserPersonalDetails() { const session = useSession(); - const personalDetails = usePersonalDetails() ?? CONST.EMPTY_OBJECT; + const personalDetails = usePersonalDetails(); const accountID = session?.accountID ?? 0; const accountPersonalDetails = personalDetails?.[accountID]; - const currentUserPersonalDetails: CurrentUserPersonalDetails = useMemo( - () => (accountPersonalDetails ? {...accountPersonalDetails, accountID} : {}) as CurrentUserPersonalDetails, - [accountPersonalDetails, accountID], - ); + const currentUserPersonalDetails: PersonalDetails = useMemo(() => ({...accountPersonalDetails, accountID}), [accountPersonalDetails, accountID]); return currentUserPersonalDetails; } diff --git a/src/libs/DistanceRequestUtils.ts b/src/libs/DistanceRequestUtils.ts index 9cb48534214..5c47458bdc1 100644 --- a/src/libs/DistanceRequestUtils.ts +++ b/src/libs/DistanceRequestUtils.ts @@ -7,7 +7,6 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {LastSelectedDistanceRates, 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'; import * as CurrencyUtils from './CurrencyUtils'; import * as PolicyUtils from './PolicyUtils'; import * as ReportUtils from './ReportUtils'; @@ -48,7 +47,7 @@ const METERS_TO_MILES = 0.000621371; // There are approximately 0.000621371 mile * @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: OnyxEntry): MileageRate | null { if (!policy?.customUnits) { return null; } diff --git a/src/libs/NextStepUtils.ts b/src/libs/NextStepUtils.ts index daa2015b5cd..8d7c5d21d74 100644 --- a/src/libs/NextStepUtils.ts +++ b/src/libs/NextStepUtils.ts @@ -1,14 +1,13 @@ import {format, lastDayOfMonth, setDate} from 'date-fns'; import Str from 'expensify-common/lib/str'; import Onyx from 'react-native-onyx'; -import type {OnyxCollection} from 'react-native-onyx'; +import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Policy, Report, ReportNextStep} from '@src/types/onyx'; import type {Message} from '@src/types/onyx/ReportNextStep'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import DateUtils from './DateUtils'; import EmailUtils from './EmailUtils'; import * as PersonalDetailsUtils from './PersonalDetailsUtils'; @@ -73,16 +72,12 @@ type BuildNextStepParameters = { * @param parameters.isPaidWithExpensify - Whether a report has been paid with Expensify or outside * @returns nextStep */ -function buildNextStep( - report: Report | EmptyObject, - predictedNextStatus: ValueOf, - {isPaidWithExpensify}: BuildNextStepParameters = {}, -): ReportNextStep | null { +function buildNextStep(report: OnyxEntry, predictedNextStatus: ValueOf, {isPaidWithExpensify}: BuildNextStepParameters = {}): ReportNextStep | null { if (!ReportUtils.isExpenseReport(report)) { return null; } - const {policyID = '', ownerAccountID = -1, managerID = -1} = report; + const {policyID = '', ownerAccountID = -1, managerID = -1} = report ?? {}; const policy = allPolicies?.[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? ({} as Policy); const {harvesting, preventSelfApproval, autoReportingFrequency, autoReportingOffset} = policy; const submitToAccountID = PolicyUtils.getSubmitToAccountID(policy, ownerAccountID); @@ -282,7 +277,7 @@ function buildNextStep( accountID: currentUserAccountID, email: currentUserEmail, }, - report as Report, + report, ) ) { optimisticNextStep = { diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index f321c10c686..722c4694864 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -34,7 +34,6 @@ import type { import type {Participant} from '@src/types/onyx/IOU'; import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import times from '@src/utils/times'; import Timing from './actions/Timing'; @@ -2050,23 +2049,23 @@ function getShareLogOptions(options: OptionList, searchValue = '', betas: Beta[] /** * Build the IOUConfirmation options for showing the payee personalDetail */ -function getIOUConfirmationOptionsFromPayeePersonalDetail(personalDetail: PersonalDetails | EmptyObject, amountText?: string): PayeePersonalDetails { - const formattedLogin = LocalePhoneNumber.formatPhoneNumber(personalDetail.login ?? ''); +function getIOUConfirmationOptionsFromPayeePersonalDetail(personalDetail: OnyxEntry, amountText?: string): PayeePersonalDetails { + const formattedLogin = LocalePhoneNumber.formatPhoneNumber(personalDetail?.login ?? ''); return { text: PersonalDetailsUtils.getDisplayNameOrDefault(personalDetail, formattedLogin), alternateText: formattedLogin || PersonalDetailsUtils.getDisplayNameOrDefault(personalDetail, '', false), icons: [ { - source: personalDetail.avatar ?? FallbackAvatar, - name: personalDetail.login ?? '', + source: personalDetail?.avatar ?? FallbackAvatar, + name: personalDetail?.login ?? '', type: CONST.ICON_TYPE_AVATAR, - id: personalDetail.accountID, + id: personalDetail?.accountID, }, ], descriptiveText: amountText ?? '', - login: personalDetail.login ?? '', - accountID: personalDetail.accountID, - keyForList: String(personalDetail.accountID), + login: personalDetail?.login ?? '', + accountID: personalDetail?.accountID ?? 0, + keyForList: String(personalDetail?.accountID), }; } diff --git a/src/libs/PersonalDetailsUtils.ts b/src/libs/PersonalDetailsUtils.ts index d58ac4d5218..5ec494f5177 100644 --- a/src/libs/PersonalDetailsUtils.ts +++ b/src/libs/PersonalDetailsUtils.ts @@ -1,7 +1,6 @@ import Str from 'expensify-common/lib/str'; import type {OnyxEntry, OnyxUpdate} from 'react-native-onyx'; 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'; @@ -272,7 +271,7 @@ function createDisplayName(login: string, passedPersonalDetails: Pick): PolicyEmployee[] { /** * Returns the policy of the report */ -function getPolicy(policyID: string | undefined): Policy | EmptyObject { +function getPolicy(policyID: string | undefined): OnyxEntry { if (!allPolicies || !policyID) { - return {}; + return null; } - return allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? {}; + return allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; } /** Return active policies where current user is an admin */ diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 8a59958c208..50138241aae 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -6292,7 +6292,7 @@ function isHoldCreator(transaction: OnyxEntry, reportID: string): b /** * Get all held transactions of a iouReport */ -function getAllHeldTransactions(iouReportID: string): Transaction[] { +function getAllHeldTransactions(iouReportID?: string): Transaction[] { const transactions = TransactionUtils.getAllReportTransactions(iouReportID); return transactions.filter((transaction) => TransactionUtils.isOnHold(transaction)); } diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 08ce01263a8..29d0cdf95ae 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -6078,7 +6078,7 @@ function canIOUBePaid(iouReport: OnyxEntry | EmptyObject, chat return chatReport?.invoiceReceiver?.accountID === userAccountID; } - return PolicyUtils.getPolicy(chatReport?.invoiceReceiver?.policyID).role === CONST.POLICY.ROLE.ADMIN; + return PolicyUtils.getPolicy(chatReport?.invoiceReceiver?.policyID)?.role === CONST.POLICY.ROLE.ADMIN; } const isPayer = ReportUtils.isPayer( @@ -6112,20 +6112,20 @@ function hasIOUToApproveOrPay(chatReport: OnyxEntry | EmptyObj }); } -function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject, full?: boolean) { - const currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`] ?? null; - let total = expenseReport.total ?? 0; - const hasHeldExpenses = ReportUtils.hasHeldExpenses(expenseReport.reportID); - if (hasHeldExpenses && !full && !!expenseReport.unheldTotal) { - total = expenseReport.unheldTotal; +function approveMoneyRequest(expenseReport: OnyxEntry, full?: boolean) { + const currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport?.reportID}`] ?? null; + let total = expenseReport?.total ?? 0; + const hasHeldExpenses = ReportUtils.hasHeldExpenses(expenseReport?.reportID); + if (hasHeldExpenses && !full && !!expenseReport?.unheldTotal) { + total = expenseReport?.unheldTotal; } - const optimisticApprovedReportAction = ReportUtils.buildOptimisticApprovedReportAction(total, expenseReport.currency ?? '', expenseReport.reportID); + const optimisticApprovedReportAction = ReportUtils.buildOptimisticApprovedReportAction(total, expenseReport?.currency ?? '', expenseReport?.reportID ?? ''); const optimisticNextStep = NextStepUtils.buildNextStep(expenseReport, CONST.REPORT.STATUS_NUM.APPROVED); - const chatReport = ReportUtils.getReport(expenseReport.chatReportID); + const chatReport = ReportUtils.getReport(expenseReport?.chatReportID); const optimisticReportActionsData: OnyxUpdate = { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport?.reportID}`, value: { [optimisticApprovedReportAction.reportActionID]: { ...(optimisticApprovedReportAction as OnyxTypes.ReportAction), @@ -6135,7 +6135,7 @@ function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject, full }; const optimisticIOUReportData: OnyxUpdate = { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport?.reportID}`, value: { ...expenseReport, lastMessageText: optimisticApprovedReportAction.message?.[0]?.text, @@ -6158,7 +6158,7 @@ function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject, full const optimisticNextStepData: OnyxUpdate = { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport?.reportID}`, value: optimisticNextStep, }; const optimisticData: OnyxUpdate[] = [optimisticIOUReportData, optimisticReportActionsData, optimisticNextStepData, optimisticChatReportData]; @@ -6166,7 +6166,7 @@ function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject, full const successData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport?.reportID}`, value: { [optimisticApprovedReportAction.reportActionID]: { pendingAction: null, @@ -6175,7 +6175,7 @@ function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject, full }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport?.reportID}`, value: { pendingFields: { partial: null, @@ -6187,7 +6187,7 @@ function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject, full const failureData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${expenseReport?.reportID}`, value: { [optimisticApprovedReportAction.reportActionID]: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.other'), @@ -6196,7 +6196,7 @@ function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject, full }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.chatReportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport?.chatReportID}`, value: { hasOutstandingChildRequest: chatReport?.hasOutstandingChildRequest, pendingFields: { @@ -6206,14 +6206,14 @@ function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject, full }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport?.reportID}`, value: currentNextStep, }, ]; // Clear hold reason of all transactions if we approve all requests if (full && hasHeldExpenses) { - const heldTransactions = ReportUtils.getAllHeldTransactions(expenseReport.reportID); + const heldTransactions = ReportUtils.getAllHeldTransactions(expenseReport?.reportID); heldTransactions.forEach((heldTransaction) => { optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, @@ -6237,7 +6237,7 @@ function approveMoneyRequest(expenseReport: OnyxTypes.Report | EmptyObject, full } const parameters: ApproveMoneyRequestParams = { - reportID: expenseReport.reportID, + reportID: expenseReport?.reportID ?? '', approvedReportActionID: optimisticApprovedReportAction.reportActionID, full, }; @@ -6251,7 +6251,7 @@ function submitReport(expenseReport: OnyxTypes.Report) { const policy = PolicyUtils.getPolicy(expenseReport.policyID); const isCurrentUserManager = currentUserPersonalDetails.accountID === expenseReport.managerID; const isSubmitAndClosePolicy = PolicyUtils.isSubmitAndClose(policy); - const adminAccountID = policy.role === CONST.POLICY.ROLE.ADMIN ? currentUserPersonalDetails.accountID : undefined; + const adminAccountID = policy?.role === CONST.POLICY.ROLE.ADMIN ? currentUserPersonalDetails.accountID : undefined; const optimisticSubmittedReportAction = ReportUtils.buildOptimisticSubmittedReportAction(expenseReport?.total ?? 0, expenseReport.currency ?? '', expenseReport.reportID, adminAccountID); const optimisticNextStep = NextStepUtils.buildNextStep(expenseReport, isSubmitAndClosePolicy ? CONST.REPORT.STATUS_NUM.CLOSED : CONST.REPORT.STATUS_NUM.SUBMITTED); @@ -6374,7 +6374,7 @@ function cancelPayment(expenseReport: OnyxTypes.Report, chatReport: OnyxTypes.Re const optimisticReportAction = ReportUtils.buildOptimisticCancelPaymentReportAction(expenseReport.reportID, -(expenseReport.total ?? 0), expenseReport.currency ?? ''); const policy = PolicyUtils.getPolicy(chatReport.policyID); const isFree = policy && policy.type === CONST.POLICY.TYPE.FREE; - const approvalMode = policy.approvalMode ?? CONST.POLICY.APPROVAL_MODE.BASIC; + const approvalMode = policy?.approvalMode ?? CONST.POLICY.APPROVAL_MODE.BASIC; let stateNum: ValueOf = CONST.REPORT.STATE_NUM.SUBMITTED; let statusNum: ValueOf = CONST.REPORT.STATUS_NUM.SUBMITTED; if (!isFree) { diff --git a/src/libs/getReportPolicyID.ts b/src/libs/getReportPolicyID.ts index 12124f24fbe..8751ce640b6 100644 --- a/src/libs/getReportPolicyID.ts +++ b/src/libs/getReportPolicyID.ts @@ -2,7 +2,6 @@ import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Report} from '@src/types/onyx'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; let allReports: OnyxCollection; Onyx.connect({ @@ -14,12 +13,12 @@ Onyx.connect({ /** * Get the report given a reportID */ -function getReport(reportID: string | undefined): OnyxEntry | EmptyObject { +function getReport(reportID: string | undefined): OnyxEntry { if (!allReports) { - return {}; + return null; } - return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] ?? {}; + return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; } /** diff --git a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx index adf358ab416..d0ede3f6eb3 100644 --- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx +++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx @@ -104,7 +104,7 @@ const willBlurTextInputOnTapOutside = willBlurTextInputOnTapOutsideFunc(); function ReportActionCompose({ blockedFromConcierge, - currentUserPersonalDetails = {}, + currentUserPersonalDetails, disabled = false, isComposerFullSize = false, onSubmit, From 5024f05740ea997a7e89e5ee8c22dda7bdd38f89 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 31 May 2024 00:50:17 +0700 Subject: [PATCH 02/21] remove EmptyObject in PolicyUtils --- src/components/ConnectionLayout.tsx | 4 ++-- src/components/SelectionScreen.tsx | 4 ++-- src/libs/PolicyUtils.ts | 19 +++++++++---------- src/libs/ReportUtils.ts | 27 ++++++++++++--------------- src/libs/actions/IOU.ts | 4 ++-- 5 files changed, 27 insertions(+), 31 deletions(-) diff --git a/src/components/ConnectionLayout.tsx b/src/components/ConnectionLayout.tsx index bcb2a083308..dc0d7fbc5ac 100644 --- a/src/components/ConnectionLayout.tsx +++ b/src/components/ConnectionLayout.tsx @@ -94,8 +94,8 @@ function ConnectionLayout({ }: ConnectionLayoutProps) { const {translate} = useLocalize(); - const policy = PolicyUtils.getPolicy(policyID ?? ''); - const isConnectionEmpty = isEmpty(policy.connections?.[connectionName]); + const policy = PolicyUtils.getPolicy(policyID); + const isConnectionEmpty = isEmpty(policy?.connections?.[connectionName]); const renderSelectionContent = useMemo( () => ( diff --git a/src/components/SelectionScreen.tsx b/src/components/SelectionScreen.tsx index c8c290b562b..3c51f17948b 100644 --- a/src/components/SelectionScreen.tsx +++ b/src/components/SelectionScreen.tsx @@ -76,8 +76,8 @@ function SelectionScreen({ }: SelectionScreenProps) { const {translate} = useLocalize(); - const policy = PolicyUtils.getPolicy(policyID ?? ''); - const isConnectionEmpty = isEmpty(policy.connections?.[connectionName]); + const policy = PolicyUtils.getPolicy(policyID); + const isConnectionEmpty = isEmpty(policy?.connections?.[connectionName]); return ( | EmptyObject): boolean => policy?.role === CONST.POLICY.ROLE.ADMIN; +const isPolicyAdmin = (policy: OnyxEntry): boolean => policy?.role === CONST.POLICY.ROLE.ADMIN; /** * Checks if the policy is a free group policy. */ -const isFreeGroupPolicy = (policy: OnyxEntry | EmptyObject): boolean => policy?.type === CONST.POLICY.TYPE.FREE; +const isFreeGroupPolicy = (policy: OnyxEntry): boolean => policy?.type === CONST.POLICY.TYPE.FREE; const isPolicyEmployee = (policyID: string, policies: OnyxCollection): boolean => Object.values(policies ?? {}).some((policy) => policy?.id === policyID); @@ -267,7 +266,7 @@ function isPendingDeletePolicy(policy: OnyxEntry): boolean { return policy?.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE; } -function isPaidGroupPolicy(policy: OnyxEntry | EmptyObject): boolean { +function isPaidGroupPolicy(policy: OnyxEntry): boolean { return policy?.type === CONST.POLICY.TYPE.TEAM || policy?.type === CONST.POLICY.TYPE.CORPORATE; } @@ -284,14 +283,14 @@ function isTaxTrackingEnabled(isPolicyExpenseChat: boolean, policy: OnyxEntry | EmptyObject): boolean { +function isInstantSubmitEnabled(policy: OnyxEntry): 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: OnyxEntry): boolean { return policy?.approvalMode === CONST.POLICY.APPROVAL_MODE.OPTIONAL; } @@ -334,7 +333,7 @@ function canEditTaxRate(policy: Policy, taxID: string): boolean { return policy.taxRates?.defaultExternalID !== taxID; } -function isPolicyFeatureEnabled(policy: OnyxEntry | EmptyObject, featureName: PolicyFeatureName): boolean { +function isPolicyFeatureEnabled(policy: OnyxEntry, featureName: PolicyFeatureName): boolean { if (featureName === CONST.POLICY.MORE_FEATURES.ARE_TAXES_ENABLED) { return Boolean(policy?.tax?.trackingEnabled); } @@ -342,7 +341,7 @@ function isPolicyFeatureEnabled(policy: OnyxEntry | EmptyObject, feature return Boolean(policy?.[featureName]); } -function getApprovalWorkflow(policy: OnyxEntry | EmptyObject): ValueOf { +function getApprovalWorkflow(policy: OnyxEntry): ValueOf { if (policy?.type === CONST.POLICY.TYPE.PERSONAL) { return CONST.POLICY.APPROVAL_MODE.OPTIONAL; } @@ -350,14 +349,14 @@ function getApprovalWorkflow(policy: OnyxEntry | EmptyObject): ValueOf | EmptyObject): string { +function getDefaultApprover(policy: OnyxEntry): string { return policy?.approver ?? policy?.owner ?? ''; } /** * Returns the accountID to whom the given employeeAccountID submits reports to in the given Policy. */ -function getSubmitToAccountID(policy: OnyxEntry | EmptyObject, employeeAccountID: number): number { +function getSubmitToAccountID(policy: OnyxEntry, employeeAccountID: number): number { const employeeLogin = getLoginsByAccountIDs([employeeAccountID])[0]; const defaultApprover = getDefaultApprover(policy); diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 19575be659b..451ffd3df09 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -656,11 +656,11 @@ function getRootParentReport(report: OnyxEntry | undefined | EmptyObject /** * Returns the policy of the report */ -function getPolicy(policyID: string | undefined): Policy | EmptyObject { +function getPolicy(policyID: string | undefined): OnyxEntry { if (!allPolicies || !policyID) { - return {}; + return null; } - return allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? {}; + return allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; } /** @@ -1254,7 +1254,7 @@ function isJoinRequestInAdminRoom(report: OnyxEntry): boolean { // since they are not a part of the company, and should not action it on their behalf. if (report.policyID) { const policy = getPolicy(report.policyID); - if (!PolicyUtils.isExpensifyTeam(policy.owner) && PolicyUtils.isExpensifyTeam(currentUserPersonalDetails?.login)) { + if (!PolicyUtils.isExpensifyTeam(policy?.owner) && PolicyUtils.isExpensifyTeam(currentUserPersonalDetails?.login)) { return false; } } @@ -2623,8 +2623,8 @@ function canEditMoneyRequest(reportAction: OnyxEntry): boolean { return isProcessingReport(moneyRequestReport) && isRequestor; } - const policy = getPolicy(moneyRequestReport?.policyID ?? ''); - const isAdmin = policy.role === CONST.POLICY.ROLE.ADMIN; + const policy = getPolicy(moneyRequestReport?.policyID); + const isAdmin = policy?.role === CONST.POLICY.ROLE.ADMIN; const isManager = currentUserAccountID === moneyRequestReport?.managerID; if (isInvoiceReport(moneyRequestReport) && isManager) { @@ -2679,8 +2679,8 @@ function canEditFieldOfMoneyRequest(reportAction: OnyxEntry, field } if ((fieldToEdit === CONST.EDIT_REQUEST_FIELD.AMOUNT || fieldToEdit === CONST.EDIT_REQUEST_FIELD.CURRENCY) && TransactionUtils.isDistanceRequest(transaction)) { - const policy = getPolicy(moneyRequestReport?.reportID ?? ''); - const isAdmin = isExpenseReport(moneyRequestReport) && policy.role === CONST.POLICY.ROLE.ADMIN; + const policy = getPolicy(moneyRequestReport?.reportID); + const isAdmin = isExpenseReport(moneyRequestReport) && policy?.role === CONST.POLICY.ROLE.ADMIN; const isManager = isExpenseReport(moneyRequestReport) && currentUserAccountID === moneyRequestReport?.managerID; return isAdmin || isManager; @@ -3677,7 +3677,7 @@ function getHumanReadableStatus(statusNum: number): string { * If after all replacements the formula is empty, the original formula is returned. * See {@link https://help.expensify.com/articles/expensify-classic/insights-and-custom-reporting/Custom-Templates} */ -function populateOptimisticReportFormula(formula: string, report: OptimisticExpenseReport, policy: Policy | EmptyObject): string { +function populateOptimisticReportFormula(formula: string, report: OptimisticExpenseReport, policy: OnyxEntry): string { const createdDate = report.lastVisibleActionCreated ? new Date(report.lastVisibleActionCreated) : undefined; const result = formula // We don't translate because the server response is always in English @@ -3685,7 +3685,7 @@ function populateOptimisticReportFormula(formula: string, report: OptimisticExpe .replaceAll('{report:startdate}', createdDate ? format(createdDate, CONST.DATE.FNS_FORMAT_STRING) : '') .replaceAll('{report:total}', report.total !== undefined ? CurrencyUtils.convertToDisplayString(Math.abs(report.total), report.currency).toString() : '') .replaceAll('{report:currency}', report.currency ?? '') - .replaceAll('{report:policyname}', policy.name ?? '') + .replaceAll('{report:policyname}', policy?.name ?? '') .replaceAll('{report:created}', createdDate ? format(createdDate, CONST.DATE.FNS_DATE_TIME_FORMAT_STRING) : '') .replaceAll('{report:created:yyyy-MM-dd}', createdDate ? format(createdDate, CONST.DATE.FNS_FORMAT_STRING) : '') .replaceAll('{report:status}', report.statusNum !== undefined ? getHumanReadableStatus(report.statusNum) : '') @@ -3776,7 +3776,7 @@ function buildOptimisticExpenseReport(chatReportID: string, policyID: string, pa function getIOUSubmittedMessage(report: OnyxEntry) { const policy = getPolicy(report?.policyID); - if (report?.ownerAccountID !== currentUserAccountID && policy.role === CONST.POLICY.ROLE.ADMIN) { + if (report?.ownerAccountID !== currentUserAccountID && policy?.role === CONST.POLICY.ROLE.ADMIN) { const ownerPersonalDetail = getPersonalDetailsForAccountID(report?.ownerAccountID ?? 0); const ownerDisplayName = `${ownerPersonalDetail.displayName ?? ''}${ownerPersonalDetail.displayName !== ownerPersonalDetail.login ? ` (${ownerPersonalDetail.login})` : ''}`; @@ -6537,11 +6537,8 @@ function isReportOwner(report: OnyxEntry): boolean { function isAllowedToApproveExpenseReport(report: OnyxEntry, approverAccountID?: number): boolean { const policy = getPolicy(report?.policyID); - const {preventSelfApproval} = policy; - const isOwner = (approverAccountID ?? currentUserAccountID) === report?.ownerAccountID; - - return !(preventSelfApproval && isOwner); + return !(policy?.preventSelfApproval && isOwner); } function isAllowedToSubmitDraftExpenseReport(report: OnyxEntry): boolean { diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 29d0cdf95ae..388ffa71636 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -6034,7 +6034,7 @@ 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: OnyxEntry | EmptyObject, chatReport: OnyxEntry | EmptyObject, policy: OnyxEntry) { if (isEmptyObject(chatReport)) { return false; } @@ -6061,7 +6061,7 @@ 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: OnyxEntry | EmptyObject, chatReport: OnyxEntry | EmptyObject, policy: OnyxEntry) { const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(chatReport); const isChatReportArchived = ReportUtils.isArchivedRoom(chatReport); From ded2bce727d0e6a1bfd9a01736f3245cb1a2198d Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 31 May 2024 01:21:30 +0700 Subject: [PATCH 03/21] remove EmptyObject in ReportActionsUtils --- src/libs/ReportActionsUtils.ts | 25 +++++++++++----------- src/libs/ReportUtils.ts | 18 ++++++++-------- src/libs/actions/Policy/Policy.ts | 6 +++--- src/pages/settings/Profile/ProfilePage.tsx | 4 ++-- 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 1b2b03e7e2c..3fabc2983c4 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -22,7 +22,6 @@ import type { import type Report from '@src/types/onyx/Report'; import type {Message, ReportActionBase, ReportActionMessageJSON, ReportActions} from '@src/types/onyx/ReportAction'; import type ReportAction from '@src/types/onyx/ReportAction'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import DateUtils from './DateUtils'; import * as Environment from './Environment/Environment'; @@ -121,7 +120,7 @@ function isReversedTransaction(reportAction: OnyxEntry 0; } -function isPendingRemove(reportAction: OnyxEntry | EmptyObject): boolean { +function isPendingRemove(reportAction: OnyxEntry): boolean { if (isEmptyObject(reportAction)) { return false; } @@ -148,7 +147,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: OnyxEntry): number[] { const originalMessage = reportAction?.originalMessage; const message = reportAction?.message; @@ -163,7 +162,7 @@ function getWhisperedTo(reportAction: OnyxEntry | EmptyObject): nu return []; } -function isWhisperAction(reportAction: OnyxEntry | EmptyObject): boolean { +function isWhisperAction(reportAction: OnyxEntry): boolean { return getWhisperedTo(reportAction).length > 0; } @@ -216,11 +215,11 @@ function isThreadParentMessage(reportAction: OnyxEntry, reportID: * * @deprecated Use Onyx.connect() or withOnyx() instead */ -function getParentReportAction(report: OnyxEntry | EmptyObject): ReportAction | EmptyObject { +function getParentReportAction(report: OnyxEntry): OnyxEntry { if (!report?.parentReportID || !report.parentReportActionID) { - return {}; + return null; } - return allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] ?? {}; + return allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] ?? null; } /** @@ -238,7 +237,7 @@ function isSentMoneyReportAction(reportAction: OnyxEntry | EmptyObject): boolean { +function isTransactionThread(parentReportAction: OnyxEntry): boolean { return ( parentReportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && (parentReportAction.originalMessage.type === CONST.IOU.REPORT_ACTION_TYPE.CREATE || @@ -1176,9 +1175,9 @@ function isReportActionUnread(reportAction: OnyxEntry, lastReadTim * Check whether the current report action of the report is unread or not * */ -function isCurrentActionUnread(report: Report | EmptyObject, reportAction: ReportAction): boolean { - const lastReadTime = report.lastReadTime ?? ''; - const sortedReportActions = getSortedReportActions(Object.values(getAllReportActions(report.reportID))); +function isCurrentActionUnread(report: OnyxEntry, reportAction: ReportAction): boolean { + const lastReadTime = report?.lastReadTime ?? ''; + const sortedReportActions = getSortedReportActions(Object.values(getAllReportActions(report?.reportID ?? ''))); const currentActionIndex = sortedReportActions.findIndex((action) => action.reportActionID === reportAction.reportActionID); if (currentActionIndex === -1) { return false; @@ -1205,14 +1204,14 @@ function isActionableJoinRequestPending(reportID: string): boolean { return !!findPendingRequest; } -function isApprovedOrSubmittedReportAction(action: OnyxEntry | EmptyObject) { +function isApprovedOrSubmittedReportAction(action: OnyxEntry) { return [CONST.REPORT.ACTIONS.TYPE.APPROVED, CONST.REPORT.ACTIONS.TYPE.SUBMITTED].some((type) => type === action?.actionName); } /** * Gets the text version of the message in a report action */ -function getReportActionMessageText(reportAction: OnyxEntry | EmptyObject): string { +function getReportActionMessageText(reportAction: OnyxEntry): string { return reportAction?.message?.reduce((acc, curr) => `${acc}${curr?.text}`, '') ?? ''; } diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 451ffd3df09..f7ccd1dbbd6 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1940,11 +1940,11 @@ function getIcons( const parentReportAction = ReportActionsUtils.getParentReportAction(report); const workspaceIcon = getWorkspaceIcon(report, policy); const memberIcon = { - source: personalDetails?.[parentReportAction.actorAccountID ?? -1]?.avatar ?? FallbackAvatar, - id: parentReportAction.actorAccountID, + source: personalDetails?.[parentReportAction?.actorAccountID ?? -1]?.avatar ?? FallbackAvatar, + id: parentReportAction?.actorAccountID, type: CONST.ICON_TYPE_AVATAR, - name: personalDetails?.[parentReportAction.actorAccountID ?? -1]?.displayName ?? '', - fallbackIcon: personalDetails?.[parentReportAction.actorAccountID ?? -1]?.fallbackIcon, + name: personalDetails?.[parentReportAction?.actorAccountID ?? -1]?.displayName ?? '', + fallbackIcon: personalDetails?.[parentReportAction?.actorAccountID ?? -1]?.fallbackIcon, }; return [memberIcon, workspaceIcon]; @@ -1952,14 +1952,14 @@ function getIcons( if (isChatThread(report)) { const parentReportAction = ReportActionsUtils.getParentReportAction(report); - const actorAccountID = parentReportAction.actorAccountID; + const actorAccountID = parentReportAction?.actorAccountID; const actorDisplayName = PersonalDetailsUtils.getDisplayNameOrDefault(allPersonalDetails?.[actorAccountID ?? -1], '', false); const actorIcon = { id: actorAccountID, source: personalDetails?.[actorAccountID ?? -1]?.avatar ?? FallbackAvatar, name: actorDisplayName, type: CONST.ICON_TYPE_AVATAR, - fallbackIcon: personalDetails?.[parentReportAction.actorAccountID ?? -1]?.fallbackIcon, + fallbackIcon: personalDetails?.[parentReportAction?.actorAccountID ?? -1]?.fallbackIcon, }; if (isWorkspaceThread(report)) { @@ -3057,7 +3057,7 @@ function isChangeLogObject(originalMessage?: ChangeLog): ChangeLog | undefined { * @param parentReportAction * @param parentReportActionMessage */ -function getAdminRoomInvitedParticipants(parentReportAction: ReportAction | Record, parentReportActionMessage: string) { +function getAdminRoomInvitedParticipants(parentReportAction: OnyxEntry, parentReportActionMessage: string) { if (!parentReportAction?.originalMessage) { return parentReportActionMessage || Localize.translateLocal('parentReportAction.deletedMessage'); } @@ -3108,7 +3108,7 @@ function getInvoicePayerName(report: OnyxEntry): string { /** * Get the report action message for a report action. */ -function getReportActionMessage(reportAction: ReportAction | EmptyObject, parentReportID?: string) { +function getReportActionMessage(reportAction: OnyxEntry, parentReportID?: string) { if (isEmptyObject(reportAction)) { return ''; } @@ -6414,7 +6414,7 @@ function getAllAncestorReportActions(report: Report | null | undefined): Ancesto break; } - const isParentReportActionUnread = ReportActionsUtils.isCurrentActionUnread(parentReport ?? {}, parentReportAction); + const isParentReportActionUnread = ReportActionsUtils.isCurrentActionUnread(parentReport, parentReportAction); allAncestors.push({ report: currentReport, reportAction: parentReportAction, diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index fc2a8ad7970..0f00edc7d2c 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -3012,12 +3012,12 @@ function createWorkspaceFromIOUPayment(iouReport: Report | EmptyObject): string optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oldChatReportID}`, - value: {[reportPreview.reportActionID]: null}, + value: {[reportPreview?.reportActionID ?? '']: null}, }); failureData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oldChatReportID}`, - value: {[reportPreview.reportActionID]: reportPreview}, + value: {[reportPreview?.reportActionID ?? '']: reportPreview}, }); // To optimistically remove the GBR from the DM we need to update the hasOutstandingChildRequest param to false @@ -3059,7 +3059,7 @@ function createWorkspaceFromIOUPayment(iouReport: Report | EmptyObject): string failureData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${memberData.workspaceChatReportID}`, - value: {[reportPreview.reportActionID]: null}, + value: {[reportPreview?.reportActionID ?? '']: null}, }); // Create the MOVED report action and add it to the DM chat which indicates to the user where the report has been moved diff --git a/src/pages/settings/Profile/ProfilePage.tsx b/src/pages/settings/Profile/ProfilePage.tsx index 4c5ed88e689..ae252da6fff 100755 --- a/src/pages/settings/Profile/ProfilePage.tsx +++ b/src/pages/settings/Profile/ProfilePage.tsx @@ -26,7 +26,7 @@ import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {LoginList, PersonalDetails, PrivatePersonalDetails} from '@src/types/onyx'; +import type {LoginList, PrivatePersonalDetails} from '@src/types/onyx'; type ProfilePageOnyxProps = { loginList: OnyxEntry; @@ -102,7 +102,7 @@ function ProfilePage({ ]; useEffect(() => { - App.openProfile(currentUserPersonalDetails as PersonalDetails); + App.openProfile(currentUserPersonalDetails); }, [currentUserPersonalDetails]); const privateOptions = [ From a3ed5745d49fa2d9da8df4e6baf43b8a2fb14f12 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 31 May 2024 02:06:12 +0700 Subject: [PATCH 04/21] remove EmptyObject in Task --- src/libs/ReportUtils.ts | 89 +++++++++---------- src/libs/WorkspacesSettingsUtils.ts | 6 +- src/libs/actions/IOU.ts | 46 +++++----- src/libs/actions/Policy/Policy.ts | 4 +- src/libs/actions/Task.ts | 6 +- .../home/report/ReportActionItemSingle.tsx | 2 +- 6 files changed, 75 insertions(+), 78 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index f7ccd1dbbd6..f00c38319d6 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -53,7 +53,6 @@ import type {Status} from '@src/types/onyx/PersonalDetails'; import type {NotificationPreference, Participants, PendingChatMember, Participant as ReportParticipant} from '@src/types/onyx/Report'; import type {Message, ReportActionBase, ReportActions, ReportPreviewAction} from '@src/types/onyx/ReportAction'; import type {Comment, Receipt, TransactionChanges, WaypointCollection} from '@src/types/onyx/Transaction'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import type IconAsset from '@src/types/utils/IconAsset'; import * as IOU from './actions/IOU'; @@ -596,7 +595,7 @@ function getCurrentUserDisplayNameOrEmail(): string | undefined { return currentUserPersonalDetails?.displayName ?? currentUserEmail; } -function getChatType(report: OnyxEntry | Participant | EmptyObject): ValueOf | undefined { +function getChatType(report: OnyxEntry | Participant): ValueOf | undefined { return report?.chatType; } @@ -626,20 +625,20 @@ function isDraftReport(reportID: string | undefined): boolean { /** * Returns the parentReport if the given report is a thread */ -function getParentReport(report: OnyxEntry | EmptyObject): OnyxEntry | EmptyObject { +function getParentReport(report: OnyxEntry): OnyxEntry { if (!report?.parentReportID) { - return {}; + return null; } - return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`] ?? {}; + return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`] ?? null; } /** * Returns the root parentReport if the given report is nested. * Uses recursion to iterate any depth of nested reports. */ -function getRootParentReport(report: OnyxEntry | undefined | EmptyObject): OnyxEntry | EmptyObject { +function getRootParentReport(report: OnyxEntry | undefined): OnyxEntry { if (!report) { - return {}; + return null; } // Returns the current report as the root report, because it does not have a parentReportID @@ -674,7 +673,7 @@ function getPolicyType(report: OnyxEntry, policies: OnyxCollection | undefined | EmptyObject, returnEmptyIfNotFound = false, policy: OnyxEntry | undefined = undefined): string { +function getPolicyName(report: OnyxEntry | undefined, returnEmptyIfNotFound = false, policy: OnyxEntry | undefined = undefined): string { const noPolicyFound = returnEmptyIfNotFound ? '' : Localize.translateLocal('workspace.common.unavailable'); if (isEmptyObject(report)) { return noPolicyFound; @@ -706,25 +705,25 @@ function getReportParticipantsTitle(accountIDs: number[]): string { /** * Checks if a report is a chat report. */ -function isChatReport(report: OnyxEntry | EmptyObject): boolean { +function isChatReport(report: OnyxEntry): boolean { return report?.type === CONST.REPORT.TYPE.CHAT; } -function isInvoiceReport(report: OnyxEntry | EmptyObject): boolean { +function isInvoiceReport(report: OnyxEntry): 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: OnyxEntry): 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: OnyxEntry | string): boolean { const report = typeof reportOrID === 'string' ? allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? null : reportOrID; return report?.type === CONST.REPORT.TYPE.IOU; } @@ -732,7 +731,7 @@ function isIOUReport(reportOrID: OnyxEntry | string | EmptyObject): bool /** * Checks if a report is an IOU report using report */ -function isIOUReportUsingReport(report: OnyxEntry | EmptyObject): report is Report { +function isIOUReportUsingReport(report: OnyxEntry): report is Report { return report?.type === CONST.REPORT.TYPE.IOU; } /** @@ -749,7 +748,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: OnyxEntry, parentReportAction: OnyxEntry = null): boolean { if (!isEmptyObject(parentReportAction) && (parentReportAction?.message?.[0]?.isDeletedParentAction ?? false)) { return true; } @@ -766,7 +765,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: OnyxEntry, parentReportAction: OnyxEntry = null): boolean { return ( isTaskReport(report) && !isCanceledTaskReport(report, parentReportAction) && report?.stateNum === CONST.REPORT.STATE_NUM.OPEN && report?.statusNum === CONST.REPORT.STATUS_NUM.OPEN ); @@ -789,7 +788,7 @@ function isReportManager(report: OnyxEntry): boolean { /** * Checks if the supplied report has been approved */ -function isReportApproved(reportOrID: OnyxEntry | string | EmptyObject): boolean { +function isReportApproved(reportOrID: OnyxEntry | string): 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; } @@ -797,7 +796,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: OnyxEntry): boolean { return isExpenseReport(report) && report?.stateNum === CONST.REPORT.STATE_NUM.OPEN && report?.statusNum === CONST.REPORT.STATUS_NUM.OPEN; } @@ -827,7 +826,7 @@ function isSettled(reportID: string | undefined): boolean { if (!allReports || !reportID) { return false; } - const report: Report | EmptyObject = allReports[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] ?? {}; + const report = allReports[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`] ?? null; if (isEmptyObject(report) || report.isWaitingOnBankAccount) { return false; } @@ -897,7 +896,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: OnyxEntry | Participant): boolean { return getChatType(report) === CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT || (report?.isPolicyExpenseChat ?? false); } @@ -967,7 +966,7 @@ function isPaidGroupPolicyExpenseReport(report: OnyxEntry): boolean { /** * Checks if the supplied report is an invoice report in Open state and status. */ -function isOpenInvoiceReport(report: OnyxEntry | EmptyObject): boolean { +function isOpenInvoiceReport(report: OnyxEntry): boolean { return isInvoiceReport(report) && report?.statusNum === CONST.REPORT.STATUS_NUM.OPEN; } @@ -1102,7 +1101,7 @@ function sortReportsByLastRead(reports: Array>, reportMetadata /** * Returns true if report is still being processed */ -function isProcessingReport(report: OnyxEntry | EmptyObject): boolean { +function isProcessingReport(report: OnyxEntry): boolean { return report?.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && report?.statusNum === CONST.REPORT.STATUS_NUM.SUBMITTED; } @@ -1227,7 +1226,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: OnyxEntry, reportNameValuePairs?: OnyxEntry): boolean { if (reportNameValuePairs) { return reportNameValuePairs.isArchived; } @@ -1238,7 +1237,7 @@ function isArchivedRoom(report: OnyxEntry | EmptyObject, reportNameValue /** * Whether the provided report is a closed report */ -function isClosedReport(report: OnyxEntry | EmptyObject): boolean { +function isClosedReport(report: OnyxEntry): boolean { return report?.statusNum === CONST.REPORT.STATUS_NUM.CLOSED; } @@ -1405,7 +1404,7 @@ function isMoneyRequest(reportOrID: OnyxEntry | string): boolean { /** * Checks if a report is an IOU or expense report. */ -function isMoneyRequestReport(reportOrID: OnyxEntry | EmptyObject | string): boolean { +function isMoneyRequestReport(reportOrID: OnyxEntry | string): boolean { const report = typeof reportOrID === 'object' ? reportOrID : allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportOrID}`] ?? null; return isIOUReport(report) || isExpenseReport(report); } @@ -2177,11 +2176,7 @@ function getReimbursementQueuedActionMessage(reportAction: OnyxEntry, - report: OnyxEntry | EmptyObject, - isLHNPreview = false, -): string { +function getReimbursementDeQueuedActionMessage(reportAction: OnyxEntry, report: OnyxEntry, isLHNPreview = false): string { const originalMessage = reportAction?.originalMessage as ReimbursementDeQueuedMessage | undefined; const amount = originalMessage?.amount; const currency = originalMessage?.currency; @@ -2260,7 +2255,7 @@ function getLastVisibleMessage(reportID: string | undefined, actionsToMerge: Rep * * @param [parentReportAction] - The parent report action of the report (Used to check if the task has been canceled) */ -function isWaitingForAssigneeToCompleteTask(report: OnyxEntry, parentReportAction: OnyxEntry | EmptyObject = {}): boolean { +function isWaitingForAssigneeToCompleteTask(report: OnyxEntry, parentReportAction: OnyxEntry): boolean { return isTaskReport(report) && isReportManager(report) && isOpenTaskReport(report, parentReportAction); } @@ -2283,7 +2278,7 @@ function isUnreadWithMention(reportOrOption: OnyxEntry | OptionData): bo * @param option (report or optionItem) * @param parentReportAction (the report action the current report is a thread of) */ -function requiresAttentionFromCurrentUser(optionOrReport: OnyxEntry | OptionData, parentReportAction: EmptyObject | OnyxEntry = {}) { +function requiresAttentionFromCurrentUser(optionOrReport: OnyxEntry | OptionData, parentReportAction: OnyxEntry = null) { if (!optionOrReport) { return false; } @@ -2755,14 +2750,14 @@ function hasMissingSmartscanFields(iouReportID: string): boolean { * * NOTE: This method is only meant to be used inside this action file. Do not export and use it elsewhere. Use withOnyx or Onyx.connect() instead. */ -function getLinkedTransaction(reportAction: OnyxEntry): Transaction | EmptyObject { +function getLinkedTransaction(reportAction: OnyxEntry): OnyxEntry { let transactionID = ''; if (reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU) { transactionID = (reportAction?.originalMessage as IOUMessage)?.IOUTransactionID ?? ''; } - return allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] ?? {}; + return allTransactions?.[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] ?? null; } /** @@ -2818,13 +2813,13 @@ function getTransactionReportName(reportAction: OnyxEntry | EmptyObject, - iouReportAction: OnyxEntry | EmptyObject = {}, + report: OnyxEntry, + iouReportAction: OnyxEntry = null, shouldConsiderScanningReceiptOrPendingRoute = false, isPreviewMessageForParentChatReport = false, policy: OnyxEntry = null, isForListPreview = false, - originalReportAction: OnyxEntry | EmptyObject = iouReportAction, + originalReportAction: OnyxEntry = iouReportAction, ): string { const reportActionMessage = iouReportAction?.message?.[0]?.html ?? ''; @@ -3942,7 +3937,7 @@ function buildOptimisticIOUReportAction( receipt: Receipt = {}, isOwnPolicyExpenseChat = false, created = DateUtils.getDBTime(), - linkedExpenseReportAction: ReportAction | EmptyObject = {}, + linkedExpenseReportAction: OnyxEntry = null, ): OptimisticIOUReportAction { const IOUReportID = iouReportID || generateReportID(); @@ -4977,7 +4972,7 @@ function buildOptimisticMoneyRequestEntities( isPersonalTrackingExpense?: boolean, existingTransactionThreadReportID?: string, linkedTrackedExpenseReportAction?: ReportAction, -): [OptimisticCreatedReportAction, OptimisticCreatedReportAction, OptimisticIOUReportAction, OptimisticChatReport, OptimisticCreatedReportAction | EmptyObject] { +): [OptimisticCreatedReportAction, OptimisticCreatedReportAction, OptimisticIOUReportAction, OptimisticChatReport, OptimisticCreatedReportAction | null] { const createdActionForChat = buildOptimisticCreatedReportAction(payeeEmail); // The `CREATED` action must be optimistically generated before the IOU action so that it won't appear after the IOU action in the chat. @@ -5003,7 +4998,7 @@ function buildOptimisticMoneyRequestEntities( // Create optimistic transactionThread and the `CREATED` action for it, if existingTransactionThreadReportID is undefined const transactionThread = buildTransactionThread(iouAction, iouReport, existingTransactionThreadReportID); - const createdActionForTransactionThread = existingTransactionThreadReportID ? {} : buildOptimisticCreatedReportAction(payeeEmail); + const createdActionForTransactionThread = existingTransactionThreadReportID ? null : buildOptimisticCreatedReportAction(payeeEmail); // The IOU action and the transactionThread are co-dependent as parent-child, so we need to link them together iouAction.childReportID = existingTransactionThreadReportID ?? transactionThread.reportID; @@ -5351,7 +5346,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: OnyxEntry): boolean { const participantAccountIDs = Object.keys(report?.participants ?? {}).map(Number); return participantAccountIDs.includes(CONST.ACCOUNT_ID.CHRONOS); } @@ -5852,7 +5847,7 @@ function getAddWorkspaceRoomOrChatReportErrors(report: OnyxEntry): Error /** * Return true if the expense report is marked for deletion. */ -function isMoneyRequestReportPendingDeletion(report: OnyxEntry | EmptyObject): boolean { +function isMoneyRequestReportPendingDeletion(report: OnyxEntry): boolean { if (!isMoneyRequestReport(report)) { return false; } @@ -6481,7 +6476,7 @@ function getAllAncestorReportActionIDs(report: Report | null | undefined, includ * @param lastVisibleActionCreated Last visible action created of the child report * @param type The type of action in the child report */ -function getOptimisticDataForParentReportAction(reportID: string, lastVisibleActionCreated: string, type: string): Array { +function getOptimisticDataForParentReportAction(reportID: string, lastVisibleActionCreated: string, type: string): Array { const report = getReport(reportID); if (!report || isEmptyObject(report)) { @@ -6495,13 +6490,13 @@ function getOptimisticDataForParentReportAction(reportID: string, lastVisibleAct const ancestorReport = getReport(ancestors.reportIDs[index]); if (!ancestorReport || isEmptyObject(ancestorReport)) { - return {} as EmptyObject; + return null; } const ancestorReportAction = ReportActionsUtils.getReportAction(ancestorReport.reportID, ancestors.reportActionsIDs[index]); if (!ancestorReportAction || isEmptyObject(ancestorReportAction)) { - return {} as EmptyObject; + return null; } return { @@ -6514,7 +6509,7 @@ function getOptimisticDataForParentReportAction(reportID: string, lastVisibleAct }); } -function canBeAutoReimbursed(report: OnyxEntry, policy: OnyxEntry | EmptyObject): boolean { +function canBeAutoReimbursed(report: OnyxEntry, policy: OnyxEntry): boolean { if (isEmptyObject(policy)) { return false; } @@ -6723,7 +6718,7 @@ function createDraftTransactionAndNavigateToParticipantSelector(transactionID: s /** * @returns the object to update `report.hasOutstandingChildRequest` */ -function getOutstandingChildRequest(iouReport: OnyxEntry | EmptyObject): OutstandingChildRequest { +function getOutstandingChildRequest(iouReport: OnyxEntry): OutstandingChildRequest { if (!iouReport || isEmptyObject(iouReport)) { return {}; } @@ -6757,7 +6752,7 @@ function canReportBeMentionedWithinPolicy(report: OnyxEntry, policyID: s } function shouldShowMerchantColumn(transactions: Transaction[]) { - return transactions.some((transaction) => isExpenseReport(allReports?.[transaction.reportID] ?? {})); + return transactions.some((transaction) => isExpenseReport(allReports?.[transaction.reportID] ?? null)); } export { diff --git a/src/libs/WorkspacesSettingsUtils.ts b/src/libs/WorkspacesSettingsUtils.ts index 6c57c2a6f99..74c5125855d 100644 --- a/src/libs/WorkspacesSettingsUtils.ts +++ b/src/libs/WorkspacesSettingsUtils.ts @@ -4,7 +4,7 @@ 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 {Policy, ReimbursementAccount, Report, ReportActions} from '@src/types/onyx'; +import type {Policy, ReimbursementAccount, Report, ReportAction, ReportActions} from '@src/types/onyx'; import type {Unit} from '@src/types/onyx/Policy'; import * as CurrencyUtils from './CurrencyUtils'; import type {Phrase, PhraseParameters} from './Localize'; @@ -66,10 +66,10 @@ const getBrickRoadForPolicy = (report: Report, altReportActions?: OnyxCollection } // To determine if the report requires attention from the current user, we need to load the parent report action - let itemParentReportAction = {}; + let itemParentReportAction: OnyxEntry = null; if (report.parentReportID) { const itemParentReportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`] ?? {}; - itemParentReportAction = report.parentReportActionID ? itemParentReportActions[report.parentReportActionID] : {}; + itemParentReportAction = report.parentReportActionID ? itemParentReportActions[report.parentReportActionID] : null; } const reportOption = {...report, isUnread: ReportUtils.isUnread(report), isUnreadWithMention: ReportUtils.isUnreadWithMention(report)}; const shouldShowGreenDotIndicator = ReportUtils.requiresAttentionFromCurrentUser(reportOption, itemParentReportAction); diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 388ffa71636..d657ba27f17 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -462,7 +462,7 @@ function buildOnyxDataForMoneyRequest( optimisticPolicyRecentlyUsedTags: OnyxTypes.RecentlyUsedTags, isNewChatReport: boolean, transactionThreadReport: OptimisticChatReport | EmptyObject, - transactionThreadCreatedReportAction: OptimisticCreatedReportAction | EmptyObject, + transactionThreadCreatedReportAction: OptimisticCreatedReportAction | null, shouldCreateNewMoneyRequestReport: boolean, policy?: OnyxEntry, policyTagList?: OnyxEntry, @@ -850,7 +850,7 @@ function buildOnyxDataForInvoice( optimisticPolicyRecentlyUsedTags: OnyxTypes.RecentlyUsedTags, isNewChatReport: boolean, transactionThreadReport: OptimisticChatReport, - transactionThreadCreatedReportAction: OptimisticCreatedReportAction | EmptyObject, + transactionThreadCreatedReportAction: OptimisticCreatedReportAction | null, policy?: OnyxEntry, policyTagList?: OnyxEntry, policyCategories?: OnyxEntry, @@ -907,7 +907,7 @@ function buildOnyxDataForInvoice( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, value: { - [transactionThreadCreatedReportAction.reportActionID]: transactionThreadCreatedReportAction, + [transactionThreadCreatedReportAction?.reportActionID ?? '']: transactionThreadCreatedReportAction, }, }, // Remove the temporary transaction used during the creation flow @@ -1037,7 +1037,7 @@ function buildOnyxDataForInvoice( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, value: { - [transactionThreadCreatedReportAction.reportActionID]: { + [transactionThreadCreatedReportAction?.reportActionID ?? '']: { pendingAction: null, errors: null, }, @@ -1124,7 +1124,7 @@ function buildOnyxDataForInvoice( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, value: { - [transactionThreadCreatedReportAction.reportActionID]: { + [transactionThreadCreatedReportAction?.reportActionID ?? '']: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateInvoiceFailureMessage', false, errorKey), }, }, @@ -1159,7 +1159,7 @@ function buildOnyxDataForTrackExpense( iouAction: OptimisticIOUReportAction, reportPreviewAction: OnyxEntry, transactionThreadReport: OptimisticChatReport | EmptyObject, - transactionThreadCreatedReportAction: OptimisticCreatedReportAction | EmptyObject, + transactionThreadCreatedReportAction: OptimisticCreatedReportAction | null, shouldCreateNewMoneyRequestReport: boolean, policy?: OnyxEntry, policyTagList?: OnyxEntry, @@ -1493,7 +1493,7 @@ function buildOnyxDataForTrackExpense( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, value: { - [transactionThreadCreatedReportAction.reportActionID]: { + [transactionThreadCreatedReportAction?.reportActionID ?? '']: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, }, @@ -2020,7 +2020,7 @@ function getMoneyRequestInformation( optimisticPolicyRecentlyUsedTags, isNewChatReport, optimisticTransactionThread ?? {}, - optimisticCreatedActionForTransactionThread ?? {}, + optimisticCreatedActionForTransactionThread, shouldCreateNewMoneyRequestReport, policy, policyTagList, @@ -2230,7 +2230,7 @@ function getTrackExpenseInformation( iouAction, reportPreviewAction, optimisticTransactionThread ?? {}, - (optimisticCreatedActionForTransactionThread as OptimisticCreatedReportAction) ?? {}, // Add type assertion here + optimisticCreatedActionForTransactionThread, shouldCreateNewMoneyRequestReport, policy, policyTagList, @@ -2249,7 +2249,7 @@ function getTrackExpenseInformation( createdIOUReportActionID: shouldCreateNewMoneyRequestReport ? optimisticCreatedActionForIOUReport.reportActionID : '0', reportPreviewAction: reportPreviewAction ?? undefined, transactionThreadReportID: optimisticTransactionThread.reportID, - createdReportActionIDForThread: optimisticCreatedActionForTransactionThread.reportActionID, + createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID ?? '0', actionableWhisperReportActionIDParam: actionableTrackExpenseWhisper?.reportActionID ?? '', onyxData: { optimisticData: [...optimisticData, ...trackExpenseOnyxData[0]], @@ -2527,9 +2527,9 @@ function getUpdateMoneyRequestParams( // Step 4: Compute the IOU total and update the report preview message (and report header) so LHN amount owed is correct. const diff = calculateDiffAmount(iouReport, updatedTransaction, transaction); - let updatedMoneyRequestReport: OnyxTypes.Report | EmptyObject; + let updatedMoneyRequestReport: OnyxEntry; if (!iouReport) { - updatedMoneyRequestReport = {}; + updatedMoneyRequestReport = null; } else if ((ReportUtils.isExpenseReport(iouReport) || ReportUtils.isInvoiceReport(iouReport)) && typeof iouReport.total === 'number') { // For expense report, the amount is negative, so we should subtract total from diff updatedMoneyRequestReport = { @@ -2543,7 +2543,9 @@ function getUpdateMoneyRequestParams( updatedMoneyRequestReport = IOUUtils.updateIOUOwnerAndTotal(iouReport, updatedReportAction.actorAccountID ?? -1, diff, TransactionUtils.getCurrency(transaction), false, true); } - updatedMoneyRequestReport.cachedTotal = CurrencyUtils.convertToDisplayString(updatedMoneyRequestReport.total, transactionDetails?.currency); + if (updatedMoneyRequestReport) { + updatedMoneyRequestReport.cachedTotal = CurrencyUtils.convertToDisplayString(updatedMoneyRequestReport.total, transactionDetails?.currency); + } optimisticData.push( { @@ -4142,7 +4144,7 @@ function createSplitsAndOnyxData( createdIOUReportActionID: oneOnOneCreatedActionForIOU.reportActionID, reportPreviewReportActionID: oneOnOneReportPreviewAction.reportActionID, transactionThreadReportID: optimisticTransactionThread.reportID, - createdReportActionIDForThread: optimisticCreatedActionForTransactionThread.reportActionID, + createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID, }; splits.push(individualSplit); @@ -4829,7 +4831,7 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA createdIOUReportActionID: oneOnOneCreatedActionForIOU.reportActionID, reportPreviewReportActionID: oneOnOneReportPreviewAction.reportActionID, transactionThreadReportID: optimisticTransactionThread.reportID, - createdReportActionIDForThread: optimisticCreatedActionForTransactionThread.reportActionID, + createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID, }); optimisticData.push(...oneOnOneOptimisticData); @@ -5644,7 +5646,7 @@ function getSendMoneyParams( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTransactionThread.reportID}`, value: { - [optimisticCreatedActionForTransactionThread.reportActionID]: optimisticCreatedActionForTransactionThread, + [optimisticCreatedActionForTransactionThread?.reportActionID ?? '']: optimisticCreatedActionForTransactionThread, }, }; @@ -5729,7 +5731,7 @@ function getSendMoneyParams( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTransactionThread.reportID}`, value: { - [optimisticCreatedActionForTransactionThread.reportActionID]: { + [optimisticCreatedActionForTransactionThread?.reportActionID ?? '']: { pendingAction: null, }, }, @@ -5757,7 +5759,7 @@ function getSendMoneyParams( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTransactionThread.reportID}`, value: { - [optimisticCreatedActionForTransactionThread.reportActionID]: { + [optimisticCreatedActionForTransactionThread?.reportActionID ?? '']: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, }, @@ -5835,7 +5837,7 @@ function getSendMoneyParams( reportPreviewReportActionID: reportPreviewAction.reportActionID, createdIOUReportActionID: optimisticCreatedActionForIOUReport.reportActionID, transactionThreadReportID: optimisticTransactionThread.reportID, - createdReportActionIDForThread: optimisticCreatedActionForTransactionThread.reportActionID, + createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID ?? '0', }, optimisticData, successData, @@ -6034,7 +6036,7 @@ function sendMoneyWithWallet(report: OnyxEntry, amount: number Report.notifyNewAction(params.chatReportID, managerID); } -function canApproveIOU(iouReport: OnyxEntry | EmptyObject, chatReport: OnyxEntry | EmptyObject, policy: OnyxEntry) { +function canApproveIOU(iouReport: OnyxEntry, chatReport: OnyxEntry, policy: OnyxEntry) { if (isEmptyObject(chatReport)) { return false; } @@ -6061,7 +6063,7 @@ function canApproveIOU(iouReport: OnyxEntry | EmptyObject, cha return isCurrentUserManager && !isOpenExpenseReport && !isApproved && !iouSettled && !isArchivedReport; } -function canIOUBePaid(iouReport: OnyxEntry | EmptyObject, chatReport: OnyxEntry | EmptyObject, policy: OnyxEntry) { +function canIOUBePaid(iouReport: OnyxEntry | EmptyObject, chatReport: OnyxEntry, policy: OnyxEntry) { const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(chatReport); const isChatReportArchived = ReportUtils.isArchivedRoom(chatReport); @@ -6101,7 +6103,7 @@ function canIOUBePaid(iouReport: OnyxEntry | EmptyObject, chat ); } -function hasIOUToApproveOrPay(chatReport: OnyxEntry | EmptyObject, excludedIOUReportID: string): boolean { +function hasIOUToApproveOrPay(chatReport: OnyxEntry, excludedIOUReportID: string): boolean { const chatReportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${chatReport?.reportID}`] ?? {}; return Object.values(chatReportActions).some((action) => { diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 0f00edc7d2c..006b8c0e559 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -2686,7 +2686,7 @@ function dismissAddedWithPrimaryLoginMessages(policyID: string) { * * @returns policyID of the workspace we have created */ -function createWorkspaceFromIOUPayment(iouReport: Report | EmptyObject): string | undefined { +function createWorkspaceFromIOUPayment(iouReport: OnyxEntry): string | undefined { // This flow only works for IOU reports if (!ReportUtils.isIOUReportUsingReport(iouReport)) { return; @@ -3047,7 +3047,7 @@ function createWorkspaceFromIOUPayment(iouReport: Report | EmptyObject): string message: [ { type: CONST.REPORT.MESSAGE.TYPE.TEXT, - text: ReportUtils.getReportPreviewMessage(expenseReport, {}, false, false, newWorkspace), + text: ReportUtils.getReportPreviewMessage(expenseReport, null, false, false, newWorkspace), }, ], created: DateUtils.getDBTime(), diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 55d898d3d4f..fe749b9d0ea 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -814,11 +814,11 @@ function getParentReportAction(report: OnyxEntry): ReportActio /** * Returns the parentReport if the given report is a thread */ -function getParentReport(report: OnyxEntry | EmptyObject): OnyxEntry | EmptyObject { +function getParentReport(report: OnyxEntry | EmptyObject): OnyxEntry { if (!report?.parentReportID) { - return {}; + return null; } - return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`] ?? {}; + return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`] ?? null; } /** diff --git a/src/pages/home/report/ReportActionItemSingle.tsx b/src/pages/home/report/ReportActionItemSingle.tsx index f71db06c2d4..07a4636cf50 100644 --- a/src/pages/home/report/ReportActionItemSingle.tsx +++ b/src/pages/home/report/ReportActionItemSingle.tsx @@ -85,7 +85,7 @@ function ReportActionItemSingle({ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing let actorHint = (login || (displayName ?? '')).replace(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''); const displayAllActors = useMemo(() => action?.actionName === CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW && iouReport, [action?.actionName, iouReport]); - const isInvoiceReport = ReportUtils.isInvoiceReport(iouReport ?? {}); + const isInvoiceReport = ReportUtils.isInvoiceReport(iouReport ?? null); const isWorkspaceActor = isInvoiceReport || (ReportUtils.isPolicyExpenseChat(report) && (!actorAccountID || displayAllActors)); let avatarSource = avatar; let avatarId: number | string | undefined = actorAccountID; From 16b1e368ae30477abc89cd07762c3110b4d0962c Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 31 May 2024 02:38:21 +0700 Subject: [PATCH 05/21] remove EmptyObject in Navigation, Report, Task, User and Welcome actions --- src/libs/Navigation/Navigation.ts | 4 ++-- src/libs/Navigation/dismissModalWithReport.ts | 8 ++++---- src/libs/actions/Report.ts | 17 ++++++++--------- src/libs/actions/Task.ts | 3 +-- src/libs/actions/User.ts | 3 +-- src/libs/actions/Welcome.ts | 3 +-- 6 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/libs/Navigation/Navigation.ts b/src/libs/Navigation/Navigation.ts index 3fa3e0c5c31..7a4254a96b4 100644 --- a/src/libs/Navigation/Navigation.ts +++ b/src/libs/Navigation/Navigation.ts @@ -1,6 +1,7 @@ import {findFocusedRoute} from '@react-navigation/core'; import type {EventArg, NavigationContainerEventMap} from '@react-navigation/native'; import {CommonActions, getPathFromState, StackActions} from '@react-navigation/native'; +import type {OnyxEntry} from 'react-native-onyx'; import Log from '@libs/Log'; import * as ReportUtils from '@libs/ReportUtils'; import {getReport} from '@libs/ReportUtils'; @@ -10,7 +11,6 @@ import type {HybridAppRoute, Route} from '@src/ROUTES'; import ROUTES, {HYBRID_APP_ROUTES} from '@src/ROUTES'; import {PROTECTED_SCREENS} from '@src/SCREENS'; import type {Report} from '@src/types/onyx'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import originalCloseRHPFlow from './closeRHPFlow'; import originalDismissModal from './dismissModal'; import originalDismissModalWithReport from './dismissModalWithReport'; @@ -68,7 +68,7 @@ const closeRHPFlow = (ref = navigationRef) => originalCloseRHPFlow(ref); // Re-exporting the dismissModalWithReport here to fill in default value for navigationRef. The dismissModalWithReport isn't defined in this file to avoid cyclic dependencies. // This method is needed because it allows to dismiss the modal and then open the report. Within this method is checked whether the report belongs to a specific workspace. Sometimes the report we want to check, hasn't been added to the Onyx yet. // Then we can pass the report as a param without getting it from the Onyx. -const dismissModalWithReport = (report: Report | EmptyObject, ref = navigationRef) => originalDismissModalWithReport(report, ref); +const dismissModalWithReport = (report: OnyxEntry, ref = navigationRef) => originalDismissModalWithReport(report, ref); /** Method for finding on which index in stack we are. */ function getActiveRouteIndex(stateOrRoute: StateOrRoute, index?: number): number | undefined { diff --git a/src/libs/Navigation/dismissModalWithReport.ts b/src/libs/Navigation/dismissModalWithReport.ts index c0405c2c9da..c63e4ba1367 100644 --- a/src/libs/Navigation/dismissModalWithReport.ts +++ b/src/libs/Navigation/dismissModalWithReport.ts @@ -2,6 +2,7 @@ import {getActionFromState} from '@react-navigation/core'; import type {NavigationContainerRef} from '@react-navigation/native'; import {StackActions} from '@react-navigation/native'; import {findLastIndex} from 'lodash'; +import type {OnyxEntry} from 'react-native-onyx'; import Log from '@libs/Log'; import getPolicyEmployeeAccountIDs from '@libs/PolicyEmployeeListUtils'; import {doesReportBelongToWorkspace} from '@libs/ReportUtils'; @@ -9,7 +10,6 @@ import NAVIGATORS from '@src/NAVIGATORS'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; import type {Report} from '@src/types/onyx'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import getPolicyIDFromState from './getPolicyIDFromState'; import getStateFromPath from './getStateFromPath'; @@ -25,7 +25,7 @@ import type {RootStackParamList, StackNavigationAction, State} from './types'; * * @param targetReportID - The reportID to navigate to after dismissing the modal */ -function dismissModalWithReport(targetReport: Report | EmptyObject, navigationRef: NavigationContainerRef) { +function dismissModalWithReport(targetReport: OnyxEntry, navigationRef: NavigationContainerRef) { if (!navigationRef.isReady()) { return; } @@ -44,8 +44,8 @@ function dismissModalWithReport(targetReport: Report | EmptyObject, navigationRe case SCREENS.REPORT_AVATAR: case SCREENS.CONCIERGE: // If we are not in the target report, we need to navigate to it after dismissing the modal - if (targetReport.reportID !== getTopmostReportId(state)) { - const reportState = getStateFromPath(ROUTES.REPORT_WITH_ID.getRoute(targetReport.reportID)); + if (targetReport?.reportID !== getTopmostReportId(state)) { + const reportState = getStateFromPath(ROUTES.REPORT_WITH_ID.getRoute(targetReport?.reportID ?? '')); const policyID = getPolicyIDFromState(state as State); const policyMemberAccountIDs = getPolicyEmployeeAccountIDs(policyID); const shouldOpenAllWorkspace = isEmptyObject(targetReport) ? true : !doesReportBelongToWorkspace(targetReport, policyMemberAccountIDs, policyID); diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 88c33c9d98a..44046f2cf85 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -99,7 +99,6 @@ import type {Decision, OriginalMessageIOU} from '@src/types/onyx/OriginalMessage import type {NotificationPreference, Participants, Participant as ReportParticipant, RoomVisibility, WriteCapability} from '@src/types/onyx/Report'; import type Report from '@src/types/onyx/Report'; import type {Message, ReportActionBase, ReportActions} from '@src/types/onyx/ReportAction'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import * as CachedPDFPaths from './CachedPDFPaths'; import * as Modal from './Modal'; @@ -974,8 +973,8 @@ function navigateToAndOpenReport( optimisticReportID?: string, isGroupChat = false, ) { - let newChat: ReportUtils.OptimisticChatReport | EmptyObject = {}; - let chat: OnyxEntry | EmptyObject = {}; + let newChat: ReportUtils.OptimisticChatReport | null = null; + let chat: OnyxEntry = null; const participantAccountIDs = PersonalDetailsUtils.getAccountIDsByLogins(userLogins); // If we are not creating a new Group Chat then we are creating a 1:1 DM and will look for an existing chat @@ -994,12 +993,12 @@ function navigateToAndOpenReport( const report = isEmptyObject(chat) ? newChat : chat; // We want to pass newChat here because if anything is passed in that param (even an existing chat), we will try to create a chat on the server - openReport(report.reportID, '', userLogins, newChat, undefined, undefined, undefined, avatarFile); + openReport(report?.reportID ?? '', '', userLogins, newChat ?? {}, undefined, undefined, undefined, avatarFile); if (shouldDismissModal) { Navigation.dismissModalWithReport(report); } else { Navigation.navigateWithSwitchPolicyID({route: ROUTES.HOME}); - Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(report.reportID)); + Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(report?.reportID ?? '')); } } @@ -1009,7 +1008,7 @@ function navigateToAndOpenReport( * @param participantAccountIDs of user logins to start a chat report with. */ function navigateToAndOpenReportWithAccountIDs(participantAccountIDs: number[]) { - let newChat: ReportUtils.OptimisticChatReport | EmptyObject = {}; + let newChat: ReportUtils.OptimisticChatReport | null = null; const chat = ReportUtils.getChatByParticipants([...participantAccountIDs, currentUserAccountID]); if (!chat) { newChat = ReportUtils.buildOptimisticChatReport([...participantAccountIDs, currentUserAccountID]); @@ -1017,7 +1016,7 @@ function navigateToAndOpenReportWithAccountIDs(participantAccountIDs: number[]) const report = chat ?? newChat; // We want to pass newChat here because if anything is passed in that param (even an existing chat), we will try to create a chat on the server - openReport(report.reportID, '', [], newChat, '0', false, participantAccountIDs); + openReport(report?.reportID ?? '', '', [], newChat ?? {}, '0', false, participantAccountIDs); Navigation.dismissModalWithReport(report); } @@ -1602,7 +1601,7 @@ function updateNotificationPreference( navigate: boolean, parentReportID?: string, parentReportActionID?: string, - report: OnyxEntry | EmptyObject = {}, + report: OnyxEntry = null, ) { if (previousValue === newValue) { if (navigate && !isEmptyObject(report) && report.reportID) { @@ -1648,7 +1647,7 @@ function updateNotificationPreference( } } -function updateRoomVisibility(reportID: string, previousValue: RoomVisibility | undefined, newValue: RoomVisibility, navigate: boolean, report: OnyxEntry | EmptyObject = {}) { +function updateRoomVisibility(reportID: string, previousValue: RoomVisibility | undefined, newValue: RoomVisibility, navigate: boolean, report: OnyxEntry = null) { if (previousValue === newValue) { if (navigate && !isEmptyObject(report) && report.reportID) { ReportUtils.goBackToDetailsPage(report); diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index fe749b9d0ea..f13ae0303d3 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -22,7 +22,6 @@ import type {Icon} from '@src/types/onyx/OnyxCommon'; import type {ReportActions} from '@src/types/onyx/ReportAction'; import type ReportAction from '@src/types/onyx/ReportAction'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import * as Report from './Report'; type OptimisticReport = Pick; @@ -814,7 +813,7 @@ function getParentReportAction(report: OnyxEntry): ReportActio /** * Returns the parentReport if the given report is a thread */ -function getParentReport(report: OnyxEntry | EmptyObject): OnyxEntry { +function getParentReport(report: OnyxEntry): OnyxEntry { if (!report?.parentReportID) { return null; } diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index f7e90f775b6..3212aff7112 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -44,7 +44,6 @@ import type {Status} from '@src/types/onyx/PersonalDetails'; import type ReportAction from '@src/types/onyx/ReportAction'; import type {OriginalMessage} from '@src/types/onyx/ReportAction'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import applyOnyxUpdatesReliably from './applyOnyxUpdatesReliably'; import * as Link from './Link'; import * as Report from './Report'; @@ -60,7 +59,7 @@ Onyx.connect({ }, }); -let myPersonalDetails: OnyxEntry | EmptyObject = {}; +let myPersonalDetails: OnyxEntry; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, callback: (value) => { diff --git a/src/libs/actions/Welcome.ts b/src/libs/actions/Welcome.ts index 119b7da42e2..c4b6d86794a 100644 --- a/src/libs/actions/Welcome.ts +++ b/src/libs/actions/Welcome.ts @@ -4,7 +4,6 @@ import type {OnboardingPurposeType} from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type Onboarding from '@src/types/onyx/Onboarding'; import type OnyxPolicy from '@src/types/onyx/Policy'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; let onboarding: Onboarding | [] | undefined; let hasDismissedModal: boolean | undefined; @@ -110,7 +109,7 @@ Onyx.connect({ }, }); -const allPolicies: OnyxCollection | EmptyObject = {}; +const allPolicies: OnyxCollection = {}; Onyx.connect({ key: ONYXKEYS.COLLECTION.POLICY, callback: (val, key) => { From 2243993909ac216fbd290034039ddffa184666e6 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 31 May 2024 03:01:25 +0700 Subject: [PATCH 06/21] remove EmptyObject in several components --- src/libs/actions/Policy/Policy.ts | 45 +++++++++++---------- src/pages/ProfilePage.tsx | 12 +++--- src/pages/home/report/ReportActionsList.tsx | 7 ++-- src/pages/home/report/ReportFooter.tsx | 9 ++--- src/types/onyx/ReportAction.ts | 3 +- 5 files changed, 37 insertions(+), 39 deletions(-) diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 006b8c0e559..f94482e018d 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -82,7 +82,6 @@ import type {ErrorFields, Errors, PendingAction} from '@src/types/onyx/OnyxCommo import type {OriginalMessageJoinPolicyChangeLog} from '@src/types/onyx/OriginalMessage'; import type {Attributes, CompanyAddress, CustomUnit, Rate, Unit} from '@src/types/onyx/Policy'; import type {OnyxData} from '@src/types/onyx/Request'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; type AnnounceRoomMembersOnyxData = { @@ -222,11 +221,11 @@ function isCurrencySupportedForDirectReimbursement(currency: string) { /** * Returns the policy of the report */ -function getPolicy(policyID: string | undefined): Policy | EmptyObject { +function getPolicy(policyID: string | undefined): OnyxEntry { if (!allPolicies || !policyID) { - return {}; + return null; } - return allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`] ?? {}; + return allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; } /** @@ -461,11 +460,11 @@ function setWorkspaceAutoReporting(policyID: string, enabled: boolean, frequency onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - autoReporting: policy.autoReporting ?? null, + autoReporting: policy?.autoReporting ?? null, harvesting: { - enabled: policy.harvesting?.enabled ?? null, + enabled: policy?.harvesting?.enabled ?? null, }, - autoReportingFrequency: policy.autoReportingFrequency ?? null, + autoReportingFrequency: policy?.autoReportingFrequency ?? null, pendingFields: {autoReporting: null}, errorFields: {autoReporting: ErrorUtils.getMicroSecondOnyxError('workflowsDelayedSubmissionPage.autoReportingErrorMessage')}, }, @@ -506,7 +505,7 @@ function setWorkspaceAutoReportingFrequency(policyID: string, frequency: ValueOf onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - autoReportingFrequency: policy.autoReportingFrequency ?? null, + autoReportingFrequency: policy?.autoReportingFrequency ?? null, pendingFields: {autoReportingFrequency: null}, errorFields: {autoReportingFrequency: ErrorUtils.getMicroSecondOnyxError('workflowsDelayedSubmissionPage.autoReportingFrequencyErrorMessage')}, }, @@ -547,7 +546,7 @@ function setWorkspaceAutoReportingMonthlyOffset(policyID: string, autoReportingO onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - autoReportingOffset: policy.autoReportingOffset ?? null, + autoReportingOffset: policy?.autoReportingOffset ?? null, pendingFields: {autoReportingOffset: null}, errorFields: {autoReportingOffset: ErrorUtils.getMicroSecondOnyxError('workflowsDelayedSubmissionPage.monthlyOffsetErrorMessage')}, }, @@ -592,8 +591,8 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - approver: policy.approver ?? null, - approvalMode: policy.approvalMode ?? null, + approver: policy?.approver ?? null, + approvalMode: policy?.approvalMode ?? null, pendingFields: {approvalMode: null}, errorFields: {approvalMode: ErrorUtils.getMicroSecondOnyxError('workflowsApprovalPage.genericErrorMessage')}, }, @@ -652,7 +651,7 @@ function setWorkspacePayer(policyID: string, reimburserEmail: string) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - achAccount: {reimburser: policy.achAccount?.reimburser ?? null}, + achAccount: {reimburser: policy?.achAccount?.reimburser ?? null}, errorFields: {reimburser: ErrorUtils.getMicroSecondOnyxError('workflowsPayerPage.genericErrorMessage')}, pendingFields: {reimburser: null}, }, @@ -711,8 +710,8 @@ function setWorkspaceReimbursement(policyID: string, reimbursementChoice: ValueO key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { isLoadingWorkspaceReimbursement: false, - reimbursementChoice: policy.reimbursementChoice ?? null, - achAccount: {reimburser: policy.achAccount?.reimburser ?? null}, + reimbursementChoice: policy?.reimbursementChoice ?? null, + achAccount: {reimburser: policy?.achAccount?.reimburser ?? null}, errorFields: {reimbursementChoice: ErrorUtils.getMicroSecondOnyxError('common.genericErrorMessage')}, pendingFields: {reimbursementChoice: null}, }, @@ -800,9 +799,11 @@ function removeMembers(accountIDs: number[], policyID: string) { const workspaceChats = ReportUtils.getWorkspaceChats(policyID, accountIDs); const emailList = accountIDs.map((accountID) => allPersonalDetails?.[accountID]?.login).filter((login) => !!login) as string[]; - const optimisticClosedReportActions = workspaceChats.map(() => ReportUtils.buildOptimisticClosedReportAction(sessionEmail, policy.name, CONST.REPORT.ARCHIVE_REASON.REMOVED_FROM_POLICY)); + const optimisticClosedReportActions = workspaceChats.map(() => + ReportUtils.buildOptimisticClosedReportAction(sessionEmail, policy?.name ?? '', CONST.REPORT.ARCHIVE_REASON.REMOVED_FROM_POLICY), + ); - const announceRoomMembers = removeOptimisticAnnounceRoomMembers(policy.id, policy.name, accountIDs); + const announceRoomMembers = removeOptimisticAnnounceRoomMembers(policy?.id ?? '', policy?.name ?? '', accountIDs); const optimisticMembersState: OnyxCollection = {}; const successMembersState: OnyxCollection = {}; @@ -849,7 +850,7 @@ function removeMembers(accountIDs: number[], policyID: string) { value: { statusNum: CONST.REPORT.STATUS_NUM.CLOSED, stateNum: CONST.REPORT.STATE_NUM.APPROVED, - oldPolicyName: policy.name, + oldPolicyName: policy?.name ?? '', pendingChatMembers, }, }); @@ -885,7 +886,7 @@ function removeMembers(accountIDs: number[], policyID: string) { const remainingLogins = employeeListEmails.filter((email) => !emailList.includes(email)); const invitedPrimaryToSecondaryLogins: Record = {}; - if (policy.primaryLoginsInvited) { + if (policy?.primaryLoginsInvited) { Object.keys(policy.primaryLoginsInvited).forEach((key) => (invitedPrimaryToSecondaryLogins[policy.primaryLoginsInvited?.[key] ?? ''] = key)); } @@ -3551,10 +3552,10 @@ function enablePolicyWorkflows(policyID: string, enabled: boolean) { areWorkflowsEnabled: !enabled, ...(!enabled ? { - approvalMode: policy.approvalMode, - autoReporting: policy.autoReporting, - harvesting: policy.harvesting, - reimbursementChoice: policy.reimbursementChoice, + approvalMode: policy?.approvalMode ?? null, + autoReporting: policy?.autoReporting ?? null, + harvesting: policy?.harvesting ?? null, + reimbursementChoice: policy?.reimbursementChoice ?? null, } : {}), pendingFields: { diff --git a/src/pages/ProfilePage.tsx b/src/pages/ProfilePage.tsx index 7ce9bcf47c9..3618918be48 100755 --- a/src/pages/ProfilePage.tsx +++ b/src/pages/ProfilePage.tsx @@ -36,7 +36,6 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type {PersonalDetails, Report} from '@src/types/onyx'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; type ProfilePageProps = StackScreenProps; @@ -44,7 +43,8 @@ type ProfilePageProps = StackScreenProps { +const getPhoneNumber = (details: OnyxEntry): string | undefined => { + const {login = '', displayName = ''} = details ?? {}; // If the user hasn't set a displayName, it is set to their phone number const parsedPhoneNumber = parsePhoneNumber(displayName); @@ -92,7 +92,7 @@ function ProfilePage({route}: ProfilePageProps) { const {translate, formatPhoneNumber} = useLocalize(); const accountID = Number(route.params?.accountID ?? 0); const isCurrentUser = session?.accountID === accountID; - const details: PersonalDetails | EmptyObject = personalDetails?.[accountID] ?? (ValidationUtils.isValidAccountRoute(accountID) ? {} : {accountID: 0}); + const details: OnyxEntry = personalDetails?.[accountID] ?? (ValidationUtils.isValidAccountRoute(accountID) ? null : {accountID: 0}); const displayName = PersonalDetailsUtils.getDisplayNameOrDefault(details, undefined, undefined, isCurrentUser); const fallbackIcon = details?.fallbackIcon ?? ''; @@ -114,7 +114,7 @@ function ProfilePage({route}: ProfilePageProps) { const phoneNumber = getPhoneNumber(details); const phoneOrEmail = isSMSLogin ? getPhoneNumber(details) : login; - const hasAvatar = Boolean(details.avatar); + const hasAvatar = Boolean(details?.avatar); const isLoading = Boolean(personalDetailsMetadata?.[accountID]?.isLoading) || isEmptyObject(details); const statusEmojiCode = details?.status?.emojiCode ?? ''; @@ -158,7 +158,7 @@ function ProfilePage({route}: ProfilePageProps) { - + {isSMSLogin ? formatPhoneNumber(phoneNumber ?? '') : login} diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index c700fea4fb8..ea305830d77 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -29,7 +29,6 @@ import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; import type * as OnyxTypes from '@src/types/onyx'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import FloatingMessageCounter from './FloatingMessageCounter'; import getInitialNumToRender from './getInitialNumReportActionsToRender'; import ListBoundaryLoader from './ListBoundaryLoader'; @@ -607,7 +606,7 @@ function ReportActionsList({ [isLoadingNewerReportActions, styles.chatContentScrollView, styles.chatContentScrollViewWithHeaderLoader, canShowHeader], ); - const lastReportAction: OnyxTypes.ReportAction | EmptyObject = useMemo(() => sortedReportActions.at(-1) ?? {}, [sortedReportActions]); + const lastReportAction: OnyxTypes.ReportAction | null = useMemo(() => sortedReportActions.at(-1) ?? null, [sortedReportActions]); const retryLoadOlderChatsError = useCallback(() => { loadOlderChats(true); @@ -628,12 +627,12 @@ function ReportActionsList({ type={CONST.LIST_COMPONENTS.FOOTER} isLoadingOlderReportActions={isLoadingOlderReportActions} isLoadingInitialReportActions={isLoadingInitialReportActions} - lastReportActionName={lastReportAction.actionName} + lastReportActionName={lastReportAction?.actionName} hasError={hasLoadingOlderReportActionsError} onRetry={retryLoadOlderChatsError} /> ); - }, [isLoadingInitialReportActions, isLoadingOlderReportActions, lastReportAction.actionName, isOffline, hasLoadingOlderReportActionsError, retryLoadOlderChatsError]); + }, [isLoadingInitialReportActions, isLoadingOlderReportActions, lastReportAction?.actionName, isOffline, hasLoadingOlderReportActionsError, retryLoadOlderChatsError]); const onLayoutInner = useCallback( (event: LayoutChangeEvent) => { diff --git a/src/pages/home/report/ReportFooter.tsx b/src/pages/home/report/ReportFooter.tsx index ac56fe916bc..39824b6622b 100644 --- a/src/pages/home/report/ReportFooter.tsx +++ b/src/pages/home/report/ReportFooter.tsx @@ -21,7 +21,6 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type * as OnyxTypes from '@src/types/onyx'; import type {PendingAction} from '@src/types/onyx/OnyxCommon'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import ReportActionCompose from './ReportActionCompose/ReportActionCompose'; import SystemChatReportFooterMessage from './SystemChatReportFooterMessage'; @@ -118,18 +117,18 @@ function ReportFooter({ const mention = match[1] ? match[1].trim() : undefined; const mentionWithDomain = ReportUtils.addDomainToShortMention(mention ?? '') ?? mention; - let assignee: OnyxTypes.PersonalDetails | EmptyObject = {}; + let assignee: OnyxEntry = null; let assigneeChatReport; if (mentionWithDomain) { - assignee = Object.values(allPersonalDetails).find((value) => value?.login === mentionWithDomain) ?? {}; - if (!Object.keys(assignee).length) { + assignee = Object.values(allPersonalDetails).find((value) => value?.login === mentionWithDomain) ?? null; + if (!Object.keys(assignee ?? {}).length) { const assigneeAccountID = UserUtils.generateAccountID(mentionWithDomain); const optimisticDataForNewAssignee = Task.setNewOptimisticAssignee(mentionWithDomain, assigneeAccountID); assignee = optimisticDataForNewAssignee.assignee; assigneeChatReport = optimisticDataForNewAssignee.assigneeReport; } } - Task.createTaskAndNavigate(report.reportID, title, '', assignee?.login ?? '', assignee.accountID, assigneeChatReport, report.policyID); + Task.createTaskAndNavigate(report.reportID, title, '', assignee?.login ?? '', assignee?.accountID, assigneeChatReport, report.policyID); return true; }, [allPersonalDetails, report.policyID, report.reportID], diff --git a/src/types/onyx/ReportAction.ts b/src/types/onyx/ReportAction.ts index d7333feb865..7ae3eb47295 100644 --- a/src/types/onyx/ReportAction.ts +++ b/src/types/onyx/ReportAction.ts @@ -4,7 +4,6 @@ import type {AvatarSource} from '@libs/UserUtils'; import type CONST from '@src/CONST'; import type ONYXKEYS from '@src/ONYXKEYS'; import type CollectionDataSet from '@src/types/utils/CollectionDataSet'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import type * as OnyxCommon from './OnyxCommon'; import type {Decision, OriginalMessageModifiedExpense, OriginalMessageReportPreview, Reaction} from './OriginalMessage'; import type OriginalMessage from './OriginalMessage'; @@ -191,7 +190,7 @@ type ReportActionBase = OnyxCommon.OnyxValueWithOfflineFeedback<{ isFirstItem?: boolean; /** Informations about attachments of report action */ - attachmentInfo?: FileObject | EmptyObject; + attachmentInfo?: FileObject; /** Receipt tied to report action */ receipt?: Receipt; From beb4150076575e9fde7d4c928867670f8ce3dfec Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 31 May 2024 03:08:39 +0700 Subject: [PATCH 07/21] remove EmptyObject in API --- src/libs/API/types.ts | 23 +++++++++++------------ src/libs/actions/MapboxToken.ts | 4 ++-- src/libs/actions/PaymentMethods.ts | 14 +++++--------- src/libs/actions/PersonalDetails.ts | 2 +- src/libs/actions/Session/index.ts | 2 +- src/libs/actions/Travel.ts | 2 +- src/libs/actions/User.ts | 2 +- src/libs/actions/Wallet.ts | 6 +++--- tests/unit/APITest.ts | 2 +- 9 files changed, 26 insertions(+), 31 deletions(-) diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 40deec85bc4..6a623246ad7 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -1,6 +1,5 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import type * as Parameters from './parameters'; import type SignInUserParams from './parameters/SignInUserParams'; import type UpdateBeneficialOwnersForBankAccountParams from './parameters/UpdateBeneficialOwnersForBankAccountParams'; @@ -253,7 +252,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.UPDATE_AUTOMATIC_TIMEZONE]: Parameters.UpdateAutomaticTimezoneParams; [WRITE_COMMANDS.UPDATE_SELECTED_TIMEZONE]: Parameters.UpdateSelectedTimezoneParams; [WRITE_COMMANDS.UPDATE_USER_AVATAR]: Parameters.UpdateUserAvatarParams; - [WRITE_COMMANDS.DELETE_USER_AVATAR]: EmptyObject; + [WRITE_COMMANDS.DELETE_USER_AVATAR]: null; [WRITE_COMMANDS.REFER_TEACHERS_UNITE_VOLUNTEER]: Parameters.ReferTeachersUniteVolunteerParams; [WRITE_COMMANDS.ADD_SCHOOL_PRINCIPAL]: Parameters.AddSchoolPrincipalParams; [WRITE_COMMANDS.CLOSE_ACCOUNT]: Parameters.CloseAccountParams; @@ -269,7 +268,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.SET_CONTACT_METHOD_AS_DEFAULT]: Parameters.SetContactMethodAsDefaultParams; [WRITE_COMMANDS.UPDATE_THEME]: Parameters.UpdateThemeParams; [WRITE_COMMANDS.UPDATE_STATUS]: Parameters.UpdateStatusParams; - [WRITE_COMMANDS.CLEAR_STATUS]: EmptyObject; + [WRITE_COMMANDS.CLEAR_STATUS]: null; [WRITE_COMMANDS.UPDATE_PERSONAL_DETAILS_FOR_WALLET]: Parameters.UpdatePersonalDetailsForWalletParams; [WRITE_COMMANDS.VERIFY_IDENTITY]: Parameters.VerifyIdentityParams; [WRITE_COMMANDS.ACCEPT_WALLET_TERMS]: Parameters.AcceptWalletTermsParams; @@ -284,8 +283,8 @@ type WriteCommandParameters = { [WRITE_COMMANDS.SIGN_IN_USER_WITH_LINK]: Parameters.SignInUserWithLinkParams; [WRITE_COMMANDS.REQUEST_UNLINK_VALIDATION_LINK]: Parameters.RequestUnlinkValidationLinkParams; [WRITE_COMMANDS.UNLINK_LOGIN]: Parameters.UnlinkLoginParams; - [WRITE_COMMANDS.ENABLE_TWO_FACTOR_AUTH]: EmptyObject; - [WRITE_COMMANDS.DISABLE_TWO_FACTOR_AUTH]: EmptyObject; + [WRITE_COMMANDS.ENABLE_TWO_FACTOR_AUTH]: null; + [WRITE_COMMANDS.DISABLE_TWO_FACTOR_AUTH]: null; [WRITE_COMMANDS.TWO_FACTOR_AUTH_VALIDATE]: Parameters.ValidateTwoFactorAuthParams; [WRITE_COMMANDS.ADD_COMMENT]: Parameters.AddCommentOrAttachementParams; [WRITE_COMMANDS.ADD_ATTACHMENT]: Parameters.AddCommentOrAttachementParams; @@ -433,7 +432,7 @@ type WriteCommandParameters = { [WRITE_COMMANDS.CATEGORIZE_TRACKED_EXPENSE]: Parameters.CategorizeTrackedExpenseParams; [WRITE_COMMANDS.SHARE_TRACKED_EXPENSE]: Parameters.ShareTrackedExpenseParams; [WRITE_COMMANDS.LEAVE_POLICY]: Parameters.LeavePolicyParams; - [WRITE_COMMANDS.ACCEPT_SPOTNANA_TERMS]: EmptyObject; + [WRITE_COMMANDS.ACCEPT_SPOTNANA_TERMS]: null; [WRITE_COMMANDS.SEND_INVOICE]: Parameters.SendInvoiceParams; [WRITE_COMMANDS.MARK_AS_CASH]: Parameters.MarkAsCashParams; }; @@ -492,9 +491,9 @@ type ReadCommandParameters = { [READ_COMMANDS.SYNC_POLICY_TO_XERO]: Parameters.SyncPolicyToXeroParams; [READ_COMMANDS.OPEN_REIMBURSEMENT_ACCOUNT_PAGE]: Parameters.OpenReimbursementAccountPageParams; [READ_COMMANDS.OPEN_WORKSPACE_VIEW]: Parameters.OpenWorkspaceViewParams; - [READ_COMMANDS.GET_MAPBOX_ACCESS_TOKEN]: EmptyObject; - [READ_COMMANDS.OPEN_PAYMENTS_PAGE]: EmptyObject; - [READ_COMMANDS.OPEN_PERSONAL_DETAILS]: EmptyObject; + [READ_COMMANDS.GET_MAPBOX_ACCESS_TOKEN]: null; + [READ_COMMANDS.OPEN_PAYMENTS_PAGE]: null; + [READ_COMMANDS.OPEN_PERSONAL_DETAILS]: null; [READ_COMMANDS.OPEN_PUBLIC_PROFILE_PAGE]: Parameters.OpenPublicProfilePageParams; [READ_COMMANDS.OPEN_PLAID_BANK_LOGIN]: Parameters.OpenPlaidBankLoginParams; [READ_COMMANDS.OPEN_PLAID_BANK_ACCOUNT_SELECTOR]: Parameters.OpenPlaidBankAccountSelectorParams; @@ -509,9 +508,9 @@ type ReadCommandParameters = { [READ_COMMANDS.GET_ROUTE]: Parameters.GetRouteParams; [READ_COMMANDS.GET_ROUTE_FOR_DRAFT]: Parameters.GetRouteParams; [READ_COMMANDS.GET_STATEMENT_PDF]: Parameters.GetStatementPDFParams; - [READ_COMMANDS.OPEN_ONFIDO_FLOW]: EmptyObject; - [READ_COMMANDS.OPEN_INITIAL_SETTINGS_PAGE]: EmptyObject; - [READ_COMMANDS.OPEN_ENABLE_PAYMENTS_PAGE]: EmptyObject; + [READ_COMMANDS.OPEN_ONFIDO_FLOW]: null; + [READ_COMMANDS.OPEN_INITIAL_SETTINGS_PAGE]: null; + [READ_COMMANDS.OPEN_ENABLE_PAYMENTS_PAGE]: null; [READ_COMMANDS.BEGIN_SIGNIN]: Parameters.BeginSignInParams; [READ_COMMANDS.SIGN_IN_WITH_SHORT_LIVED_AUTH_TOKEN]: Parameters.SignInWithShortLivedAuthTokenParams; [READ_COMMANDS.SIGN_IN_WITH_SUPPORT_AUTH_TOKEN]: Parameters.SignInWithSupportAuthTokenParams; diff --git a/src/libs/actions/MapboxToken.ts b/src/libs/actions/MapboxToken.ts index 3b98f79698b..db3999c6f75 100644 --- a/src/libs/actions/MapboxToken.ts +++ b/src/libs/actions/MapboxToken.ts @@ -39,7 +39,7 @@ const setExpirationTimer = () => { return; } console.debug(`[MapboxToken] Fetching a new token after waiting ${REFRESH_INTERVAL / 1000 / 60} minutes`); - API.read(READ_COMMANDS.GET_MAPBOX_ACCESS_TOKEN, {}, {}); + API.read(READ_COMMANDS.GET_MAPBOX_ACCESS_TOKEN, null, {}); }, REFRESH_INTERVAL); }; @@ -52,7 +52,7 @@ const clearToken = () => { }; const fetchToken = () => { - API.read(READ_COMMANDS.GET_MAPBOX_ACCESS_TOKEN, {}, {}); + API.read(READ_COMMANDS.GET_MAPBOX_ACCESS_TOKEN, null, {}); isCurrentlyFetchingToken = true; }; diff --git a/src/libs/actions/PaymentMethods.ts b/src/libs/actions/PaymentMethods.ts index c5a74bdc6ac..a33a36d575c 100644 --- a/src/libs/actions/PaymentMethods.ts +++ b/src/libs/actions/PaymentMethods.ts @@ -63,15 +63,11 @@ function openWalletPage() { }, ]; - return API.read( - READ_COMMANDS.OPEN_PAYMENTS_PAGE, - {}, - { - optimisticData, - successData, - failureData, - }, - ); + return API.read(READ_COMMANDS.OPEN_PAYMENTS_PAGE, null, { + optimisticData, + successData, + failureData, + }); } function getMakeDefaultPaymentOnyxData( diff --git a/src/libs/actions/PersonalDetails.ts b/src/libs/actions/PersonalDetails.ts index b9cea5c9447..e93ba560dc6 100644 --- a/src/libs/actions/PersonalDetails.ts +++ b/src/libs/actions/PersonalDetails.ts @@ -397,7 +397,7 @@ function deleteAvatar() { }, ]; - API.write(WRITE_COMMANDS.DELETE_USER_AVATAR, {}, {optimisticData, failureData}); + API.write(WRITE_COMMANDS.DELETE_USER_AVATAR, null, {optimisticData, failureData}); } /** diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index 30351755820..7174199e930 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -859,7 +859,7 @@ function toggleTwoFactorAuth(enable: boolean) { }, ]; - API.write(enable ? WRITE_COMMANDS.ENABLE_TWO_FACTOR_AUTH : WRITE_COMMANDS.DISABLE_TWO_FACTOR_AUTH, {}, {optimisticData, successData, failureData}); + API.write(enable ? WRITE_COMMANDS.ENABLE_TWO_FACTOR_AUTH : WRITE_COMMANDS.DISABLE_TWO_FACTOR_AUTH, null, {optimisticData, successData, failureData}); } function validateTwoFactorAuth(twoFactorAuthCode: string) { diff --git a/src/libs/actions/Travel.ts b/src/libs/actions/Travel.ts index 02affae0fe6..f13a978d4e7 100644 --- a/src/libs/actions/Travel.ts +++ b/src/libs/actions/Travel.ts @@ -19,7 +19,7 @@ function acceptSpotnanaTerms() { }, ]; - API.write(WRITE_COMMANDS.ACCEPT_SPOTNANA_TERMS, {}, {successData}); + API.write(WRITE_COMMANDS.ACCEPT_SPOTNANA_TERMS, null, {successData}); } // eslint-disable-next-line import/prefer-default-export diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 3212aff7112..a68f20557da 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -951,7 +951,7 @@ function clearCustomStatus() { }, }, ]; - API.write(WRITE_COMMANDS.CLEAR_STATUS, {}, {optimisticData}); + API.write(WRITE_COMMANDS.CLEAR_STATUS, null, {optimisticData}); } /** diff --git a/src/libs/actions/Wallet.ts b/src/libs/actions/Wallet.ts index 045cc34f39e..19d44c2406f 100644 --- a/src/libs/actions/Wallet.ts +++ b/src/libs/actions/Wallet.ts @@ -49,7 +49,7 @@ function openOnfidoFlow() { }, ]; - API.read(READ_COMMANDS.OPEN_ONFIDO_FLOW, {}, {optimisticData, finallyData}); + API.read(READ_COMMANDS.OPEN_ONFIDO_FLOW, null, {optimisticData, finallyData}); } function setAdditionalDetailsQuestions(questions: WalletAdditionalQuestionDetails[] | null, idNumber?: string) { @@ -212,14 +212,14 @@ function acceptWalletTerms(parameters: AcceptWalletTermsParams) { * Fetches data when the user opens the InitialSettingsPage */ function openInitialSettingsPage() { - API.read(READ_COMMANDS.OPEN_INITIAL_SETTINGS_PAGE, {}); + API.read(READ_COMMANDS.OPEN_INITIAL_SETTINGS_PAGE, null); } /** * Fetches data when the user opens the EnablePaymentsPage */ function openEnablePaymentsPage() { - API.read(READ_COMMANDS.OPEN_ENABLE_PAYMENTS_PAGE, {}); + API.read(READ_COMMANDS.OPEN_ENABLE_PAYMENTS_PAGE, null); } function updateCurrentStep(currentStep: ValueOf) { diff --git a/tests/unit/APITest.ts b/tests/unit/APITest.ts index 07633b19802..d2498c16c16 100644 --- a/tests/unit/APITest.ts +++ b/tests/unit/APITest.ts @@ -538,7 +538,7 @@ describe('APITests', () => { // WHEN we make a request that should be retried, one that should not, and another that should API.write('MockCommandOne' as WriteCommand, {}); - API.read('MockCommandTwo' as ReadCommand, {}); + API.read('MockCommandTwo' as ReadCommand, null); API.write('MockCommandThree' as WriteCommand, {}); // THEN the retryable requests should immediately be added to the persisted requests From 7a2d0d4e2de37c6127a7751f8c098aa08fe73a88 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 31 May 2024 03:41:13 +0700 Subject: [PATCH 08/21] remove EmptyObject in IOU --- src/libs/actions/IOU.ts | 169 +++++++++++++++++++++------------------- 1 file changed, 87 insertions(+), 82 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index d657ba27f17..84d95d67575 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -52,13 +52,12 @@ import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; import type {Participant, Split} from '@src/types/onyx/IOU'; import type {ErrorFields, Errors} from '@src/types/onyx/OnyxCommon'; -import type {IOUMessage, PaymentMethodType} from '@src/types/onyx/OriginalMessage'; +import type {IOUMessage, OriginalMessageReportPreview, PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import type ReportAction from '@src/types/onyx/ReportAction'; import type {ReportPreviewAction} from '@src/types/onyx/ReportAction'; import type {OnyxData} from '@src/types/onyx/Request'; import type {Comment, Receipt, ReceiptSource, Routes, SplitShares, TransactionChanges, WaypointCollection} from '@src/types/onyx/Transaction'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import * as CachedPDFPaths from './CachedPDFPaths'; import * as Category from './Policy/Category'; @@ -237,11 +236,11 @@ Onyx.connect({ }, }); -let currentUserPersonalDetails: OnyxTypes.PersonalDetails | EmptyObject = {}; +let currentUserPersonalDetails: OnyxEntry; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, callback: (value) => { - currentUserPersonalDetails = value?.[userAccountID] ?? {}; + currentUserPersonalDetails = value?.[userAccountID] ?? null; }, }); @@ -293,7 +292,10 @@ function getReportPreviewAction(chatReportID: string, iouReportID: string): Onyx // Find the report preview action from the chat report return ( Object.values(reportActions).find( - (reportAction) => reportAction && reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW && reportAction.originalMessage.linkedReportID === iouReportID, + (reportAction) => + reportAction && + reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW && + (reportAction as ReportAction & OriginalMessageReportPreview).originalMessage.linkedReportID === iouReportID, ) ?? null ); } @@ -332,13 +334,13 @@ function initMoneyRequest(reportID: string, policy: OnyxEntry, amount: 0, comment, created, - currency: currentUserPersonalDetails.localCurrencyCode ?? CONST.CURRENCY.USD, + currency: currentUserPersonalDetails?.localCurrencyCode ?? CONST.CURRENCY.USD, iouRequestType, reportID, transactionID: newTransactionID, isFromGlobalCreate, merchant: CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT, - splitPayerAccountIDs: [currentUserPersonalDetails.accountID], + splitPayerAccountIDs: currentUserPersonalDetails ? [currentUserPersonalDetails.accountID] : undefined, }); } @@ -461,7 +463,7 @@ function buildOnyxDataForMoneyRequest( optimisticPolicyRecentlyUsedCategories: string[], optimisticPolicyRecentlyUsedTags: OnyxTypes.RecentlyUsedTags, isNewChatReport: boolean, - transactionThreadReport: OptimisticChatReport | EmptyObject, + transactionThreadReport: OptimisticChatReport | null, transactionThreadCreatedReportAction: OptimisticCreatedReportAction | null, shouldCreateNewMoneyRequestReport: boolean, policy?: OnyxEntry, @@ -550,7 +552,7 @@ function buildOnyxDataForMoneyRequest( }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.reportID}`, value: { ...transactionThreadReport, pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, @@ -567,7 +569,7 @@ function buildOnyxDataForMoneyRequest( if (!isEmptyObject(transactionThreadCreatedReportAction)) { optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport?.reportID}`, value: { [transactionThreadCreatedReportAction.reportActionID]: transactionThreadCreatedReportAction, }, @@ -659,7 +661,7 @@ function buildOnyxDataForMoneyRequest( }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.reportID}`, value: { participants: redundantParticipants, pendingFields: null, @@ -716,7 +718,7 @@ function buildOnyxDataForMoneyRequest( if (!isEmptyObject(transactionThreadCreatedReportAction)) { successData.push({ onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport?.reportID}`, value: { [transactionThreadCreatedReportAction.reportActionID]: { pendingAction: null, @@ -758,7 +760,7 @@ function buildOnyxDataForMoneyRequest( }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.reportID}`, value: { pendingFields: null, errorFields: existingTransactionThreadReport @@ -808,7 +810,7 @@ function buildOnyxDataForMoneyRequest( if (!isEmptyObject(transactionThreadCreatedReportAction)) { failureData.push({ onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport?.reportID}`, value: { [transactionThreadCreatedReportAction.reportActionID]: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), @@ -1158,7 +1160,7 @@ function buildOnyxDataForTrackExpense( iouCreatedAction: OptimisticCreatedReportAction, iouAction: OptimisticIOUReportAction, reportPreviewAction: OnyxEntry, - transactionThreadReport: OptimisticChatReport | EmptyObject, + transactionThreadReport: OptimisticChatReport | null, transactionThreadCreatedReportAction: OptimisticCreatedReportAction | null, shouldCreateNewMoneyRequestReport: boolean, policy?: OnyxEntry, @@ -1293,7 +1295,7 @@ function buildOnyxDataForTrackExpense( }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.reportID}`, value: { ...transactionThreadReport, pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}, @@ -1310,7 +1312,7 @@ function buildOnyxDataForTrackExpense( if (!isEmptyObject(transactionThreadCreatedReportAction)) { optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport?.reportID}`, value: { [transactionThreadCreatedReportAction.reportActionID]: transactionThreadCreatedReportAction, }, @@ -1370,7 +1372,7 @@ function buildOnyxDataForTrackExpense( successData.push( { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.reportID}`, value: { pendingFields: null, errorFields: null, @@ -1389,7 +1391,7 @@ function buildOnyxDataForTrackExpense( if (!isEmptyObject(transactionThreadCreatedReportAction)) { successData.push({ onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport?.reportID}`, value: { [transactionThreadCreatedReportAction.reportActionID]: { pendingAction: null, @@ -1468,7 +1470,7 @@ function buildOnyxDataForTrackExpense( }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT}${transactionThreadReport?.reportID}`, value: { pendingFields: null, errorFields: existingTransactionThreadReport @@ -1491,7 +1493,7 @@ function buildOnyxDataForTrackExpense( }, { onyxMethod: Onyx.METHOD.MERGE, - key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport?.reportID}`, value: { [transactionThreadCreatedReportAction?.reportActionID ?? '']: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), @@ -1838,7 +1840,7 @@ function getSendInvoiceInformation( * it creates optimistic versions of them and uses those instead */ function getMoneyRequestInformation( - parentChatReport: OnyxEntry | EmptyObject, + parentChatReport: OnyxEntry, participant: Participant, comment: string, amount: number, @@ -2053,7 +2055,7 @@ function getMoneyRequestInformation( * it creates optimistic versions of them and uses those instead */ function getTrackExpenseInformation( - parentChatReport: OnyxEntry | EmptyObject, + parentChatReport: OnyxEntry, participant: Participant, comment: string, amount: number, @@ -2074,7 +2076,7 @@ function getTrackExpenseInformation( moneyRequestReportID = '', linkedTrackedExpenseReportAction?: OnyxTypes.ReportAction, existingTransactionID?: string, -): TrackExpenseInformation | EmptyObject { +): TrackExpenseInformation | null { const optimisticData: OnyxUpdate[] = []; const successData: OnyxUpdate[] = []; const failureData: OnyxUpdate[] = []; @@ -2092,7 +2094,7 @@ function getTrackExpenseInformation( // If we still don't have a report, it likely doesn't exist, and we will early return here as it should not happen // Maybe later, we can build an optimistic selfDM chat. if (!chatReport) { - return {}; + return null; } // Check if the report is a draft @@ -3217,7 +3219,7 @@ function categorizeTrackedExpense( linkedTrackedExpenseReportID: string, transactionThreadReportID: string, reportPreviewReportActionID: string, - onyxData: OnyxData, + onyxData: OnyxData | undefined, amount: number, currency: string, comment: string, @@ -3231,7 +3233,7 @@ function categorizeTrackedExpense( receipt?: Receipt, createdWorkspaceParams?: CreateWorkspaceParams, ) { - const {optimisticData, successData, failureData} = onyxData; + const {optimisticData, successData, failureData} = onyxData ?? {}; const { optimisticData: moveTransactionOptimisticData, @@ -3294,7 +3296,7 @@ function shareTrackedExpense( linkedTrackedExpenseReportID: string, transactionThreadReportID: string, reportPreviewReportActionID: string, - onyxData: OnyxData, + onyxData: OnyxData | undefined, amount: number, currency: string, comment: string, @@ -3308,7 +3310,7 @@ function shareTrackedExpense( receipt?: Receipt, createdWorkspaceParams?: CreateWorkspaceParams, ) { - const {optimisticData, successData, failureData} = onyxData; + const {optimisticData, successData, failureData} = onyxData ?? {}; const { optimisticData: moveTransactionOptimisticData, @@ -3409,7 +3411,7 @@ function requestMoney( createdReportActionIDForThread, onyxData, } = getMoneyRequestInformation( - isMovingTransactionFromTrackExpense ? {} : currentChatReport, + isMovingTransactionFromTrackExpense ? null : currentChatReport, participant, comment, amount, @@ -3598,30 +3600,31 @@ function trackExpense( createdReportActionIDForThread, actionableWhisperReportActionIDParam, onyxData, - } = getTrackExpenseInformation( - currentChatReport, - participant, - comment, - amount, - currency, - currentCreated, - merchant, - receipt, - category, - tag, - taxCode, - taxAmount, - billable, - policy, - policyTagList, - policyCategories, - payeeEmail, - payeeAccountID, - moneyRequestReportID, - linkedTrackedExpenseReportAction, - isMovingTransactionFromTrackExpense ? (linkedTrackedExpenseReportAction?.originalMessage as IOUMessage)?.IOUTransactionID : undefined, - ); - const activeReportID = isMoneyRequestReport ? report.reportID : chatReport.reportID; + } = + getTrackExpenseInformation( + currentChatReport, + participant, + comment, + amount, + currency, + currentCreated, + merchant, + receipt, + category, + tag, + taxCode, + taxAmount, + billable, + policy, + policyTagList, + policyCategories, + payeeEmail, + payeeAccountID, + moneyRequestReportID, + linkedTrackedExpenseReportAction, + isMovingTransactionFromTrackExpense ? (linkedTrackedExpenseReportAction?.originalMessage as IOUMessage)?.IOUTransactionID : undefined, + ) ?? {}; + const activeReportID = isMoneyRequestReport ? report.reportID : chatReport?.reportID; switch (action) { case CONST.IOU.ACTION.CATEGORIZE: { @@ -3629,15 +3632,15 @@ function trackExpense( return; } categorizeTrackedExpense( - chatReport.policyID ?? '', - transaction.transactionID, - iouAction.reportActionID, + chatReport?.policyID ?? '', + transaction?.transactionID ?? '', + iouAction?.reportActionID ?? '', iouReport?.reportID ?? '', createdIOUReportActionID ?? '', actionableWhisperReportActionID, linkedTrackedExpenseReportAction, linkedTrackedExpenseReportID, - transactionThreadReportID, + transactionThreadReportID ?? '', reportPreviewAction?.reportActionID ?? '', onyxData, amount, @@ -3660,15 +3663,15 @@ function trackExpense( return; } shareTrackedExpense( - chatReport.policyID ?? '', - transaction.transactionID, - iouAction.reportActionID, + chatReport?.policyID ?? '', + transaction?.transactionID ?? '', + iouAction?.reportActionID ?? '', iouReport?.reportID ?? '', createdIOUReportActionID ?? '', actionableWhisperReportActionID, linkedTrackedExpenseReportAction, linkedTrackedExpenseReportID, - transactionThreadReportID, + transactionThreadReportID ?? '', reportPreviewAction?.reportActionID ?? '', onyxData, amount, @@ -3694,10 +3697,10 @@ function trackExpense( created: currentCreated, merchant, iouReportID: iouReport?.reportID, - chatReportID: chatReport.reportID, - transactionID: transaction.transactionID, - reportActionID: iouAction.reportActionID, - createdChatReportActionID, + chatReportID: chatReport?.reportID ?? '', + transactionID: transaction?.transactionID ?? '', + reportActionID: iouAction?.reportActionID ?? '', + createdChatReportActionID: createdChatReportActionID ?? '', createdIOUReportActionID, reportPreviewReportActionID: reportPreviewAction?.reportActionID, receipt, @@ -3709,8 +3712,8 @@ function trackExpense( billable, // This needs to be a string of JSON because of limitations with the fetch() API and nested objects receiptGpsPoints: gpsPoints ? JSON.stringify(gpsPoints) : undefined, - transactionThreadReportID, - createdReportActionIDForThread, + transactionThreadReportID: transactionThreadReportID ?? '', + createdReportActionIDForThread: createdReportActionIDForThread ?? '', waypoints: validWaypoints ? JSON.stringify(validWaypoints) : undefined, }; if (actionableWhisperReportActionIDParam) { @@ -3725,7 +3728,7 @@ function trackExpense( Navigation.navigate(ROUTES.ROOM_INVITE.getRoute(activeReportID ?? '', CONST.IOU.SHARE.ROLE.ACCOUNTANT)); } - Report.notifyNewAction(activeReportID, payeeAccountID); + Report.notifyNewAction(activeReportID ?? '', payeeAccountID); } function getOrCreateOptimisticSplitChatReport(existingSplitChatReportID: string, participants: Participant[], participantAccountIDs: number[], currentUserAccountID: number) { @@ -4722,7 +4725,7 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA // In case this is still the optimistic accountID saved in the splits array, return early as we cannot know // if there is an existing chat between the split creator and this participant // Instead, we will rely on Auth generating the report IDs and the user won't see any optimistic chats or reports created - const participantPersonalDetails: OnyxTypes.PersonalDetails | EmptyObject = allPersonalDetails[participant?.accountID ?? -1] ?? {}; + const participantPersonalDetails: OnyxEntry = allPersonalDetails[participant?.accountID ?? -1]; if (!participantPersonalDetails || participantPersonalDetails.isOptimisticPersonalDetail) { splits.push({ email: participant.email, @@ -4731,7 +4734,7 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA } } - let oneOnOneChatReport: OnyxTypes.Report | null; + let oneOnOneChatReport: OnyxEntry; let isNewOneOnOneChatReport = false; if (isPolicyExpenseChat) { // The workspace chat reportID is saved in the splits array when starting a split expense with a workspace @@ -5244,10 +5247,12 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor iouReportLastMessageText.length === 0 && !ReportActionsUtils.isDeletedParentAction(lastVisibleAction) && (!transactionThreadID || shouldDeleteTransactionThread); // STEP 4: Update the iouReport and reportPreview with new totals and messages if it wasn't deleted - let updatedIOUReport: OnyxTypes.Report | null; + let updatedIOUReport: OnyxEntry; const currency = TransactionUtils.getCurrency(transaction); - const updatedReportPreviewAction: OnyxTypes.ReportAction | EmptyObject = {...reportPreviewAction}; - updatedReportPreviewAction.pendingAction = shouldDeleteIOUReport ? CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE : CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE; + const updatedReportPreviewAction: OnyxEntry = reportPreviewAction; + if (updatedReportPreviewAction) { + updatedReportPreviewAction.pendingAction = shouldDeleteIOUReport ? CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE : CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE; + } if (iouReport && ReportUtils.isExpenseReport(iouReport)) { updatedIOUReport = {...iouReport}; @@ -5341,7 +5346,7 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor }, ); - if (!shouldDeleteIOUReport && updatedReportPreviewAction.childMoneyRequestCount === 0) { + if (!shouldDeleteIOUReport && updatedReportPreviewAction?.childMoneyRequestCount === 0) { optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`, @@ -5470,7 +5475,7 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor }); } - if (!shouldDeleteIOUReport && updatedReportPreviewAction.childMoneyRequestCount === 0) { + if (!shouldDeleteIOUReport && updatedReportPreviewAction?.childMoneyRequestCount === 0) { failureData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${chatReport?.reportID}`, @@ -5527,7 +5532,7 @@ function deleteTrackExpense(chatReportID: string, transactionID: string, reportA * @param recipient - The user receiving the money */ function getSendMoneyParams( - report: OnyxEntry | EmptyObject, + report: OnyxEntry, amount: number, currency: string, comment: string, @@ -5653,7 +5658,7 @@ function getSendMoneyParams( const successData: OnyxUpdate[] = []; // Add optimistic personal details for recipient - let optimisticPersonalDetailListData: OnyxUpdate | EmptyObject = {}; + let optimisticPersonalDetailListData: OnyxUpdate | null = null; const optimisticPersonalDetailListAction = isNewChat ? { [recipientAccountID]: { @@ -6063,7 +6068,7 @@ function canApproveIOU(iouReport: OnyxEntry, chatReport: OnyxE return isCurrentUserManager && !isOpenExpenseReport && !isApproved && !iouSettled && !isArchivedReport; } -function canIOUBePaid(iouReport: OnyxEntry | EmptyObject, chatReport: OnyxEntry, policy: OnyxEntry) { +function canIOUBePaid(iouReport: OnyxEntry, chatReport: OnyxEntry, policy: OnyxEntry) { const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(chatReport); const isChatReportArchived = ReportUtils.isArchivedRoom(chatReport); @@ -6251,9 +6256,9 @@ function submitReport(expenseReport: OnyxTypes.Report) { const currentNextStep = allNextSteps[`${ONYXKEYS.COLLECTION.NEXT_STEP}${expenseReport.reportID}`] ?? null; const parentReport = ReportUtils.getReport(expenseReport.parentReportID); const policy = PolicyUtils.getPolicy(expenseReport.policyID); - const isCurrentUserManager = currentUserPersonalDetails.accountID === expenseReport.managerID; + const isCurrentUserManager = currentUserPersonalDetails?.accountID === expenseReport.managerID; const isSubmitAndClosePolicy = PolicyUtils.isSubmitAndClose(policy); - const adminAccountID = policy?.role === CONST.POLICY.ROLE.ADMIN ? currentUserPersonalDetails.accountID : undefined; + const adminAccountID = policy?.role === CONST.POLICY.ROLE.ADMIN ? currentUserPersonalDetails?.accountID : undefined; const optimisticSubmittedReportAction = ReportUtils.buildOptimisticSubmittedReportAction(expenseReport?.total ?? 0, expenseReport.currency ?? '', expenseReport.reportID, adminAccountID); const optimisticNextStep = NextStepUtils.buildNextStep(expenseReport, isSubmitAndClosePolicy ? CONST.REPORT.STATUS_NUM.CLOSED : CONST.REPORT.STATUS_NUM.SUBMITTED); @@ -6564,7 +6569,7 @@ function replaceReceipt(transactionID: string, file: File, source: string) { function setMoneyRequestParticipantsFromReport(transactionID: string, report: OnyxEntry): Participant[] { // If the report is iou or expense report, we should get the chat report to set participant for request money const chatReport = ReportUtils.isMoneyRequestReport(report) ? ReportUtils.getReport(report?.chatReportID) : report; - const currentUserAccountID = currentUserPersonalDetails.accountID; + const currentUserAccountID = currentUserPersonalDetails?.accountID; const shouldAddAsReport = !isEmptyObject(chatReport) && ReportUtils.isSelfDM(chatReport); let participants: Participant[] = []; From decf834db265600098262da07c6263d22e351680 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 31 May 2024 03:51:20 +0700 Subject: [PATCH 09/21] remove Record --- src/components/PopoverProvider/types.ts | 3 ++- src/hooks/useKeyboardShortcut.ts | 3 ++- src/libs/ModifiedExpenseMessage.ts | 2 +- src/libs/ReportActionsUtils.ts | 2 +- src/libs/actions/Task.ts | 16 ++++++++-------- .../migrations/CheckForPreviousReportActionID.ts | 3 ++- .../withReportAndReportActionOrNotFound.tsx | 4 ++-- src/types/onyx/OriginalMessage.ts | 3 ++- 8 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/components/PopoverProvider/types.ts b/src/components/PopoverProvider/types.ts index 5022aee0f84..c532905a3a4 100644 --- a/src/components/PopoverProvider/types.ts +++ b/src/components/PopoverProvider/types.ts @@ -1,6 +1,7 @@ import type {ReactNode, RefObject} from 'react'; // eslint-disable-next-line no-restricted-imports import type {Text, View} from 'react-native'; +import type {EmptyObject} from '@src/types/utils/EmptyObject'; type PopoverContextProps = { children: ReactNode; @@ -8,7 +9,7 @@ type PopoverContextProps = { type PopoverContextValue = { onOpen?: (popoverParams: AnchorRef) => void; - popover?: AnchorRef | Record | null; + popover?: AnchorRef | EmptyObject | null; close: (anchorRef?: RefObject) => void; isOpen: boolean; }; diff --git a/src/hooks/useKeyboardShortcut.ts b/src/hooks/useKeyboardShortcut.ts index 6bf8b2c52bc..7339aa0b9e1 100644 --- a/src/hooks/useKeyboardShortcut.ts +++ b/src/hooks/useKeyboardShortcut.ts @@ -3,6 +3,7 @@ import type {GestureResponderEvent} from 'react-native'; import type {ValueOf} from 'type-fest'; import KeyboardShortcut from '@libs/KeyboardShortcut'; import CONST from '@src/CONST'; +import type {EmptyObject} from '@src/types/utils/EmptyObject'; type Shortcut = ValueOf; type KeyboardShortcutConfig = { @@ -26,7 +27,7 @@ type KeyboardShortcutConfig = { * Register a keyboard shortcut handler. * Recommendation: To ensure stability, wrap the `callback` function with the useCallback hook before using it with this hook. */ -export default function useKeyboardShortcut(shortcut: Shortcut, callback: (e?: GestureResponderEvent | KeyboardEvent) => void, config: KeyboardShortcutConfig | Record = {}) { +export default function useKeyboardShortcut(shortcut: Shortcut, callback: (e?: GestureResponderEvent | KeyboardEvent) => void, config: KeyboardShortcutConfig | EmptyObject = {}) { const { captureOnInputs = true, shouldBubble = false, diff --git a/src/libs/ModifiedExpenseMessage.ts b/src/libs/ModifiedExpenseMessage.ts index 2df75030ac1..1991c4549f8 100644 --- a/src/libs/ModifiedExpenseMessage.ts +++ b/src/libs/ModifiedExpenseMessage.ts @@ -105,7 +105,7 @@ function getForDistanceRequest(newDistance: string, oldDistance: string, newAmou * ModifiedExpense::getNewDotComment in Web-Expensify should match this. * If we change this function be sure to update the backend as well. */ -function getForReportAction(reportID: string | undefined, reportAction: OnyxEntry | ReportAction | Record): string { +function getForReportAction(reportID: string | undefined, reportAction: OnyxEntry): string { if (reportAction?.actionName !== CONST.REPORT.ACTIONS.TYPE.MODIFIED_EXPENSE) { return ''; } diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 3fabc2983c4..4c0b89a82a6 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -139,7 +139,7 @@ function isReportActionSubmitted(reportAction: OnyxEntry): boolean return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.SUBMITTED; } -function isModifiedExpenseAction(reportAction: OnyxEntry | ReportAction | Record): boolean { +function isModifiedExpenseAction(reportAction: OnyxEntry): boolean { return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.MODIFIED_EXPENSE; } diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index f13ae0303d3..ef258bc153a 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -802,12 +802,12 @@ function getShareDestination(reportID: string, reports: OnyxCollection): ReportAction | Record { +function getParentReportAction(report: OnyxEntry): OnyxEntry { // If the report is not a thread report, then it won't have a parent and an empty object can be returned. if (!report?.parentReportID || !report.parentReportActionID) { - return {}; + return null; } - return allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] ?? {}; + return allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] ?? null; } /** @@ -837,7 +837,7 @@ function deleteTask(report: OnyxEntry) { const shouldDeleteTaskReport = !ReportActionsUtils.doesReportHaveVisibleActions(report.reportID ?? ''); const optimisticReportAction: Partial = { pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, - previousMessage: parentReportAction.message, + previousMessage: parentReportAction?.message, message: [ { translationKey: '', @@ -852,7 +852,7 @@ function deleteTask(report: OnyxEntry) { linkMetadata: [], }; const optimisticReportActions = { - [parentReportAction.reportActionID]: optimisticReportAction, + [parentReportAction?.reportActionID ?? '']: optimisticReportAction, }; const optimisticData: OnyxUpdate[] = [ @@ -918,7 +918,7 @@ function deleteTask(report: OnyxEntry) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReport?.reportID}`, value: { - [parentReportAction.reportActionID]: { + [parentReportAction?.reportActionID ?? '']: { pendingAction: null, }, }, @@ -945,7 +945,7 @@ function deleteTask(report: OnyxEntry) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReport?.reportID}`, value: { - [parentReportAction.reportActionID]: { + [parentReportAction?.reportActionID ?? '']: { pendingAction: null, }, }, @@ -986,7 +986,7 @@ function getTaskAssigneeAccountID(taskReport: OnyxEntry): numb } const reportAction = getParentReportAction(taskReport); - return reportAction.childManagerAccountID; + return reportAction?.childManagerAccountID; } /** diff --git a/src/libs/migrations/CheckForPreviousReportActionID.ts b/src/libs/migrations/CheckForPreviousReportActionID.ts index 7e4bbe9ffb3..7a2a294af85 100644 --- a/src/libs/migrations/CheckForPreviousReportActionID.ts +++ b/src/libs/migrations/CheckForPreviousReportActionID.ts @@ -3,6 +3,7 @@ import Onyx from 'react-native-onyx'; import Log from '@libs/Log'; import ONYXKEYS from '@src/ONYXKEYS'; import type * as OnyxTypes from '@src/types/onyx'; +import type {EmptyObject} from '@src/types/utils/EmptyObject'; function getReportActionsFromOnyx(): Promise> { return new Promise((resolve) => { @@ -60,6 +61,6 @@ export default function (): Promise { onyxData[onyxKey] = {}; }); - return Onyx.multiSet(onyxData as Record<`${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS}`, Record>); + return Onyx.multiSet(onyxData as Record<`${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS}`, EmptyObject>); }); } diff --git a/src/pages/home/report/withReportAndReportActionOrNotFound.tsx b/src/pages/home/report/withReportAndReportActionOrNotFound.tsx index e5e203fb503..3b6dca6cf8c 100644 --- a/src/pages/home/report/withReportAndReportActionOrNotFound.tsx +++ b/src/pages/home/report/withReportAndReportActionOrNotFound.tsx @@ -53,11 +53,11 @@ export default function > { function WithReportOrNotFound(props: TProps, ref: ForwardedRef) { const getReportAction = useCallback(() => { - let reportAction: OnyxTypes.ReportAction | Record | undefined = props.reportActions?.[`${props.route.params.reportActionID}`]; + let reportAction: OnyxEntry = props.reportActions?.[`${props.route.params.reportActionID}`] ?? null; // Handle threads if needed if (!reportAction?.reportActionID) { - reportAction = props?.parentReportAction ?? {}; + reportAction = props?.parentReportAction ?? null; } return reportAction; diff --git a/src/types/onyx/OriginalMessage.ts b/src/types/onyx/OriginalMessage.ts index b079a64ebb4..5d8a7ad113a 100644 --- a/src/types/onyx/OriginalMessage.ts +++ b/src/types/onyx/OriginalMessage.ts @@ -1,6 +1,7 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; import type DeepValueOf from '@src/types/utils/DeepValueOf'; +import type {EmptyObject} from '@src/types/utils/EmptyObject'; type PaymentMethodType = DeepValueOf; @@ -331,7 +332,7 @@ type OriginalMessageMoved = { type OriginalMessageMergedWithCashTransaction = { actionName: typeof CONST.REPORT.ACTIONS.TYPE.MERGED_WITH_CASH_TRANSACTION; - originalMessage: Record; // No data is sent with this action + originalMessage: EmptyObject; // No data is sent with this action }; type OriginalMessageDismissedViolation = { From bbc5694ba41f722dc309547f729f99559f6d8d03 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 31 May 2024 04:14:39 +0700 Subject: [PATCH 10/21] fix receipt type --- .../CategorizeTrackedExpenseParams.ts | 2 +- .../parameters/ShareTrackedExpenseParams.ts | 2 +- src/libs/API/parameters/TrackExpenseParams.ts | 2 +- src/libs/TransactionUtils.ts | 2 +- src/libs/actions/IOU.ts | 32 +++++++++---------- .../step/IOURequestStepConfirmation.tsx | 4 +-- src/types/onyx/Transaction.ts | 2 +- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts b/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts index 78eb0adecc5..12a5075477f 100644 --- a/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts +++ b/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts @@ -16,7 +16,7 @@ type CategorizeTrackedExpenseParams = { reportPreviewReportActionID: string; category?: string; tag?: string; - receipt?: Receipt; + receipt: Receipt | null; taxCode: string; taxAmount: number; billable?: boolean; diff --git a/src/libs/API/parameters/ShareTrackedExpenseParams.ts b/src/libs/API/parameters/ShareTrackedExpenseParams.ts index cee4bc40d9a..c1f07d496ba 100644 --- a/src/libs/API/parameters/ShareTrackedExpenseParams.ts +++ b/src/libs/API/parameters/ShareTrackedExpenseParams.ts @@ -16,7 +16,7 @@ type ShareTrackedExpenseParams = { reportPreviewReportActionID: string; category?: string; tag?: string; - receipt?: Receipt; + receipt: Receipt | null; taxCode: string; taxAmount: number; billable?: boolean; diff --git a/src/libs/API/parameters/TrackExpenseParams.ts b/src/libs/API/parameters/TrackExpenseParams.ts index d5e1de2e625..458cc8b7976 100644 --- a/src/libs/API/parameters/TrackExpenseParams.ts +++ b/src/libs/API/parameters/TrackExpenseParams.ts @@ -15,7 +15,7 @@ type TrackExpenseParams = { createdChatReportActionID: string; createdIOUReportActionID?: string; reportPreviewReportActionID?: string; - receipt?: Receipt; + receipt: Receipt | null; receiptState?: ValueOf; category?: string; tag?: string; diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index 79e73f1585d..414011303ee 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -97,7 +97,7 @@ function buildOptimisticTransaction( source = '', originalTransactionID = '', merchant = '', - receipt: Receipt = {}, + receipt: OnyxEntry = null, filename = '', existingTransactionID: string | null = null, category = '', diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 84d95d67575..26945be3e94 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -444,7 +444,7 @@ function updateDistanceRequestRate(transactionID: string, rateID: string, policy } /** Helper function to get the receipt error for expenses, or the generic error if there's no receipt */ -function getReceiptError(receipt?: Receipt, filename?: string, isScanRequest = true, errorKey?: number): Errors | ErrorFields { +function getReceiptError(receipt: OnyxEntry, filename?: string, isScanRequest = true, errorKey?: number): Errors | ErrorFields { return isEmptyObject(receipt) || !isScanRequest ? ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage', false, errorKey) : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: receipt.source?.toString() ?? '', filename: filename ?? ''}, errorKey); @@ -776,7 +776,7 @@ function buildOnyxDataForMoneyRequest( value: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest, errorKey), + errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest, errorKey), pendingAction: null, pendingFields: clearedPendingFields, }, @@ -790,7 +790,7 @@ function buildOnyxDataForMoneyRequest( [iouCreatedAction.reportActionID]: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest, errorKey), + errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest, errorKey), }, [iouAction.reportActionID]: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), @@ -800,7 +800,7 @@ function buildOnyxDataForMoneyRequest( [iouAction.reportActionID]: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest, errorKey), + errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest, errorKey), }, }), }, @@ -1115,7 +1115,7 @@ function buildOnyxDataForInvoice( [iouCreatedAction.reportActionID]: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, false, errorKey), + errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, false, errorKey), }, [iouAction.reportActionID]: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateInvoiceFailureMessage'), @@ -1428,7 +1428,7 @@ function buildOnyxDataForTrackExpense( [iouCreatedAction.reportActionID]: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest), + errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest), }, [iouAction.reportActionID]: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), @@ -1438,7 +1438,7 @@ function buildOnyxDataForTrackExpense( [iouAction.reportActionID]: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest), + errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest), }, }), }, @@ -1452,7 +1452,7 @@ function buildOnyxDataForTrackExpense( [iouAction.reportActionID]: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest), + errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest), }, }, }); @@ -1486,7 +1486,7 @@ function buildOnyxDataForTrackExpense( value: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest), + errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest), pendingAction: null, pendingFields: clearedPendingFields, }, @@ -1706,7 +1706,7 @@ function getSendInvoiceInformation( transaction: OnyxEntry, currentUserAccountID: number, invoiceChatReport?: OnyxEntry, - receipt?: Receipt, + receipt: OnyxEntry = null, policy?: OnyxEntry, policyTagList?: OnyxEntry, policyCategories?: OnyxEntry, @@ -2062,7 +2062,7 @@ function getTrackExpenseInformation( currency: string, created: string, merchant: string, - receipt: Receipt | undefined, + receipt: OnyxEntry, category: string | undefined, tag: string | undefined, taxCode: string | undefined, @@ -3230,7 +3230,7 @@ function categorizeTrackedExpense( taxCode = '', taxAmount = 0, billable?: boolean, - receipt?: Receipt, + receipt: Receipt | null = null, createdWorkspaceParams?: CreateWorkspaceParams, ) { const {optimisticData, successData, failureData} = onyxData ?? {}; @@ -3307,7 +3307,7 @@ function shareTrackedExpense( taxCode = '', taxAmount = 0, billable?: boolean, - receipt?: Receipt, + receipt: Receipt | null = null, createdWorkspaceParams?: CreateWorkspaceParams, ) { const {optimisticData, successData, failureData} = onyxData ?? {}; @@ -3509,13 +3509,13 @@ function sendInvoice( currentUserAccountID: number, transaction: OnyxEntry, invoiceChatReport?: OnyxEntry, - receiptFile?: Receipt, + receiptFile?: Receipt | null, policy?: OnyxEntry, policyTagList?: OnyxEntry, policyCategories?: OnyxEntry, ) { const {senderWorkspaceID, receiver, invoiceRoom, createdChatReportActionID, invoiceReportID, reportPreviewReportActionID, transactionID, transactionThreadReportID, onyxData} = - getSendInvoiceInformation(transaction, currentUserAccountID, invoiceChatReport, receiptFile, policy, policyTagList, policyCategories); + getSendInvoiceInformation(transaction, currentUserAccountID, invoiceChatReport, receiptFile ?? null, policy, policyTagList, policyCategories); let parameters: SendInvoiceParams = { senderWorkspaceID, @@ -3565,7 +3565,7 @@ function trackExpense( payeeAccountID: number, participant: Participant, comment: string, - receipt?: Receipt, + receipt: Receipt | null = null, category?: string, tag?: string, taxCode = '', diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx index b4eb9f1082e..73a3080dbe5 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx @@ -80,7 +80,7 @@ function IOURequestStepConfirmation({ const {translate} = useLocalize(); const {windowWidth} = useWindowDimensions(); const {isOffline} = useNetwork(); - const [receiptFile, setReceiptFile] = useState(); + const [receiptFile, setReceiptFile] = useState>(); const receiptFilename = transaction?.filename; const receiptPath = transaction?.receipt?.source; @@ -254,7 +254,7 @@ function IOURequestStepConfirmation({ ); const trackExpense = useCallback( - (selectedParticipants: Participant[], trimmedComment: string, receiptObj?: Receipt, gpsPoints?: IOU.GpsPoint) => { + (selectedParticipants: Participant[], trimmedComment: string, receiptObj?: OnyxEntry, gpsPoints?: IOU.GpsPoint) => { if (!report || !transaction) { return; } diff --git a/src/types/onyx/Transaction.ts b/src/types/onyx/Transaction.ts index 460bd279048..b504f1e2eab 100644 --- a/src/types/onyx/Transaction.ts +++ b/src/types/onyx/Transaction.ts @@ -183,7 +183,7 @@ type Transaction = OnyxCommon.OnyxValueWithOfflineFeedback< participants?: Participant[]; /** The receipt object associated with the transaction */ - receipt?: Receipt; + receipt?: Receipt | null; /** The iouReportID associated with the transaction */ reportID: string; From 1aff409fa45bd06300d8a973924b43b5fa964057 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Jun 2024 17:27:31 +0700 Subject: [PATCH 11/21] remove EmptyObject in PopoverProvider and useKeyboardShortcut --- src/components/PopoverProvider/index.native.tsx | 4 ++-- src/components/PopoverProvider/index.tsx | 2 +- src/components/PopoverProvider/types.ts | 3 +-- src/hooks/useKeyboardShortcut.ts | 5 ++--- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/components/PopoverProvider/index.native.tsx b/src/components/PopoverProvider/index.native.tsx index b13909945be..d58322fafe6 100644 --- a/src/components/PopoverProvider/index.native.tsx +++ b/src/components/PopoverProvider/index.native.tsx @@ -3,7 +3,7 @@ import type {PopoverContextProps, PopoverContextValue} from './types'; const PopoverContext = React.createContext({ onOpen: () => {}, - popover: {}, + popover: null, close: () => {}, isOpen: false, }); @@ -13,7 +13,7 @@ function PopoverContextProvider(props: PopoverContextProps) { () => ({ onOpen: () => {}, close: () => {}, - popover: {}, + popover: null, isOpen: false, }), [], diff --git a/src/components/PopoverProvider/index.tsx b/src/components/PopoverProvider/index.tsx index cc6c8447752..82f3c6c7d61 100644 --- a/src/components/PopoverProvider/index.tsx +++ b/src/components/PopoverProvider/index.tsx @@ -6,7 +6,7 @@ import type {AnchorRef, PopoverContextProps, PopoverContextValue} from './types' const PopoverContext = createContext({ onOpen: () => {}, - popover: {}, + popover: null, close: () => {}, isOpen: false, }); diff --git a/src/components/PopoverProvider/types.ts b/src/components/PopoverProvider/types.ts index c532905a3a4..b3d21e9ed5d 100644 --- a/src/components/PopoverProvider/types.ts +++ b/src/components/PopoverProvider/types.ts @@ -1,7 +1,6 @@ import type {ReactNode, RefObject} from 'react'; // eslint-disable-next-line no-restricted-imports import type {Text, View} from 'react-native'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; type PopoverContextProps = { children: ReactNode; @@ -9,7 +8,7 @@ type PopoverContextProps = { type PopoverContextValue = { onOpen?: (popoverParams: AnchorRef) => void; - popover?: AnchorRef | EmptyObject | null; + popover?: AnchorRef | null; close: (anchorRef?: RefObject) => void; isOpen: boolean; }; diff --git a/src/hooks/useKeyboardShortcut.ts b/src/hooks/useKeyboardShortcut.ts index 7339aa0b9e1..87a16fcbfa5 100644 --- a/src/hooks/useKeyboardShortcut.ts +++ b/src/hooks/useKeyboardShortcut.ts @@ -3,7 +3,6 @@ import type {GestureResponderEvent} from 'react-native'; import type {ValueOf} from 'type-fest'; import KeyboardShortcut from '@libs/KeyboardShortcut'; import CONST from '@src/CONST'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; type Shortcut = ValueOf; type KeyboardShortcutConfig = { @@ -27,7 +26,7 @@ type KeyboardShortcutConfig = { * Register a keyboard shortcut handler. * Recommendation: To ensure stability, wrap the `callback` function with the useCallback hook before using it with this hook. */ -export default function useKeyboardShortcut(shortcut: Shortcut, callback: (e?: GestureResponderEvent | KeyboardEvent) => void, config: KeyboardShortcutConfig | EmptyObject = {}) { +export default function useKeyboardShortcut(shortcut: Shortcut, callback: (e?: GestureResponderEvent | KeyboardEvent) => void, config?: KeyboardShortcutConfig) { const { captureOnInputs = true, shouldBubble = false, @@ -41,7 +40,7 @@ export default function useKeyboardShortcut(shortcut: Shortcut, callback: (e?: G // This flag is used to prevent auto submit form when press enter key on selection modal. shouldStopPropagation = false, - } = config; + } = config ?? {}; useEffect(() => { if (!isActive) { From 7fadca4c3ac81122778c4e535764ea7ceec806de Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Jun 2024 17:36:33 +0700 Subject: [PATCH 12/21] remove EmptyObject in Report actions --- src/libs/actions/Report.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 8b27bcaa290..51175e38efd 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -745,7 +745,7 @@ function openReport( reportID: string, reportActionID?: string, participantLoginList: string[] = [], - newReportObject: Partial = {}, + newReportObject: ReportUtils.OptimisticChatReport | null = null, parentReportActionID = '0', isFromDeepLink = false, participantAccountIDList: number[] = [], @@ -821,8 +821,8 @@ function openReport( if (ReportUtils.isGroupChat(newReportObject)) { parameters.chatType = CONST.REPORT.CHAT_TYPE.GROUP; parameters.groupChatAdminLogins = currentUserEmail; - parameters.optimisticAccountIDList = Object.keys(newReportObject.participants ?? {}).join(','); - parameters.reportName = newReportObject.reportName ?? ''; + parameters.optimisticAccountIDList = Object.keys(newReportObject?.participants ?? {}).join(','); + parameters.reportName = newReportObject?.reportName ?? ''; // If we have an avatar then include it with the parameters if (avatar) { @@ -990,7 +990,7 @@ function navigateToAndOpenReport( const report = isEmptyObject(chat) ? newChat : chat; // We want to pass newChat here because if anything is passed in that param (even an existing chat), we will try to create a chat on the server - openReport(report?.reportID ?? '', '', userLogins, newChat ?? {}, undefined, undefined, undefined, avatarFile); + openReport(report?.reportID ?? '', '', userLogins, newChat, undefined, undefined, undefined, avatarFile); if (shouldDismissModal) { Navigation.dismissModalWithReport(report); } else { @@ -1013,7 +1013,7 @@ function navigateToAndOpenReportWithAccountIDs(participantAccountIDs: number[]) const report = chat ?? newChat; // We want to pass newChat here because if anything is passed in that param (even an existing chat), we will try to create a chat on the server - openReport(report?.reportID ?? '', '', [], newChat ?? {}, '0', false, participantAccountIDs); + openReport(report?.reportID ?? '', '', [], newChat, '0', false, participantAccountIDs); Navigation.dismissModalWithReport(report); } @@ -2487,7 +2487,7 @@ function openReportFromDeepLink(url: string, shouldNavigate = true) { if (reportID && !isAuthenticated) { // Call the OpenReport command to check in the server if it's a public room. If so, we'll open it as an anonymous user - openReport(reportID, '', [], {}, '0', true); + openReport(reportID, '', [], null, '0', true); // Show the sign-in page if the app is offline if (networkStatus === CONST.NETWORK.NETWORK_STATUS.OFFLINE) { From 66e25d3720c5aa284ccb0b1cd20cd6fb78619d36 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Jun 2024 19:56:39 +0700 Subject: [PATCH 13/21] resolve minor comments --- src/hooks/useKeyboardShortcut.ts | 4 ++-- src/libs/OptionsListUtils.ts | 2 +- src/libs/actions/IOU.ts | 7 ++----- src/libs/actions/Policy/Policy.ts | 12 ++++++------ .../migrations/CheckForPreviousReportActionID.ts | 4 ++-- 5 files changed, 13 insertions(+), 16 deletions(-) diff --git a/src/hooks/useKeyboardShortcut.ts b/src/hooks/useKeyboardShortcut.ts index 87a16fcbfa5..1c5bbc426ef 100644 --- a/src/hooks/useKeyboardShortcut.ts +++ b/src/hooks/useKeyboardShortcut.ts @@ -26,7 +26,7 @@ type KeyboardShortcutConfig = { * Register a keyboard shortcut handler. * Recommendation: To ensure stability, wrap the `callback` function with the useCallback hook before using it with this hook. */ -export default function useKeyboardShortcut(shortcut: Shortcut, callback: (e?: GestureResponderEvent | KeyboardEvent) => void, config?: KeyboardShortcutConfig) { +export default function useKeyboardShortcut(shortcut: Shortcut, callback: (e?: GestureResponderEvent | KeyboardEvent) => void, config: KeyboardShortcutConfig = {}) { const { captureOnInputs = true, shouldBubble = false, @@ -40,7 +40,7 @@ export default function useKeyboardShortcut(shortcut: Shortcut, callback: (e?: G // This flag is used to prevent auto submit form when press enter key on selection modal. shouldStopPropagation = false, - } = config ?? {}; + } = config; useEffect(() => { if (!isActive) { diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 95822ebf083..7379c64a2fc 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -2103,7 +2103,7 @@ function getIOUConfirmationOptionsFromPayeePersonalDetail(personalDetail: OnyxEn ], descriptiveText: amountText ?? '', login: personalDetail?.login ?? '', - accountID: personalDetail?.accountID ?? 0, + accountID: personalDetail?.accountID ?? -1, keyForList: String(personalDetail?.accountID), }; } diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 23ae79c50ca..0e1c29cbe42 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -52,7 +52,7 @@ import ROUTES from '@src/ROUTES'; import type * as OnyxTypes from '@src/types/onyx'; import type {Participant, Split} from '@src/types/onyx/IOU'; import type {ErrorFields, Errors} from '@src/types/onyx/OnyxCommon'; -import type {IOUMessage, OriginalMessageReportPreview, PaymentMethodType} from '@src/types/onyx/OriginalMessage'; +import type {IOUMessage, PaymentMethodType} from '@src/types/onyx/OriginalMessage'; import type ReportAction from '@src/types/onyx/ReportAction'; import type {ReportPreviewAction} from '@src/types/onyx/ReportAction'; import type {OnyxData} from '@src/types/onyx/Request'; @@ -292,10 +292,7 @@ function getReportPreviewAction(chatReportID: string, iouReportID: string): Onyx // Find the report preview action from the chat report return ( Object.values(reportActions).find( - (reportAction) => - reportAction && - reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW && - (reportAction as ReportAction & OriginalMessageReportPreview).originalMessage.linkedReportID === iouReportID, + (reportAction) => reportAction && reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.REPORT_PREVIEW && reportAction.originalMessage.linkedReportID === iouReportID, ) ?? null ); } diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index da3cad3933b..86ccf488194 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -583,8 +583,8 @@ function setWorkspaceApprovalMode(policyID: string, approver: string, approvalMo onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - approver: policy?.approver ?? null, - approvalMode: policy?.approvalMode ?? null, + approver: policy?.approver, + approvalMode: policy?.approvalMode, pendingFields: {approvalMode: null}, errorFields: {approvalMode: ErrorUtils.getMicroSecondOnyxError('workflowsApprovalPage.genericErrorMessage')}, }, @@ -3470,10 +3470,10 @@ function enablePolicyWorkflows(policyID: string, enabled: boolean) { areWorkflowsEnabled: !enabled, ...(!enabled ? { - approvalMode: policy?.approvalMode ?? null, - autoReporting: policy?.autoReporting ?? null, - harvesting: policy?.harvesting ?? null, - reimbursementChoice: policy?.reimbursementChoice ?? null, + approvalMode: policy?.approvalMode, + autoReporting: policy?.autoReporting, + harvesting: policy?.harvesting, + reimbursementChoice: policy?.reimbursementChoice, } : {}), pendingFields: { diff --git a/src/libs/migrations/CheckForPreviousReportActionID.ts b/src/libs/migrations/CheckForPreviousReportActionID.ts index 7a2a294af85..83658ff961c 100644 --- a/src/libs/migrations/CheckForPreviousReportActionID.ts +++ b/src/libs/migrations/CheckForPreviousReportActionID.ts @@ -3,7 +3,7 @@ import Onyx from 'react-native-onyx'; import Log from '@libs/Log'; import ONYXKEYS from '@src/ONYXKEYS'; import type * as OnyxTypes from '@src/types/onyx'; -import type {EmptyObject} from '@src/types/utils/EmptyObject'; +import type {ReportActionsCollectionDataSet} from '@src/types/onyx/ReportAction'; function getReportActionsFromOnyx(): Promise> { return new Promise((resolve) => { @@ -61,6 +61,6 @@ export default function (): Promise { onyxData[onyxKey] = {}; }); - return Onyx.multiSet(onyxData as Record<`${typeof ONYXKEYS.COLLECTION.REPORT_ACTIONS}`, EmptyObject>); + return Onyx.multiSet(onyxData as ReportActionsCollectionDataSet); }); } From 8230dbe8fb8d3a596f8237616c7a768bbc3acb9f Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 6 Jun 2024 20:26:38 +0700 Subject: [PATCH 14/21] fix lint --- src/libs/PolicyUtils.ts | 8 ++++---- src/libs/TransactionUtils.ts | 2 +- src/pages/iou/request/step/IOURequestStepDistanceRate.tsx | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 6af994ffaaf..0af41a28e34 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -7,7 +7,7 @@ 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 {PolicyFeatureName, Rate, Tenant} from '@src/types/onyx/Policy'; +import type {CustomUnit, PolicyFeatureName, Rate, Tenant} from '@src/types/onyx/Policy'; import type PolicyEmployee from '@src/types/onyx/PolicyEmployee'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import Navigation from './Navigation/Navigation'; @@ -92,16 +92,16 @@ function getNumericValue(value: number | string, toLocaleDigit: (arg: string) => /** * Retrieves the distance custom unit object for the given policy */ -function getCustomUnit(policy: OnyxEntry) { +function getCustomUnit(policy: OnyxEntry): CustomUnit | undefined { return Object.values(policy?.customUnits ?? {}).find((unit) => unit.name === CONST.CUSTOM_UNITS.NAME_DISTANCE); } /** * Retrieves custom unit rate object from the given customUnitRateID */ -function getCustomUnitRate(policy: OnyxEntry | EmptyObject, customUnitRateID: string): Rate | EmptyObject { +function getCustomUnitRate(policy: OnyxEntry, customUnitRateID: string): Rate | undefined { const distanceUnit = getCustomUnit(policy); - return distanceUnit?.rates[customUnitRateID] ?? {}; + return distanceUnit?.rates[customUnitRateID]; } function getRateDisplayValue(value: number, toLocaleDigit: (arg: string) => string): string { diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index 5150c4c7cfb..694d3cb000c 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -699,7 +699,7 @@ function getRateID(transaction: OnyxEntry): string | undefined { * If it is distance request, then returns the tax code corresponding to the custom unit rate * Else returns policy default tax rate if transaction is in policy default currency, otherwise foreign default tax rate */ -function getDefaultTaxCode(policy: OnyxEntry, transaction: OnyxEntry, currency?: string | undefined) { +function getDefaultTaxCode(policy: OnyxEntry, transaction: OnyxEntry, currency?: string | undefined): string | undefined { if (isDistanceRequest(transaction)) { const customUnitRateID = getRateID(transaction) ?? ''; const customUnitRate = getCustomUnitRate(policy, customUnitRateID); diff --git a/src/pages/iou/request/step/IOURequestStepDistanceRate.tsx b/src/pages/iou/request/step/IOURequestStepDistanceRate.tsx index f8879a3f425..e584f661194 100644 --- a/src/pages/iou/request/step/IOURequestStepDistanceRate.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistanceRate.tsx @@ -78,7 +78,7 @@ function IOURequestStepDistanceRate({ function selectDistanceRate(customUnitRateID: string) { if (shouldShowTax) { const policyCustomUnitRate = getCustomUnitRate(policy, customUnitRateID); - const taxRateExternalID = policyCustomUnitRate.attributes?.taxRateExternalID ?? ''; + const taxRateExternalID = policyCustomUnitRate?.attributes?.taxRateExternalID ?? ''; const taxableAmount = DistanceRequestUtils.getTaxableAmount(policy, customUnitRateID, TransactionUtils.getDistance(transaction)); const taxPercentage = TransactionUtils.getTaxValue(policy, transaction, taxRateExternalID) ?? ''; const taxAmount = CurrencyUtils.convertToBackendAmount(TransactionUtils.calculateTaxAmount(taxPercentage, taxableAmount)); From 7fc2963d820332b4ed697a507e61553d2a3c385a Mon Sep 17 00:00:00 2001 From: tienifr Date: Mon, 17 Jun 2024 16:22:33 +0700 Subject: [PATCH 15/21] fix typecheck --- .../MoneyRequestPreviewContent.tsx | 2 +- .../ReportActionItem/ReportPreview.tsx | 2 +- src/components/SettlementButton.tsx | 6 +-- .../CategorizeTrackedExpenseParams.ts | 2 +- .../parameters/ShareTrackedExpenseParams.ts | 2 +- src/libs/API/parameters/TrackExpenseParams.ts | 2 +- src/libs/PolicyUtils.ts | 2 +- src/libs/ReportActionsUtils.ts | 4 +- src/libs/ReportUtils.ts | 24 +++++------ src/libs/TransactionUtils.ts | 2 +- src/libs/WorkspacesSettingsUtils.ts | 4 +- src/libs/actions/IOU.ts | 42 +++++++++---------- src/libs/actions/Policy/Member.ts | 2 +- src/libs/actions/Policy/Policy.ts | 2 +- src/libs/actions/Report.ts | 14 +++---- src/libs/actions/Search.ts | 2 +- src/libs/actions/Task.ts | 8 ++-- src/libs/actions/User.ts | 2 +- src/libs/getReportPolicyID.ts | 2 +- src/pages/ProfilePage.tsx | 4 +- src/pages/home/report/ReportFooter.tsx | 4 +- .../withReportAndReportActionOrNotFound.tsx | 4 +- src/types/onyx/Transaction.ts | 2 +- 23 files changed, 70 insertions(+), 70 deletions(-) diff --git a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx index fc5206502a5..b5c7895c4bd 100644 --- a/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx +++ b/src/components/ReportActionItem/MoneyRequestPreview/MoneyRequestPreviewContent.tsx @@ -225,7 +225,7 @@ function MoneyRequestPreviewContent({ }; const getDisplayDeleteAmountText = (): string => { - const iouOriginalMessage: OnyxEntry = action?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU ? action.originalMessage : null; + const iouOriginalMessage: OnyxEntry = action?.actionName === CONST.REPORT.ACTIONS.TYPE.IOU ? action.originalMessage : undefined; return CurrencyUtils.convertToDisplayString(iouOriginalMessage?.amount, iouOriginalMessage?.currency); }; diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index daa7e24709c..4be2a139781 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -197,7 +197,7 @@ function ReportPreview({ if (ReportUtils.hasHeldExpenses(iouReport?.reportID)) { setIsHoldMenuVisible(true); } else { - IOU.approveMoneyRequest(iouReport ?? {}, true); + IOU.approveMoneyRequest(iouReport, true); } }; diff --git a/src/components/SettlementButton.tsx b/src/components/SettlementButton.tsx index abb75f65bc6..cc3d4555be0 100644 --- a/src/components/SettlementButton.tsx +++ b/src/components/SettlementButton.tsx @@ -120,9 +120,9 @@ function SettlementButton({ chatReportID = '', currency = CONST.CURRENCY.USD, enablePaymentsRoute, - // The "iouReport" and "nvpLastPaymentMethod" objects needs to be stable to prevent the "useMemo" - // hook from being recreated unnecessarily, hence the use of CONST.EMPTY_ARRAY and CONST.EMPTY_OBJECT - iouReport = null, + iouReport, + // The "nvpLastPaymentMethod" object needs to be stable to prevent the "useMemo" + // hook from being recreated unnecessarily, hence the use of CONST.EMPTY_OBJECT nvpLastPaymentMethod = CONST.EMPTY_OBJECT, isDisabled = false, isLoading = false, diff --git a/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts b/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts index 12a5075477f..78eb0adecc5 100644 --- a/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts +++ b/src/libs/API/parameters/CategorizeTrackedExpenseParams.ts @@ -16,7 +16,7 @@ type CategorizeTrackedExpenseParams = { reportPreviewReportActionID: string; category?: string; tag?: string; - receipt: Receipt | null; + receipt?: Receipt; taxCode: string; taxAmount: number; billable?: boolean; diff --git a/src/libs/API/parameters/ShareTrackedExpenseParams.ts b/src/libs/API/parameters/ShareTrackedExpenseParams.ts index c1f07d496ba..cee4bc40d9a 100644 --- a/src/libs/API/parameters/ShareTrackedExpenseParams.ts +++ b/src/libs/API/parameters/ShareTrackedExpenseParams.ts @@ -16,7 +16,7 @@ type ShareTrackedExpenseParams = { reportPreviewReportActionID: string; category?: string; tag?: string; - receipt: Receipt | null; + receipt?: Receipt; taxCode: string; taxAmount: number; billable?: boolean; diff --git a/src/libs/API/parameters/TrackExpenseParams.ts b/src/libs/API/parameters/TrackExpenseParams.ts index 458cc8b7976..d5e1de2e625 100644 --- a/src/libs/API/parameters/TrackExpenseParams.ts +++ b/src/libs/API/parameters/TrackExpenseParams.ts @@ -15,7 +15,7 @@ type TrackExpenseParams = { createdChatReportActionID: string; createdIOUReportActionID?: string; reportPreviewReportActionID?: string; - receipt: Receipt | null; + receipt?: Receipt; receiptState?: ValueOf; category?: string; tag?: string; diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index 4c3f05e6786..702c65c2f97 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -407,7 +407,7 @@ function getAdminEmployees(policy: OnyxEntry): PolicyEmployee[] { */ function getPolicy(policyID: string | undefined): OnyxEntry { if (!allPolicies || !policyID) { - return null; + return undefined; } return allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; } diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index cd13febe74f..9768089a17b 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -219,9 +219,9 @@ function isThreadParentMessage(reportAction: OnyxEntry, reportID: */ function getParentReportAction(report: OnyxInputOrEntry): OnyxEntry { if (!report?.parentReportID || !report.parentReportActionID) { - return null; + return undefined; } - return allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] ?? null; + return allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; } /** diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 918118a9a2e..e19a0fc894a 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -611,18 +611,18 @@ function isDraftReport(reportID: string | undefined): boolean { */ function getParentReport(report: OnyxEntry): OnyxEntry { if (!report?.parentReportID) { - return null; + return undefined; } - return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`] ?? null; + return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`]; } /** * Returns the root parentReport if the given report is nested. * Uses recursion to iterate any depth of nested reports. */ -function getRootParentReport(report: OnyxEntry | undefined): OnyxEntry { +function getRootParentReport(report: OnyxEntry): OnyxEntry { if (!report) { - return null; + return undefined; } // Returns the current report as the root report, because it does not have a parentReportID @@ -641,7 +641,7 @@ function getRootParentReport(report: OnyxEntry | undefined): OnyxEntry { if (!allPolicies || !policyID) { - return null; + return undefined; } return allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; } @@ -657,7 +657,7 @@ function getPolicyType(report: OnyxInputOrEntry, policies: OnyxCollectio /** * Get the policy name from a given report */ -function getPolicyName(report: OnyxInputOrEntry | undefined, returnEmptyIfNotFound = false, policy?: OnyxInputOrEntry): string { +function getPolicyName(report: OnyxInputOrEntry, returnEmptyIfNotFound = false, policy?: OnyxInputOrEntry): string { const noPolicyFound = returnEmptyIfNotFound ? '' : Localize.translateLocal('workspace.common.unavailable'); if (isEmptyObject(report)) { return noPolicyFound; @@ -1172,7 +1172,7 @@ function findLastAccessedReport( let sortedReports = sortReportsByLastRead(reportsValues, reportMetadata); - let adminReport: OnyxEntry | undefined; + let adminReport: OnyxEntry; if (openOnAdminRoom) { adminReport = sortedReports.find((report) => { const chatType = getChatType(report); @@ -2284,7 +2284,7 @@ function isUnreadWithMention(reportOrOption: OnyxEntry | OptionData): bo * @param option (report or optionItem) * @param parentReportAction (the report action the current report is a thread of) */ -function requiresAttentionFromCurrentUser(optionOrReport: OnyxEntry | OptionData, parentReportAction: OnyxEntry = null) { +function requiresAttentionFromCurrentUser(optionOrReport: OnyxEntry | OptionData, parentReportAction?: OnyxEntry) { if (!optionOrReport) { return false; } @@ -2828,7 +2828,7 @@ function getLinkedTransaction(reportAction: OnyxEntry = null, + linkedExpenseReportAction?: OnyxEntry, ): OptimisticIOUReportAction { const IOUReportID = iouReportID || generateReportID(); @@ -6404,7 +6404,7 @@ function shouldUseFullTitleToDisplay(report: OnyxEntry): boolean { ); } -function getRoom(type: ValueOf, policyID: string): OnyxEntry | undefined { +function getRoom(type: ValueOf, policyID: string): OnyxEntry { const room = Object.values(allReports ?? {}).find((report) => report?.policyID === policyID && report?.chatType === type && !isThread(report)); return room; } @@ -6412,7 +6412,7 @@ function getRoom(type: ValueOf, policyID: string) /** * We only want policy members who are members of the report to be able to modify the report description, but not in thread chat. */ -function canEditReportDescription(report: OnyxEntry, policy: OnyxEntry | undefined): boolean { +function canEditReportDescription(report: OnyxEntry, policy: OnyxEntry): boolean { return ( !isMoneyRequestReport(report) && !isArchivedRoom(report) && diff --git a/src/libs/TransactionUtils.ts b/src/libs/TransactionUtils.ts index 44cb999b1b3..91d5d891de1 100644 --- a/src/libs/TransactionUtils.ts +++ b/src/libs/TransactionUtils.ts @@ -107,7 +107,7 @@ function buildOptimisticTransaction( source = '', originalTransactionID = '', merchant = '', - receipt: OnyxEntry = null, + receipt?: OnyxEntry, filename = '', existingTransactionID: string | null = null, category = '', diff --git a/src/libs/WorkspacesSettingsUtils.ts b/src/libs/WorkspacesSettingsUtils.ts index 74c5125855d..62c034145d4 100644 --- a/src/libs/WorkspacesSettingsUtils.ts +++ b/src/libs/WorkspacesSettingsUtils.ts @@ -66,10 +66,10 @@ const getBrickRoadForPolicy = (report: Report, altReportActions?: OnyxCollection } // To determine if the report requires attention from the current user, we need to load the parent report action - let itemParentReportAction: OnyxEntry = null; + let itemParentReportAction: OnyxEntry; if (report.parentReportID) { const itemParentReportActions = allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`] ?? {}; - itemParentReportAction = report.parentReportActionID ? itemParentReportActions[report.parentReportActionID] : null; + itemParentReportAction = report.parentReportActionID ? itemParentReportActions[report.parentReportActionID] : undefined; } const reportOption = {...report, isUnread: ReportUtils.isUnread(report), isUnreadWithMention: ReportUtils.isUnreadWithMention(report)}; const shouldShowGreenDotIndicator = ReportUtils.requiresAttentionFromCurrentUser(reportOption, itemParentReportAction); diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index a778b17930c..f375f01d9b6 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -240,7 +240,7 @@ let currentUserPersonalDetails: OnyxEntry; Onyx.connect({ key: ONYXKEYS.PERSONAL_DETAILS_LIST, callback: (value) => { - currentUserPersonalDetails = value?.[userAccountID] ?? null; + currentUserPersonalDetails = value?.[userAccountID] ?? undefined; }, }); @@ -774,7 +774,7 @@ function buildOnyxDataForMoneyRequest( value: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest, errorKey), + errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest, errorKey), pendingAction: null, pendingFields: clearedPendingFields, }, @@ -788,7 +788,7 @@ function buildOnyxDataForMoneyRequest( [iouCreatedAction.reportActionID]: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest, errorKey), + errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest, errorKey), }, [iouAction.reportActionID]: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), @@ -798,7 +798,7 @@ function buildOnyxDataForMoneyRequest( [iouAction.reportActionID]: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest, errorKey), + errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest, errorKey), }, }), }, @@ -1121,7 +1121,7 @@ function buildOnyxDataForInvoice( [iouCreatedAction.reportActionID]: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, false, errorKey), + errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, false, errorKey), }, [iouAction.reportActionID]: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateInvoiceFailureMessage'), @@ -1442,7 +1442,7 @@ function buildOnyxDataForTrackExpense( [iouCreatedAction.reportActionID]: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest), + errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest), }, [iouAction.reportActionID]: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), @@ -1452,7 +1452,7 @@ function buildOnyxDataForTrackExpense( [iouAction.reportActionID]: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest), + errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest), }, }), }, @@ -1466,7 +1466,7 @@ function buildOnyxDataForTrackExpense( [iouAction.reportActionID]: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest), + errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest), }, }, }); @@ -1500,7 +1500,7 @@ function buildOnyxDataForTrackExpense( value: { // Disabling this line since transaction.filename can be an empty string // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing - errors: getReceiptError(transaction.receipt ?? null, transaction.filename || transaction.receipt?.filename, isScanRequest), + errors: getReceiptError(transaction.receipt, transaction.filename || transaction.receipt?.filename, isScanRequest), pendingAction: null, pendingFields: clearedPendingFields, }, @@ -1728,7 +1728,7 @@ function getSendInvoiceInformation( transaction: OnyxEntry, currentUserAccountID: number, invoiceChatReport?: OnyxEntry, - receipt: OnyxEntry = null, + receipt?: Receipt, policy?: OnyxEntry, policyTagList?: OnyxEntry, policyCategories?: OnyxEntry, @@ -2555,7 +2555,7 @@ function getUpdateMoneyRequestParams( // Step 4: Compute the IOU total and update the report preview message (and report header) so LHN amount owed is correct. const diff = calculateDiffAmount(iouReport, updatedTransaction, transaction); - let updatedMoneyRequestReport: OnyxEntry; + let updatedMoneyRequestReport: OnyxTypes.OnyxInputOrEntry; if (!iouReport) { updatedMoneyRequestReport = null; } else if ((ReportUtils.isExpenseReport(iouReport) || ReportUtils.isInvoiceReport(iouReport)) && typeof iouReport.total === 'number') { @@ -3257,7 +3257,7 @@ function categorizeTrackedExpense( taxCode = '', taxAmount = 0, billable?: boolean, - receipt: Receipt | null = null, + receipt?: Receipt, createdWorkspaceParams?: CreateWorkspaceParams, ) { const {optimisticData, successData, failureData} = onyxData ?? {}; @@ -3334,7 +3334,7 @@ function shareTrackedExpense( taxCode = '', taxAmount = 0, billable?: boolean, - receipt: Receipt | null = null, + receipt?: Receipt, createdWorkspaceParams?: CreateWorkspaceParams, ) { const {optimisticData, successData, failureData} = onyxData ?? {}; @@ -3437,7 +3437,7 @@ function requestMoney( createdReportActionIDForThread, onyxData, } = getMoneyRequestInformation( - isMovingTransactionFromTrackExpense ? null : currentChatReport, + isMovingTransactionFromTrackExpense ? undefined : currentChatReport, participant, comment, amount, @@ -3535,13 +3535,13 @@ function sendInvoice( currentUserAccountID: number, transaction: OnyxEntry, invoiceChatReport?: OnyxEntry, - receiptFile?: Receipt | null, + receiptFile?: Receipt, policy?: OnyxEntry, policyTagList?: OnyxEntry, policyCategories?: OnyxEntry, ) { const {senderWorkspaceID, receiver, invoiceRoom, createdChatReportActionID, invoiceReportID, reportPreviewReportActionID, transactionID, transactionThreadReportID, onyxData} = - getSendInvoiceInformation(transaction, currentUserAccountID, invoiceChatReport, receiptFile ?? null, policy, policyTagList, policyCategories); + getSendInvoiceInformation(transaction, currentUserAccountID, invoiceChatReport, receiptFile, policy, policyTagList, policyCategories); const parameters: SendInvoiceParams = { senderWorkspaceID, @@ -3580,7 +3580,7 @@ function trackExpense( payeeAccountID: number, participant: Participant, comment: string, - receipt: Receipt | null = null, + receipt?: Receipt, category?: string, tag?: string, taxCode = '', @@ -4765,7 +4765,7 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA // In case this is still the optimistic accountID saved in the splits array, return early as we cannot know // if there is an existing chat between the split creator and this participant // Instead, we will rely on Auth generating the report IDs and the user won't see any optimistic chats or reports created - const participantPersonalDetails: OnyxEntry = allPersonalDetails[participant?.accountID ?? -1]; + const participantPersonalDetails: OnyxTypes.PersonalDetails | null = allPersonalDetails[participant?.accountID ?? -1]; if (!participantPersonalDetails || participantPersonalDetails.isOptimisticPersonalDetail) { splits.push({ email: participant.email, @@ -4778,7 +4778,7 @@ function completeSplitBill(chatReportID: string, reportAction: OnyxTypes.ReportA let isNewOneOnOneChatReport = false; if (isPolicyExpenseChat) { // The workspace chat reportID is saved in the splits array when starting a split expense with a workspace - oneOnOneChatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${participant.chatReportID}`] ?? null; + oneOnOneChatReport = allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${participant.chatReportID}`]; } else { const existingChatReport = ReportUtils.getChatByParticipants(participant.accountID ? [participant.accountID, sessionAccountID] : []); isNewOneOnOneChatReport = !existingChatReport; @@ -5292,9 +5292,9 @@ function deleteMoneyRequest(transactionID: string, reportAction: OnyxTypes.Repor iouReportLastMessageText.length === 0 && !ReportActionsUtils.isDeletedParentAction(lastVisibleAction) && (!transactionThreadID || shouldDeleteTransactionThread); // STEP 4: Update the iouReport and reportPreview with new totals and messages if it wasn't deleted - let updatedIOUReport: OnyxEntry; + let updatedIOUReport: OnyxInputValue; const currency = TransactionUtils.getCurrency(transaction); - const updatedReportPreviewAction: OnyxEntry = reportPreviewAction; + const updatedReportPreviewAction: OnyxInputValue = reportPreviewAction; if (updatedReportPreviewAction) { updatedReportPreviewAction.pendingAction = shouldDeleteIOUReport ? CONST.RED_BRICK_ROAD_PENDING_ACTION.DELETE : CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE; } diff --git a/src/libs/actions/Policy/Member.ts b/src/libs/actions/Policy/Member.ts index 672e95be93c..98b8ab62e96 100644 --- a/src/libs/actions/Policy/Member.ts +++ b/src/libs/actions/Policy/Member.ts @@ -105,7 +105,7 @@ Onyx.connect({ */ function getPolicy(policyID: string | undefined): OnyxEntry { if (!allPolicies || !policyID) { - return null; + return undefined; } return allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; } diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 1de35607905..3a0a5bc7a9a 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -174,7 +174,7 @@ function isCurrencySupportedForDirectReimbursement(currency: string) { */ function getPolicy(policyID: string | undefined): OnyxEntry { if (!allPolicies || !policyID) { - return null; + return undefined; } return allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`]; } diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index ab04951816d..c0d9e51f779 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -738,7 +738,7 @@ function openReport( reportID: string, reportActionID?: string, participantLoginList: string[] = [], - newReportObject: ReportUtils.OptimisticChatReport | null = null, + newReportObject?: ReportUtils.OptimisticChatReport, parentReportActionID = '-1', isFromDeepLink = false, participantAccountIDList: number[] = [], @@ -963,8 +963,8 @@ function navigateToAndOpenReport( optimisticReportID?: string, isGroupChat = false, ) { - let newChat: ReportUtils.OptimisticChatReport | null = null; - let chat: OnyxEntry = null; + let newChat: ReportUtils.OptimisticChatReport | undefined; + let chat: OnyxEntry; const participantAccountIDs = PersonalDetailsUtils.getAccountIDsByLogins(userLogins); // If we are not creating a new Group Chat then we are creating a 1:1 DM and will look for an existing chat @@ -998,7 +998,7 @@ function navigateToAndOpenReport( * @param participantAccountIDs of user logins to start a chat report with. */ function navigateToAndOpenReportWithAccountIDs(participantAccountIDs: number[]) { - let newChat: ReportUtils.OptimisticChatReport | null = null; + let newChat: ReportUtils.OptimisticChatReport | undefined; const chat = ReportUtils.getChatByParticipants([...participantAccountIDs, currentUserAccountID]); if (!chat) { newChat = ReportUtils.buildOptimisticChatReport([...participantAccountIDs, currentUserAccountID]); @@ -1595,7 +1595,7 @@ function updateNotificationPreference( navigate: boolean, parentReportID?: string, parentReportActionID?: string, - report: OnyxEntry = null, + report?: OnyxEntry, ) { if (previousValue === newValue) { if (navigate && !isEmptyObject(report) && report.reportID) { @@ -1641,7 +1641,7 @@ function updateNotificationPreference( } } -function updateRoomVisibility(reportID: string, previousValue: RoomVisibility | undefined, newValue: RoomVisibility, navigate: boolean, report: OnyxEntry = null) { +function updateRoomVisibility(reportID: string, previousValue: RoomVisibility | undefined, newValue: RoomVisibility, navigate: boolean, report?: OnyxEntry) { if (previousValue === newValue) { if (navigate && !isEmptyObject(report) && report.reportID) { ReportUtils.goBackToDetailsPage(report); @@ -2490,7 +2490,7 @@ function openReportFromDeepLink(url: string, shouldNavigate = true) { if (reportID && !isAuthenticated) { // Call the OpenReport command to check in the server if it's a public room. If so, we'll open it as an anonymous user - openReport(reportID, '', [], null, '0', true); + openReport(reportID, '', [], undefined, '0', true); // Show the sign-in page if the app is offline if (networkStatus === CONST.NETWORK.NETWORK_STATUS.OFFLINE) { diff --git a/src/libs/actions/Search.ts b/src/libs/actions/Search.ts index ea63d78dd68..ec45298c391 100644 --- a/src/libs/actions/Search.ts +++ b/src/libs/actions/Search.ts @@ -48,7 +48,7 @@ function search({hash, query, policyIDs, offset, sortBy, sortOrder}: SearchParam * In that case, when users select the search result row, we need to create the transaction thread on the fly and update the search result with the new transactionThreadReport */ function createTransactionThread(hash: number, transactionID: string, reportID: string, moneyRequestReportActionID: string) { - Report.openReport(reportID, '', [currentUserEmail], null, moneyRequestReportActionID); + Report.openReport(reportID, '', [currentUserEmail], undefined, moneyRequestReportActionID); const onyxUpdate: Record>> = { data: { diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 8f335cb8214..1b324e8193b 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -799,9 +799,9 @@ function getShareDestination(reportID: string, reports: OnyxCollection): OnyxEntry { // If the report is not a thread report, then it won't have a parent and an empty object can be returned. if (!report?.parentReportID || !report.parentReportActionID) { - return null; + return undefined; } - return allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID] ?? null; + return allReportActions?.[`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${report.parentReportID}`]?.[report.parentReportActionID]; } /** @@ -809,9 +809,9 @@ function getParentReportAction(report: OnyxEntry): OnyxEntry): OnyxEntry { if (!report?.parentReportID) { - return null; + return undefined; } - return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`] ?? null; + return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${report.parentReportID}`]; } /** diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 5d5c27e62d9..a808d483c0e 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -68,7 +68,7 @@ Onyx.connect({ return; } - myPersonalDetails = value[currentUserAccountID] ?? {}; + myPersonalDetails = value[currentUserAccountID] ?? undefined; }, }); diff --git a/src/libs/getReportPolicyID.ts b/src/libs/getReportPolicyID.ts index 8751ce640b6..3d0510283a3 100644 --- a/src/libs/getReportPolicyID.ts +++ b/src/libs/getReportPolicyID.ts @@ -15,7 +15,7 @@ Onyx.connect({ */ function getReport(reportID: string | undefined): OnyxEntry { if (!allReports) { - return null; + return undefined; } return allReports?.[`${ONYXKEYS.COLLECTION.REPORT}${reportID}`]; diff --git a/src/pages/ProfilePage.tsx b/src/pages/ProfilePage.tsx index 37df2b05ebb..f088de064cc 100755 --- a/src/pages/ProfilePage.tsx +++ b/src/pages/ProfilePage.tsx @@ -102,11 +102,11 @@ function ProfilePage({route}: ProfilePageProps) { const details = useMemo((): OnyxEntry => { // Check if we have the personal details already in Onyx if (personalDetails?.[accountID]) { - return personalDetails?.[accountID]; + return personalDetails?.[accountID] ?? undefined; } // Check if we have the login param if (!loginParams) { - return isValidAccountID ? null : {accountID: 0}; + return isValidAccountID ? undefined : {accountID: 0}; } // Look up the personal details by login const foundDetails = Object.values(personalDetails ?? {}).find((personalDetail) => personalDetail?.login === loginParams?.toLowerCase()); diff --git a/src/pages/home/report/ReportFooter.tsx b/src/pages/home/report/ReportFooter.tsx index 3fb11f70c75..d7e5e713752 100644 --- a/src/pages/home/report/ReportFooter.tsx +++ b/src/pages/home/report/ReportFooter.tsx @@ -140,10 +140,10 @@ function ReportFooter({ const mention = match[1] ? match[1].trim() : undefined; const mentionWithDomain = ReportUtils.addDomainToShortMention(mention ?? '') ?? mention; - let assignee: OnyxEntry = null; + let assignee: OnyxEntry; let assigneeChatReport; if (mentionWithDomain) { - assignee = Object.values(allPersonalDetails).find((value) => value?.login === mentionWithDomain) ?? null; + assignee = Object.values(allPersonalDetails).find((value) => value?.login === mentionWithDomain) ?? undefined; if (!Object.keys(assignee ?? {}).length) { const assigneeAccountID = UserUtils.generateAccountID(mentionWithDomain); const optimisticDataForNewAssignee = Task.setNewOptimisticAssignee(mentionWithDomain, assigneeAccountID); diff --git a/src/pages/home/report/withReportAndReportActionOrNotFound.tsx b/src/pages/home/report/withReportAndReportActionOrNotFound.tsx index dc5038168c4..9ffb8c227e7 100644 --- a/src/pages/home/report/withReportAndReportActionOrNotFound.tsx +++ b/src/pages/home/report/withReportAndReportActionOrNotFound.tsx @@ -52,11 +52,11 @@ export default function > { function WithReportOrNotFound(props: TProps, ref: ForwardedRef) { const getReportAction = useCallback(() => { - let reportAction: OnyxEntry = props.reportActions?.[`${props.route.params.reportActionID}`] ?? null; + let reportAction: OnyxEntry = props.reportActions?.[`${props.route.params.reportActionID}`]; // Handle threads if needed if (!reportAction?.reportActionID) { - reportAction = props?.parentReportAction ?? null; + reportAction = props?.parentReportAction ?? undefined; } return reportAction; diff --git a/src/types/onyx/Transaction.ts b/src/types/onyx/Transaction.ts index 438c8581218..21ffaee3f5c 100644 --- a/src/types/onyx/Transaction.ts +++ b/src/types/onyx/Transaction.ts @@ -361,7 +361,7 @@ type Transaction = OnyxCommon.OnyxValueWithOfflineFeedback< participants?: Participant[]; /** The receipt object associated with the transaction */ - receipt?: Receipt | null; + receipt?: Receipt; /** The iouReportID associated with the transaction */ reportID: string; From 8196d3f4982d7c6d9bf5f20024af58dae154941e Mon Sep 17 00:00:00 2001 From: tienifr Date: Mon, 17 Jun 2024 17:09:44 +0700 Subject: [PATCH 16/21] fallback to -1 for IDs --- src/libs/Navigation/dismissModalWithReport.ts | 2 +- src/libs/OptionsListUtils.ts | 2 +- src/libs/ReportActionsUtils.ts | 2 +- src/libs/actions/IOU.ts | 34 +++++++++---------- src/libs/actions/Policy/Member.ts | 2 +- src/libs/actions/Policy/Policy.ts | 6 ++-- src/libs/actions/Report.ts | 6 ++-- src/libs/actions/Task.ts | 6 ++-- 8 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/libs/Navigation/dismissModalWithReport.ts b/src/libs/Navigation/dismissModalWithReport.ts index a41164191cf..d4906eb719a 100644 --- a/src/libs/Navigation/dismissModalWithReport.ts +++ b/src/libs/Navigation/dismissModalWithReport.ts @@ -45,7 +45,7 @@ function dismissModalWithReport(targetReport: OnyxEntry, navigationRef: case SCREENS.CONCIERGE: // If we are not in the target report, we need to navigate to it after dismissing the modal if (targetReport?.reportID !== getTopmostReportId(state)) { - const reportState = getStateFromPath(ROUTES.REPORT_WITH_ID.getRoute(targetReport?.reportID ?? '')); + const reportState = getStateFromPath(ROUTES.REPORT_WITH_ID.getRoute(targetReport?.reportID ?? '-1')); const policyID = getPolicyIDFromState(state as State); const policyMemberAccountIDs = getPolicyEmployeeAccountIDs(policyID); const shouldOpenAllWorkspace = isEmptyObject(targetReport) ? true : !doesReportBelongToWorkspace(targetReport, policyMemberAccountIDs, policyID); diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 60b97ad6598..721230c447e 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -2122,7 +2122,7 @@ function getIOUConfirmationOptionsFromPayeePersonalDetail(personalDetail: OnyxEn descriptiveText: amountText ?? '', login: personalDetail?.login ?? '', accountID: personalDetail?.accountID ?? -1, - keyForList: String(personalDetail?.accountID), + keyForList: String(personalDetail?.accountID ?? -1), }; } diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 9768089a17b..5981e6f6f25 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -1178,7 +1178,7 @@ function isReportActionUnread(reportAction: OnyxEntry, lastReadTim */ function isCurrentActionUnread(report: OnyxEntry, reportAction: ReportAction): boolean { const lastReadTime = report?.lastReadTime ?? ''; - const sortedReportActions = getSortedReportActions(Object.values(getAllReportActions(report?.reportID ?? ''))); + const sortedReportActions = getSortedReportActions(Object.values(getAllReportActions(report?.reportID ?? '-1'))); const currentActionIndex = sortedReportActions.findIndex((action) => action.reportActionID === reportAction.reportActionID); if (currentActionIndex === -1) { return false; diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index f375f01d9b6..131aece75b5 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -915,7 +915,7 @@ function buildOnyxDataForInvoice( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, value: { - [transactionThreadCreatedReportAction?.reportActionID ?? '']: transactionThreadCreatedReportAction, + [transactionThreadCreatedReportAction?.reportActionID ?? '-1']: transactionThreadCreatedReportAction, }, }, // Remove the temporary transaction used during the creation flow @@ -1045,7 +1045,7 @@ function buildOnyxDataForInvoice( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, value: { - [transactionThreadCreatedReportAction?.reportActionID ?? '']: { + [transactionThreadCreatedReportAction?.reportActionID ?? '-1']: { pendingAction: null, errors: null, }, @@ -1132,7 +1132,7 @@ function buildOnyxDataForInvoice( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport.reportID}`, value: { - [transactionThreadCreatedReportAction?.reportActionID ?? '']: { + [transactionThreadCreatedReportAction?.reportActionID ?? '-1']: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateInvoiceFailureMessage', false, errorKey), }, }, @@ -1509,7 +1509,7 @@ function buildOnyxDataForTrackExpense( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${transactionThreadReport?.reportID}`, value: { - [transactionThreadCreatedReportAction?.reportActionID ?? '']: { + [transactionThreadCreatedReportAction?.reportActionID ?? '-1']: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, }, @@ -2274,7 +2274,7 @@ function getTrackExpenseInformation( createdIOUReportActionID: shouldCreateNewMoneyRequestReport ? optimisticCreatedActionForIOUReport.reportActionID : '-1', reportPreviewAction: reportPreviewAction ?? undefined, transactionThreadReportID: optimisticTransactionThread.reportID, - createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID ?? '0', + createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1', actionableWhisperReportActionIDParam: actionableTrackExpenseWhisper?.reportActionID ?? '', onyxData: { optimisticData: optimisticData.concat(trackExpenseOnyxData[0]), @@ -3711,10 +3711,10 @@ function trackExpense( created, merchant, iouReportID: iouReport?.reportID, - chatReportID: chatReport?.reportID ?? '', - transactionID: transaction?.transactionID ?? '', - reportActionID: iouAction?.reportActionID ?? '', - createdChatReportActionID: createdChatReportActionID ?? '', + chatReportID: chatReport?.reportID ?? '-1', + transactionID: transaction?.transactionID ?? '-1', + reportActionID: iouAction?.reportActionID ?? '-1', + createdChatReportActionID: createdChatReportActionID ?? '-1', createdIOUReportActionID, reportPreviewReportActionID: reportPreviewAction?.reportActionID, receipt, @@ -3726,8 +3726,8 @@ function trackExpense( billable, // This needs to be a string of JSON because of limitations with the fetch() API and nested objects receiptGpsPoints: gpsPoints ? JSON.stringify(gpsPoints) : undefined, - transactionThreadReportID: transactionThreadReportID ?? '', - createdReportActionIDForThread: createdReportActionIDForThread ?? '', + transactionThreadReportID: transactionThreadReportID ?? '-1', + createdReportActionIDForThread: createdReportActionIDForThread ?? '-1', waypoints: validWaypoints ? JSON.stringify(validWaypoints) : undefined, }; if (actionableWhisperReportActionIDParam) { @@ -5695,7 +5695,7 @@ function getSendMoneyParams( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTransactionThread.reportID}`, value: { - [optimisticCreatedActionForTransactionThread?.reportActionID ?? '']: optimisticCreatedActionForTransactionThread, + [optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1']: optimisticCreatedActionForTransactionThread, }, }; @@ -5780,7 +5780,7 @@ function getSendMoneyParams( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTransactionThread.reportID}`, value: { - [optimisticCreatedActionForTransactionThread?.reportActionID ?? '']: { + [optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1']: { pendingAction: null, }, }, @@ -5808,7 +5808,7 @@ function getSendMoneyParams( onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${optimisticTransactionThread.reportID}`, value: { - [optimisticCreatedActionForTransactionThread?.reportActionID ?? '']: { + [optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1']: { errors: ErrorUtils.getMicroSecondOnyxError('iou.error.genericCreateFailureMessage'), }, }, @@ -5886,7 +5886,7 @@ function getSendMoneyParams( reportPreviewReportActionID: reportPreviewAction.reportActionID, createdIOUReportActionID: optimisticCreatedActionForIOUReport.reportActionID, transactionThreadReportID: optimisticTransactionThread.reportID, - createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID ?? '0', + createdReportActionIDForThread: optimisticCreatedActionForTransactionThread?.reportActionID ?? '-1', }, optimisticData, successData, @@ -6185,7 +6185,7 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: if (hasHeldExpenses && !full && !!expenseReport?.unheldTotal) { total = expenseReport?.unheldTotal; } - const optimisticApprovedReportAction = ReportUtils.buildOptimisticApprovedReportAction(total, expenseReport?.currency ?? '', expenseReport?.reportID ?? ''); + const optimisticApprovedReportAction = ReportUtils.buildOptimisticApprovedReportAction(total, expenseReport?.currency ?? '', expenseReport?.reportID ?? '-1'); const optimisticNextStep = NextStepUtils.buildNextStep(expenseReport, CONST.REPORT.STATUS_NUM.APPROVED); const chatReport = ReportUtils.getReport(expenseReport?.chatReportID); @@ -6303,7 +6303,7 @@ function approveMoneyRequest(expenseReport: OnyxEntry, full?: } const parameters: ApproveMoneyRequestParams = { - reportID: expenseReport?.reportID ?? '', + reportID: expenseReport?.reportID ?? '-1', approvedReportActionID: optimisticApprovedReportAction.reportActionID, full, }; diff --git a/src/libs/actions/Policy/Member.ts b/src/libs/actions/Policy/Member.ts index 98b8ab62e96..0623765cdd7 100644 --- a/src/libs/actions/Policy/Member.ts +++ b/src/libs/actions/Policy/Member.ts @@ -231,7 +231,7 @@ function removeMembers(accountIDs: number[], policyID: string) { ReportUtils.buildOptimisticClosedReportAction(sessionEmail, policy?.name ?? '', CONST.REPORT.ARCHIVE_REASON.REMOVED_FROM_POLICY), ); - const announceRoomMembers = removeOptimisticAnnounceRoomMembers(policy?.id ?? '', policy?.name ?? '', accountIDs); + const announceRoomMembers = removeOptimisticAnnounceRoomMembers(policy?.id ?? '-1', policy?.name ?? '', accountIDs); const optimisticMembersState: OnyxCollectionInputValue = {}; const successMembersState: OnyxCollectionInputValue = {}; diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index 3a0a5bc7a9a..51d745734b0 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -2328,12 +2328,12 @@ function createWorkspaceFromIOUPayment(iouReport: OnyxEntry): string | u optimisticData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oldChatReportID}`, - value: {[reportPreview?.reportActionID ?? '']: null}, + value: {[reportPreview?.reportActionID ?? '-1']: null}, }); failureData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${oldChatReportID}`, - value: {[reportPreview?.reportActionID ?? '']: reportPreview}, + value: {[reportPreview?.reportActionID ?? '-1']: reportPreview}, }); // To optimistically remove the GBR from the DM we need to update the hasOutstandingChildRequest param to false @@ -2375,7 +2375,7 @@ function createWorkspaceFromIOUPayment(iouReport: OnyxEntry): string | u failureData.push({ onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${memberData.workspaceChatReportID}`, - value: {[reportPreview?.reportActionID ?? '']: null}, + value: {[reportPreview?.reportActionID ?? '-1']: null}, }); // Create the MOVED report action and add it to the DM chat which indicates to the user where the report has been moved diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index c0d9e51f779..4a207eefe52 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -983,12 +983,12 @@ function navigateToAndOpenReport( const report = isEmptyObject(chat) ? newChat : chat; // We want to pass newChat here because if anything is passed in that param (even an existing chat), we will try to create a chat on the server - openReport(report?.reportID ?? '', '', userLogins, newChat, undefined, undefined, undefined, avatarFile); + openReport(report?.reportID ?? '-1', '', userLogins, newChat, undefined, undefined, undefined, avatarFile); if (shouldDismissModal) { Navigation.dismissModalWithReport(report); } else { Navigation.navigateWithSwitchPolicyID({route: ROUTES.HOME}); - Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(report?.reportID ?? '')); + Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(report?.reportID ?? '-1')); } } @@ -1006,7 +1006,7 @@ function navigateToAndOpenReportWithAccountIDs(participantAccountIDs: number[]) const report = chat ?? newChat; // We want to pass newChat here because if anything is passed in that param (even an existing chat), we will try to create a chat on the server - openReport(report?.reportID ?? '', '', [], newChat, '0', false, participantAccountIDs); + openReport(report?.reportID ?? '-1', '', [], newChat, '0', false, participantAccountIDs); Navigation.dismissModalWithReport(report); } diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index 1b324e8193b..bcbca77c585 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -846,7 +846,7 @@ function deleteTask(report: OnyxEntry) { linkMetadata: [], }; const optimisticReportActions = { - [parentReportAction?.reportActionID ?? '']: optimisticReportAction, + [parentReportAction?.reportActionID ?? '-1']: optimisticReportAction, }; const optimisticData: OnyxUpdate[] = [ @@ -912,7 +912,7 @@ function deleteTask(report: OnyxEntry) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReport?.reportID}`, value: { - [parentReportAction?.reportActionID ?? '']: { + [parentReportAction?.reportActionID ?? '-1']: { pendingAction: null, }, }, @@ -939,7 +939,7 @@ function deleteTask(report: OnyxEntry) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${parentReport?.reportID}`, value: { - [parentReportAction?.reportActionID ?? '']: { + [parentReportAction?.reportActionID ?? '-1']: { pendingAction: null, }, }, From 0056068934531fc0c5199512cc4dd486cd487b49 Mon Sep 17 00:00:00 2001 From: tienifr Date: Mon, 17 Jun 2024 18:39:49 +0700 Subject: [PATCH 17/21] fix test --- tests/unit/SidebarOrderTest.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/unit/SidebarOrderTest.ts b/tests/unit/SidebarOrderTest.ts index 98120a53b6d..0abfa2efd75 100644 --- a/tests/unit/SidebarOrderTest.ts +++ b/tests/unit/SidebarOrderTest.ts @@ -860,8 +860,6 @@ describe('Sidebar', () => { describe('in #focus mode', () => { it('alphabetizes chats', () => { - LHNTestUtils.getDefaultRenderedSidebarLinks(); - const report1 = {...LHNTestUtils.getFakeReport([1, 2], 3, true), lastMessageText: 'test'}; const report2 = {...LHNTestUtils.getFakeReport([3, 4], 2, true), lastMessageText: 'test'}; const report3 = {...LHNTestUtils.getFakeReport([5, 6], 1, true), lastMessageText: 'test'}; @@ -875,7 +873,7 @@ describe('Sidebar', () => { return ( waitForBatchedUpdates() - .then(() => LHNTestUtils.getDefaultRenderedSidebarLinks()) + .then(() => LHNTestUtils.getDefaultRenderedSidebarLinks('0')) // Given the sidebar is rendered in #focus mode (hides read chats) // with all reports having unread comments .then(() => From 51fea9ede9a02fed55212678e532f5c6f9a9a25b Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 18 Jun 2024 15:51:31 +0700 Subject: [PATCH 18/21] resolve feedbacks --- src/components/AddPaymentMethodMenu.tsx | 4 ++-- src/pages/home/report/ReportActionsList.tsx | 2 +- src/types/onyx/OriginalMessage.ts | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/AddPaymentMethodMenu.tsx b/src/components/AddPaymentMethodMenu.tsx index 188e47d86ab..325bab091be 100644 --- a/src/components/AddPaymentMethodMenu.tsx +++ b/src/components/AddPaymentMethodMenu.tsx @@ -64,9 +64,9 @@ function AddPaymentMethodMenu({ // Users can choose to pay with business bank account in case of Expense reports or in case of P2P IOU report // which then starts a bottom up flow and creates a Collect workspace where the payer is an admin and payee is an employee. - const isIOUReport = ReportUtils.isIOUReport(iouReport ?? null); + const isIOUReport = ReportUtils.isIOUReport(iouReport); const canUseBusinessBankAccount = - ReportUtils.isExpenseReport(iouReport ?? null) || (isIOUReport && !ReportActionsUtils.hasRequestFromCurrentAccount(iouReport?.reportID ?? '-1', session?.accountID ?? -1)); + ReportUtils.isExpenseReport(iouReport) || (isIOUReport && !ReportActionsUtils.hasRequestFromCurrentAccount(iouReport?.reportID ?? '-1', session?.accountID ?? -1)); const canUsePersonalBankAccount = shouldShowPersonalBankAccountOption || isIOUReport; diff --git a/src/pages/home/report/ReportActionsList.tsx b/src/pages/home/report/ReportActionsList.tsx index 6e77424ed47..4f133ea539d 100644 --- a/src/pages/home/report/ReportActionsList.tsx +++ b/src/pages/home/report/ReportActionsList.tsx @@ -603,7 +603,7 @@ function ReportActionsList({ [isLoadingNewerReportActions, styles.chatContentScrollView, styles.chatContentScrollViewWithHeaderLoader, canShowHeader], ); - const lastReportAction: OnyxTypes.ReportAction | null = useMemo(() => sortedReportActions.at(-1) ?? null, [sortedReportActions]); + const lastReportAction: OnyxTypes.ReportAction | undefined = useMemo(() => sortedReportActions.at(-1) ?? undefined, [sortedReportActions]); const retryLoadOlderChatsError = useCallback(() => { loadOlderChats(true); diff --git a/src/types/onyx/OriginalMessage.ts b/src/types/onyx/OriginalMessage.ts index 1ec84b87cb2..1f87ff3bdc4 100644 --- a/src/types/onyx/OriginalMessage.ts +++ b/src/types/onyx/OriginalMessage.ts @@ -593,7 +593,7 @@ type OriginalMessageMergedWithCashTransaction = { actionName: typeof CONST.REPORT.ACTIONS.TYPE.MERGED_WITH_CASH_TRANSACTION; /** Content of the original message */ - originalMessage: undefined | null; // No data is sent with this action + originalMessage: undefined; // No data is sent with this action }; /** Model of `dismissed violation` report action */ From d3f0dca3804ae803a7db874191f4ce50c3e9508f Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 19 Jun 2024 16:27:59 +0700 Subject: [PATCH 19/21] do not fallback to -1 in some places where truthy check is used --- src/libs/actions/Report.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 267f2b851c9..17f1350fc87 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -981,7 +981,7 @@ function navigateToAndOpenReport( const report = isEmptyObject(chat) ? newChat : chat; // We want to pass newChat here because if anything is passed in that param (even an existing chat), we will try to create a chat on the server - openReport(report?.reportID ?? '-1', '', userLogins, newChat, undefined, undefined, undefined, avatarFile); + openReport(report?.reportID ?? '', '', userLogins, newChat, undefined, undefined, undefined, avatarFile); if (shouldDismissModal) { Navigation.dismissModalWithReport(report); } else { @@ -1004,7 +1004,7 @@ function navigateToAndOpenReportWithAccountIDs(participantAccountIDs: number[]) const report = chat ?? newChat; // We want to pass newChat here because if anything is passed in that param (even an existing chat), we will try to create a chat on the server - openReport(report?.reportID ?? '-1', '', [], newChat, '0', false, participantAccountIDs); + openReport(report?.reportID ?? '', '', [], newChat, '0', false, participantAccountIDs); Navigation.dismissModalWithReport(report); } From ab246da40ef0f0e3140154161d75831f00dc928f Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 21 Jun 2024 16:46:25 +0700 Subject: [PATCH 20/21] fix lint --- src/libs/actions/IOU.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/actions/IOU.ts b/src/libs/actions/IOU.ts index 1178b8d3b92..da009fc5d8f 100644 --- a/src/libs/actions/IOU.ts +++ b/src/libs/actions/IOU.ts @@ -3661,8 +3661,8 @@ function trackExpense( moneyRequestReportID, linkedTrackedExpenseReportAction, isMovingTransactionFromTrackExpense && linkedTrackedExpenseReportAction && ReportActionsUtils.isMoneyRequestAction(linkedTrackedExpenseReportAction) - ? ReportActionsUtils.getOriginalMessage(linkedTrackedExpenseReportAction)?.IOUTransactionID - : undefined, + ? ReportActionsUtils.getOriginalMessage(linkedTrackedExpenseReportAction)?.IOUTransactionID + : undefined, ) ?? {}; const activeReportID = isMoneyRequestReport ? report.reportID : chatReport?.reportID; From 30a875ecbb5e5ff002b01ae3857cc8dd0f1efe5e Mon Sep 17 00:00:00 2001 From: tienifr Date: Tue, 25 Jun 2024 17:18:06 +0700 Subject: [PATCH 21/21] fix lint --- src/libs/PolicyUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/PolicyUtils.ts b/src/libs/PolicyUtils.ts index d37c1bdee75..da4323a077b 100644 --- a/src/libs/PolicyUtils.ts +++ b/src/libs/PolicyUtils.ts @@ -155,7 +155,7 @@ const isPolicyAdmin = (policy: OnyxInputOrEntry, currentUserLogin?: stri /** * Checks if the current user is an user of the policy. */ -const isPolicyUser = (policy: OnyxInputOrEntry | EmptyObject, currentUserLogin?: string): boolean => +const isPolicyUser = (policy: OnyxInputOrEntry, currentUserLogin?: string): boolean => (policy?.role ?? (currentUserLogin && policy?.employeeList?.[currentUserLogin]?.role)) === CONST.POLICY.ROLE.USER; /**