diff --git a/src/ROUTES.js b/src/ROUTES.js
index 3f96d77d477e..6da2c5bf7ae9 100644
--- a/src/ROUTES.js
+++ b/src/ROUTES.js
@@ -92,6 +92,7 @@ export default {
MONEY_REQUEST_DATE: ':iouType/new/date/:reportID?',
MONEY_REQUEST_CURRENCY: ':iouType/new/currency/:reportID?',
MONEY_REQUEST_DESCRIPTION: ':iouType/new/description/:reportID?',
+ MONEY_REQUEST_CATEGORY: ':iouType/new/category/:reportID?',
MONEY_REQUEST_MERCHANT: ':iouType/new/merchant/:reportID?',
MONEY_REQUEST_MANUAL_TAB: ':iouType/new/:reportID?/manual',
MONEY_REQUEST_SCAN_TAB: ':iouType/new/:reportID?/scan',
@@ -107,6 +108,7 @@ export default {
getMoneyRequestCreatedRoute: (iouType, reportID = '') => `${iouType}/new/date/${reportID}`,
getMoneyRequestCurrencyRoute: (iouType, reportID = '', currency, backTo) => `${iouType}/new/currency/${reportID}?currency=${currency}&backTo=${backTo}`,
getMoneyRequestDescriptionRoute: (iouType, reportID = '') => `${iouType}/new/description/${reportID}`,
+ getMoneyRequestCategoryRoute: (iouType, reportID = '') => `${iouType}/new/category/${reportID}`,
getMoneyRequestMerchantRoute: (iouType, reportID = '') => `${iouType}/new/merchant/${reportID}`,
getMoneyRequestDistanceTabRoute: (iouType, reportID = '') => `${iouType}/new/${reportID}/distance`,
getMoneyRequestWaypointRoute: (iouType, waypointIndex) => `${iouType}/new/waypoint/${waypointIndex}`,
diff --git a/src/components/CategoryPicker/categoryPickerPropTypes.js b/src/components/CategoryPicker/categoryPickerPropTypes.js
new file mode 100644
index 000000000000..ccc1643021ce
--- /dev/null
+++ b/src/components/CategoryPicker/categoryPickerPropTypes.js
@@ -0,0 +1,24 @@
+import PropTypes from 'prop-types';
+import categoryPropTypes from '../categoryPropTypes';
+
+const propTypes = {
+ /** The report ID of the IOU */
+ reportID: PropTypes.string.isRequired,
+
+ /** The policyID we are getting categories for */
+ policyID: PropTypes.string,
+
+ /** The type of IOU report, i.e. bill, request, send */
+ iouType: PropTypes.string.isRequired,
+
+ /* Onyx Props */
+ /** Collection of categories attached to a policy */
+ policyCategories: PropTypes.objectOf(categoryPropTypes),
+};
+
+const defaultProps = {
+ policyID: '',
+ policyCategories: null,
+};
+
+export {propTypes, defaultProps};
diff --git a/src/components/CategoryPicker/index.js b/src/components/CategoryPicker/index.js
new file mode 100644
index 000000000000..163ab6673ca2
--- /dev/null
+++ b/src/components/CategoryPicker/index.js
@@ -0,0 +1,56 @@
+import React, {useMemo} from 'react';
+import _ from 'underscore';
+import {withOnyx} from 'react-native-onyx';
+import ONYXKEYS from '../../ONYXKEYS';
+import {propTypes, defaultProps} from './categoryPickerPropTypes';
+import OptionsList from '../OptionsList';
+import styles from '../../styles/styles';
+import ScreenWrapper from '../ScreenWrapper';
+import Navigation from '../../libs/Navigation/Navigation';
+import ROUTES from '../../ROUTES';
+
+function CategoryPicker({policyCategories, reportID, iouType}) {
+ const sections = useMemo(() => {
+ const categoryList = _.chain(policyCategories)
+ .values()
+ .map((category) => ({
+ text: category.name,
+ keyForList: category.name,
+ tooltipText: category.name,
+ }))
+ .value();
+
+ return [
+ {
+ data: categoryList,
+ },
+ ];
+ }, [policyCategories]);
+
+ const navigateBack = () => {
+ Navigation.goBack(ROUTES.getMoneyRequestConfirmationRoute(iouType, reportID));
+ };
+
+ return (
+
+ {({safeAreaPaddingBottomStyle}) => (
+
+ )}
+
+ );
+}
+
+CategoryPicker.displayName = 'CategoryPicker';
+CategoryPicker.propTypes = propTypes;
+CategoryPicker.defaultProps = defaultProps;
+
+export default withOnyx({
+ policyCategories: {
+ key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`,
+ },
+})(CategoryPicker);
diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js
index ffd65cfb8f74..3dc7f06acfad 100755
--- a/src/components/MoneyRequestConfirmationList.js
+++ b/src/components/MoneyRequestConfirmationList.js
@@ -27,6 +27,7 @@ import themeColors from '../styles/themes/default';
import Image from './Image';
import useLocalize from '../hooks/useLocalize';
import * as ReceiptUtils from '../libs/ReceiptUtils';
+import categoryPropTypes from './categoryPropTypes';
const propTypes = {
/** Callback to inform parent modal of success */
@@ -59,6 +60,9 @@ const propTypes = {
/** IOU merchant */
iouMerchant: PropTypes.string,
+ /** IOU Category */
+ iouCategory: PropTypes.string,
+
/** Selected participants from MoneyRequestModal with login / accountID */
selectedParticipants: PropTypes.arrayOf(optionPropTypes).isRequired,
@@ -92,6 +96,10 @@ const propTypes = {
/** File source of the receipt */
receiptSource: PropTypes.string,
+
+ /* Onyx Props */
+ /** Collection of categories attached to a policy */
+ policyCategories: PropTypes.objectOf(categoryPropTypes),
};
const defaultProps = {
@@ -99,6 +107,7 @@ const defaultProps = {
onSendMoney: () => {},
onSelectParticipant: () => {},
iouType: CONST.IOU.MONEY_REQUEST_TYPE.REQUEST,
+ iouCategory: '',
payeePersonalDetails: null,
canModifyParticipants: false,
isReadOnly: false,
@@ -111,6 +120,7 @@ const defaultProps = {
...withCurrentUserPersonalDetailsDefaultProps,
receiptPath: '',
receiptSource: '',
+ policyCategories: {},
};
function MoneyRequestConfirmationList(props) {
@@ -393,6 +403,16 @@ function MoneyRequestConfirmationList(props) {
onPress={() => Navigation.navigate(ROUTES.getMoneyRequestMerchantRoute(props.iouType, props.reportID))}
disabled={didConfirm || props.isReadOnly || !isTypeRequest}
/>
+ {!_.isEmpty(props.policyCategories) && (
+ Navigation.navigate(ROUTES.getMoneyRequestCategoryRoute(props.iouType, props.reportID))}
+ style={[styles.moneyRequestMenuItem, styles.mb2]}
+ disabled={didConfirm || props.isReadOnly}
+ />
+ )}
>
)}
@@ -408,5 +428,8 @@ export default compose(
session: {
key: ONYXKEYS.SESSION,
},
+ policyCategories: {
+ key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`,
+ },
}),
)(MoneyRequestConfirmationList);
diff --git a/src/components/categoryPropTypes.js b/src/components/categoryPropTypes.js
new file mode 100644
index 000000000000..90c3ac368d1c
--- /dev/null
+++ b/src/components/categoryPropTypes.js
@@ -0,0 +1,9 @@
+import PropTypes from 'prop-types';
+
+export default PropTypes.shape({
+ /** Name of a category */
+ name: PropTypes.string.isRequired,
+
+ /** Flag that determines if a category is active and able to be selected */
+ enabled: PropTypes.bool.isRequired,
+});
diff --git a/src/languages/en.js b/src/languages/en.js
index d0c945fbc37d..477564053939 100755
--- a/src/languages/en.js
+++ b/src/languages/en.js
@@ -155,6 +155,7 @@ export default {
edit: 'Edit',
showMore: 'Show more',
merchant: 'Merchant',
+ category: 'Category',
receipt: 'Receipt',
replace: 'Replace',
},
diff --git a/src/languages/es.js b/src/languages/es.js
index 7f7457f686b8..4852c23326cb 100644
--- a/src/languages/es.js
+++ b/src/languages/es.js
@@ -154,6 +154,7 @@ export default {
edit: 'Editar',
showMore: 'Mostrar más',
merchant: 'Comerciante',
+ category: 'Categoría',
receipt: 'Recibo',
replace: 'Sustituir',
},
diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
index aa4fcc02c906..d172911d68ed 100644
--- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
+++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
@@ -83,6 +83,13 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator([
},
name: 'Money_Request_Description',
},
+ {
+ getComponent: () => {
+ const MoneyRequestCategoryPage = require('../../../pages/iou/MoneyRequestCategoryPage').default;
+ return MoneyRequestCategoryPage;
+ },
+ name: 'Money_Request_Category',
+ },
{
getComponent: () => {
const MoneyRequestMerchantPage = require('../../../pages/iou/MoneyRequestMerchantPage').default;
diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js
index a76ebbf776da..ebea00d4b05b 100644
--- a/src/libs/Navigation/linkingConfig.js
+++ b/src/libs/Navigation/linkingConfig.js
@@ -310,6 +310,7 @@ export default {
Money_Request_Date: ROUTES.MONEY_REQUEST_DATE,
Money_Request_Currency: ROUTES.MONEY_REQUEST_CURRENCY,
Money_Request_Description: ROUTES.MONEY_REQUEST_DESCRIPTION,
+ Money_Request_Category: ROUTES.MONEY_REQUEST_CATEGORY,
Money_Request_Merchant: ROUTES.MONEY_REQUEST_MERCHANT,
Money_Request_Waypoint: ROUTES.MONEY_REQUEST_WAYPOINT,
IOU_Send_Enable_Payments: ROUTES.IOU_SEND_ENABLE_PAYMENTS,
diff --git a/src/pages/iou/MoneyRequestCategoryPage.js b/src/pages/iou/MoneyRequestCategoryPage.js
new file mode 100644
index 000000000000..80b88a762609
--- /dev/null
+++ b/src/pages/iou/MoneyRequestCategoryPage.js
@@ -0,0 +1,72 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import lodashGet from 'lodash/get';
+import {withOnyx} from 'react-native-onyx';
+import ROUTES from '../../ROUTES';
+import Navigation from '../../libs/Navigation/Navigation';
+import useLocalize from '../../hooks/useLocalize';
+import ScreenWrapper from '../../components/ScreenWrapper';
+import HeaderWithBackButton from '../../components/HeaderWithBackButton';
+import CategoryPicker from '../../components/CategoryPicker';
+import ONYXKEYS from '../../ONYXKEYS';
+import reportPropTypes from '../reportPropTypes';
+
+const propTypes = {
+ /** Navigation route context info provided by react navigation */
+ route: PropTypes.shape({
+ /** Route specific parameters used on this screen via route :iouType/new/category/:reportID? */
+ params: PropTypes.shape({
+ /** The type of IOU report, i.e. bill, request, send */
+ iouType: PropTypes.string,
+
+ /** The report ID of the IOU */
+ reportID: PropTypes.string,
+ }),
+ }).isRequired,
+
+ /** The report currently being used */
+ report: reportPropTypes,
+};
+
+const defaultProps = {
+ report: {},
+};
+
+function MoneyRequestCategoryPage({route, report}) {
+ const {translate} = useLocalize();
+
+ const reportID = lodashGet(route, 'params.reportID', '');
+ const iouType = lodashGet(route, 'params.iouType', '');
+
+ const navigateBack = () => {
+ Navigation.goBack(ROUTES.getMoneyRequestConfirmationRoute(iouType, reportID));
+ };
+
+ return (
+
+
+
+
+
+ );
+}
+
+MoneyRequestCategoryPage.displayName = 'MoneyRequestCategoryPage';
+MoneyRequestCategoryPage.propTypes = propTypes;
+MoneyRequestCategoryPage.defaultProps = defaultProps;
+
+export default withOnyx({
+ report: {
+ key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${lodashGet(route, 'params.reportID', '')}`,
+ },
+})(MoneyRequestCategoryPage);