From 9b4818eeb00c3cf99d18e6e97fa8b0d8d743b8b4 Mon Sep 17 00:00:00 2001 From: Thiago Brezinski Date: Wed, 20 Sep 2023 13:51:32 +0100 Subject: [PATCH 01/11] feat(workspace-settings): currency selector push to page --- src/ROUTES.ts | 2 + .../AppNavigator/ModalStackNavigators.js | 7 ++ src/libs/Navigation/linkingConfig.js | 3 + .../WorkspaceSettingsCurrencyPage.js | 106 ++++++++++++++++++ src/pages/workspace/WorkspaceSettingsPage.js | 40 +++---- 5 files changed, 136 insertions(+), 22 deletions(-) create mode 100644 src/pages/workspace/WorkspaceSettingsCurrencyPage.js diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 2c37116db395..8c3f60802ec3 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -190,6 +190,7 @@ export default { WORKSPACE_INVITE: 'workspace/:policyID/invite', WORKSPACE_INVITE_MESSAGE: 'workspace/:policyID/invite-message', WORKSPACE_SETTINGS: 'workspace/:policyID/settings', + WORKSPACE_SETTINGS_CURRENCY: 'workspace/:policyID/settings/currency', WORKSPACE_CARD: 'workspace/:policyID/card', WORKSPACE_REIMBURSE: 'workspace/:policyID/reimburse', WORKSPACE_RATE_AND_UNIT: 'workspace/:policyID/rateandunit', @@ -202,6 +203,7 @@ export default { getWorkspaceInviteRoute: (policyID: string) => `workspace/${policyID}/invite`, getWorkspaceInviteMessageRoute: (policyID: string) => `workspace/${policyID}/invite-message`, getWorkspaceSettingsRoute: (policyID: string) => `workspace/${policyID}/settings`, + getWorkspaceSettingsCurrencyRoute: (policyID: string) => `workspace/${policyID}/settings/currency`, getWorkspaceCardRoute: (policyID: string) => `workspace/${policyID}/card`, getWorkspaceReimburseRoute: (policyID: string) => `workspace/${policyID}/reimburse`, getWorkspaceRateAndUnitRoute: (policyID: string) => `workspace/${policyID}/rateandunit`, diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 392781a777db..eabce0686e14 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -599,6 +599,13 @@ const SettingsModalStackNavigator = createModalStackNavigator([ }, name: 'Workspace_Settings', }, + { + getComponent: () => { + const WorkspaceSettingsCurrencyPage = require('../../../pages/workspace/WorkspaceSettingsCurrencyPage').default; + return WorkspaceSettingsCurrencyPage; + }, + name: 'Workspace_Settings_Currency', + }, { getComponent: () => { const WorkspaceCardPage = require('../../../pages/workspace/card/WorkspaceCardPage').default; diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index 11d21d6d005c..925d786cc6b4 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -173,6 +173,9 @@ export default { Workspace_Settings: { path: ROUTES.WORKSPACE_SETTINGS, }, + Workspace_Settings_Currency: { + path: ROUTES.WORKSPACE_SETTINGS_CURRENCY, + }, Workspace_Card: { path: ROUTES.WORKSPACE_CARD, }, diff --git a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js new file mode 100644 index 000000000000..de554d95860a --- /dev/null +++ b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js @@ -0,0 +1,106 @@ +import React, {useState, useMemo, 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'; + +const propTypes = { + // List of available currencies + currencyList: PropTypes.objectOf( + PropTypes.shape({ + // Symbol for the currency + symbol: PropTypes.string, + }), + ), + ...policyPropTypes, +}; + +const defaultProps = { + currencyList: {}, + ...policyDefaultProps, +}; + +function WorkspaceSettingsCurrencyPage({currencyList, policy}) { + const {translate} = useLocalize(); + const [searchText, setSearchText] = useState(''); + + const getDisplayText = useCallback((currencyCode, currencySymbol) => `${currencyCode} - ${currencySymbol}`, []); + + const {sections, initiallyFocusedOptionKey} = useMemo(() => { + 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 selectedCurrencyCode; + + const currencyItems = _.map(filteredItems, (currencyCode) => { + const currency = currencyList[currencyCode]; + const isSelected = policy.outputCurrency === currencyCode; + + if (isSelected) { + selectedCurrencyCode = currencyCode; + } + + return { + text: getDisplayText(currencyCode, currency.symbol), + keyForList: currencyCode, + isSelected, + }; + }); + + return { + sections: [{data: currencyItems, indexOffset: 0}], + initiallyFocusedOptionKey: selectedCurrencyCode, + }; + }, [getDisplayText, currencyList, policy.outputCurrency, searchText]); + + const headerMessage = Boolean(searchText.trim()) && !sections[0].data.length ? translate('common.noResultsFound') : ''; + + const onSelectCurrency = (item) => { + Policy.updateGeneralSettings(policy.id, policy.name, item.keyForList); + Navigation.goBack(ROUTES.getWorkspaceSettingsRoute(policy.id)); + }; + + return ( + + Navigation.goBack(ROUTES.getWorkspaceSettingsRoute(policy.id))} + /> + + + + ); +} + +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 2a9576d5d8d3..00dcb99a92dc 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -1,8 +1,7 @@ -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'; @@ -12,7 +11,6 @@ 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,6 +23,8 @@ 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'; const propTypes = { // The currency list constant object from Onyx @@ -45,25 +45,19 @@ const defaultProps = { }; 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]); + const formattedCurrency = `${props.policy.outputCurrency} - ${props.currencyList[props.policy.outputCurrency].symbol}`; const submit = useCallback( (values) => { if (props.policy.isPolicyUpdating) { return; } - const outputCurrency = values.currency; - Policy.updateGeneralSettings(props.policy.id, values.name.trim(), outputCurrency); + + Policy.updateGeneralSettings(props.policy.id, values.name.trim(), props.policy.outputCurrency); Keyboard.dismiss(); Navigation.goBack(ROUTES.getWorkspaceInitialRoute(props.policy.id)); }, - [props.policy.id, props.policy.isPolicyUpdating], + [props.policy.id, props.policy.isPolicyUpdating, props.policy.outputCurrency], ); const validate = useCallback((values) => { @@ -93,7 +87,7 @@ function WorkspaceSettingsPage(props) {
- Navigation.navigate(ROUTES.getWorkspaceSettingsCurrencyRoute(props.policy.id))} /> + + {hasVBA ? props.translate('workspace.editor.currencyInputDisabledText') : props.translate('workspace.editor.currencyInputHelpText')} +
From 4847ec46bb5c67000fd09ad98b3de4f7820e117a Mon Sep 17 00:00:00 2001 From: Thiago Brezinski Date: Wed, 20 Sep 2023 14:05:21 +0100 Subject: [PATCH 02/11] chore: cleanup --- src/pages/workspace/WorkspaceSettingsCurrencyPage.js | 6 +++--- src/pages/workspace/WorkspaceSettingsPage.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js index de554d95860a..aa5e1701f8ce 100644 --- a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js +++ b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js @@ -14,10 +14,10 @@ import withPolicy, {policyDefaultProps, policyPropTypes} from './withPolicy'; import * as Policy from '../../libs/actions/Policy'; const propTypes = { - // List of available currencies + /** Constant, list of available currencies */ currencyList: PropTypes.objectOf( PropTypes.shape({ - // Symbol for the currency + /** Symbol of the currency */ symbol: PropTypes.string, }), ), @@ -88,8 +88,8 @@ function WorkspaceSettingsCurrencyPage({currencyList, policy}) { onChangeText={setSearchText} onSelectRow={onSelectCurrency} headerMessage={headerMessage} - showScrollIndicator initiallyFocusedOptionKey={initiallyFocusedOptionKey} + showScrollIndicator /> ); diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index 00dcb99a92dc..d680d6f38625 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -27,10 +27,10 @@ import MenuItemWithTopDescription from '../../components/MenuItemWithTopDescript import Text from '../../components/Text'; const propTypes = { - // The currency list constant object from Onyx + /** Constant, list of available currencies */ currencyList: PropTypes.objectOf( PropTypes.shape({ - // Symbol for the currency + /** Symbol of the currency */ symbol: PropTypes.string, }), ), From 2f2286d0573f280deca2ccee06d2c7612a5fd684 Mon Sep 17 00:00:00 2001 From: Thiago Brezinski Date: Wed, 20 Sep 2023 15:28:09 +0100 Subject: [PATCH 03/11] chore: address pr comments --- .../WorkspaceSettingsCurrencyPage.js | 56 +++++++++---------- src/pages/workspace/WorkspaceSettingsPage.js | 6 +- 2 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js index aa5e1701f8ce..649943cdbf56 100644 --- a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js +++ b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js @@ -18,7 +18,7 @@ const propTypes = { currencyList: PropTypes.objectOf( PropTypes.shape({ /** Symbol of the currency */ - symbol: PropTypes.string, + symbol: PropTypes.string.isRequired, }), ), ...policyPropTypes, @@ -29,45 +29,41 @@ const defaultProps = { ...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 getDisplayText = useCallback((currencyCode, currencySymbol) => `${currencyCode} - ${currencySymbol}`, []); - - const {sections, initiallyFocusedOptionKey} = useMemo(() => { - 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); - }); + const filteredItems = _.filter(currencyListKeys, (currencyCode) => { + const currency = currencyList[currencyCode]; + return getDisplayText(currencyCode, currency.symbol).toLowerCase().includes(trimmedText); + }); - let selectedCurrencyCode; + let initiallyFocusedOptionKey; - const currencyItems = _.map(filteredItems, (currencyCode) => { - const currency = currencyList[currencyCode]; - const isSelected = policy.outputCurrency === currencyCode; + const currencyItems = _.map(filteredItems, (currencyCode) => { + const currency = currencyList[currencyCode]; + const isSelected = policy.outputCurrency === currencyCode; - if (isSelected) { - selectedCurrencyCode = currencyCode; - } - - return { - text: getDisplayText(currencyCode, currency.symbol), - keyForList: currencyCode, - isSelected, - }; - }); + if (isSelected) { + initiallyFocusedOptionKey = currencyCode; + } return { - sections: [{data: currencyItems, indexOffset: 0}], - initiallyFocusedOptionKey: selectedCurrencyCode, + text: getDisplayText(currencyCode, currency.symbol), + keyForList: currencyCode, + isSelected, }; - }, [getDisplayText, currencyList, policy.outputCurrency, searchText]); + }); + + const sections = [{data: currencyItems, indexOffset: 0}]; + + const headerMessage = searchText.trim() && !sections[0].data.length ? translate('common.noResultsFound') : ''; - const headerMessage = Boolean(searchText.trim()) && !sections[0].data.length ? translate('common.noResultsFound') : ''; + const onBackButtonPress = useCallback(() => Navigation.goBack(ROUTES.getWorkspaceSettingsRoute(policy.id)), [policy.id]); const onSelectCurrency = (item) => { Policy.updateGeneralSettings(policy.id, policy.name, item.keyForList); @@ -78,7 +74,7 @@ function WorkspaceSettingsCurrencyPage({currencyList, policy}) { Navigation.goBack(ROUTES.getWorkspaceSettingsRoute(policy.id))} + onBackButtonPress={onBackButtonPress} /> { @@ -87,7 +87,7 @@ function WorkspaceSettingsPage(props) {
Date: Wed, 20 Sep 2023 15:46:56 +0100 Subject: [PATCH 04/11] chore: cleanup --- src/pages/workspace/WorkspaceSettingsCurrencyPage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js index 649943cdbf56..63457f491951 100644 --- a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js +++ b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js @@ -1,4 +1,4 @@ -import React, {useState, useMemo, useCallback} from 'react'; +import React, {useState, useCallback} from 'react'; import _ from 'underscore'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; From 55392425d06d0b9edcc2fc61e7878d9a0705a2af Mon Sep 17 00:00:00 2001 From: Thiago Brezinski Date: Wed, 20 Sep 2023 18:16:59 +0100 Subject: [PATCH 05/11] chore: address pr comments --- .../WorkspaceSettingsCurrencyPage.js | 2 +- src/pages/workspace/WorkspaceSettingsPage.js | 77 +++++++++++-------- 2 files changed, 45 insertions(+), 34 deletions(-) diff --git a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js index 63457f491951..a7b3739edfb2 100644 --- a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js +++ b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js @@ -61,7 +61,7 @@ function WorkspaceSettingsCurrencyPage({currencyList, policy}) { const sections = [{data: currencyItems, indexOffset: 0}]; - const headerMessage = searchText.trim() && !sections[0].data.length ? translate('common.noResultsFound') : ''; + const headerMessage = searchText.trim() && !currencyItems.length ? translate('common.noResultsFound') : ''; const onBackButtonPress = useCallback(() => Navigation.goBack(ROUTES.getWorkspaceSettingsRoute(policy.id)), [policy.id]); diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index d6dc5150d0cb..c472bfbfd7a6 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -4,7 +4,6 @@ import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; 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'; @@ -25,6 +24,7 @@ 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 = { /** Constant, list of available currencies */ @@ -34,8 +34,17 @@ const propTypes = { 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,20 +53,21 @@ const defaultProps = { ...policyDefaultProps, }; -function WorkspaceSettingsPage(props) { - const formattedCurrency = props.policy ? `${props.policy.outputCurrency} - ${props.currencyList[props.policy.outputCurrency].symbol}` : ''; +function WorkspaceSettingsPage({policy, currencyList, windowWidth, route}) { + const {translate} = useLocalize(); + const formattedCurrency = policy ? `${policy.outputCurrency} - ${currencyList[policy.outputCurrency].symbol}` : ''; const submit = useCallback( (values) => { - if (props.policy.isPolicyUpdating) { + if (policy.isPolicyUpdating) { return; } - Policy.updateGeneralSettings(props.policy.id, values.name.trim(), props.policy.outputCurrency); + Policy.updateGeneralSettings(policy.id, values.name.trim(), policy.outputCurrency); Keyboard.dismiss(); - Navigation.goBack(ROUTES.getWorkspaceInitialRoute(props.policy.id)); + Navigation.goBack(ROUTES.getWorkspaceInitialRoute(policy.id)); }, - [props.policy.id, props.policy.isPolicyUpdating, props.policy.outputCurrency], + [policy.id, policy.isPolicyUpdating, policy.outputCurrency], ); const validate = useCallback((values) => { @@ -75,18 +85,20 @@ function WorkspaceSettingsPage(props) { return errors; }, []); - const policyName = lodashGet(props.policy, 'name', ''); + const onPressCurrency = useCallback(() => Navigation.navigate(ROUTES.getWorkspaceSettingsCurrencyRoute(policy.id)), [policy.id]); + + const policyName = lodashGet(policy, 'name', ''); return ( {(hasVBA) => ( ( Policy.updateWorkspaceAvatar(lodashGet(props.policy, 'id', ''), file)} - onImageRemoved={() => Policy.deleteWorkspaceAvatar(lodashGet(props.policy, 'id', ''))} + isUsingDefaultAvatar={!lodashGet(policy, 'avatar', null)} + onImageSelected={(file) => Policy.updateWorkspaceAvatar(lodashGet(policy, 'id', ''), file)} + onImageRemoved={() => Policy.deleteWorkspaceAvatar(lodashGet(policy, 'id', ''))} editorMaskImage={Expensicons.ImageCropSquareMask} - pendingAction={lodashGet(props.policy, 'pendingFields.avatar', null)} - errors={lodashGet(props.policy, 'errorFields.avatar', null)} - onErrorClose={() => Policy.clearAvatarErrors(props.policy.id)} - previewSource={UserUtils.getFullSizeAvatar(props.policy.avatar, '')} - headerTitle={props.translate('workspace.common.workspaceAvatar')} - originalFileName={props.policy.originalFileName} + pendingAction={lodashGet(policy, 'pendingFields.avatar', null)} + errors={lodashGet(policy, 'errorFields.avatar', null)} + onErrorClose={() => Policy.clearAvatarErrors(policy.id)} + previewSource={UserUtils.getFullSizeAvatar(policy.avatar, '')} + headerTitle={translate('workspace.common.workspaceAvatar')} + originalFileName={policy.originalFileName} /> - + Navigation.navigate(ROUTES.getWorkspaceSettingsCurrencyRoute(props.policy.id))} + onPress={onPressCurrency} /> - {hasVBA ? props.translate('workspace.editor.currencyInputDisabledText') : props.translate('workspace.editor.currencyInputHelpText')} + {hasVBA ? translate('workspace.editor.currencyInputDisabledText') : translate('workspace.editor.currencyInputHelpText')} @@ -164,6 +176,5 @@ export default compose( withOnyx({ currencyList: {key: ONYXKEYS.CURRENCY_LIST}, }), - withLocalize, withNetwork(), )(WorkspaceSettingsPage); From 43140ea100b2c7737db7fc2f487913a2fa37d3b6 Mon Sep 17 00:00:00 2001 From: Thiago Brezinski Date: Thu, 21 Sep 2023 12:07:58 +0100 Subject: [PATCH 06/11] chore: fix submit button style --- src/components/Form.js | 7 ++++++- src/pages/workspace/WorkspaceSettingsPage.js | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/Form.js b/src/components/Form.js index ef6c3ea10474..be73f448548b 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 diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index c472bfbfd7a6..2ff1491c7ed9 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -100,6 +100,7 @@ function WorkspaceSettingsPage({policy, currencyList, windowWidth, route}) { formID={ONYXKEYS.FORMS.WORKSPACE_SETTINGS_FORM} submitButtonText={translate('workspace.editor.save')} style={styles.flexGrow1} + submitButtonStyles={[styles.mh5]} scrollContextEnabled validate={validate} onSubmit={submit} From 86b650f4aabc0223a436b4d760909a9636f32980 Mon Sep 17 00:00:00 2001 From: Thiago Brezinski Date: Thu, 21 Sep 2023 12:14:07 +0100 Subject: [PATCH 07/11] chore: cleanup --- src/components/Form.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Form.js b/src/components/Form.js index be73f448548b..7d62d936c159 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -477,6 +477,7 @@ function Form(props) { props.isSubmitActionDangerous, props.isSubmitButtonVisible, props.submitButtonText, + props.submitButtonStyles, ], ); From 4dff71dc234b62908cf6a599a0079e1626a0f17c Mon Sep 17 00:00:00 2001 From: Thiago Brezinski Date: Wed, 27 Sep 2023 11:54:11 +0100 Subject: [PATCH 08/11] chore: fix get route calls --- src/pages/workspace/WorkspaceSettingsCurrencyPage.js | 4 ++-- src/pages/workspace/WorkspaceSettingsPage.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js index a7b3739edfb2..b8d3b4404eae 100644 --- a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js +++ b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js @@ -63,11 +63,11 @@ function WorkspaceSettingsCurrencyPage({currencyList, policy}) { const headerMessage = searchText.trim() && !currencyItems.length ? translate('common.noResultsFound') : ''; - const onBackButtonPress = useCallback(() => Navigation.goBack(ROUTES.getWorkspaceSettingsRoute(policy.id)), [policy.id]); + 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.getWorkspaceSettingsRoute(policy.id)); + Navigation.goBack(ROUTES.WORKSPACE_SETTINGS.getRoute(policy.id)); }; return ( diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index 93a55f0c0e4b..204efc9a1fe1 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -85,7 +85,7 @@ function WorkspaceSettingsPage({policy, currencyList, windowWidth, route}) { return errors; }, []); - const onPressCurrency = useCallback(() => Navigation.navigate(ROUTES.getWorkspaceSettingsCurrencyRoute(policy.id)), [policy.id]); + const onPressCurrency = useCallback(() => Navigation.navigate(ROUTES.WORKSPACE_SETTINGS_CURRENCY.getRoute(policy.id)), [policy.id]); const policyName = lodashGet(policy, 'name', ''); From a47040071f1a5b3fbdea22163bad01ce06aff6a3 Mon Sep 17 00:00:00 2001 From: Thiago Brezinski Date: Wed, 27 Sep 2023 13:51:26 +0100 Subject: [PATCH 09/11] chore: fix linkingConfig and empty currencyList --- src/libs/Navigation/linkingConfig.js | 2 +- src/pages/workspace/WorkspaceSettingsPage.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index ac4fe1c77654..6d0b1f3f78cf 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -174,7 +174,7 @@ export default { path: ROUTES.WORKSPACE_SETTINGS.route, }, Workspace_Settings_Currency: { - path: ROUTES.WORKSPACE_SETTINGS_CURRENCY, + path: ROUTES.WORKSPACE_SETTINGS_CURRENCY.route, }, Workspace_Card: { path: ROUTES.WORKSPACE_CARD.route, diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index 204efc9a1fe1..2de7ffdde1e5 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -2,6 +2,7 @@ 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 styles from '../../styles/styles'; @@ -55,7 +56,8 @@ const defaultProps = { function WorkspaceSettingsPage({policy, currencyList, windowWidth, route}) { const {translate} = useLocalize(); - const formattedCurrency = policy ? `${policy.outputCurrency} - ${currencyList[policy.outputCurrency].symbol}` : ''; + + const formattedCurrency = policy && !_.isEmpty(currencyList) ? `${policy.outputCurrency} - ${currencyList[policy.outputCurrency].symbol}` : ''; const submit = useCallback( (values) => { From 50ee3a862cd0cd2babab34c8e42cafbd202026fe Mon Sep 17 00:00:00 2001 From: Thiago Brezinski Date: Thu, 5 Oct 2023 09:12:15 +0100 Subject: [PATCH 10/11] chore: fix lint --- src/ROUTES.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index bc79f1597644..38a660e535a4 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -288,7 +288,7 @@ export default { }, WORKSPACE_SETTINGS_CURRENCY: { route: 'workspace/:policyID/settings/currency', - getRoute: (policyID: string) => `workspace/${policyID}/settings/currency` + getRoute: (policyID: string) => `workspace/${policyID}/settings/currency`, }, WORKSPACE_CARD: { route: 'workspace/:policyID/card', From c559c5cfa2d95149bceb8c47fe5b135f3ac00589 Mon Sep 17 00:00:00 2001 From: Thiago Brezinski Date: Fri, 6 Oct 2023 09:24:31 +0100 Subject: [PATCH 11/11] feat(workspace-settings): currency page offline view --- .../WorkspaceSettingsCurrencyPage.js | 44 ++++++++++++------- src/pages/workspace/WorkspaceSettingsPage.js | 2 +- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js index b8d3b4404eae..9c757b730cef 100644 --- a/src/pages/workspace/WorkspaceSettingsCurrencyPage.js +++ b/src/pages/workspace/WorkspaceSettingsCurrencyPage.js @@ -12,6 +12,8 @@ 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 */ @@ -71,26 +73,36 @@ function WorkspaceSettingsCurrencyPage({currencyList, policy}) { }; 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; diff --git a/src/pages/workspace/WorkspaceSettingsPage.js b/src/pages/workspace/WorkspaceSettingsPage.js index 2de7ffdde1e5..fd975ebc9247 100644 --- a/src/pages/workspace/WorkspaceSettingsPage.js +++ b/src/pages/workspace/WorkspaceSettingsPage.js @@ -57,7 +57,7 @@ const defaultProps = { function WorkspaceSettingsPage({policy, currencyList, windowWidth, route}) { const {translate} = useLocalize(); - const formattedCurrency = policy && !_.isEmpty(currencyList) ? `${policy.outputCurrency} - ${currencyList[policy.outputCurrency].symbol}` : ''; + const formattedCurrency = !_.isEmpty(policy) && !_.isEmpty(currencyList) ? `${policy.outputCurrency} - ${currencyList[policy.outputCurrency].symbol}` : ''; const submit = useCallback( (values) => {