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 ac96576945002..93786cd9c437e 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 af7f482198bba..8943262d3a5fa 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 345bd338f365d..261e01af42278 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 53ed00e04143b..568f2a15903f6 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 6405e3026b1a0..5ae35b7adb3ce 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 eb7d9324d2abd..22c5a76312410 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 198eba1f969cb..8f469b01272cb 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 8a3cf039a3225..d0ae956246b2c 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 f56c4dd1a863f..f0a5224220d02 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 8bbaf1c9305c9..91fd388eabf1a 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 9cb48534214ed..5c47458bdc141 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 daa2015b5cd0e..8d7c5d21d74cf 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 f321c10c686eb..722c469486428 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 d58ac4d5218cd..5ec494f517793 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 8a59958c208b1..50138241aae65 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 08ce01263a83a..29d0cdf95ae4f 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 12124f24fbe7d..8751ce640b6f9 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 adf358ab416d6..d0ede3f6eb3b3 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 bcb2a08330860..dc0d7fbc5ac7c 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 c8c290b562b67..3c51f17948bd9 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 19575be659b7b..451ffd3df0960 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 29d0cdf95ae4f..388ffa716364c 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 1b2b03e7e2c46..3fabc2983c4ed 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 451ffd3df0960..f7ccd1dbbd650 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 fc2a8ad7970e0..0f00edc7d2c65 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 4c5ed88e6898f..ae252da6fff62 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 f7ccd1dbbd650..f00c38319d68d 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 6c57c2a6f99d2..74c5125855d45 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 388ffa716364c..d657ba27f170a 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 0f00edc7d2c65..006b8c0e55983 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 55d898d3d4f32..fe749b9d0ea1d 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 f71db06c2d447..07a4636cf50e4 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 3fa3e0c5c3171..7a4254a96b4f5 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 c0405c2c9da00..c63e4ba1367eb 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 88c33c9d98ad7..44046f2cf85d9 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 fe749b9d0ea1d..f13ae0303d373 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 f7e90f775b657..3212aff71122a 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 119b7da42e210..c4b6d86794a34 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 006b8c0e55983..f94482e018df6 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 7ce9bcf47c9c9..3618918be4891 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 c700fea4fb855..ea305830d7706 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 ac56fe916bc9d..39824b6622b65 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 d7333feb86505..7ae3eb472959e 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 40deec85bc47c..6a623246ad758 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 3b98f79698ba6..db3999c6f75d4 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 c5a74bdc6acee..a33a36d575c5f 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 b9cea5c9447c0..e93ba560dc64d 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 3035175582061..7174199e93015 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 02affae0fe67b..f13a978d4e74d 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 3212aff71122a..a68f20557daee 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 045cc34f39efe..19d44c2406feb 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 07633b19802b1..d2498c16c16a6 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 d657ba27f170a..84d95d6757557 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 5022aee0f8436..c532905a3a4f2 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 6bf8b2c52bc3e..7339aa0b9e1f2 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 2df75030ac192..1991c4549f840 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 3fabc2983c4ed..4c0b89a82a6a8 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 f13ae0303d373..ef258bc153a97 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 7e4bbe9ffb3ea..7a2a294af8598 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 e5e203fb50306..3b6dca6cf8cfe 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 b079a64ebb4b2..5d8a7ad113a70 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 78eb0adecc5e3..12a5075477f54 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 cee4bc40d9ac6..c1f07d496baa1 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 d5e1de2e625b4..458cc8b7976f3 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 79e73f1585d27..414011303eecb 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 84d95d6757557..26945be3e9405 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 b4eb9f1082edb..73a3080dbe535 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 460bd279048ba..b504f1e2eabd2 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 b13909945bef1..d58322fafe638 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 cc6c844775259..82f3c6c7d61ae 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 c532905a3a4f2..b3d21e9ed5d92 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 7339aa0b9e1f2..87a16fcbfa5da 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 8b27bcaa290f2..51175e38efd26 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 87a16fcbfa5da..1c5bbc426ef2a 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 95822ebf083ce..7379c64a2fcb0 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 23ae79c50cac0..0e1c29cbe423c 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 da3cad3933b9a..86ccf48819406 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 7a2a294af8598..83658ff961c0d 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 6af994ffaafbf..0af41a28e3498 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 5150c4c7cfb61..694d3cb000cb7 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 f8879a3f42504..e584f6611941c 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 fc5206502a51c..b5c7895c4bdfc 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 daa7e24709c2b..4be2a139781c1 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 abb75f65bc686..cc3d4555be0a2 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 12a5075477f54..78eb0adecc5e3 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 c1f07d496baa1..cee4bc40d9ac6 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 458cc8b7976f3..d5e1de2e625b4 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 4c3f05e678624..702c65c2f9766 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 cd13febe74faf..9768089a17b20 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 918118a9a2e07..e19a0fc894a69 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 44cb999b1b381..91d5d891de138 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 74c5125855d45..62c034145d4b3 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 a778b17930cee..f375f01d9b6b6 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 672e95be93c6e..98b8ab62e96e5 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 1de356079050f..3a0a5bc7a9a76 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 ab04951816dc1..c0d9e51f77956 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 ea63d78dd6859..ec45298c3910a 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 8f335cb821409..1b324e8193ba9 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 5d5c27e62d9b5..a808d483c0e5e 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 8751ce640b6f9..3d0510283a336 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 37df2b05ebb9e..f088de064cc7d 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 3fb11f70c752a..d7e5e713752e2 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 dc5038168c440..9ffb8c227e7e7 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 438c858121886..21ffaee3f5ce2 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 a41164191cfe7..d4906eb719ac5 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 60b97ad65984d..721230c447e5e 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 9768089a17b20..5981e6f6f25b8 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 f375f01d9b6b6..131aece75b59d 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 98b8ab62e96e5..0623765cdd78b 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 3a0a5bc7a9a76..51d745734b019 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 c0d9e51f77956..4a207eefe5260 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 1b324e8193ba9..bcbca77c58598 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 98120a53b6d41..0abfa2efd7526 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 188e47d86ab6d..325bab091becb 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 6e77424ed4793..4f133ea539d03 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 1ec84b87cb2bf..1f87ff3bdc464 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 267f2b851c94b..17f1350fc87d7 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 1178b8d3b92f6..da009fc5d8f32 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 d37c1bdee7523..da4323a077b8c 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; /**