Skip to content

Commit c38cbcb

Browse files
committed
Migrate CategorySelectorModal to be nv RHP
1 parent c70c52b commit c38cbcb

13 files changed

Lines changed: 198 additions & 178 deletions

File tree

src/ROUTES.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,16 @@ const DYNAMIC_ROUTES = {
293293
path: 'imported',
294294
entryScreens: [SCREENS.WORKSPACE.CATEGORIES],
295295
},
296+
SPEND_CATEGORY_SELECTOR: {
297+
path: 'spend-category-selector/:groupID',
298+
entryScreens: [SCREENS.WORKSPACE.CATEGORIES_SETTINGS],
299+
getRoute: (groupID: string) => `spend-category-selector/${groupID}` as const,
300+
},
301+
DEFAULT_CATEGORY_SELECTOR: {
302+
path: 'default-category-selector/:customUnitID',
303+
entryScreens: [SCREENS.WORKSPACE.DISTANCE_RATES_SETTINGS, SCREENS.WORKSPACE.PER_DIEM_SETTINGS],
304+
getRoute: (customUnitID: string) => `default-category-selector/${customUnitID}` as const,
305+
},
296306
WORKSPACE_INVITE: {
297307
path: 'invite',
298308
entryScreens: [SCREENS.WORKSPACE.PROFILE, SCREENS.WORKSPACE.MEMBERS],
@@ -1517,6 +1527,12 @@ const ROUTES = {
15171527
// eslint-disable-next-line no-restricted-syntax -- Legacy route generation
15181528
getRoute: (policyID: string, backTo = '') => getUrlWithBackToParam(`settings/${policyID}/categories/new`, backTo),
15191529
},
1530+
SETTINGS_SPEND_CATEGORY_SELECTOR: {
1531+
route: 'settings/:policyID/categories/spend-category-selector/:groupID',
1532+
getRoute: (policyID: string, groupID: string, backTo = '') =>
1533+
// eslint-disable-next-line no-restricted-syntax -- Legacy route generation
1534+
getUrlWithBackToParam(`settings/${policyID}/categories/spend-category-selector/${groupID}` as const, backTo),
1535+
},
15201536
SETTINGS_CATEGORIES_IMPORT: {
15211537
route: 'settings/:policyID/categories/import',
15221538

src/SCREENS.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ const SCREENS = {
429429
SETTINGS_CATEGORIES_SETTINGS: 'Settings_Categories_Settings',
430430
SETTINGS_CATEGORY_CREATE: 'Settings_Category_Create',
431431
DYNAMIC_SETTINGS_CATEGORY_EDIT: 'Dynamic_Settings_Category_Edit',
432+
SETTINGS_SPEND_CATEGORY_SELECTOR: 'Settings_Spend_Category_Selector',
432433
SETTINGS_CATEGORIES_ROOT: 'Settings_Categories',
433434
SETTINGS_CATEGORIES_IMPORT: 'Settings_Categories_Import',
434435
SETTINGS_CATEGORIES_IMPORTED: 'Settings_Categories_Imported',
@@ -784,6 +785,8 @@ const SCREENS = {
784785
CATEGORIES_SETTINGS: 'Categories_Settings',
785786
DYNAMIC_CATEGORIES_IMPORT: 'Dynamic_Categories_Import',
786787
DYNAMIC_CATEGORIES_IMPORTED: 'Dynamic_Categories_Imported',
788+
DYNAMIC_SPEND_CATEGORY_SELECTOR: 'Dynamic_Spend_Category_Selector',
789+
DYNAMIC_DEFAULT_CATEGORY_SELECTOR: 'Dynamic_Default_Category_Selector',
787790
MORE_FEATURES: 'Workspace_More_Features',
788791
MEMBER_DETAILS: 'Workspace_Member_Details',
789792
MEMBER_DETAILS_ROLE: 'Workspace_Member_Details_Role',

src/components/CategorySelector/CategorySelectorModal.tsx

Lines changed: 0 additions & 64 deletions
This file was deleted.

src/components/CategorySelector/index.tsx

Lines changed: 20 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,14 @@
11
import React from 'react';
22
import type {StyleProp, ViewStyle} from 'react-native';
3-
import {View} from 'react-native';
43
import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription';
5-
import type {ListItem} from '@components/SelectionList/types';
64
import useThemeStyles from '@hooks/useThemeStyles';
75
import {getDecodedCategoryName} from '@libs/CategoryUtils';
6+
import createDynamicRoute from '@libs/Navigation/helpers/dynamicRoutesUtils/createDynamicRoute';
7+
import Navigation from '@libs/Navigation/Navigation';
88
import CONST from '@src/CONST';
9-
import CategorySelectorModal from './CategorySelectorModal';
9+
import {DYNAMIC_ROUTES} from '@src/ROUTES';
1010

1111
type CategorySelectorProps = {
12-
/** The ID of the associated policy */
13-
policyID: string;
14-
15-
/** Function to call when the user selects a category */
16-
setNewCategory: (value: ListItem) => void;
17-
1812
/** Currently selected category */
1913
defaultValue?: string;
2014

@@ -27,48 +21,31 @@ type CategorySelectorProps = {
2721
/** Whether item is focused or active */
2822
focused?: boolean;
2923

30-
/** Whether category item picker is visible */
31-
isPickerVisible: boolean;
32-
33-
/** Callback to show category picker */
34-
showPickerModal: () => void;
35-
36-
/** Callback to hide category picker */
37-
hidePickerModal: () => void;
24+
/** The custom unit ID to update when selecting a category */
25+
customUnitID: string;
3826
};
3927

40-
function CategorySelector({defaultValue = '', wrapperStyle, label, setNewCategory, policyID, focused, isPickerVisible, showPickerModal, hidePickerModal}: CategorySelectorProps) {
28+
function CategorySelector({defaultValue = '', wrapperStyle, label, focused, customUnitID}: CategorySelectorProps) {
4129
const styles = useThemeStyles();
4230

43-
const updateCategoryInput = (categoryItem: ListItem) => {
44-
setNewCategory(categoryItem);
45-
hidePickerModal();
46-
};
47-
4831
const decodedCategoryName = getDecodedCategoryName(defaultValue);
4932
const descStyle = decodedCategoryName.length === 0 ? styles.textNormal : null;
5033

34+
const onPress = () => {
35+
Navigation.navigate(createDynamicRoute(DYNAMIC_ROUTES.DEFAULT_CATEGORY_SELECTOR.getRoute(customUnitID)));
36+
};
37+
5138
return (
52-
<View>
53-
<MenuItemWithTopDescription
54-
shouldShowRightIcon
55-
title={decodedCategoryName}
56-
description={label}
57-
descriptionTextStyle={descStyle}
58-
onPress={showPickerModal}
59-
wrapperStyle={wrapperStyle}
60-
focused={focused}
61-
sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.RULES.CATEGORY_SELECTOR}
62-
/>
63-
<CategorySelectorModal
64-
policyID={policyID}
65-
isVisible={isPickerVisible}
66-
currentCategory={defaultValue}
67-
onClose={hidePickerModal}
68-
onCategorySelected={updateCategoryInput}
69-
label={label}
70-
/>
71-
</View>
39+
<MenuItemWithTopDescription
40+
shouldShowRightIcon
41+
title={decodedCategoryName}
42+
description={label}
43+
descriptionTextStyle={descStyle}
44+
onPress={onPress}
45+
wrapperStyle={wrapperStyle}
46+
focused={focused}
47+
sentryLabel={CONST.SENTRY_LABEL.WORKSPACE.RULES.CATEGORY_SELECTOR}
48+
/>
7249
);
7350
}
7451

src/libs/Navigation/AppNavigator/ModalStackNavigators/index.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ const CategoriesModalStackNavigator = createModalStackNavigator({
315315
[SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORIES_SETTINGS]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/WorkspaceCategoriesSettingsPage').default,
316316
[SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORY_CREATE]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/CreateCategoryPage').default,
317317
[SCREENS.SETTINGS_CATEGORIES.DYNAMIC_SETTINGS_CATEGORY_EDIT]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/EditCategoryPage').default,
318+
[SCREENS.SETTINGS_CATEGORIES.SETTINGS_SPEND_CATEGORY_SELECTOR]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/DynamicSpendCategorySelectorPage').default,
318319
[SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORY_SETTINGS]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/CategorySettingsPage').default,
319320
[SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORIES_IMPORT]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/ImportCategoriesPage').default,
320321
[SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORIES_IMPORTED]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/ImportedCategoriesPage').default,
@@ -524,6 +525,8 @@ const SettingsModalStackNavigator = createModalStackNavigator<SettingsNavigatorP
524525
[SCREENS.WORKSPACE.CATEGORIES_SETTINGS]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/WorkspaceCategoriesSettingsPage').default,
525526
[SCREENS.WORKSPACE.DYNAMIC_CATEGORIES_IMPORT]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/ImportCategoriesPage').default,
526527
[SCREENS.WORKSPACE.DYNAMIC_CATEGORIES_IMPORTED]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/ImportedCategoriesPage').default,
528+
[SCREENS.WORKSPACE.DYNAMIC_SPEND_CATEGORY_SELECTOR]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/DynamicSpendCategorySelectorPage').default,
529+
[SCREENS.WORKSPACE.DYNAMIC_DEFAULT_CATEGORY_SELECTOR]: () => require<ReactComponentModule>('../../../../pages/workspace/categories/DynamicDefaultCategorySelectorPage').default,
527530
[SCREENS.WORKSPACE.UPGRADE]: () => require<ReactComponentModule>('../../../../pages/workspace/upgrade/WorkspaceUpgradePage').default,
528531
[SCREENS.WORKSPACE.DOWNGRADE]: () => require<ReactComponentModule>('../../../../pages/workspace/downgrade/WorkspaceDowngradePage').default,
529532
[SCREENS.WORKSPACE.PAY_AND_DOWNGRADE]: () => require<ReactComponentModule>('../../../../pages/workspace/downgrade/PayAndDowngradePage').default,

src/libs/Navigation/linkingConfig/RELATIONS/WORKSPACE_TO_RHP.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ const WORKSPACE_TO_RHP: Partial<Record<keyof WorkspaceSplitNavigatorParamList, s
211211
SCREENS.WORKSPACE.CATEGORY_REQUIRE_RECEIPTS_OVER,
212212
SCREENS.WORKSPACE.CATEGORY_REQUIRE_ITEMIZED_RECEIPTS_OVER,
213213
SCREENS.WORKSPACE.CATEGORY_REQUIRED_FIELDS,
214+
SCREENS.WORKSPACE.DYNAMIC_SPEND_CATEGORY_SELECTOR,
214215
],
215216
[SCREENS.WORKSPACE.DISTANCE_RATES]: [
216217
SCREENS.WORKSPACE.DISTANCE_RATES_SETTINGS,
@@ -220,6 +221,7 @@ const WORKSPACE_TO_RHP: Partial<Record<keyof WorkspaceSplitNavigatorParamList, s
220221
SCREENS.WORKSPACE.DISTANCE_RATE_TAX_RATE_EDIT,
221222
SCREENS.WORKSPACE.DISTANCE_RATE_DETAILS,
222223
SCREENS.WORKSPACE.CREATE_DISTANCE_RATE,
224+
SCREENS.WORKSPACE.DYNAMIC_DEFAULT_CATEGORY_SELECTOR,
223225
],
224226
[SCREENS.WORKSPACE.TRAVEL]: [
225227
SCREENS.WORKSPACE.TRAVEL_SETTINGS_ACCOUNT,
@@ -326,6 +328,7 @@ const WORKSPACE_TO_RHP: Partial<Record<keyof WorkspaceSplitNavigatorParamList, s
326328
SCREENS.WORKSPACE.PER_DIEM_EDIT_SUBRATE,
327329
SCREENS.WORKSPACE.PER_DIEM_EDIT_AMOUNT,
328330
SCREENS.WORKSPACE.PER_DIEM_EDIT_CURRENCY,
331+
SCREENS.WORKSPACE.DYNAMIC_DEFAULT_CATEGORY_SELECTOR,
329332
],
330333
[SCREENS.WORKSPACE.TIME_TRACKING]: [SCREENS.WORKSPACE.TIME_TRACKING_DEFAULT_RATE],
331334
[SCREENS.WORKSPACE.MORE_FEATURES]: [],

src/libs/Navigation/linkingConfig/config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -996,6 +996,8 @@ const config: LinkingOptions<RootNavigatorParamList>['config'] = {
996996
},
997997
[SCREENS.WORKSPACE.DYNAMIC_CATEGORIES_IMPORT]: DYNAMIC_ROUTES.WORKSPACE_CATEGORIES_IMPORT.path,
998998
[SCREENS.WORKSPACE.DYNAMIC_CATEGORIES_IMPORTED]: DYNAMIC_ROUTES.WORKSPACE_CATEGORIES_IMPORTED.path,
999+
[SCREENS.WORKSPACE.DYNAMIC_SPEND_CATEGORY_SELECTOR]: DYNAMIC_ROUTES.SPEND_CATEGORY_SELECTOR.path,
1000+
[SCREENS.WORKSPACE.DYNAMIC_DEFAULT_CATEGORY_SELECTOR]: DYNAMIC_ROUTES.DEFAULT_CATEGORY_SELECTOR.path,
9991001
[SCREENS.WORKSPACE.WORKFLOWS_PAYER]: {
10001002
path: ROUTES.WORKSPACE_WORKFLOWS_PAYER.route,
10011003
},
@@ -1478,6 +1480,9 @@ const config: LinkingOptions<RootNavigatorParamList>['config'] = {
14781480
path: ROUTES.SETTINGS_CATEGORY_CREATE.route,
14791481
},
14801482
[SCREENS.SETTINGS_CATEGORIES.DYNAMIC_SETTINGS_CATEGORY_EDIT]: DYNAMIC_ROUTES.SETTINGS_CATEGORY_EDIT.path,
1483+
[SCREENS.SETTINGS_CATEGORIES.SETTINGS_SPEND_CATEGORY_SELECTOR]: {
1484+
path: ROUTES.SETTINGS_SPEND_CATEGORY_SELECTOR.route,
1485+
},
14811486
[SCREENS.SETTINGS_CATEGORIES.SETTINGS_CATEGORIES_IMPORT]: {
14821487
path: ROUTES.SETTINGS_CATEGORIES_IMPORT.route,
14831488
},

src/libs/Navigation/types.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,18 @@ type SettingsNavigatorParamList = {
438438
// eslint-disable-next-line no-restricted-syntax -- `backTo` usages in this file are legacy. Do not add new `backTo` params to screens. See contributingGuides/NAVIGATION.md
439439
backTo?: Routes;
440440
};
441+
[SCREENS.WORKSPACE.DYNAMIC_SPEND_CATEGORY_SELECTOR]: {
442+
policyID: string;
443+
groupID: string;
444+
};
445+
[SCREENS.SETTINGS_CATEGORIES.SETTINGS_SPEND_CATEGORY_SELECTOR]: {
446+
policyID: string;
447+
groupID: string;
448+
};
449+
[SCREENS.WORKSPACE.DYNAMIC_DEFAULT_CATEGORY_SELECTOR]: {
450+
policyID: string;
451+
customUnitID: string;
452+
};
441453
[SCREENS.WORKSPACE.DYNAMIC_CATEGORIES_IMPORT]: {
442454
policyID: string;
443455
};
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from 'react';
2+
import CategoryPicker from '@components/CategoryPicker';
3+
import HeaderWithBackButton from '@components/HeaderWithBackButton';
4+
import ScreenWrapper from '@components/ScreenWrapper';
5+
import type {ListItem} from '@components/SelectionList/types';
6+
import useDynamicBackPath from '@hooks/useDynamicBackPath';
7+
import useLocalize from '@hooks/useLocalize';
8+
import useOnyx from '@hooks/useOnyx';
9+
import useThemeStyles from '@hooks/useThemeStyles';
10+
import Navigation from '@libs/Navigation/Navigation';
11+
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
12+
import type {SettingsNavigatorParamList} from '@libs/Navigation/types';
13+
import {setPolicyCustomUnitDefaultCategory} from '@userActions/Policy/Category';
14+
import ONYXKEYS from '@src/ONYXKEYS';
15+
import {DYNAMIC_ROUTES} from '@src/ROUTES';
16+
import type SCREENS from '@src/SCREENS';
17+
18+
type DynamicDefaultCategorySelectorPageProps = PlatformStackScreenProps<SettingsNavigatorParamList, typeof SCREENS.WORKSPACE.DYNAMIC_DEFAULT_CATEGORY_SELECTOR>;
19+
20+
function DynamicDefaultCategorySelectorPage({route}: DynamicDefaultCategorySelectorPageProps) {
21+
const {policyID, customUnitID} = route.params;
22+
const styles = useThemeStyles();
23+
const {translate} = useLocalize();
24+
const [policy] = useOnyx(`${ONYXKEYS.COLLECTION.POLICY}${policyID}`);
25+
const currentCategory = policy?.customUnits?.[customUnitID]?.defaultCategory ?? '';
26+
const backPath = useDynamicBackPath(DYNAMIC_ROUTES.DEFAULT_CATEGORY_SELECTOR.path);
27+
28+
const onCategorySelected = (selectedCategory: ListItem) => {
29+
if (!selectedCategory.searchText || currentCategory === selectedCategory.searchText) {
30+
return;
31+
}
32+
setPolicyCustomUnitDefaultCategory(policyID, customUnitID, currentCategory, selectedCategory.searchText);
33+
Navigation.goBack(backPath);
34+
};
35+
36+
return (
37+
<ScreenWrapper
38+
style={styles.pb0}
39+
includePaddingTop={false}
40+
enableEdgeToEdgeBottomSafeAreaPadding
41+
shouldEnableKeyboardAvoidingView={false}
42+
testID="DynamicDefaultCategorySelectorPage"
43+
>
44+
<HeaderWithBackButton
45+
title={translate('workspace.common.defaultCategory')}
46+
shouldShowBackButton
47+
onBackButtonPress={() => Navigation.goBack(backPath)}
48+
/>
49+
<CategoryPicker
50+
policyID={policyID}
51+
selectedCategory={currentCategory}
52+
onSubmit={onCategorySelected}
53+
addBottomSafeAreaPadding
54+
/>
55+
</ScreenWrapper>
56+
);
57+
}
58+
59+
export default DynamicDefaultCategorySelectorPage;

0 commit comments

Comments
 (0)