diff --git a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx index 6e6e81030e08..8ee06151f2f3 100644 --- a/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx +++ b/src/pages/home/report/ReportActionCompose/AttachmentPickerWithMenuItems.tsx @@ -124,7 +124,7 @@ function AttachmentPickerWithMenuItems({ const {shouldUseNarrowLayout} = useResponsiveLayout(); const {isDelegateAccessRestricted, delegatorEmail} = useDelegateUserDetails(); const [isNoDelegateAccessMenuVisible, setIsNoDelegateAccessMenuVisible] = useState(false); - const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID ?? '-1'}`, {initialValue: {} as OnyxTypes.Policy}); + const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID}`); const {canUseCombinedTrackSubmit} = usePermissions(); /** diff --git a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx index fd5eadd10b79..a49b474b185e 100644 --- a/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx +++ b/src/pages/home/sidebar/SidebarScreen/FloatingActionButtonAndPopover.tsx @@ -1,10 +1,10 @@ import {useIsFocused as useIsFocusedOriginal, useNavigationState} from '@react-navigation/native'; import type {ImageContentFit} from 'expo-image'; -import type {ForwardedRef} from 'react'; +import type {ForwardedRef, RefAttributes} from 'react'; import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState} from 'react'; import {View} from 'react-native'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; -import {useOnyx} from 'react-native-onyx'; +import {useOnyx, withOnyx} from 'react-native-onyx'; import type {SvgProps} from 'react-native-svg'; import FloatingActionButton from '@components/FloatingActionButton'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -39,7 +39,6 @@ import SCREENS from '@src/SCREENS'; import type * as OnyxTypes from '@src/types/onyx'; import type {QuickActionName} from '@src/types/onyx/QuickAction'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import mapOnyxCollectionItems from '@src/utils/mapOnyxCollectionItems'; // On small screen we hide the search page from central pane to show the search bottom tab page with bottom tab bar. // We need to take this in consideration when checking if the screen is focused. @@ -52,7 +51,33 @@ const useIsFocused = () => { type PolicySelector = Pick; -type FloatingActionButtonAndPopoverProps = { +type FloatingActionButtonAndPopoverOnyxProps = { + /** The list of policies the user has access to. */ + allPolicies: OnyxCollection; + + /** Whether app is in loading state */ + isLoading: OnyxEntry; + + /** Information on the last taken action to display as Quick Action */ + quickAction: OnyxEntry; + + /** The report data of the quick action */ + quickActionReport: OnyxEntry; + + /** The policy data of the quick action */ + quickActionPolicy: OnyxEntry; + + /** The current session */ + session: OnyxEntry; + + /** Personal details of all the users */ + personalDetails: OnyxEntry; + + /** Has user seen track expense training interstitial */ + hasSeenTrackTraining: OnyxEntry; +}; + +type FloatingActionButtonAndPopoverProps = FloatingActionButtonAndPopoverOnyxProps & { /* Callback function when the menu is shown */ onShowCreateMenu?: () => void; @@ -136,16 +161,21 @@ const getQuickActionTitle = (action: QuickActionName): TranslationPaths => { * Responsible for rendering the {@link PopoverMenu}, and the accompanying * FAB that can open or close the menu. */ -function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: FloatingActionButtonAndPopoverProps, ref: ForwardedRef) { - const [allPolicies] = useOnyx(ONYXKEYS.COLLECTION.POLICY, {selector: (c) => mapOnyxCollectionItems(c, policySelector)}); - const [isLoading = false] = useOnyx(ONYXKEYS.IS_LOADING_APP); - const [quickAction] = useOnyx(ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE); - const [quickActionReport] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${quickAction?.chatReportID ?? '-1'}`); - const [quickActionPolicy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${quickActionReport?.policyID ?? '-1'}`); - const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); - const [session] = useOnyx(ONYXKEYS.SESSION); - const [hasSeenTrackTraining] = useOnyx(ONYXKEYS.NVP_HAS_SEEN_TRACK_TRAINING); - +function FloatingActionButtonAndPopover( + { + onHideCreateMenu, + onShowCreateMenu, + isLoading = false, + allPolicies, + quickAction, + quickActionReport, + quickActionPolicy, + session, + personalDetails, + hasSeenTrackTraining, + }: FloatingActionButtonAndPopoverProps, + ref: ForwardedRef, +) { const styles = useThemeStyles(); const {translate} = useLocalize(); const [reportNameValuePairs] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_NAME_VALUE_PAIRS}${quickActionReport?.reportID ?? -1}`); @@ -480,6 +510,32 @@ function FloatingActionButtonAndPopover({onHideCreateMenu, onShowCreateMenu}: Fl FloatingActionButtonAndPopover.displayName = 'FloatingActionButtonAndPopover'; -export default forwardRef(FloatingActionButtonAndPopover); +export default withOnyx, FloatingActionButtonAndPopoverOnyxProps>({ + allPolicies: { + key: ONYXKEYS.COLLECTION.POLICY, + selector: policySelector, + }, + isLoading: { + key: ONYXKEYS.IS_LOADING_APP, + }, + quickAction: { + key: ONYXKEYS.NVP_QUICK_ACTION_GLOBAL_CREATE, + }, + quickActionReport: { + key: ({quickAction}) => `${ONYXKEYS.COLLECTION.REPORT}${quickAction?.chatReportID}`, + }, + quickActionPolicy: { + key: ({quickActionReport}) => `${ONYXKEYS.COLLECTION.POLICY}${quickActionReport?.policyID}`, + }, + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + }, + session: { + key: ONYXKEYS.SESSION, + }, + hasSeenTrackTraining: { + key: ONYXKEYS.NVP_HAS_SEEN_TRACK_TRAINING, + }, +})(forwardRef(FloatingActionButtonAndPopover)); export type {PolicySelector}; diff --git a/src/pages/iou/request/step/IOURequestStepAmount.tsx b/src/pages/iou/request/step/IOURequestStepAmount.tsx index 8b0b7e551a2a..4e2cc03b8cc4 100644 --- a/src/pages/iou/request/step/IOURequestStepAmount.tsx +++ b/src/pages/iou/request/step/IOURequestStepAmount.tsx @@ -1,7 +1,7 @@ import {useFocusEffect} from '@react-navigation/native'; import React, {useCallback, useEffect, useMemo, useRef} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; -import {useOnyx} from 'react-native-onyx'; +import {useOnyx, withOnyx} from 'react-native-onyx'; import type {BaseTextInputRef} from '@components/TextInput/BaseTextInput/types'; import withCurrentUserPersonalDetails from '@components/withCurrentUserPersonalDetails'; import type {WithCurrentUserPersonalDetailsProps} from '@components/withCurrentUserPersonalDetails'; @@ -32,7 +32,25 @@ type AmountParams = { paymentMethod?: PaymentMethodType; }; -type IOURequestStepAmountProps = WithCurrentUserPersonalDetailsProps & +type IOURequestStepAmountOnyxProps = { + /** The draft transaction that holds data to be persisted on the current transaction */ + splitDraftTransaction: OnyxEntry; + + /** Whether the confirmation step should be skipped */ + skipConfirmation: OnyxEntry; + + /** The draft transaction object being modified in Onyx */ + draftTransaction: OnyxEntry; + + /** Personal details of all users */ + personalDetails: OnyxEntry; + + /** The policy which the user has access to and which the report is tied to */ + policy: OnyxEntry; +}; + +type IOURequestStepAmountProps = IOURequestStepAmountOnyxProps & + WithCurrentUserPersonalDetailsProps & WithWritableReportOrNotFoundProps & { /** The transaction object being modified in Onyx */ transaction: OnyxEntry; @@ -47,15 +65,14 @@ function IOURequestStepAmount({ params: {iouType, reportID, transactionID, backTo, pageIndex, action, currency: selectedCurrency = ''}, }, transaction, + policy, + personalDetails, currentUserPersonalDetails, + splitDraftTransaction, + skipConfirmation, + draftTransaction, shouldKeepUserInput = false, }: IOURequestStepAmountProps) { - const [splitDraftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID ?? '-1'}`); - const [draftTransaction] = useOnyx(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID ?? '0'}`); - const [skipConfirmation] = useOnyx(`${ONYXKEYS.COLLECTION.SKIP_CONFIRMATION}${transactionID ?? '-1'}`); - const [personalDetails] = useOnyx(ONYXKEYS.PERSONAL_DETAILS_LIST); - const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${report?.policyID ?? '-1'}`); - const {translate} = useLocalize(); const textInput = useRef(null); const focusTimeoutRef = useRef(null); @@ -314,7 +331,34 @@ function IOURequestStepAmount({ IOURequestStepAmount.displayName = 'IOURequestStepAmount'; -const IOURequestStepAmountWithCurrentUserPersonalDetails = withCurrentUserPersonalDetails(IOURequestStepAmount); +const IOURequestStepAmountWithOnyx = withOnyx({ + splitDraftTransaction: { + key: ({route}) => { + const transactionID = route.params.transactionID ?? -1; + return `${ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT}${transactionID}`; + }, + }, + draftTransaction: { + key: ({route}) => { + const transactionID = route.params.transactionID ?? 0; + return `${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transactionID}`; + }, + }, + skipConfirmation: { + key: ({route}) => { + const transactionID = route.params.transactionID ?? -1; + return `${ONYXKEYS.COLLECTION.SKIP_CONFIRMATION}${transactionID}`; + }, + }, + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS_LIST, + }, + policy: { + key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY}${report ? report.policyID : '-1'}`, + }, +})(IOURequestStepAmount); + +const IOURequestStepAmountWithCurrentUserPersonalDetails = withCurrentUserPersonalDetails(IOURequestStepAmountWithOnyx); // eslint-disable-next-line rulesdir/no-negated-variables const IOURequestStepAmountWithWritableReportOrNotFound = withWritableReportOrNotFound(IOURequestStepAmountWithCurrentUserPersonalDetails, true); // eslint-disable-next-line rulesdir/no-negated-variables diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index 55fad403374a..899f024de4be 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -551,7 +551,9 @@ function IOURequestStepDistance({ IOURequestStepDistance.displayName = 'IOURequestStepDistance'; -const IOURequestStepDistanceWithCurrentUserPersonalDetails = withCurrentUserPersonalDetails(IOURequestStepDistance); +const IOURequestStepDistanceWithOnyx = IOURequestStepDistance; + +const IOURequestStepDistanceWithCurrentUserPersonalDetails = withCurrentUserPersonalDetails(IOURequestStepDistanceWithOnyx); // eslint-disable-next-line rulesdir/no-negated-variables const IOURequestStepDistanceWithWritableReportOrNotFound = withWritableReportOrNotFound(IOURequestStepDistanceWithCurrentUserPersonalDetails, true); // eslint-disable-next-line rulesdir/no-negated-variables diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.tsx b/src/pages/iou/request/step/IOURequestStepParticipants.tsx index 5128762232a3..e8f02f0c1975 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.tsx +++ b/src/pages/iou/request/step/IOURequestStepParticipants.tsx @@ -1,6 +1,7 @@ import {useIsFocused} from '@react-navigation/core'; import React, {useCallback, useEffect, useMemo, useRef} from 'react'; -import {useOnyx} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; import FormHelpMessage from '@components/FormHelpMessage'; import useLocalize from '@hooks/useLocalize'; import usePermissions from '@hooks/usePermissions'; @@ -25,7 +26,13 @@ import withFullTransactionOrNotFound from './withFullTransactionOrNotFound'; import type {WithWritableReportOrNotFoundProps} from './withWritableReportOrNotFound'; import withWritableReportOrNotFound from './withWritableReportOrNotFound'; -type IOURequestStepParticipantsProps = WithWritableReportOrNotFoundProps & +type IOURequestStepParticipantsOnyxProps = { + /** Whether the confirmation step should be skipped */ + skipConfirmation: OnyxEntry; +}; + +type IOURequestStepParticipantsProps = IOURequestStepParticipantsOnyxProps & + WithWritableReportOrNotFoundProps & WithFullTransactionOrNotFoundProps; function IOURequestStepParticipants({ @@ -33,9 +40,8 @@ function IOURequestStepParticipants({ params: {iouType, reportID, transactionID, action}, }, transaction, + skipConfirmation, }: IOURequestStepParticipantsProps) { - const [skipConfirmation] = useOnyx(`${ONYXKEYS.COLLECTION.SKIP_CONFIRMATION}${transactionID ?? '-1'}`); - const participants = transaction?.participants; const {translate} = useLocalize(); const styles = useThemeStyles(); @@ -201,4 +207,13 @@ function IOURequestStepParticipants({ IOURequestStepParticipants.displayName = 'IOURequestStepParticipants'; -export default withWritableReportOrNotFound(withFullTransactionOrNotFound(IOURequestStepParticipants)); +const IOURequestStepParticipantsWithOnyx = withOnyx({ + skipConfirmation: { + key: ({route}) => { + const transactionID = route.params.transactionID ?? -1; + return `${ONYXKEYS.COLLECTION.SKIP_CONFIRMATION}${transactionID}`; + }, + }, +})(IOURequestStepParticipants); + +export default withWritableReportOrNotFound(withFullTransactionOrNotFound(IOURequestStepParticipantsWithOnyx)); diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx index 9d20aea6273b..5b868e21ca02 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.native.tsx @@ -683,7 +683,9 @@ function IOURequestStepScan({ IOURequestStepScan.displayName = 'IOURequestStepScan'; -const IOURequestStepScanWithCurrentUserPersonalDetails = withCurrentUserPersonalDetails(IOURequestStepScan); +const IOURequestStepScanWithOnyx = IOURequestStepScan; + +const IOURequestStepScanWithCurrentUserPersonalDetails = withCurrentUserPersonalDetails(IOURequestStepScanWithOnyx); // eslint-disable-next-line rulesdir/no-negated-variables const IOURequestStepScanWithWritableReportOrNotFound = withWritableReportOrNotFound(IOURequestStepScanWithCurrentUserPersonalDetails, true); // eslint-disable-next-line rulesdir/no-negated-variables diff --git a/src/pages/iou/request/step/IOURequestStepScan/index.tsx b/src/pages/iou/request/step/IOURequestStepScan/index.tsx index f30d54ec8055..508190f33edf 100644 --- a/src/pages/iou/request/step/IOURequestStepScan/index.tsx +++ b/src/pages/iou/request/step/IOURequestStepScan/index.tsx @@ -796,7 +796,9 @@ function IOURequestStepScan({ IOURequestStepScan.displayName = 'IOURequestStepScan'; -const IOURequestStepScanWithCurrentUserPersonalDetails = withCurrentUserPersonalDetails(IOURequestStepScan); +const IOURequestStepScanWithOnyx = IOURequestStepScan; + +const IOURequestStepScanWithCurrentUserPersonalDetails = withCurrentUserPersonalDetails(IOURequestStepScanWithOnyx); // eslint-disable-next-line rulesdir/no-negated-variables const IOURequestStepScanWithWritableReportOrNotFound = withWritableReportOrNotFound(IOURequestStepScanWithCurrentUserPersonalDetails, true); // eslint-disable-next-line rulesdir/no-negated-variables diff --git a/src/pages/workspace/AccessOrNotFoundWrapper.tsx b/src/pages/workspace/AccessOrNotFoundWrapper.tsx index 5b82b0c365f8..b83c703fbe77 100644 --- a/src/pages/workspace/AccessOrNotFoundWrapper.tsx +++ b/src/pages/workspace/AccessOrNotFoundWrapper.tsx @@ -1,5 +1,5 @@ /* eslint-disable rulesdir/no-negated-variables */ -import React, {useEffect, useMemo, useState} from 'react'; +import React, {useEffect, useState} from 'react'; import type {OnyxCollection, OnyxEntry} from 'react-native-onyx'; import {useOnyx} from 'react-native-onyx'; import type {FullPageNotFoundViewProps} from '@components/BlockingViews/FullPageNotFoundView'; @@ -44,7 +44,6 @@ const ACCESS_VARIANTS = { >; type AccessVariant = keyof typeof ACCESS_VARIANTS; - type AccessOrNotFoundWrapperChildrenProps = { /** The report that holds the transaction */ report: OnyxEntry; @@ -117,8 +116,8 @@ function AccessOrNotFoundWrapper({ featureName, ...props }: AccessOrNotFoundWrapperProps) { - const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID ?? '-1'}`); - const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID ?? '-1'}`); + const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`); + const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`); const [isLoadingReportData] = useOnyx(ONYXKEYS.IS_LOADING_REPORT_DATA, {initialValue: true}); const {login = ''} = useCurrentUserPersonalDetails(); const isPolicyIDInRoute = !!policyID?.length; @@ -161,8 +160,6 @@ function AccessOrNotFoundWrapper({ setIsPolicyFeatureEnabled(isFeatureEnabled); }, [pendingField, isOffline, isFeatureEnabled]); - const childrenProps = useMemo(() => ({report, policy, isLoadingReportData}), [report, policy, isLoadingReportData]); - if (shouldShowFullScreenLoadingIndicator) { return ; } @@ -178,7 +175,7 @@ function AccessOrNotFoundWrapper({ ); } - return callOrReturn(props.children, childrenProps); + return callOrReturn(props.children, {report, policy, isLoadingReportData}); } export type {AccessVariant};