diff --git a/src/components/UnitPicker.tsx b/src/components/UnitPicker.tsx index 02f056e04dad..19ee25c98529 100644 --- a/src/components/UnitPicker.tsx +++ b/src/components/UnitPicker.tsx @@ -15,7 +15,7 @@ type UnitItemType = { }; type UnitPickerProps = { - defaultValue: Unit; + defaultValue?: Unit; onOptionSelected: (unit: UnitItemType) => void; }; diff --git a/src/libs/actions/Policy/Policy.ts b/src/libs/actions/Policy/Policy.ts index eeff15d8d32f..47a38a8a0ea2 100644 --- a/src/libs/actions/Policy/Policy.ts +++ b/src/libs/actions/Policy/Policy.ts @@ -2906,11 +2906,11 @@ function enableDistanceRequestTax(policyID: string, customUnitName: string, cust customUnits: { [customUnitID]: { attributes, + pendingFields: { + taxEnabled: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + }, }, }, - pendingFields: { - customUnits: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, - }, }, }, ], @@ -2919,8 +2919,12 @@ function enableDistanceRequestTax(policyID: string, customUnitName: string, cust onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, value: { - pendingFields: { - customUnits: null, + customUnits: { + [customUnitID]: { + pendingFields: { + taxEnabled: null, + }, + }, }, }, }, @@ -2933,6 +2937,9 @@ function enableDistanceRequestTax(policyID: string, customUnitName: string, cust customUnits: { [customUnitID]: { attributes: policy?.customUnits ? policy?.customUnits[customUnitID].attributes : null, + errorFields: { + taxEnabled: ErrorUtils.getMicroSecondOnyxErrorWithTranslationKey('common.genericErrorMessage'), + }, }, }, }, diff --git a/src/pages/workspace/distanceRates/CreateDistanceRatePage.tsx b/src/pages/workspace/distanceRates/CreateDistanceRatePage.tsx index f86a5a1dbb73..b2dca63ecd34 100644 --- a/src/pages/workspace/distanceRates/CreateDistanceRatePage.tsx +++ b/src/pages/workspace/distanceRates/CreateDistanceRatePage.tsx @@ -1,8 +1,10 @@ import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback} from 'react'; +import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import AmountForm from '@components/AmountForm'; +import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView'; import FormProvider from '@components/Form/FormProvider'; import InputWrapperWithRef from '@components/Form/InputWrapper'; import type {FormOnyxValues} from '@components/Form/types'; @@ -40,6 +42,8 @@ function CreateDistanceRatePage({policy, route}: CreateDistanceRatePageProps) { const customUnitRateID = generateCustomUnitID(); const {inputCallbackRef} = useAutoFocusInput(); + const FullPageBlockingView = !customUnitID ? FullPageOfflineBlockingView : View; + const validate = useCallback( (values: FormOnyxValues) => validateRateValue(values, currency, toLocaleDigit), [currency, toLocaleDigit], @@ -71,26 +75,28 @@ function CreateDistanceRatePage({policy, route}: CreateDistanceRatePageProps) { shouldEnableMaxHeight > - - - + + + + + ); diff --git a/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx b/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx index 03c96e7f67e2..04411cb15c1f 100644 --- a/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx +++ b/src/pages/workspace/distanceRates/PolicyDistanceRatesSettingsPage.tsx @@ -3,6 +3,7 @@ import React from 'react'; import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; +import FullPageOfflineBlockingView from '@components/BlockingViews/FullPageOfflineBlockingView'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import OfflineWithFeedback from '@components/OfflineWithFeedback'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -52,9 +53,11 @@ function PolicyDistanceRatesSettingsPage({policy, policyCategories, route}: Poli const isPolicyTrackTaxEnabled = !!policy?.tax?.trackingEnabled; const defaultCategory = customUnits[customUnitID]?.defaultCategory; - const defaultUnit = customUnits[customUnitID]?.attributes.unit; + const defaultUnit = customUnits[customUnitID]?.attributes?.unit; const errorFields = customUnits[customUnitID]?.errorFields; + const FullPageBlockingView = !customUnit ? FullPageOfflineBlockingView : View; + const setNewUnit = (unit: UnitItemType) => { const attributes = {...customUnits[customUnitID].attributes, unit: unit.value}; DistanceRate.setPolicyDistanceRatesUnit(policyID, customUnit, {...customUnit, attributes}); @@ -77,8 +80,9 @@ function PolicyDistanceRatesSettingsPage({policy, policyCategories, route}: Poli const onToggleTrackTax = (isOn: boolean) => { const attributes = {...customUnits[customUnitID].attributes, taxEnabled: isOn}; - Policy.enableDistanceRequestTax(policyID, customUnit.name, customUnitID, attributes); + Policy.enableDistanceRequestTax(policyID, customUnit?.name, customUnitID, attributes); }; + return ( - - - clearErrorFields('attributes')} - > - - - {policy?.areCategoriesEnabled && OptionsListUtils.hasEnabledOptions(policyCategories ?? {}) && ( + + + + {defaultUnit && ( + clearErrorFields('attributes')} + > + + + )} + {policy?.areCategoriesEnabled && OptionsListUtils.hasEnabledOptions(policyCategories ?? {}) && ( + clearErrorFields('defaultCategory')} + > + + + )} clearErrorFields('defaultCategory')} + pendingAction={customUnits[customUnitID]?.pendingFields?.taxEnabled} > - - - )} - - - - {translate('workspace.distanceRates.trackTax')} - - - - {!isPolicyTrackTaxEnabled && ( - - - {translate('workspace.distanceRates.taxFeatureNotEnabledMessage')} - { - Navigation.dismissModal(); - Navigation.goBack(ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID)); - }} - > - {translate('workspace.common.moreFeatures')} - - {translate('workspace.distanceRates.changePromptMessage')} - + + + {translate('workspace.distanceRates.trackTax')} + + - )} - - - + {!isPolicyTrackTaxEnabled && ( + + + {translate('workspace.distanceRates.taxFeatureNotEnabledMessage')} + { + Navigation.dismissModal(); + Navigation.goBack(ROUTES.WORKSPACE_MORE_FEATURES.getRoute(policyID)); + }} + > + {translate('workspace.common.moreFeatures')} + + {translate('workspace.distanceRates.changePromptMessage')} + + + )} + + + + ); diff --git a/src/pages/workspace/distanceRates/UnitSelector/UnitSelectorModal.tsx b/src/pages/workspace/distanceRates/UnitSelector/UnitSelectorModal.tsx index 5a9f5e7c6ea1..34eb21ce19c4 100644 --- a/src/pages/workspace/distanceRates/UnitSelector/UnitSelectorModal.tsx +++ b/src/pages/workspace/distanceRates/UnitSelector/UnitSelectorModal.tsx @@ -13,7 +13,7 @@ type UnitSelectorModalProps = { isVisible: boolean; /** Selected unit */ - currentUnit: Unit; + currentUnit?: Unit; /** Function to call when the user selects a unit */ onUnitSelected: (value: UnitItemType) => void; diff --git a/src/pages/workspace/distanceRates/UnitSelector/index.tsx b/src/pages/workspace/distanceRates/UnitSelector/index.tsx index 166d0df786a1..883ef0a5e593 100644 --- a/src/pages/workspace/distanceRates/UnitSelector/index.tsx +++ b/src/pages/workspace/distanceRates/UnitSelector/index.tsx @@ -14,7 +14,7 @@ type UnitSelectorProps = { setNewUnit: (value: UnitItemType) => void; /** Currently selected unit */ - defaultValue: Unit; + defaultValue?: Unit; /** Label to display on field */ label: string; @@ -41,7 +41,7 @@ function UnitSelector({defaultValue, wrapperStyle, label, setNewUnit}: UnitSelec hidePickerModal(); }; - const title = Str.recapitalize(translate(getUnitTranslationKey(defaultValue))); + const title = defaultValue ? Str.recapitalize(translate(getUnitTranslationKey(defaultValue))) : ''; return ( diff --git a/src/types/onyx/Policy.ts b/src/types/onyx/Policy.ts index c717d6579cc8..3311959cf8bf 100644 --- a/src/types/onyx/Policy.ts +++ b/src/types/onyx/Policy.ts @@ -57,31 +57,34 @@ type Attributes = { }; /** Policy custom unit */ -type CustomUnit = OnyxCommon.OnyxValueWithOfflineFeedback<{ - /** Custom unit name */ - name: string; +type CustomUnit = OnyxCommon.OnyxValueWithOfflineFeedback< + { + /** Custom unit name */ + name: string; - /** ID that identifies this custom unit */ - customUnitID: string; + /** ID that identifies this custom unit */ + customUnitID: string; - /** Contains custom attributes like unit, for this custom unit */ - attributes: Attributes; + /** Contains custom attributes like unit, for this custom unit */ + attributes: Attributes; - /** Distance rates using this custom unit */ - rates: Record; + /** Distance rates using this custom unit */ + rates: Record; - /** The default category in which this custom unit is used */ - defaultCategory?: string; + /** The default category in which this custom unit is used */ + defaultCategory?: string; - /** Whether this custom unit is enabled */ - enabled?: boolean; + /** Whether this custom unit is enabled */ + enabled?: boolean; - /** Error messages to show in UI */ - errors?: OnyxCommon.Errors; + /** Error messages to show in UI */ + errors?: OnyxCommon.Errors; - /** Form fields that triggered errors */ - errorFields?: OnyxCommon.ErrorFields; -}>; + /** Form fields that triggered errors */ + errorFields?: OnyxCommon.ErrorFields; + }, + keyof Attributes +>; /** Policy company address data */ type CompanyAddress = { @@ -1552,7 +1555,7 @@ type Policy = OnyxCommon.OnyxValueWithOfflineFeedback< /** Workspace account ID configured for Expensify Card */ workspaceAccountID?: number; } & Partial, - 'generalSettings' | 'addWorkspaceRoom' | keyof ACHAccount + 'generalSettings' | 'addWorkspaceRoom' | keyof ACHAccount | keyof Attributes >; /** Stages of policy connection sync */