From 002bcf025ae3979271a85ab494b37a5ee8d755af Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Thu, 7 Sep 2023 11:28:19 +0100 Subject: [PATCH 01/22] feat: tag picker component --- src/CONST.ts | 1 + src/ONYXKEYS.ts | 3 + src/components/TagPicker/index.js | 90 +++++++++++++++++++ .../TagPicker/tagPickerPropTypes.js | 39 ++++++++ 4 files changed, 133 insertions(+) create mode 100644 src/components/TagPicker/index.js create mode 100644 src/components/TagPicker/tagPickerPropTypes.js diff --git a/src/CONST.ts b/src/CONST.ts index 56f61536b3cb..795d09d48322 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -235,6 +235,7 @@ const CONST = { TASKS: 'tasks', THREADS: 'threads', CUSTOM_STATUS: 'customStatus', + NEW_DOT_TAGS: 'newDotTags', }, BUTTON_STATES: { DEFAULT: 'default', diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index b3ef88cc0094..d8d584df18bf 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -236,12 +236,15 @@ const ONYXKEYS = { // Max width supported for HTML element MAX_CANVAS_WIDTH: 'maxCanvasWidth', + RECENTLY_USED_POLICY_TAGS: 'recentlyUsedPolicyTags_', + /** Collection Keys */ COLLECTION: { DOWNLOAD: 'download_', POLICY: 'policy_', POLICY_MEMBERS: 'policyMembers_', POLICY_CATEGORIES: 'policyCategories_', + POLICY_TAGS: 'policyTags_', WORKSPACE_INVITE_MEMBERS_DRAFT: 'workspaceInviteMembersDraft_', REPORT: 'report_', REPORT_ACTIONS: 'reportActions_', diff --git a/src/components/TagPicker/index.js b/src/components/TagPicker/index.js new file mode 100644 index 000000000000..61856c1033cc --- /dev/null +++ b/src/components/TagPicker/index.js @@ -0,0 +1,90 @@ +import React, {useMemo} from 'react'; +import _ from 'underscore'; +import lodashGet from 'lodash/get'; +import {withOnyx} from 'react-native-onyx'; +import ONYXKEYS from '../../ONYXKEYS'; +import styles from '../../styles/styles'; +import Navigation from '../../libs/Navigation/Navigation'; +import ROUTES from '../../ROUTES'; +import useLocalize from '../../hooks/useLocalize'; +import * as OptionsListUtils from '../../libs/OptionsListUtils'; +import OptionsSelector from '../OptionsSelector'; +import {propTypes, defaultProps} from './tagPickerPropTypes'; + +function TagPicker({policyTags, reportID, iouType, iou}) { + const {translate} = useLocalize(); + + const selectedOptions = useMemo(() => { + if (!iou.tag) { + return []; + } + + return [ + { + name: iou.tag, + enabled: true, + accountID: null, + }, + ]; + }, [iou.tag]); + + // Only shows one section, which will be the default behavior if there are + // less than 8 policy tags + // TODO: support sections with search + const sections = useMemo(() => { + const tagList = _.chain(policyTags) + .values() + .map((tag) => ({ + text: tag.name, + keyForList: tag.name, + tooltipText: tag.name, + })) + .value(); + + return [ + { + data: tagList, + }, + ]; + }, [policyTags]); + + const headerMessage = OptionsListUtils.getHeaderMessage(lodashGet(sections, '[0].data.length', 0) > 0, false, ''); + + const navigateBack = () => { + Navigation.goBack(ROUTES.getMoneyRequestConfirmationRoute(iouType, reportID)); + }; + + const updateTag = () => { + // TODO: add logic to save the selected tag + navigateBack(); + }; + + return ( + + ); +} + +TagPicker.displayName = 'TagPicker'; +TagPicker.propTypes = propTypes; +TagPicker.defaultProps = defaultProps; + +export default withOnyx({ + policyTags: { + key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, + }, + recentlyUsedPolicyTags: { + key: ({policyID}) => `${ONYXKEYS.RECENTLY_USED_POLICY_TAGS}${policyID}`, + }, + iou: { + key: ONYXKEYS.IOU, + }, +})(TagPicker); diff --git a/src/components/TagPicker/tagPickerPropTypes.js b/src/components/TagPicker/tagPickerPropTypes.js new file mode 100644 index 000000000000..fb3942d94c80 --- /dev/null +++ b/src/components/TagPicker/tagPickerPropTypes.js @@ -0,0 +1,39 @@ +import PropTypes from 'prop-types'; +import tagPropTypes from '../tagPropTypes'; + +const propTypes = { + /** The report ID of the IOU */ + reportID: PropTypes.string.isRequired, + + /** The policyID we are getting tags for */ + policyID: PropTypes.string.isRequired, + + /** The type of IOU report, i.e. bill, request, send */ + iouType: PropTypes.string.isRequired, + + /** Callback to submit the selected tag */ + onSubmit: PropTypes.func, + + /* Onyx Props */ + /** Collection of tags attached to a policy */ + policyTags: PropTypes.objectOf(tagPropTypes), + + /* Onyx Props */ + /** List of recently used tags */ + recentlyUsedPolicyTags: PropTypes.arrayOf(PropTypes.string), + + /* Onyx Props */ + /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ + iou: PropTypes.shape({ + tag: PropTypes.string, + }), +}; + +const defaultProps = { + policyID: '', + policyTags: {}, + recentlyUsedPolicyTags: [], + iou: {}, +}; + +export {propTypes, defaultProps}; From c0e23527ae3bba9c256dd2f78e4d7a66346179ca Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Thu, 7 Sep 2023 11:31:22 +0100 Subject: [PATCH 02/22] feat: money request tag page and tag menu item --- src/ROUTES.js | 2 + .../MoneyRequestConfirmationList.js | 32 ++++++++ src/components/tagPropTypes.js | 9 +++ src/languages/en.ts | 2 + src/languages/es.ts | 2 + .../AppNavigator/ModalStackNavigators.js | 7 ++ src/libs/Navigation/linkingConfig.js | 1 + src/libs/Permissions.js | 9 +++ src/pages/iou/MoneyRequestTagPage.js | 74 +++++++++++++++++++ 9 files changed, 138 insertions(+) create mode 100644 src/components/tagPropTypes.js create mode 100644 src/pages/iou/MoneyRequestTagPage.js diff --git a/src/ROUTES.js b/src/ROUTES.js index b38ce25f590f..ae4b45c19437 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -92,6 +92,7 @@ export default { MONEY_REQUEST_CURRENCY: ':iouType/new/currency/:reportID?', MONEY_REQUEST_DESCRIPTION: ':iouType/new/description/:reportID?', MONEY_REQUEST_CATEGORY: ':iouType/new/category/:reportID?', + MONEY_REQUEST_TAG: ':iouType/new/tag/:reportID?', MONEY_REQUEST_MERCHANT: ':iouType/new/merchant/:reportID?', MONEY_REQUEST_MANUAL_TAB: ':iouType/new/:reportID?/manual', MONEY_REQUEST_SCAN_TAB: ':iouType/new/:reportID?/scan', @@ -108,6 +109,7 @@ export default { 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}`, + getMoneyRequestTagRoute: (iouType, reportID = '') => `${iouType}/new/tag/${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/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index a7695c939907..ea2e213b4c26 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -8,6 +8,7 @@ import lodashGet from 'lodash/get'; import styles from '../styles/styles'; import * as ReportUtils from '../libs/ReportUtils'; import * as OptionsListUtils from '../libs/OptionsListUtils'; +import Permissions from '../libs/Permissions'; import OptionsSelector from './OptionsSelector'; import ONYXKEYS from '../ONYXKEYS'; import compose from '../libs/compose'; @@ -29,6 +30,7 @@ import Image from './Image'; import useLocalize from '../hooks/useLocalize'; import * as ReceiptUtils from '../libs/ReceiptUtils'; import categoryPropTypes from './categoryPropTypes'; +import tagPropTypes from './tagPropTypes'; import ConfirmedRoute from './ConfirmedRoute'; import transactionPropTypes from './transactionPropTypes'; import DistanceRequestUtils from '../libs/DistanceRequestUtils'; @@ -68,6 +70,9 @@ const propTypes = { /** IOU Category */ iouCategory: PropTypes.string, + /** IOU Tag */ + iouTag: PropTypes.string, + /** Selected participants from MoneyRequestModal with login / accountID */ selectedParticipants: PropTypes.arrayOf(optionPropTypes).isRequired, @@ -109,6 +114,14 @@ const propTypes = { /** Collection of categories attached to a policy */ policyCategories: PropTypes.objectOf(categoryPropTypes), + /* Onyx Props */ + /** Collection of tags attached to a policy */ + policyTags: PropTypes.objectOf(tagPropTypes), + + /* Onyx Props */ + /* Beta features list */ + betas: PropTypes.arrayOf(PropTypes.string), + /** ID of the transaction that represents the money request */ transactionID: PropTypes.string, @@ -151,6 +164,8 @@ const defaultProps = { receiptSource: '', listStyles: [], policyCategories: {}, + policyTags: {}, + betas: [], transactionID: '', transaction: {}, mileageRate: {unit: CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES, rate: 0, currency: 'USD'}, @@ -172,6 +187,7 @@ function MoneyRequestConfirmationList(props) { const distance = lodashGet(transaction, 'routes.route0.distance', 0); const shouldCalculateDistanceAmount = props.isDistanceRequest && props.iouAmount === 0; const shouldCategoryEditable = !_.isEmpty(props.policyCategories) && !props.isDistanceRequest; + const shouldTagsBeEditable = !_.isEmpty(props.policyTags) && Permissions.canUseNewDotTags(props.betas); const formattedAmount = CurrencyUtils.convertToDisplayString( shouldCalculateDistanceAmount ? DistanceRequestUtils.getDistanceRequestAmount(distance, unit, rate) : props.iouAmount, @@ -494,6 +510,16 @@ function MoneyRequestConfirmationList(props) { disabled={didConfirm || props.isReadOnly} /> )} + {shouldTagsBeEditable && ( + Navigation.navigate(ROUTES.getMoneyRequestTagRoute(props.iouType, props.reportID))} + style={[styles.moneyRequestMenuItem, styles.mb2]} + disabled={didConfirm || props.isReadOnly} + /> + )} )} @@ -509,9 +535,15 @@ export default compose( session: { key: ONYXKEYS.SESSION, }, + betas: { + key: ONYXKEYS.BETAS, + }, policyCategories: { key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_CATEGORIES}${policyID}`, }, + policyTags: { + key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, + }, mileageRate: { key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY}${policyID}`, selector: DistanceRequestUtils.getDefaultMileageRate, diff --git a/src/components/tagPropTypes.js b/src/components/tagPropTypes.js new file mode 100644 index 000000000000..09ba8d403cf8 --- /dev/null +++ b/src/components/tagPropTypes.js @@ -0,0 +1,9 @@ +import PropTypes from 'prop-types'; + +export default PropTypes.shape({ + /** Name of a tag */ + name: PropTypes.string.isRequired, + + /** Flag that determines if a tag is active and able to be selected */ + enabled: PropTypes.bool.isRequired, +}); diff --git a/src/languages/en.ts b/src/languages/en.ts index af7957e1a560..4bea3f64198d 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -230,6 +230,7 @@ export default { showMore: 'Show more', merchant: 'Merchant', category: 'Category', + tag: 'Tag', receipt: 'Receipt', replace: 'Replace', distance: 'Distance', @@ -525,6 +526,7 @@ export default { pendingConversionMessage: "Total will update when you're back online", threadRequestReportName: ({formattedAmount, comment}: ThreadRequestReportNameParams) => `${formattedAmount} request${comment ? ` for ${comment}` : ''}`, threadSentMoneyReportName: ({formattedAmount, comment}: ThreadSentMoneyReportNameParams) => `${formattedAmount} sent${comment ? ` for ${comment}` : ''}`, + tagSelection: 'Select a tag to add additional organization to your money', error: { invalidSplit: 'Split amounts do not equal total amount', other: 'Unexpected error, please try again later', diff --git a/src/languages/es.ts b/src/languages/es.ts index f950733b005c..5387c33d1939 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -229,6 +229,7 @@ export default { showMore: 'Mostrar más', merchant: 'Comerciante', category: 'Categoría', + tag: 'Etiqueta', receipt: 'Recibo', replace: 'Sustituir', distance: 'Distancia', @@ -526,6 +527,7 @@ export default { pendingConversionMessage: 'El total se actualizará cuando estés online', threadRequestReportName: ({formattedAmount, comment}: ThreadRequestReportNameParams) => `Solicitud de ${formattedAmount}${comment ? ` para ${comment}` : ''}`, threadSentMoneyReportName: ({formattedAmount, comment}: ThreadSentMoneyReportNameParams) => `${formattedAmount} enviado${comment ? ` para ${comment}` : ''}`, + tagSelection: '', error: { invalidSplit: 'La suma de las partes no equivale al monto total', other: 'Error inesperado, por favor inténtalo más tarde', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 2adaf0397a2c..851f7aff3a8d 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -90,6 +90,13 @@ const MoneyRequestModalStackNavigator = createModalStackNavigator([ }, name: 'Money_Request_Category', }, + { + getComponent: () => { + const MoneyRequestTagPage = require('../../../pages/iou/MoneyRequestTagPage').default; + return MoneyRequestTagPage; + }, + name: 'Money_Request_Tag', + }, { getComponent: () => { const MoneyRequestMerchantPage = require('../../../pages/iou/MoneyRequestMerchantPage').default; diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index ee3054e02f96..00bd74163418 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -318,6 +318,7 @@ export default { Money_Request_Currency: ROUTES.MONEY_REQUEST_CURRENCY, Money_Request_Description: ROUTES.MONEY_REQUEST_DESCRIPTION, Money_Request_Category: ROUTES.MONEY_REQUEST_CATEGORY, + Money_Request_Tag: ROUTES.MONEY_REQUEST_TAG, 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/libs/Permissions.js b/src/libs/Permissions.js index f37cd5bb5bf3..52cd91cc072e 100644 --- a/src/libs/Permissions.js +++ b/src/libs/Permissions.js @@ -86,6 +86,14 @@ function canUseCustomStatus(betas) { return _.contains(betas, CONST.BETAS.CUSTOM_STATUS) || canUseAllBetas(betas); } +/** + * @param {Array} betas + * @returns {Boolean} + */ +function canUseNewDotTags(betas) { + return _.contains(betas, CONST.BETAS.NEW_DOT_TAGS) || canUseAllBetas(betas); +} + /** * Link previews are temporarily disabled. * @returns {Boolean} @@ -104,5 +112,6 @@ export default { canUsePolicyRooms, canUseTasks, canUseCustomStatus, + canUseNewDotTags, canUseLinkPreviews, }; diff --git a/src/pages/iou/MoneyRequestTagPage.js b/src/pages/iou/MoneyRequestTagPage.js new file mode 100644 index 000000000000..fa1f2e886521 --- /dev/null +++ b/src/pages/iou/MoneyRequestTagPage.js @@ -0,0 +1,74 @@ +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 TagPicker from '../../components/TagPicker'; +import Text from '../../components/Text'; +import ONYXKEYS from '../../ONYXKEYS'; +import reportPropTypes from '../reportPropTypes'; +import styles from '../../styles/styles'; + +const propTypes = { + /** Navigation route context info provided by react navigation */ + route: PropTypes.shape({ + /** Route specific parameters used on this screen via route :iouType/new/tag/: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 MoneyRequestTagPage({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 ( + + + {translate('iou.tagSelection')} + + + ); +} + +MoneyRequestTagPage.displayName = 'MoneyRequestTagPage'; +MoneyRequestTagPage.propTypes = propTypes; +MoneyRequestTagPage.defaultProps = defaultProps; + +export default withOnyx({ + report: { + key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${lodashGet(route, 'params.reportID', '')}`, + }, +})(MoneyRequestTagPage); From 6e6ec88de33b64e9657e64a3ca6055301c4034c7 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Thu, 7 Sep 2023 11:31:48 +0100 Subject: [PATCH 03/22] feat: pass IOU tag to confirmation list --- src/pages/iou/steps/MoneyRequestConfirmPage.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/iou/steps/MoneyRequestConfirmPage.js b/src/pages/iou/steps/MoneyRequestConfirmPage.js index 178179f31745..bcc089adb236 100644 --- a/src/pages/iou/steps/MoneyRequestConfirmPage.js +++ b/src/pages/iou/steps/MoneyRequestConfirmPage.js @@ -272,6 +272,7 @@ function MoneyRequestConfirmPage(props) { iouAmount={props.iou.amount} iouComment={props.iou.comment} iouCurrencyCode={props.iou.currency} + iouTag={props.iou.tag} onConfirm={createTransaction} onSendMoney={sendMoney} onSelectParticipant={(option) => { From 412e191afc4ec94f60ed48d682f98b25e8e0f2c6 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Thu, 7 Sep 2023 12:29:55 +0100 Subject: [PATCH 04/22] feat: fetch reportID from IOU participants --- .../TagPicker/tagPickerPropTypes.js | 7 ++--- src/pages/iou/MoneyRequestTagPage.js | 30 ++++++++++++++----- src/pages/iou/propTypes/index.js | 4 +++ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/components/TagPicker/tagPickerPropTypes.js b/src/components/TagPicker/tagPickerPropTypes.js index fb3942d94c80..d1705670fc0b 100644 --- a/src/components/TagPicker/tagPickerPropTypes.js +++ b/src/components/TagPicker/tagPickerPropTypes.js @@ -1,5 +1,6 @@ import PropTypes from 'prop-types'; import tagPropTypes from '../tagPropTypes'; +import {iouPropTypes, iouDefaultProps} from '../../pages/iou/propTypes'; const propTypes = { /** The report ID of the IOU */ @@ -24,16 +25,14 @@ const propTypes = { /* Onyx Props */ /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ - iou: PropTypes.shape({ - tag: PropTypes.string, - }), + iou: iouPropTypes, }; const defaultProps = { policyID: '', policyTags: {}, recentlyUsedPolicyTags: [], - iou: {}, + iou: iouDefaultProps, }; export {propTypes, defaultProps}; diff --git a/src/pages/iou/MoneyRequestTagPage.js b/src/pages/iou/MoneyRequestTagPage.js index fa1f2e886521..d7562a140468 100644 --- a/src/pages/iou/MoneyRequestTagPage.js +++ b/src/pages/iou/MoneyRequestTagPage.js @@ -2,6 +2,7 @@ import React from 'react'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; import {withOnyx} from 'react-native-onyx'; +import compose from '../../libs/compose'; import ROUTES from '../../ROUTES'; import Navigation from '../../libs/Navigation/Navigation'; import useLocalize from '../../hooks/useLocalize'; @@ -12,6 +13,7 @@ import Text from '../../components/Text'; import ONYXKEYS from '../../ONYXKEYS'; import reportPropTypes from '../reportPropTypes'; import styles from '../../styles/styles'; +import {iouPropTypes, iouDefaultProps} from './propTypes'; const propTypes = { /** Navigation route context info provided by react navigation */ @@ -28,20 +30,24 @@ const propTypes = { /** The report currently being used */ report: reportPropTypes, + + /* Onyx Props */ + /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ + iou: iouPropTypes, }; const defaultProps = { report: {}, + iou: iouDefaultProps, }; function MoneyRequestTagPage({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)); + Navigation.goBack(ROUTES.getMoneyRequestConfirmationRoute(iouType, report.reportID)); }; return ( @@ -56,7 +62,7 @@ function MoneyRequestTagPage({route, report}) { {translate('iou.tagSelection')} @@ -67,8 +73,16 @@ MoneyRequestTagPage.displayName = 'MoneyRequestTagPage'; MoneyRequestTagPage.propTypes = propTypes; MoneyRequestTagPage.defaultProps = defaultProps; -export default withOnyx({ - report: { - key: ({route}) => `${ONYXKEYS.COLLECTION.REPORT}${lodashGet(route, 'params.reportID', '')}`, - }, -})(MoneyRequestTagPage); +export default compose( + withOnyx({ + iou: { + key: ONYXKEYS.IOU, + }, + }), + withOnyx({ + report: { + // Fetch report ID from IOU participants if no report ID is set in route + key: ({route, iou}) => `${ONYXKEYS.COLLECTION.REPORT}${lodashGet(route, 'params.reportID', '') || lodashGet(iou, 'participants.0.reportID', '')}`, + }, + }), +)(MoneyRequestTagPage); diff --git a/src/pages/iou/propTypes/index.js b/src/pages/iou/propTypes/index.js index c7559323ebc1..5ecd00d11876 100644 --- a/src/pages/iou/propTypes/index.js +++ b/src/pages/iou/propTypes/index.js @@ -18,6 +18,9 @@ const iouPropTypes = PropTypes.shape({ /** The merchant name */ merchant: PropTypes.string, + /** The tag */ + tag: PropTypes.string, + /** Date that the request was created */ created: PropTypes.string, @@ -34,6 +37,7 @@ const iouDefaultProps = { currency: CONST.CURRENCY.USD, comment: '', merchant: '', + tag: '', created: '', participants: [], receiptPath: '', From e2cf2b568611e0abfbb5e1b15055e802525c5c22 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Thu, 7 Sep 2023 13:35:32 +0100 Subject: [PATCH 05/22] feat: add missing translation --- src/languages/es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 5387c33d1939..2e2cfd164a6a 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -527,7 +527,7 @@ export default { pendingConversionMessage: 'El total se actualizará cuando estés online', threadRequestReportName: ({formattedAmount, comment}: ThreadRequestReportNameParams) => `Solicitud de ${formattedAmount}${comment ? ` para ${comment}` : ''}`, threadSentMoneyReportName: ({formattedAmount, comment}: ThreadSentMoneyReportNameParams) => `${formattedAmount} enviado${comment ? ` para ${comment}` : ''}`, - tagSelection: '', + tagSelection: 'Seleccione una etiqueta para agregar una organización adicional a tu dinero.', error: { invalidSplit: 'La suma de las partes no equivale al monto total', other: 'Error inesperado, por favor inténtalo más tarde', From 7aca47c3b9daa0aa9d3918553b88770c92859604 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Thu, 7 Sep 2023 13:37:47 +0100 Subject: [PATCH 06/22] fix: small typo --- src/components/MoneyRequestConfirmationList.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index ea2e213b4c26..0e28939eaece 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -187,7 +187,7 @@ function MoneyRequestConfirmationList(props) { const distance = lodashGet(transaction, 'routes.route0.distance', 0); const shouldCalculateDistanceAmount = props.isDistanceRequest && props.iouAmount === 0; const shouldCategoryEditable = !_.isEmpty(props.policyCategories) && !props.isDistanceRequest; - const shouldTagsBeEditable = !_.isEmpty(props.policyTags) && Permissions.canUseNewDotTags(props.betas); + const shouldTagBeEditable = !_.isEmpty(props.policyTags) && Permissions.canUseNewDotTags(props.betas); const formattedAmount = CurrencyUtils.convertToDisplayString( shouldCalculateDistanceAmount ? DistanceRequestUtils.getDistanceRequestAmount(distance, unit, rate) : props.iouAmount, @@ -510,7 +510,7 @@ function MoneyRequestConfirmationList(props) { disabled={didConfirm || props.isReadOnly} /> )} - {shouldTagsBeEditable && ( + {shouldTagBeEditable && ( Date: Thu, 7 Sep 2023 13:54:29 +0100 Subject: [PATCH 07/22] fix: lint errors --- src/pages/iou/MoneyRequestTagPage.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/pages/iou/MoneyRequestTagPage.js b/src/pages/iou/MoneyRequestTagPage.js index d7562a140468..f02164e77b65 100644 --- a/src/pages/iou/MoneyRequestTagPage.js +++ b/src/pages/iou/MoneyRequestTagPage.js @@ -13,7 +13,6 @@ import Text from '../../components/Text'; import ONYXKEYS from '../../ONYXKEYS'; import reportPropTypes from '../reportPropTypes'; import styles from '../../styles/styles'; -import {iouPropTypes, iouDefaultProps} from './propTypes'; const propTypes = { /** Navigation route context info provided by react navigation */ @@ -30,15 +29,10 @@ const propTypes = { /** The report currently being used */ report: reportPropTypes, - - /* Onyx Props */ - /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ - iou: iouPropTypes, }; const defaultProps = { report: {}, - iou: iouDefaultProps, }; function MoneyRequestTagPage({route, report}) { From 51b6979b4ce37ee859af5d9c0cea9f5d78c787ee Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Thu, 7 Sep 2023 17:03:54 +0100 Subject: [PATCH 08/22] docs: add missing comment for recently used tags of a policy --- src/ONYXKEYS.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index d8d584df18bf..342e69a77dfe 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -236,6 +236,7 @@ const ONYXKEYS = { // Max width supported for HTML element MAX_CANVAS_WIDTH: 'maxCanvasWidth', + // A list of recently used tags of a policy RECENTLY_USED_POLICY_TAGS: 'recentlyUsedPolicyTags_', /** Collection Keys */ From 92cf2a69c9aa7ed0b2199eed74ba4f7cb0393c5c Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Fri, 8 Sep 2023 11:05:16 +0100 Subject: [PATCH 09/22] feat: add type and change collection key according to category --- src/ONYXKEYS.ts | 5 ++--- src/components/TagPicker/index.js | 4 ++-- src/components/TagPicker/tagPickerPropTypes.js | 4 ++-- src/types/onyx/RecentlyUsedTags.ts | 3 +++ src/types/onyx/index.ts | 2 ++ 5 files changed, 11 insertions(+), 7 deletions(-) create mode 100644 src/types/onyx/RecentlyUsedTags.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 342e69a77dfe..a34b53f6c7ef 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -236,9 +236,6 @@ const ONYXKEYS = { // Max width supported for HTML element MAX_CANVAS_WIDTH: 'maxCanvasWidth', - // A list of recently used tags of a policy - RECENTLY_USED_POLICY_TAGS: 'recentlyUsedPolicyTags_', - /** Collection Keys */ COLLECTION: { DOWNLOAD: 'download_', @@ -257,6 +254,7 @@ const ONYXKEYS = { REPORT_USER_IS_TYPING: 'reportUserIsTyping_', SECURITY_GROUP: 'securityGroup_', TRANSACTION: 'transactions_', + POLICY_RECENTLY_USED_TAGS: 'policyRecentlyUsedTags_', /** This is deprecated, but needed for a migration, so we still need to include it here so that it will be initialized in Onyx.init */ DEPRECATED_POLICY_MEMBER_LIST: 'policyMemberList_', @@ -393,6 +391,7 @@ type OnyxValues = { [ONYXKEYS.COLLECTION.REPORT_USER_IS_TYPING]: boolean; [ONYXKEYS.COLLECTION.SECURITY_GROUP]: OnyxTypes.SecurityGroup; [ONYXKEYS.COLLECTION.TRANSACTION]: OnyxTypes.Transaction; + [ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS]: OnyxTypes.RecentlyUsedTags; // Forms [ONYXKEYS.FORMS.ADD_DEBIT_CARD_FORM]: OnyxTypes.AddDebitCardForm; diff --git a/src/components/TagPicker/index.js b/src/components/TagPicker/index.js index 61856c1033cc..daa26ca9d58c 100644 --- a/src/components/TagPicker/index.js +++ b/src/components/TagPicker/index.js @@ -81,8 +81,8 @@ export default withOnyx({ policyTags: { key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${policyID}`, }, - recentlyUsedPolicyTags: { - key: ({policyID}) => `${ONYXKEYS.RECENTLY_USED_POLICY_TAGS}${policyID}`, + policyRecentlyUsedTags: { + key: ({policyID}) => `${ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS}${policyID}`, }, iou: { key: ONYXKEYS.IOU, diff --git a/src/components/TagPicker/tagPickerPropTypes.js b/src/components/TagPicker/tagPickerPropTypes.js index d1705670fc0b..34353cb81f97 100644 --- a/src/components/TagPicker/tagPickerPropTypes.js +++ b/src/components/TagPicker/tagPickerPropTypes.js @@ -21,7 +21,7 @@ const propTypes = { /* Onyx Props */ /** List of recently used tags */ - recentlyUsedPolicyTags: PropTypes.arrayOf(PropTypes.string), + policyRecentlyUsedTags: PropTypes.arrayOf(PropTypes.string), /* Onyx Props */ /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ @@ -31,7 +31,7 @@ const propTypes = { const defaultProps = { policyID: '', policyTags: {}, - recentlyUsedPolicyTags: [], + policyRecentlyUsedTags: [], iou: iouDefaultProps, }; diff --git a/src/types/onyx/RecentlyUsedTags.ts b/src/types/onyx/RecentlyUsedTags.ts new file mode 100644 index 000000000000..1f593b10ecbc --- /dev/null +++ b/src/types/onyx/RecentlyUsedTags.ts @@ -0,0 +1,3 @@ +type RecentlyUsedTags = string[]; + +export default RecentlyUsedTags; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 039448fac531..66e5ee5fc979 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -43,6 +43,7 @@ import SecurityGroup from './SecurityGroup'; import Transaction from './Transaction'; import Form, {AddDebitCardForm} from './Form'; import RecentWaypoints from './RecentWaypoints'; +import RecentlyUsedTags from './RecentlyUsedTags'; export type { Account, @@ -91,4 +92,5 @@ export type { Form, AddDebitCardForm, RecentWaypoints, + RecentlyUsedTags, }; From 68a389320d416c00c30803eead2e33323dfeb59d Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Fri, 8 Sep 2023 11:38:18 +0100 Subject: [PATCH 10/22] refactor: rename method --- src/components/MoneyRequestConfirmationList.js | 2 +- src/libs/Permissions.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 0e28939eaece..0fd1966445c3 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -187,7 +187,7 @@ function MoneyRequestConfirmationList(props) { const distance = lodashGet(transaction, 'routes.route0.distance', 0); const shouldCalculateDistanceAmount = props.isDistanceRequest && props.iouAmount === 0; const shouldCategoryEditable = !_.isEmpty(props.policyCategories) && !props.isDistanceRequest; - const shouldTagBeEditable = !_.isEmpty(props.policyTags) && Permissions.canUseNewDotTags(props.betas); + const shouldTagBeEditable = !_.isEmpty(props.policyTags) && Permissions.canUseTags(props.betas); const formattedAmount = CurrencyUtils.convertToDisplayString( shouldCalculateDistanceAmount ? DistanceRequestUtils.getDistanceRequestAmount(distance, unit, rate) : props.iouAmount, diff --git a/src/libs/Permissions.js b/src/libs/Permissions.js index 52cd91cc072e..37892552f037 100644 --- a/src/libs/Permissions.js +++ b/src/libs/Permissions.js @@ -90,7 +90,7 @@ function canUseCustomStatus(betas) { * @param {Array} betas * @returns {Boolean} */ -function canUseNewDotTags(betas) { +function canUseTags(betas) { return _.contains(betas, CONST.BETAS.NEW_DOT_TAGS) || canUseAllBetas(betas); } @@ -112,6 +112,6 @@ export default { canUsePolicyRooms, canUseTasks, canUseCustomStatus, - canUseNewDotTags, + canUseTags, canUseLinkPreviews, }; From b4f8adfcdd0ea7ce2d8199f77f86b108e3828be6 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Mon, 11 Sep 2023 09:26:24 +0100 Subject: [PATCH 11/22] fix: review improvements --- .../MoneyRequestConfirmationList.js | 22 +++++++++---------- src/components/TagPicker/index.js | 1 + .../TagPicker/tagPickerPropTypes.js | 2 -- 3 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 0fd1966445c3..f629bbd00038 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -110,18 +110,6 @@ const propTypes = { /** List styles for OptionsSelector */ listStyles: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]), - /* Onyx Props */ - /** Collection of categories attached to a policy */ - policyCategories: PropTypes.objectOf(categoryPropTypes), - - /* Onyx Props */ - /** Collection of tags attached to a policy */ - policyTags: PropTypes.objectOf(tagPropTypes), - - /* Onyx Props */ - /* Beta features list */ - betas: PropTypes.arrayOf(PropTypes.string), - /** ID of the transaction that represents the money request */ transactionID: PropTypes.string, @@ -142,6 +130,16 @@ const propTypes = { /** Whether the money request is a distance request */ isDistanceRequest: PropTypes.bool, + + /* Onyx Props */ + /** Collection of categories attached to a policy */ + policyCategories: PropTypes.objectOf(categoryPropTypes), + + /** Collection of tags attached to a policy */ + policyTags: PropTypes.objectOf(tagPropTypes), + + /* Beta features list */ + betas: PropTypes.arrayOf(PropTypes.string), }; const defaultProps = { diff --git a/src/components/TagPicker/index.js b/src/components/TagPicker/index.js index daa26ca9d58c..215d6f13e3d6 100644 --- a/src/components/TagPicker/index.js +++ b/src/components/TagPicker/index.js @@ -67,6 +67,7 @@ function TagPicker({policyTags, reportID, iouType, iou}) { headerMessage={headerMessage} textInputLabel={translate('common.search')} boldStyle + value={''} onSelectRow={updateTag} shouldShowTextInput={false} /> diff --git a/src/components/TagPicker/tagPickerPropTypes.js b/src/components/TagPicker/tagPickerPropTypes.js index 34353cb81f97..a50beb40ec8b 100644 --- a/src/components/TagPicker/tagPickerPropTypes.js +++ b/src/components/TagPicker/tagPickerPropTypes.js @@ -19,11 +19,9 @@ const propTypes = { /** Collection of tags attached to a policy */ policyTags: PropTypes.objectOf(tagPropTypes), - /* Onyx Props */ /** List of recently used tags */ policyRecentlyUsedTags: PropTypes.arrayOf(PropTypes.string), - /* Onyx Props */ /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ iou: iouPropTypes, }; From feb8020dca68a8260f023022cde9204779975f92 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Mon, 11 Sep 2023 09:39:06 +0100 Subject: [PATCH 12/22] fix: small lint error --- src/components/TagPicker/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/TagPicker/index.js b/src/components/TagPicker/index.js index 215d6f13e3d6..9b6ad771cea4 100644 --- a/src/components/TagPicker/index.js +++ b/src/components/TagPicker/index.js @@ -67,7 +67,7 @@ function TagPicker({policyTags, reportID, iouType, iou}) { headerMessage={headerMessage} textInputLabel={translate('common.search')} boldStyle - value={''} + value='' onSelectRow={updateTag} shouldShowTextInput={false} /> From 40bd1512980e44bfab17d6fa9713d24336586bd6 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Mon, 11 Sep 2023 09:49:08 +0100 Subject: [PATCH 13/22] fix: small linter fix --- src/components/TagPicker/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/TagPicker/index.js b/src/components/TagPicker/index.js index 9b6ad771cea4..225473a46b5f 100644 --- a/src/components/TagPicker/index.js +++ b/src/components/TagPicker/index.js @@ -67,7 +67,7 @@ function TagPicker({policyTags, reportID, iouType, iou}) { headerMessage={headerMessage} textInputLabel={translate('common.search')} boldStyle - value='' + value="" onSelectRow={updateTag} shouldShowTextInput={false} /> From b7fd43135e54d100da8c7216bf22209c59f1ddf5 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Tue, 12 Sep 2023 10:40:52 +0100 Subject: [PATCH 14/22] fix: add missing types and fix proptypes --- src/ONYXKEYS.ts | 1 + .../MoneyRequestConfirmationList.js | 19 ++++++++++++++----- src/pages/iou/MoneyRequestTagPage.js | 2 +- src/types/onyx/PolicyTag.ts | 9 +++++++++ src/types/onyx/RecentlyUsedTags.ts | 2 +- src/types/onyx/index.ts | 2 ++ 6 files changed, 28 insertions(+), 7 deletions(-) create mode 100644 src/types/onyx/PolicyTag.ts diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index f5200b42c191..bfe4250fe42c 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -379,6 +379,7 @@ type OnyxValues = { [ONYXKEYS.COLLECTION.DOWNLOAD]: OnyxTypes.Download; [ONYXKEYS.COLLECTION.POLICY]: OnyxTypes.Policy; [ONYXKEYS.COLLECTION.POLICY_CATEGORIES]: unknown; + [ONYXKEYS.COLLECTION.POLICY_TAGS]: OnyxTypes.PolicyTag; [ONYXKEYS.COLLECTION.POLICY_MEMBERS]: OnyxTypes.PolicyMember; [ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES]: OnyxTypes.RecentlyUsedCategories; [ONYXKEYS.COLLECTION.DEPRECATED_POLICY_MEMBER_LIST]: OnyxTypes.PolicyMember; diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index f629bbd00038..d4a4ffbe6816 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -136,7 +136,12 @@ const propTypes = { policyCategories: PropTypes.objectOf(categoryPropTypes), /** Collection of tags attached to a policy */ - policyTags: PropTypes.objectOf(tagPropTypes), + policyTags: PropTypes.objectOf( + PropTypes.shape({ + name: PropTypes.string, + tags: tagPropTypes, + }), + ), /* Beta features list */ betas: PropTypes.arrayOf(PropTypes.string), @@ -185,7 +190,9 @@ function MoneyRequestConfirmationList(props) { const distance = lodashGet(transaction, 'routes.route0.distance', 0); const shouldCalculateDistanceAmount = props.isDistanceRequest && props.iouAmount === 0; const shouldCategoryEditable = !_.isEmpty(props.policyCategories) && !props.isDistanceRequest; - const shouldTagBeEditable = !_.isEmpty(props.policyTags) && Permissions.canUseTags(props.betas); + + const tags = _.keys(props.policyTags); + const canUseTags = Permissions.canUseTags(props.betas); const formattedAmount = CurrencyUtils.convertToDisplayString( shouldCalculateDistanceAmount ? DistanceRequestUtils.getDistanceRequestAmount(distance, unit, rate) : props.iouAmount, @@ -508,16 +515,18 @@ function MoneyRequestConfirmationList(props) { disabled={didConfirm || props.isReadOnly} /> )} - {shouldTagBeEditable && ( + {canUseTags ? _.map(tags, (tag) => ( + !_.isEmpty(tag.tags) && ( Navigation.navigate(ROUTES.getMoneyRequestTagRoute(props.iouType, props.reportID))} style={[styles.moneyRequestMenuItem, styles.mb2]} disabled={didConfirm || props.isReadOnly} /> - )} + ) + )) : null} )} diff --git a/src/pages/iou/MoneyRequestTagPage.js b/src/pages/iou/MoneyRequestTagPage.js index f02164e77b65..dd92d7782cbc 100644 --- a/src/pages/iou/MoneyRequestTagPage.js +++ b/src/pages/iou/MoneyRequestTagPage.js @@ -41,7 +41,7 @@ function MoneyRequestTagPage({route, report}) { const iouType = lodashGet(route, 'params.iouType', ''); const navigateBack = () => { - Navigation.goBack(ROUTES.getMoneyRequestConfirmationRoute(iouType, report.reportID)); + Navigation.goBack(ROUTES.getMoneyRequestConfirmationRoute(iouType, lodashGet(report, 'reportID', ''))); }; return ( diff --git a/src/types/onyx/PolicyTag.ts b/src/types/onyx/PolicyTag.ts new file mode 100644 index 000000000000..baee10d6e0d0 --- /dev/null +++ b/src/types/onyx/PolicyTag.ts @@ -0,0 +1,9 @@ +type PolicyTag = { + /** Name of a Tag */ + name: string; + + /** Flag that determines if a tag is active and able to be selected */ + enabled: boolean; +}; + +export default PolicyTag; diff --git a/src/types/onyx/RecentlyUsedTags.ts b/src/types/onyx/RecentlyUsedTags.ts index 1f593b10ecbc..1d6112514609 100644 --- a/src/types/onyx/RecentlyUsedTags.ts +++ b/src/types/onyx/RecentlyUsedTags.ts @@ -1,3 +1,3 @@ -type RecentlyUsedTags = string[]; +type RecentlyUsedTags = Record; export default RecentlyUsedTags; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index b40c82b58285..1aa39e879388 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -46,6 +46,7 @@ import Form, {AddDebitCardForm} from './Form'; import RecentWaypoints from './RecentWaypoints'; import RecentlyUsedCategories from './RecentlyUsedCategories'; import RecentlyUsedTags from './RecentlyUsedTags'; +import PolicyTag from './PolicyTag'; export type { Account, @@ -97,4 +98,5 @@ export type { RecentWaypoints, RecentlyUsedCategories, RecentlyUsedTags, + PolicyTag, }; From 65a6b4849f7b2af0511c2e61917b646dd88f2491 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Tue, 12 Sep 2023 11:41:00 +0100 Subject: [PATCH 15/22] feat: adapt to changes in structure and pass current tag around --- src/ROUTES.ts | 4 +-- .../MoneyRequestConfirmationList.js | 36 +++++++++++-------- src/components/TagPicker/index.js | 21 ++++++----- .../TagPicker/tagPickerPropTypes.js | 15 +++++--- src/languages/en.ts | 3 +- src/languages/es.ts | 3 +- src/languages/types.ts | 3 ++ src/pages/iou/MoneyRequestTagPage.js | 30 +++++++++++++--- src/pages/iou/propTypes/index.js | 4 +-- .../iou/steps/MoneyRequestConfirmPage.js | 2 +- src/types/onyx/IOU.ts | 1 + 11 files changed, 81 insertions(+), 41 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 6b86d88b31ec..2819740cd963 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -98,7 +98,7 @@ export default { MONEY_REQUEST_CURRENCY: ':iouType/new/currency/:reportID?', MONEY_REQUEST_DESCRIPTION: ':iouType/new/description/:reportID?', MONEY_REQUEST_CATEGORY: ':iouType/new/category/:reportID?', - MONEY_REQUEST_TAG: ':iouType/new/tag/:reportID?', + MONEY_REQUEST_TAG: ':iouType/new/tag/:reportID/:tag?', MONEY_REQUEST_MERCHANT: ':iouType/new/merchant/:reportID?', MONEY_REQUEST_MANUAL_TAB: ':iouType/new/:reportID?/manual', MONEY_REQUEST_SCAN_TAB: ':iouType/new/:reportID?/scan', @@ -118,7 +118,7 @@ export default { getMoneyRequestMerchantRoute: (iouType: string, reportID = '') => `${iouType}/new/merchant/${reportID}`, getMoneyRequestDistanceTabRoute: (iouType: string, reportID = '') => `${iouType}/new/${reportID}/distance`, getMoneyRequestWaypointRoute: (iouType: string, waypointIndex: number) => `${iouType}/new/waypoint/${waypointIndex}`, - getMoneyRequestTagRoute: (iouType: string, reportID = '') => `${iouType}/new/tag/${reportID}`, + getMoneyRequestTagRoute: (iouType: string, reportID = '', tag = '') => `${iouType}/new/tag/${reportID}/${tag}`, SPLIT_BILL_DETAILS: `r/:reportID/split/:reportActionID`, getSplitBillDetailsRoute: (reportID: string, reportActionID: string) => `r/${reportID}/split/${reportActionID}`, getNewTaskRoute: (reportID: string) => `${NEW_TASK}/${reportID}`, diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index d4a4ffbe6816..6869f413e900 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -71,7 +71,7 @@ const propTypes = { iouCategory: PropTypes.string, /** IOU Tag */ - iouTag: PropTypes.string, + iouTags: PropTypes.objectOf(PropTypes.string), /** Selected participants from MoneyRequestModal with login / accountID */ selectedParticipants: PropTypes.arrayOf(optionPropTypes).isRequired, @@ -139,7 +139,7 @@ const propTypes = { policyTags: PropTypes.objectOf( PropTypes.shape({ name: PropTypes.string, - tags: tagPropTypes, + tags: PropTypes.objectOf(tagPropTypes), }), ), @@ -153,6 +153,7 @@ const defaultProps = { onSelectParticipant: () => {}, iouType: CONST.IOU.MONEY_REQUEST_TYPE.REQUEST, iouCategory: '', + iouTags: {}, payeePersonalDetails: null, canModifyParticipants: false, isReadOnly: false, @@ -190,7 +191,7 @@ function MoneyRequestConfirmationList(props) { const distance = lodashGet(transaction, 'routes.route0.distance', 0); const shouldCalculateDistanceAmount = props.isDistanceRequest && props.iouAmount === 0; const shouldCategoryEditable = !_.isEmpty(props.policyCategories) && !props.isDistanceRequest; - + const tags = _.keys(props.policyTags); const canUseTags = Permissions.canUseTags(props.betas); @@ -515,18 +516,23 @@ function MoneyRequestConfirmationList(props) { disabled={didConfirm || props.isReadOnly} /> )} - {canUseTags ? _.map(tags, (tag) => ( - !_.isEmpty(tag.tags) && ( - Navigation.navigate(ROUTES.getMoneyRequestTagRoute(props.iouType, props.reportID))} - style={[styles.moneyRequestMenuItem, styles.mb2]} - disabled={didConfirm || props.isReadOnly} - /> - ) - )) : null} + {canUseTags + ? _.map( + tags, + (tag) => + !_.isEmpty(lodashGet(props.policyTags, [tag, 'tags'], [])) && ( + Navigation.navigate(ROUTES.getMoneyRequestTagRoute(props.iouType, props.reportID, tag))} + style={[styles.moneyRequestMenuItem, styles.mb2]} + disabled={didConfirm || props.isReadOnly} + /> + ), + ) + : null} )} diff --git a/src/components/TagPicker/index.js b/src/components/TagPicker/index.js index 225473a46b5f..cba2ffc3bc15 100644 --- a/src/components/TagPicker/index.js +++ b/src/components/TagPicker/index.js @@ -11,33 +11,32 @@ import * as OptionsListUtils from '../../libs/OptionsListUtils'; import OptionsSelector from '../OptionsSelector'; import {propTypes, defaultProps} from './tagPickerPropTypes'; -function TagPicker({policyTags, reportID, iouType, iou}) { +function TagPicker({policyTags, reportID, tag, iouType, iou}) { const {translate} = useLocalize(); const selectedOptions = useMemo(() => { - if (!iou.tag) { + if (!iou.tags || !iou.tags[tag]) { return []; } return [ { - name: iou.tag, + name: iou.tags[tag], enabled: true, - accountID: null, }, ]; - }, [iou.tag]); + }, [iou.tags, tag]); // Only shows one section, which will be the default behavior if there are // less than 8 policy tags // TODO: support sections with search const sections = useMemo(() => { - const tagList = _.chain(policyTags) + const tagList = _.chain(lodashGet(policyTags, [tag, 'tags'], {})) .values() - .map((tag) => ({ - text: tag.name, - keyForList: tag.name, - tooltipText: tag.name, + .map((t) => ({ + text: t.name, + keyForList: t.name, + tooltipText: t.name, })) .value(); @@ -46,7 +45,7 @@ function TagPicker({policyTags, reportID, iouType, iou}) { data: tagList, }, ]; - }, [policyTags]); + }, [policyTags, tag]); const headerMessage = OptionsListUtils.getHeaderMessage(lodashGet(sections, '[0].data.length', 0) > 0, false, ''); diff --git a/src/components/TagPicker/tagPickerPropTypes.js b/src/components/TagPicker/tagPickerPropTypes.js index a50beb40ec8b..35bfd0891ef6 100644 --- a/src/components/TagPicker/tagPickerPropTypes.js +++ b/src/components/TagPicker/tagPickerPropTypes.js @@ -9,6 +9,9 @@ const propTypes = { /** The policyID we are getting tags for */ policyID: PropTypes.string.isRequired, + /** The policyID we are getting tags for */ + tag: PropTypes.string.isRequired, + /** The type of IOU report, i.e. bill, request, send */ iouType: PropTypes.string.isRequired, @@ -17,19 +20,23 @@ const propTypes = { /* Onyx Props */ /** Collection of tags attached to a policy */ - policyTags: PropTypes.objectOf(tagPropTypes), + policyTags: PropTypes.objectOf( + PropTypes.shape({ + name: PropTypes.string, + tags: PropTypes.objectOf(tagPropTypes), + }), + ), /** List of recently used tags */ - policyRecentlyUsedTags: PropTypes.arrayOf(PropTypes.string), + policyRecentlyUsedTags: PropTypes.objectOf(PropTypes.arrayOf(PropTypes.string)), /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ iou: iouPropTypes, }; const defaultProps = { - policyID: '', policyTags: {}, - policyRecentlyUsedTags: [], + policyRecentlyUsedTags: {}, iou: iouDefaultProps, }; diff --git a/src/languages/en.ts b/src/languages/en.ts index f41c823e66d7..7361ca19146b 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -71,6 +71,7 @@ import type { SetTheRequestParams, UpdatedTheRequestParams, RemovedTheRequestParams, + TagSelectionParams, } from './types'; import * as ReportActionsUtils from '../libs/ReportActionsUtils'; @@ -534,7 +535,7 @@ export default { `changed the ${valueName} to ${newValueToDisplay} (previously ${oldValueToDisplay})`, threadRequestReportName: ({formattedAmount, comment}: ThreadRequestReportNameParams) => `${formattedAmount} request${comment ? ` for ${comment}` : ''}`, threadSentMoneyReportName: ({formattedAmount, comment}: ThreadSentMoneyReportNameParams) => `${formattedAmount} sent${comment ? ` for ${comment}` : ''}`, - tagSelection: 'Select a tag to add additional organization to your money', + tagSelection: ({tagName}: TagSelectionParams) => `Select a ${tagName} to add additional organization to your money`, error: { invalidSplit: 'Split amounts do not equal total amount', other: 'Unexpected error, please try again later', diff --git a/src/languages/es.ts b/src/languages/es.ts index 312b70239970..4d8b102274cd 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -71,6 +71,7 @@ import type { SetTheRequestParams, UpdatedTheRequestParams, RemovedTheRequestParams, + TagSelectionParams, } from './types'; /* eslint-disable max-len */ @@ -536,7 +537,7 @@ export default { `cambío ${valueName === 'comerciante' ? 'el' : 'la'} ${valueName} a ${newValueToDisplay} (previamente ${oldValueToDisplay})`, threadRequestReportName: ({formattedAmount, comment}: ThreadRequestReportNameParams) => `Solicitud de ${formattedAmount}${comment ? ` para ${comment}` : ''}`, threadSentMoneyReportName: ({formattedAmount, comment}: ThreadSentMoneyReportNameParams) => `${formattedAmount} enviado${comment ? ` para ${comment}` : ''}`, - tagSelection: 'Seleccione una etiqueta para agregar una organización adicional a tu dinero.', + tagSelection: ({tagName}: TagSelectionParams) => `Seleccione una ${tagName} para agregar una organización adicional a tu dinero`, error: { invalidSplit: 'La suma de las partes no equivale al monto total', other: 'Error inesperado, por favor inténtalo más tarde', diff --git a/src/languages/types.ts b/src/languages/types.ts index 059d944fd4ba..50533a4a8569 100644 --- a/src/languages/types.ts +++ b/src/languages/types.ts @@ -190,6 +190,8 @@ type RemovedTheRequestParams = {valueName: string; oldValueToDisplay: string}; type UpdatedTheRequestParams = {valueName: string; newValueToDisplay: string; oldValueToDisplay: string}; +type TagSelectionParams = {tagName: string}; + export type { AddressLineParams, CharacterLimitParams, @@ -261,4 +263,5 @@ export type { SetTheRequestParams, UpdatedTheRequestParams, RemovedTheRequestParams, + TagSelectionParams, }; diff --git a/src/pages/iou/MoneyRequestTagPage.js b/src/pages/iou/MoneyRequestTagPage.js index dd92d7782cbc..fba7bb6c1d29 100644 --- a/src/pages/iou/MoneyRequestTagPage.js +++ b/src/pages/iou/MoneyRequestTagPage.js @@ -10,6 +10,7 @@ import ScreenWrapper from '../../components/ScreenWrapper'; import HeaderWithBackButton from '../../components/HeaderWithBackButton'; import TagPicker from '../../components/TagPicker'; import Text from '../../components/Text'; +import tagPropTypes from '../../components/tagPropTypes'; import ONYXKEYS from '../../ONYXKEYS'; import reportPropTypes from '../reportPropTypes'; import styles from '../../styles/styles'; @@ -17,28 +18,43 @@ import styles from '../../styles/styles'; const propTypes = { /** Navigation route context info provided by react navigation */ route: PropTypes.shape({ - /** Route specific parameters used on this screen via route :iouType/new/tag/:reportID? */ + /** Route specific parameters used on this screen via route :iouType/new/tag/:reportID/:tag? */ 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, + + /** The tag name of the IOU */ + tag: PropTypes.string, }), }).isRequired, + /* Onyx props */ /** The report currently being used */ report: reportPropTypes, + + /** Collection of tags attached to a policy */ + policyTags: PropTypes.objectOf( + PropTypes.shape({ + name: PropTypes.string, + tags: PropTypes.objectOf(tagPropTypes), + }), + ), }; const defaultProps = { report: {}, + policyTags: {}, }; -function MoneyRequestTagPage({route, report}) { +function MoneyRequestTagPage({route, report, policyTags}) { const {translate} = useLocalize(); const iouType = lodashGet(route, 'params.iouType', ''); + const tag = lodashGet(route, 'params.tag', ''); + const tagName = lodashGet(policyTags, [tag, 'name'], ''); const navigateBack = () => { Navigation.goBack(ROUTES.getMoneyRequestConfirmationRoute(iouType, lodashGet(report, 'reportID', ''))); @@ -50,13 +66,14 @@ function MoneyRequestTagPage({route, report}) { shouldEnableMaxHeight > - {translate('iou.tagSelection')} + {translate('iou.tagSelection', {tagName} || translate('common.tag'))} @@ -79,4 +96,9 @@ export default compose( key: ({route, iou}) => `${ONYXKEYS.COLLECTION.REPORT}${lodashGet(route, 'params.reportID', '') || lodashGet(iou, 'participants.0.reportID', '')}`, }, }), + withOnyx({ + policyTags: { + key: ({report}) => `${ONYXKEYS.COLLECTION.POLICY_TAGS}${report ? report.policyID : '0'}`, + }, + }), )(MoneyRequestTagPage); diff --git a/src/pages/iou/propTypes/index.js b/src/pages/iou/propTypes/index.js index 5ecd00d11876..3ceba7d969d8 100644 --- a/src/pages/iou/propTypes/index.js +++ b/src/pages/iou/propTypes/index.js @@ -19,7 +19,7 @@ const iouPropTypes = PropTypes.shape({ merchant: PropTypes.string, /** The tag */ - tag: PropTypes.string, + tags: PropTypes.objectOf(PropTypes.string), /** Date that the request was created */ created: PropTypes.string, @@ -37,7 +37,7 @@ const iouDefaultProps = { currency: CONST.CURRENCY.USD, comment: '', merchant: '', - tag: '', + tags: {}, created: '', participants: [], receiptPath: '', diff --git a/src/pages/iou/steps/MoneyRequestConfirmPage.js b/src/pages/iou/steps/MoneyRequestConfirmPage.js index bcc089adb236..8edb97b52605 100644 --- a/src/pages/iou/steps/MoneyRequestConfirmPage.js +++ b/src/pages/iou/steps/MoneyRequestConfirmPage.js @@ -272,7 +272,7 @@ function MoneyRequestConfirmPage(props) { iouAmount={props.iou.amount} iouComment={props.iou.comment} iouCurrencyCode={props.iou.currency} - iouTag={props.iou.tag} + iouTags={props.iou.tags} onConfirm={createTransaction} onSendMoney={sendMoney} onSelectParticipant={(option) => { diff --git a/src/types/onyx/IOU.ts b/src/types/onyx/IOU.ts index 66f85c98d70c..8c01081a6482 100644 --- a/src/types/onyx/IOU.ts +++ b/src/types/onyx/IOU.ts @@ -19,6 +19,7 @@ type IOU = { receiptSource?: string; transactionID?: string; participants?: Participant[]; + tags: Record; }; export default IOU; From 016ad538d59b33be1bfe5c4115efd7cbd8b88ba1 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Tue, 12 Sep 2023 13:47:09 +0100 Subject: [PATCH 16/22] feat: udpate ES translation for tag selection --- src/languages/es.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/languages/es.ts b/src/languages/es.ts index 0a569fda161c..dcd1c7916157 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -537,7 +537,7 @@ export default { `cambío ${valueName === 'comerciante' ? 'el' : 'la'} ${valueName} a ${newValueToDisplay} (previamente ${oldValueToDisplay})`, threadRequestReportName: ({formattedAmount, comment}: ThreadRequestReportNameParams) => `Solicitud de ${formattedAmount}${comment ? ` para ${comment}` : ''}`, threadSentMoneyReportName: ({formattedAmount, comment}: ThreadSentMoneyReportNameParams) => `${formattedAmount} enviado${comment ? ` para ${comment}` : ''}`, - tagSelection: ({tagName}: TagSelectionParams) => `Seleccione una ${tagName} para agregar una organización adicional a tu dinero`, + tagSelection: ({tagName}: TagSelectionParams) => `Seleccione una ${tagName} para organizar mejor tu dinero`, error: { invalidSplit: 'La suma de las partes no equivale al monto total', other: 'Error inesperado, por favor inténtalo más tarde', From 9b7d7c16ff004dccbf9726e5bd4a69241975eeb2 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Tue, 12 Sep 2023 14:22:27 +0100 Subject: [PATCH 17/22] revert: use only first tag of policy --- .../MoneyRequestConfirmationList.js | 35 ++++++++----------- src/components/TagPicker/index.js | 6 ++-- src/pages/iou/propTypes/index.js | 4 +-- .../iou/steps/MoneyRequestConfirmPage.js | 2 +- src/types/onyx/IOU.ts | 2 +- 5 files changed, 22 insertions(+), 27 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 6869f413e900..cebea71c5779 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -71,7 +71,7 @@ const propTypes = { iouCategory: PropTypes.string, /** IOU Tag */ - iouTags: PropTypes.objectOf(PropTypes.string), + iouTag: PropTypes.string, /** Selected participants from MoneyRequestModal with login / accountID */ selectedParticipants: PropTypes.arrayOf(optionPropTypes).isRequired, @@ -153,7 +153,7 @@ const defaultProps = { onSelectParticipant: () => {}, iouType: CONST.IOU.MONEY_REQUEST_TYPE.REQUEST, iouCategory: '', - iouTags: {}, + iouTag: '', payeePersonalDetails: null, canModifyParticipants: false, isReadOnly: false, @@ -192,7 +192,9 @@ function MoneyRequestConfirmationList(props) { const shouldCalculateDistanceAmount = props.isDistanceRequest && props.iouAmount === 0; const shouldCategoryEditable = !_.isEmpty(props.policyCategories) && !props.isDistanceRequest; - const tags = _.keys(props.policyTags); + // Fetches the first tag of the policy + const tagKey = _.first(_.keys(props.policyTags)); + const tag = lodashGet(props.policyTags, tagKey, {}); const canUseTags = Permissions.canUseTags(props.betas); const formattedAmount = CurrencyUtils.convertToDisplayString( @@ -516,23 +518,16 @@ function MoneyRequestConfirmationList(props) { disabled={didConfirm || props.isReadOnly} /> )} - {canUseTags - ? _.map( - tags, - (tag) => - !_.isEmpty(lodashGet(props.policyTags, [tag, 'tags'], [])) && ( - Navigation.navigate(ROUTES.getMoneyRequestTagRoute(props.iouType, props.reportID, tag))} - style={[styles.moneyRequestMenuItem, styles.mb2]} - disabled={didConfirm || props.isReadOnly} - /> - ), - ) - : null} + {canUseTags && tag.tags ? ( + Navigation.navigate(ROUTES.getMoneyRequestTagRoute(props.iouType, props.reportID, tagKey))} + style={[styles.moneyRequestMenuItem, styles.mb2]} + disabled={didConfirm || props.isReadOnly} + /> + ) : null} )} diff --git a/src/components/TagPicker/index.js b/src/components/TagPicker/index.js index cba2ffc3bc15..25021bd817d7 100644 --- a/src/components/TagPicker/index.js +++ b/src/components/TagPicker/index.js @@ -15,17 +15,17 @@ function TagPicker({policyTags, reportID, tag, iouType, iou}) { const {translate} = useLocalize(); const selectedOptions = useMemo(() => { - if (!iou.tags || !iou.tags[tag]) { + if (!iou.tag) { return []; } return [ { - name: iou.tags[tag], + name: iou.tag, enabled: true, }, ]; - }, [iou.tags, tag]); + }, [iou.tag]); // Only shows one section, which will be the default behavior if there are // less than 8 policy tags diff --git a/src/pages/iou/propTypes/index.js b/src/pages/iou/propTypes/index.js index 3ceba7d969d8..5ecd00d11876 100644 --- a/src/pages/iou/propTypes/index.js +++ b/src/pages/iou/propTypes/index.js @@ -19,7 +19,7 @@ const iouPropTypes = PropTypes.shape({ merchant: PropTypes.string, /** The tag */ - tags: PropTypes.objectOf(PropTypes.string), + tag: PropTypes.string, /** Date that the request was created */ created: PropTypes.string, @@ -37,7 +37,7 @@ const iouDefaultProps = { currency: CONST.CURRENCY.USD, comment: '', merchant: '', - tags: {}, + tag: '', created: '', participants: [], receiptPath: '', diff --git a/src/pages/iou/steps/MoneyRequestConfirmPage.js b/src/pages/iou/steps/MoneyRequestConfirmPage.js index 7df500e8f80a..a6418df3712d 100644 --- a/src/pages/iou/steps/MoneyRequestConfirmPage.js +++ b/src/pages/iou/steps/MoneyRequestConfirmPage.js @@ -272,7 +272,7 @@ function MoneyRequestConfirmPage(props) { iouAmount={props.iou.amount} iouComment={props.iou.comment} iouCurrencyCode={props.iou.currency} - iouTags={props.iou.tags} + iouTag={props.iou.tag} onConfirm={createTransaction} onSendMoney={sendMoney} onSelectParticipant={(option) => { diff --git a/src/types/onyx/IOU.ts b/src/types/onyx/IOU.ts index 8c01081a6482..7151bb84d1f1 100644 --- a/src/types/onyx/IOU.ts +++ b/src/types/onyx/IOU.ts @@ -19,7 +19,7 @@ type IOU = { receiptSource?: string; transactionID?: string; participants?: Participant[]; - tags: Record; + tag?: string; }; export default IOU; From 77b853d10b99efecd7cca045ee78ccdd693153d4 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Tue, 12 Sep 2023 16:49:57 +0100 Subject: [PATCH 18/22] feat: remove tag from route and use hardcoded value --- src/ROUTES.ts | 4 ++-- src/components/MoneyRequestConfirmationList.js | 14 ++++++++------ src/components/TagPicker/tagPickerPropTypes.js | 2 +- src/components/tagPropTypes.js | 3 +++ src/pages/iou/MoneyRequestTagPage.js | 17 +++++++++-------- src/types/onyx/PolicyTag.ts | 4 ++++ 6 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/ROUTES.ts b/src/ROUTES.ts index 2819740cd963..6b86d88b31ec 100644 --- a/src/ROUTES.ts +++ b/src/ROUTES.ts @@ -98,7 +98,7 @@ export default { MONEY_REQUEST_CURRENCY: ':iouType/new/currency/:reportID?', MONEY_REQUEST_DESCRIPTION: ':iouType/new/description/:reportID?', MONEY_REQUEST_CATEGORY: ':iouType/new/category/:reportID?', - MONEY_REQUEST_TAG: ':iouType/new/tag/:reportID/:tag?', + MONEY_REQUEST_TAG: ':iouType/new/tag/:reportID?', MONEY_REQUEST_MERCHANT: ':iouType/new/merchant/:reportID?', MONEY_REQUEST_MANUAL_TAB: ':iouType/new/:reportID?/manual', MONEY_REQUEST_SCAN_TAB: ':iouType/new/:reportID?/scan', @@ -118,7 +118,7 @@ export default { getMoneyRequestMerchantRoute: (iouType: string, reportID = '') => `${iouType}/new/merchant/${reportID}`, getMoneyRequestDistanceTabRoute: (iouType: string, reportID = '') => `${iouType}/new/${reportID}/distance`, getMoneyRequestWaypointRoute: (iouType: string, waypointIndex: number) => `${iouType}/new/waypoint/${waypointIndex}`, - getMoneyRequestTagRoute: (iouType: string, reportID = '', tag = '') => `${iouType}/new/tag/${reportID}/${tag}`, + getMoneyRequestTagRoute: (iouType: string, reportID = '') => `${iouType}/new/tag/${reportID}`, SPLIT_BILL_DETAILS: `r/:reportID/split/:reportActionID`, getSplitBillDetailsRoute: (reportID: string, reportActionID: string) => `r/${reportID}/split/${reportActionID}`, getNewTaskRoute: (reportID: string) => `${NEW_TASK}/${reportID}`, diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index cebea71c5779..188eb8db49d5 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -139,6 +139,7 @@ const propTypes = { policyTags: PropTypes.objectOf( PropTypes.shape({ name: PropTypes.string, + required: PropTypes.bool, tags: PropTypes.objectOf(tagPropTypes), }), ), @@ -192,9 +193,10 @@ function MoneyRequestConfirmationList(props) { const shouldCalculateDistanceAmount = props.isDistanceRequest && props.iouAmount === 0; const shouldCategoryEditable = !_.isEmpty(props.policyCategories) && !props.isDistanceRequest; - // Fetches the first tag of the policy - const tagKey = _.first(_.keys(props.policyTags)); - const tag = lodashGet(props.policyTags, tagKey, {}); + // Fetches the first tag list of the policy + const tagListKey = _.first(_.keys(props.policyTags)); + const tagList = lodashGet(props.policyTags, [tagListKey, 'tags'], []); + const tagListName = lodashGet(props.policyTags, [tagListKey, 'name'], ''); const canUseTags = Permissions.canUseTags(props.betas); const formattedAmount = CurrencyUtils.convertToDisplayString( @@ -518,12 +520,12 @@ function MoneyRequestConfirmationList(props) { disabled={didConfirm || props.isReadOnly} /> )} - {canUseTags && tag.tags ? ( + {canUseTags && tagList ? ( Navigation.navigate(ROUTES.getMoneyRequestTagRoute(props.iouType, props.reportID, tagKey))} + description={tagListName || translate('common.tag')} + onPress={() => Navigation.navigate(ROUTES.getMoneyRequestTagRoute(props.iouType, props.reportID, tagListKey))} style={[styles.moneyRequestMenuItem, styles.mb2]} disabled={didConfirm || props.isReadOnly} /> diff --git a/src/components/TagPicker/tagPickerPropTypes.js b/src/components/TagPicker/tagPickerPropTypes.js index 35bfd0891ef6..250b22cfddf4 100644 --- a/src/components/TagPicker/tagPickerPropTypes.js +++ b/src/components/TagPicker/tagPickerPropTypes.js @@ -9,7 +9,7 @@ const propTypes = { /** The policyID we are getting tags for */ policyID: PropTypes.string.isRequired, - /** The policyID we are getting tags for */ + /** The tag list we are getting tags for */ tag: PropTypes.string.isRequired, /** The type of IOU report, i.e. bill, request, send */ diff --git a/src/components/tagPropTypes.js b/src/components/tagPropTypes.js index 09ba8d403cf8..7c4a6d16483b 100644 --- a/src/components/tagPropTypes.js +++ b/src/components/tagPropTypes.js @@ -6,4 +6,7 @@ export default PropTypes.shape({ /** Flag that determines if a tag is active and able to be selected */ enabled: PropTypes.bool.isRequired, + + /** "General Ledger code" that corresponds to this category in an accounting system. Similar to an ID. */ + 'GL Code': PropTypes.string, }); diff --git a/src/pages/iou/MoneyRequestTagPage.js b/src/pages/iou/MoneyRequestTagPage.js index fba7bb6c1d29..cac295ff46fa 100644 --- a/src/pages/iou/MoneyRequestTagPage.js +++ b/src/pages/iou/MoneyRequestTagPage.js @@ -1,4 +1,5 @@ import React from 'react'; +import _ from 'underscore'; import PropTypes from 'prop-types'; import lodashGet from 'lodash/get'; import {withOnyx} from 'react-native-onyx'; @@ -25,9 +26,6 @@ const propTypes = { /** The report ID of the IOU */ reportID: PropTypes.string, - - /** The tag name of the IOU */ - tag: PropTypes.string, }), }).isRequired, @@ -53,8 +51,11 @@ function MoneyRequestTagPage({route, report, policyTags}) { const {translate} = useLocalize(); const iouType = lodashGet(route, 'params.iouType', ''); - const tag = lodashGet(route, 'params.tag', ''); - const tagName = lodashGet(policyTags, [tag, 'name'], ''); + + // Fetches the first tag list of the policy + const tagListKey = _.first(_.keys(policyTags)); + const tagList = lodashGet(policyTags, tagListKey, {}); + const tagListName = lodashGet(tagList, 'name', ''); const navigateBack = () => { Navigation.goBack(ROUTES.getMoneyRequestConfirmationRoute(iouType, lodashGet(report, 'reportID', ''))); @@ -66,14 +67,14 @@ function MoneyRequestTagPage({route, report, policyTags}) { shouldEnableMaxHeight > - {translate('iou.tagSelection', {tagName} || translate('common.tag'))} + {translate('iou.tagSelection', {tagListName} || translate('common.tag'))} diff --git a/src/types/onyx/PolicyTag.ts b/src/types/onyx/PolicyTag.ts index baee10d6e0d0..2dd4880ce086 100644 --- a/src/types/onyx/PolicyTag.ts +++ b/src/types/onyx/PolicyTag.ts @@ -4,6 +4,10 @@ type PolicyTag = { /** Flag that determines if a tag is active and able to be selected */ enabled: boolean; + + /** "General Ledger code" that corresponds to this category in an accounting system. Similar to an ID. */ + // eslint-disable-next-line @typescript-eslint/naming-convention + 'GL Code': string; }; export default PolicyTag; From c42584ce3bf4401d7cd51e7667475ddd81406a10 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Tue, 12 Sep 2023 17:55:02 +0100 Subject: [PATCH 19/22] fix: review fixes --- src/components/MoneyRequestConfirmationList.js | 2 +- src/components/tagPropTypes.js | 2 +- src/pages/iou/MoneyRequestTagPage.js | 2 +- src/types/onyx/PolicyTag.ts | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 188eb8db49d5..e1df58e38abc 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -525,7 +525,7 @@ function MoneyRequestConfirmationList(props) { shouldShowRightIcon={!props.isReadOnly} title={props.iouTag} description={tagListName || translate('common.tag')} - onPress={() => Navigation.navigate(ROUTES.getMoneyRequestTagRoute(props.iouType, props.reportID, tagListKey))} + onPress={() => Navigation.navigate(ROUTES.getMoneyRequestTagRoute(props.iouType, props.reportID))} style={[styles.moneyRequestMenuItem, styles.mb2]} disabled={didConfirm || props.isReadOnly} /> diff --git a/src/components/tagPropTypes.js b/src/components/tagPropTypes.js index 7c4a6d16483b..29d913dcd035 100644 --- a/src/components/tagPropTypes.js +++ b/src/components/tagPropTypes.js @@ -7,6 +7,6 @@ export default PropTypes.shape({ /** Flag that determines if a tag is active and able to be selected */ enabled: PropTypes.bool.isRequired, - /** "General Ledger code" that corresponds to this category in an accounting system. Similar to an ID. */ + /** "General Ledger code" that corresponds to this tag in an accounting system. Similar to an ID. */ 'GL Code': PropTypes.string, }); diff --git a/src/pages/iou/MoneyRequestTagPage.js b/src/pages/iou/MoneyRequestTagPage.js index cac295ff46fa..a1795d50df8a 100644 --- a/src/pages/iou/MoneyRequestTagPage.js +++ b/src/pages/iou/MoneyRequestTagPage.js @@ -19,7 +19,7 @@ import styles from '../../styles/styles'; const propTypes = { /** Navigation route context info provided by react navigation */ route: PropTypes.shape({ - /** Route specific parameters used on this screen via route :iouType/new/tag/:reportID/:tag? */ + /** Route specific parameters used on this screen via route :iouType/new/tag/:reportID? */ params: PropTypes.shape({ /** The type of IOU report, i.e. bill, request, send */ iouType: PropTypes.string, diff --git a/src/types/onyx/PolicyTag.ts b/src/types/onyx/PolicyTag.ts index 2dd4880ce086..fe6bee3a1f31 100644 --- a/src/types/onyx/PolicyTag.ts +++ b/src/types/onyx/PolicyTag.ts @@ -5,7 +5,7 @@ type PolicyTag = { /** Flag that determines if a tag is active and able to be selected */ enabled: boolean; - /** "General Ledger code" that corresponds to this category in an accounting system. Similar to an ID. */ + /** "General Ledger code" that corresponds to this tag in an accounting system. Similar to an ID. */ // eslint-disable-next-line @typescript-eslint/naming-convention 'GL Code': string; }; From 3f40a657870c7695f82237953339ff9c573b7b85 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Wed, 13 Sep 2023 09:19:52 +0100 Subject: [PATCH 20/22] fix: small comment fix and code simplification --- src/components/MoneyRequestConfirmationList.js | 4 ++-- src/components/TagPicker/tagPickerPropTypes.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index e1df58e38abc..4cf4d2d74be9 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -520,7 +520,7 @@ function MoneyRequestConfirmationList(props) { disabled={didConfirm || props.isReadOnly} /> )} - {canUseTags && tagList ? ( + {canUseTags && !!tagList && ( - ) : null} + )} )} diff --git a/src/components/TagPicker/tagPickerPropTypes.js b/src/components/TagPicker/tagPickerPropTypes.js index 250b22cfddf4..ad57a0409f15 100644 --- a/src/components/TagPicker/tagPickerPropTypes.js +++ b/src/components/TagPicker/tagPickerPropTypes.js @@ -9,7 +9,7 @@ const propTypes = { /** The policyID we are getting tags for */ policyID: PropTypes.string.isRequired, - /** The tag list we are getting tags for */ + /** The name of tag list we are getting tags for */ tag: PropTypes.string.isRequired, /** The type of IOU report, i.e. bill, request, send */ From 40eabd8acd554793d69b3143fb8a8955fc02da21 Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Wed, 13 Sep 2023 09:25:23 +0100 Subject: [PATCH 21/22] fix: remove duplicated key from merge with main --- src/components/MoneyRequestConfirmationList.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index 615b390aaef2..cfc9289b9168 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -146,9 +146,6 @@ const propTypes = { tags: PropTypes.objectOf(tagPropTypes), }), ), - - /* Beta features list */ - betas: PropTypes.arrayOf(PropTypes.string), }; const defaultProps = { From 02d1ddddc7bbb907bfddbedcd4bd649635d6d03f Mon Sep 17 00:00:00 2001 From: Ana Margarida Silva Date: Wed, 13 Sep 2023 09:26:16 +0100 Subject: [PATCH 22/22] fix: remove duplicated key --- src/components/MoneyRequestConfirmationList.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/MoneyRequestConfirmationList.js b/src/components/MoneyRequestConfirmationList.js index cfc9289b9168..966f5f4340a7 100755 --- a/src/components/MoneyRequestConfirmationList.js +++ b/src/components/MoneyRequestConfirmationList.js @@ -171,7 +171,6 @@ const defaultProps = { listStyles: [], policyCategories: {}, policyTags: {}, - betas: [], transactionID: '', transaction: {}, mileageRate: {unit: CONST.CUSTOM_UNITS.DISTANCE_UNIT_MILES, rate: 0, currency: 'USD'},