diff --git a/src/ROUTES.ts b/src/ROUTES.ts
index b2dafa643b22..38a660e535a4 100644
--- a/src/ROUTES.ts
+++ b/src/ROUTES.ts
@@ -286,6 +286,10 @@ export default {
route: 'workspace/:policyID/settings',
getRoute: (policyID: string) => `workspace/${policyID}/settings`,
},
+ WORKSPACE_SETTINGS_CURRENCY: {
+ route: 'workspace/:policyID/settings/currency',
+ getRoute: (policyID: string) => `workspace/${policyID}/settings/currency`,
+ },
WORKSPACE_CARD: {
route: 'workspace/:policyID/card',
getRoute: (policyID: string) => `workspace/${policyID}/card`,
diff --git a/src/components/Form.js b/src/components/Form.js
index ef6c3ea10474..7d62d936c159 100644
--- a/src/components/Form.js
+++ b/src/components/Form.js
@@ -76,6 +76,10 @@ const propTypes = {
/** Container styles */
style: stylePropTypes,
+ /** Submit button container styles */
+ // eslint-disable-next-line react/forbid-prop-types
+ submitButtonStyles: PropTypes.arrayOf(PropTypes.object),
+
/** Custom content to display in the footer after submit button */
footerContent: PropTypes.oneOfType([PropTypes.func, PropTypes.node]),
@@ -98,6 +102,7 @@ const defaultProps = {
shouldValidateOnBlur: true,
footerContent: null,
style: [],
+ submitButtonStyles: [],
validate: () => ({}),
};
@@ -447,7 +452,7 @@ function Form(props) {
focusInput.focus();
}
}}
- containerStyles={[styles.mh0, styles.mt5, styles.flex1]}
+ containerStyles={[styles.mh0, styles.mt5, styles.flex1, ...props.submitButtonStyles]}
enabledWhenOffline={props.enabledWhenOffline}
isSubmitActionDangerous={props.isSubmitActionDangerous}
disablePressOnEnter
@@ -472,6 +477,7 @@ function Form(props) {
props.isSubmitActionDangerous,
props.isSubmitButtonVisible,
props.submitButtonText,
+ props.submitButtonStyles,
],
);
diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
index 6636702592c0..d71c32f7f582 100644
--- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
+++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js
@@ -151,6 +151,7 @@ const SettingsModalStackNavigator = createModalStackNavigator({
Settings_Status_Set: () => require('../../../pages/settings/Profile/CustomStatus/StatusSetPage').default,
Workspace_Initial: () => require('../../../pages/workspace/WorkspaceInitialPage').default,
Workspace_Settings: () => require('../../../pages/workspace/WorkspaceSettingsPage').default,
+ Workspace_Settings_Currency: () => require('../../../pages/workspace/WorkspaceSettingsCurrencyPage').default,
Workspace_Card: () => require('../../../pages/workspace/card/WorkspaceCardPage').default,
Workspace_Reimburse: () => require('../../../pages/workspace/reimburse/WorkspaceReimbursePage').default,
Workspace_RateAndUnit: () => require('../../../pages/workspace/reimburse/WorkspaceRateAndUnitPage').default,
diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js
index bf069aba314e..88213b699ad6 100644
--- a/src/libs/Navigation/linkingConfig.js
+++ b/src/libs/Navigation/linkingConfig.js
@@ -177,6 +177,9 @@ export default {
Workspace_Settings: {
path: ROUTES.WORKSPACE_SETTINGS.route,
},
+ Workspace_Settings_Currency: {
+ path: ROUTES.WORKSPACE_SETTINGS_CURRENCY.route,
+ },
Workspace_Card: {
path: ROUTES.WORKSPACE_CARD.route,
},
diff --git a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js
new file mode 100644
index 000000000000..9c757b730cef
--- /dev/null
+++ b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js
@@ -0,0 +1,114 @@
+import React, {useState, useCallback} from 'react';
+import _ from 'underscore';
+import {withOnyx} from 'react-native-onyx';
+import PropTypes from 'prop-types';
+import useLocalize from '../../hooks/useLocalize';
+import ScreenWrapper from '../../components/ScreenWrapper';
+import HeaderWithBackButton from '../../components/HeaderWithBackButton';
+import SelectionList from '../../components/SelectionList';
+import Navigation from '../../libs/Navigation/Navigation';
+import ROUTES from '../../ROUTES';
+import compose from '../../libs/compose';
+import ONYXKEYS from '../../ONYXKEYS';
+import withPolicy, {policyDefaultProps, policyPropTypes} from './withPolicy';
+import * as Policy from '../../libs/actions/Policy';
+import * as PolicyUtils from '../../libs/PolicyUtils';
+import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView';
+
+const propTypes = {
+ /** Constant, list of available currencies */
+ currencyList: PropTypes.objectOf(
+ PropTypes.shape({
+ /** Symbol of the currency */
+ symbol: PropTypes.string.isRequired,
+ }),
+ ),
+ ...policyPropTypes,
+};
+
+const defaultProps = {
+ currencyList: {},
+ ...policyDefaultProps,
+};
+
+const getDisplayText = (currencyCode, currencySymbol) => `${currencyCode} - ${currencySymbol}`;
+
+function WorkspaceSettingsCurrencyPage({currencyList, policy}) {
+ const {translate} = useLocalize();
+ const [searchText, setSearchText] = useState('');
+ const trimmedText = searchText.trim().toLowerCase();
+ const currencyListKeys = _.keys(currencyList);
+
+ const filteredItems = _.filter(currencyListKeys, (currencyCode) => {
+ const currency = currencyList[currencyCode];
+ return getDisplayText(currencyCode, currency.symbol).toLowerCase().includes(trimmedText);
+ });
+
+ let initiallyFocusedOptionKey;
+
+ const currencyItems = _.map(filteredItems, (currencyCode) => {
+ const currency = currencyList[currencyCode];
+ const isSelected = policy.outputCurrency === currencyCode;
+
+ if (isSelected) {
+ initiallyFocusedOptionKey = currencyCode;
+ }
+
+ return {
+ text: getDisplayText(currencyCode, currency.symbol),
+ keyForList: currencyCode,
+ isSelected,
+ };
+ });
+
+ const sections = [{data: currencyItems, indexOffset: 0}];
+
+ const headerMessage = searchText.trim() && !currencyItems.length ? translate('common.noResultsFound') : '';
+
+ const onBackButtonPress = useCallback(() => Navigation.goBack(ROUTES.WORKSPACE_SETTINGS.getRoute(policy.id)), [policy.id]);
+
+ const onSelectCurrency = (item) => {
+ Policy.updateGeneralSettings(policy.id, policy.name, item.keyForList);
+ Navigation.goBack(ROUTES.WORKSPACE_SETTINGS.getRoute(policy.id));
+ };
+
+ return (
+
+ Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)}
+ shouldShow={_.isEmpty(policy) || !PolicyUtils.isPolicyAdmin(policy) || PolicyUtils.isPendingDeletePolicy(policy)}
+ subtitleKey={_.isEmpty(policy) ? undefined : 'workspace.common.notAuthorized'}
+ >
+
+
+
+
+
+ );
+}
+
+WorkspaceSettingsCurrencyPage.displayName = 'WorkspaceSettingsCurrencyPage';
+WorkspaceSettingsCurrencyPage.propTypes = propTypes;
+WorkspaceSettingsCurrencyPage.defaultProps = defaultProps;
+
+export default compose(
+ withPolicy,
+ withOnyx({
+ currencyList: {key: ONYXKEYS.CURRENCY_LIST},
+ }),
+)(WorkspaceSettingsCurrencyPage);
diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js
index 0f1f6c283a6b..fd975ebc9247 100644
--- a/src/pages/workspace/WorkspaceSettingsPage.js
+++ b/src/pages/workspace/WorkspaceSettingsPage.js
@@ -1,18 +1,16 @@
-import React, {useCallback, useMemo} from 'react';
+import React, {useCallback} from 'react';
import {Keyboard, View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import PropTypes from 'prop-types';
import _ from 'underscore';
import lodashGet from 'lodash/get';
import ONYXKEYS from '../../ONYXKEYS';
-import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize';
import styles from '../../styles/styles';
import compose from '../../libs/compose';
import * as Policy from '../../libs/actions/Policy';
import * as Expensicons from '../../components/Icon/Expensicons';
import AvatarWithImagePicker from '../../components/AvatarWithImagePicker';
import CONST from '../../CONST';
-import Picker from '../../components/Picker';
import TextInput from '../../components/TextInput';
import WorkspacePageWithSections from './WorkspacePageWithSections';
import withPolicy, {policyPropTypes, policyDefaultProps} from './withPolicy';
@@ -25,17 +23,29 @@ import Avatar from '../../components/Avatar';
import Navigation from '../../libs/Navigation/Navigation';
import ROUTES from '../../ROUTES';
import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/withWindowDimensions';
+import MenuItemWithTopDescription from '../../components/MenuItemWithTopDescription';
+import Text from '../../components/Text';
+import useLocalize from '../../hooks/useLocalize';
const propTypes = {
- // The currency list constant object from Onyx
+ /** Constant, list of available currencies */
currencyList: PropTypes.objectOf(
PropTypes.shape({
- // Symbol for the currency
- symbol: PropTypes.string,
+ /** Symbol of the currency */
+ symbol: PropTypes.string.isRequired,
}),
),
+
+ /** The route object passed to this page from the navigator */
+ route: PropTypes.shape({
+ /** Each parameter passed via the URL */
+ params: PropTypes.shape({
+ /** The policyID that is being configured */
+ policyID: PropTypes.string.isRequired,
+ }).isRequired,
+ }).isRequired,
+
...policyPropTypes,
- ...withLocalizePropTypes,
...windowDimensionsPropTypes,
};
@@ -44,26 +54,22 @@ const defaultProps = {
...policyDefaultProps,
};
-function WorkspaceSettingsPage(props) {
- const currencyItems = useMemo(() => {
- const currencyListKeys = _.keys(props.currencyList);
- return _.map(currencyListKeys, (currencyCode) => ({
- value: currencyCode,
- label: `${currencyCode} - ${props.currencyList[currencyCode].symbol}`,
- }));
- }, [props.currencyList]);
+function WorkspaceSettingsPage({policy, currencyList, windowWidth, route}) {
+ const {translate} = useLocalize();
+
+ const formattedCurrency = !_.isEmpty(policy) && !_.isEmpty(currencyList) ? `${policy.outputCurrency} - ${currencyList[policy.outputCurrency].symbol}` : '';
const submit = useCallback(
(values) => {
- if (props.policy.isPolicyUpdating) {
+ if (policy.isPolicyUpdating) {
return;
}
- const outputCurrency = values.currency;
- Policy.updateGeneralSettings(props.policy.id, values.name.trim(), outputCurrency);
+
+ Policy.updateGeneralSettings(policy.id, values.name.trim(), policy.outputCurrency);
Keyboard.dismiss();
- Navigation.goBack(ROUTES.WORKSPACE_INITIAL.getRoute(props.policy.id));
+ Navigation.goBack(ROUTES.WORKSPACE_INITIAL.getRoute(policy.id));
},
- [props.policy.id, props.policy.isPolicyUpdating],
+ [policy.id, policy.isPolicyUpdating, policy.outputCurrency],
);
const validate = useCallback((values) => {
@@ -81,33 +87,36 @@ function WorkspaceSettingsPage(props) {
return errors;
}, []);
- const policyName = lodashGet(props.policy, 'name', '');
+ const onPressCurrency = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_SETTINGS_CURRENCY.getRoute(policy.id)), [policy.id]);
+
+ const policyName = lodashGet(policy, 'name', '');
return (
{(hasVBA) => (
@@ -168,6 +179,5 @@ export default compose(
withOnyx({
currencyList: {key: ONYXKEYS.CURRENCY_LIST},
}),
- withLocalize,
withNetwork(),
)(WorkspaceSettingsPage);