From ebf50d8820812528b6e71b1b5153a74edfce364f Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 9 Jun 2021 23:13:47 +0300 Subject: [PATCH 01/60] conditional render ActivityIndicator vs Text --- src/components/ReportTransaction.js | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index 557786e71fa6..beffd04579bb 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -1,7 +1,10 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; -import {Text, View, Pressable} from 'react-native'; +import { + Text, View, Pressable, ActivityIndicator, +} from 'react-native'; import styles from '../styles/styles'; +import themeColors from '../styles/themes/default'; import {rejectTransaction} from '../libs/actions/IOU'; import ReportActionPropTypes from '../pages/home/report/ReportActionPropTypes'; import ReportActionItemSingle from '../pages/home/report/ReportActionItemSingle'; @@ -23,6 +26,9 @@ const propTypes = { /** Text label for the reject transaction button */ rejectButtonLabelText: PropTypes.string.isRequired, + + /* eslint-disable-next-line react/no-unused-prop-types */ + rejectInProgress: PropTypes.arrayOf(PropTypes.string), }; const defaultProps = { @@ -45,7 +51,15 @@ class ReportTransaction extends Component { }); } + isRejected(rejectedIDs, transactionID) { + if (!rejectedIDs) { + return false; + } + return rejectedIDs.includes(transactionID.toString()); + } + render() { + const rejectedIDs = lodashGet(this.props, 'rejectInProgress', []); return ( - {this.props.rejectButtonLabelText} + { + this.isRejected(rejectedIDs, this.props.action.originalMessage.IOUTransactionID) + ? + : ( + + {this.props.rejectButtonLabelText} + + ) + } )} From cd6cabf5872289eb87bd89b9f9c50ba2d2af3ed4 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 9 Jun 2021 23:14:57 +0300 Subject: [PATCH 02/60] add REJECT_IN_PROGRESS Onyx key --- src/ONYXKEYS.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index d7fcd65074f3..a1c0685be7f0 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -87,6 +87,9 @@ export default { // Indicates which locale should be used PREFERRED_LOCALE: 'preferredLocale', + // List of transactions that are in progress of being rejected + REJECT_IN_PROGRESS: 'rejectInProgress', + // User's Expensify Wallet USER_WALLET: 'userWallet', From 5e45cf005aa3705ec8957a3a4f0939655d28d2d0 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 9 Jun 2021 23:17:18 +0300 Subject: [PATCH 03/60] export composed with onyx --- src/components/ReportTransaction.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index beffd04579bb..4fe7ac1becc9 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -8,6 +8,7 @@ import themeColors from '../styles/themes/default'; import {rejectTransaction} from '../libs/actions/IOU'; import ReportActionPropTypes from '../pages/home/report/ReportActionPropTypes'; import ReportActionItemSingle from '../pages/home/report/ReportActionItemSingle'; +import compose from '../libs/compose'; const propTypes = { /** The chatReport which the transaction is associated with */ @@ -100,4 +101,10 @@ class ReportTransaction extends Component { ReportTransaction.displayName = 'ReportTransaction'; ReportTransaction.defaultProps = defaultProps; ReportTransaction.propTypes = propTypes; -export default ReportTransaction; +export default compose( + withOnyx({ + rejectInProgress: { + key: ONYXKEYS.REJECT_IN_PROGRESS, + }, + }), +)(ReportTransaction); From 80126f44f51afe5edb7a29379ae5dff6ef505131 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 9 Jun 2021 23:22:27 +0300 Subject: [PATCH 04/60] import withOnyx onyxkeys lodash/get --- src/components/ReportTransaction.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index 4fe7ac1becc9..8cca9bba022e 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -1,8 +1,13 @@ import React, {Component} from 'react'; import PropTypes from 'prop-types'; +import lodashGet from 'lodash/get'; import { Text, View, Pressable, ActivityIndicator, } from 'react-native'; +import { + withOnyx, +} from 'react-native-onyx'; +import ONYXKEYS from '../ONYXKEYS'; import styles from '../styles/styles'; import themeColors from '../styles/themes/default'; import {rejectTransaction} from '../libs/actions/IOU'; From d3e31805a202c111ed5e090ee00981816c59c04f Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 9 Jun 2021 23:24:19 +0300 Subject: [PATCH 05/60] defalt prop for rejectInProgress --- src/components/ReportTransaction.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index 8cca9bba022e..4ccada7912f9 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -39,6 +39,7 @@ const propTypes = { const defaultProps = { canBeRejected: false, + rejectInProgress: [], }; class ReportTransaction extends Component { From 7a294b2efd2190f763d20d3794b0e75dd3bf5a08 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 9 Jun 2021 23:27:21 +0300 Subject: [PATCH 06/60] add rejected transactionID to Onyx --- src/libs/actions/IOU.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 3e64047eedc8..403d1c696265 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -135,6 +135,7 @@ function createIOUSplit(params) { function rejectTransaction({ reportID, chatReportID, transactionID, comment, }) { + Onyx.merge(ONYXKEYS.REJECT_IN_PROGRESS, [transactionID]); API.RejectTransaction({ reportID, transactionID, From 33cdbaf9d33fa451b9af34b7dd9b9a1d336b2a60 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 9 Jun 2021 23:28:25 +0300 Subject: [PATCH 07/60] add minWidth to Pressable --- src/components/ReportTransaction.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index 4ccada7912f9..602142c1acea 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -84,6 +84,7 @@ class ReportTransaction extends Component { styles.buttonSmall, styles.chatItemComposeSecondaryRowOffset, styles.mb3, + {minWidth: '20%'}, ]} onPress={this.rejectTransaction} > From 99e04e35f3dc7a4211ae359abb060b8a10e561d0 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 9 Jun 2021 23:33:05 +0300 Subject: [PATCH 08/60] remove rejectedID from Onyx when done --- src/components/ReportTransaction.js | 1 + src/libs/actions/IOU.js | 8 ++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index 602142c1acea..0912090ef35d 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -55,6 +55,7 @@ class ReportTransaction extends Component { chatReportID: this.props.chatReportID, transactionID: this.props.action.originalMessage.IOUTransactionID, comment: '', + rejectedIDs: this.props.rejectInProgress, }); } diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 403d1c696265..6ed9f1b3b7ba 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -133,7 +133,7 @@ function createIOUSplit(params) { * @param {String} params.comment */ function rejectTransaction({ - reportID, chatReportID, transactionID, comment, + reportID, chatReportID, transactionID, comment, rejectedIDs, }) { Onyx.merge(ONYXKEYS.REJECT_IN_PROGRESS, [transactionID]); API.RejectTransaction({ @@ -154,7 +154,11 @@ function rejectTransaction({ // we should also sync the chatReport after fetching the iouReport. fetchIOUReportByIDAndUpdateChatReport(reportID, chatReportID); }) - .catch(error => console.error(`Error rejecting transaction: ${error}`)); + .catch(error => console.error(`Error rejecting transaction: ${error}`)) + .finally(() => { + const withoutCurrentID = rejectedIDs.filter(id => id !== transactionID); + Onyx.set(ONYXKEYS.REJECT_IN_PROGRESS, withoutCurrentID); + }); } /** From e4cb02789ab21dafa422ef534e6f636708038f3c Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Wed, 9 Jun 2021 23:49:38 +0300 Subject: [PATCH 09/60] add some docs --- src/components/ReportTransaction.js | 3 +++ src/libs/actions/IOU.js | 1 + 2 files changed, 4 insertions(+) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index 0912090ef35d..2578d3621ee4 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -33,6 +33,9 @@ const propTypes = { /** Text label for the reject transaction button */ rejectButtonLabelText: PropTypes.string.isRequired, + /* Onyx Props */ + + /** List of transactionIDs in process of rejection */ /* eslint-disable-next-line react/no-unused-prop-types */ rejectInProgress: PropTypes.arrayOf(PropTypes.string), }; diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 6ed9f1b3b7ba..8306648bbce9 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -131,6 +131,7 @@ function createIOUSplit(params) { * @param {Number} params.chatReportID * @param {String} params.transactionID * @param {String} params.comment + * @param {Object} params.rejectedIDs */ function rejectTransaction({ reportID, chatReportID, transactionID, comment, rejectedIDs, From 2aa493b144cf298c2dc63d45aae0aeef41a38a2b Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 10 Jun 2021 14:02:11 +0300 Subject: [PATCH 10/60] center ActivityIndicator --- src/components/ReportTransaction.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index 2578d3621ee4..004b5a459fd7 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -94,7 +94,12 @@ class ReportTransaction extends Component { > { this.isRejected(rejectedIDs, this.props.action.originalMessage.IOUTransactionID) - ? + ? ( + + ) : ( {this.props.rejectButtonLabelText} From 012e0f09b3791e33d079679867262a9c25c3d0e5 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 10 Jun 2021 16:28:02 +0300 Subject: [PATCH 11/60] export without using compose --- src/components/ReportTransaction.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index 004b5a459fd7..7e3e5c4cd236 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -13,7 +13,6 @@ import themeColors from '../styles/themes/default'; import {rejectTransaction} from '../libs/actions/IOU'; import ReportActionPropTypes from '../pages/home/report/ReportActionPropTypes'; import ReportActionItemSingle from '../pages/home/report/ReportActionItemSingle'; -import compose from '../libs/compose'; const propTypes = { /** The chatReport which the transaction is associated with */ @@ -117,10 +116,8 @@ class ReportTransaction extends Component { ReportTransaction.displayName = 'ReportTransaction'; ReportTransaction.defaultProps = defaultProps; ReportTransaction.propTypes = propTypes; -export default compose( - withOnyx({ - rejectInProgress: { - key: ONYXKEYS.REJECT_IN_PROGRESS, - }, - }), -)(ReportTransaction); +export default withOnyx({ + rejectInProgress: { + key: ONYXKEYS.REJECT_IN_PROGRESS, + }, +})(ReportTransaction); From 74554169656ce51d463eec2bc90cdef0d397d80b Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 10 Jun 2021 18:21:45 +0300 Subject: [PATCH 12/60] remove default prop --- src/components/ReportTransaction.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index 7e3e5c4cd236..ed227baf0e1d 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -4,9 +4,7 @@ import lodashGet from 'lodash/get'; import { Text, View, Pressable, ActivityIndicator, } from 'react-native'; -import { - withOnyx, -} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; import ONYXKEYS from '../ONYXKEYS'; import styles from '../styles/styles'; import themeColors from '../styles/themes/default'; @@ -35,13 +33,12 @@ const propTypes = { /* Onyx Props */ /** List of transactionIDs in process of rejection */ - /* eslint-disable-next-line react/no-unused-prop-types */ + /* eslint-disable-next-line react/no-unused-prop-types, react/require-default-props */ rejectInProgress: PropTypes.arrayOf(PropTypes.string), }; const defaultProps = { canBeRejected: false, - rejectInProgress: [], }; class ReportTransaction extends Component { From f290d9aa661aab6bc695a5bcce63f29ad8338f23 Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 10 Jun 2021 18:27:16 +0300 Subject: [PATCH 13/60] remove inline style --- src/components/ReportTransaction.js | 2 +- src/styles/styles.js | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index ed227baf0e1d..37235e43f336 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -84,7 +84,7 @@ class ReportTransaction extends Component { styles.buttonSmall, styles.chatItemComposeSecondaryRowOffset, styles.mb3, - {minWidth: '20%'}, + styles.rejectIOU, ]} onPress={this.rejectTransaction} > diff --git a/src/styles/styles.js b/src/styles/styles.js index 170b7fea55c0..b5add8f2b40f 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1603,6 +1603,10 @@ const webViewStyles = { fontFamily: fontFamily.GTA, flex: 1, }, + + rejectIOU: { + minWidth: '20%', + } }; /** From ea0257ac9c62c021e18a6c21147a425d3be5630c Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Thu, 10 Jun 2021 18:50:11 +0300 Subject: [PATCH 14/60] fixtypo in style.js --- src/styles/styles.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/styles/styles.js b/src/styles/styles.js index b5add8f2b40f..a72ed082a7d2 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1521,6 +1521,10 @@ const styles = { cursorDisabled: { cursor: 'not-allowed', }, + + rejectIOU: { + minWidth: '20%', + }, }; const baseCodeTagStyles = { @@ -1603,10 +1607,6 @@ const webViewStyles = { fontFamily: fontFamily.GTA, flex: 1, }, - - rejectIOU: { - minWidth: '20%', - } }; /** From eb6c3f55b082ffbe11df1655da88d2962e491502 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Sat, 12 Jun 2021 14:12:56 +0800 Subject: [PATCH 15/60] Added language selector in the preferences page --- src/languages/en.js | 1 + src/languages/es.js | 3 +++ src/pages/settings/PreferencesPage.js | 35 ++++++++++++++++++++++++--- 3 files changed, 36 insertions(+), 3 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index 80cea4bba2f5..c8fe6f64814d 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -212,6 +212,7 @@ export default { notifications: 'Notifications', receiveRelevantFeatureUpdatesAndExpensifyNews: 'Receive relevant feature updates and Expensify news', priorityMode: 'Priority Mode', + language: 'Language', }, signInPage: { expensifyDotCash: 'Expensify.cash', diff --git a/src/languages/es.js b/src/languages/es.js index 894d36489822..a5f79dff2c00 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -207,6 +207,9 @@ export default { notifications: 'Notificaciones', receiveRelevantFeatureUpdatesAndExpensifyNews: 'Recibir noticias sobre Expensify y actualizaciones del producto', priorityMode: 'Modo Prioridad', + + // TODO + language: '????', }, signInPage: { expensifyDotCash: 'Expensify.cash', diff --git a/src/pages/settings/PreferencesPage.js b/src/pages/settings/PreferencesPage.js index bf4f96ef289f..53af9f6698f4 100755 --- a/src/pages/settings/PreferencesPage.js +++ b/src/pages/settings/PreferencesPage.js @@ -1,6 +1,6 @@ import React from 'react'; import {View} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; +import Onyx, {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; import HeaderWithCloseButton from '../../components/HeaderWithCloseButton'; @@ -31,6 +31,9 @@ const propTypes = { }), ...withLocalizePropTypes, + + // Indicates which locale the user currently has selected + preferredLocale: PropTypes.string.isRequired, }; const defaultProps = { @@ -38,7 +41,9 @@ const defaultProps = { user: {}, }; -const PreferencesPage = ({priorityMode, user, translate}) => { +const PreferencesPage = ({ + priorityMode, user, translate, preferredLocale, +}) => { const priorityModes = { default: { value: CONST.PRIORITY_MODE.DEFAULT, @@ -52,6 +57,17 @@ const PreferencesPage = ({priorityMode, user, translate}) => { }, }; + const locales = { + default: { + value: 'en', + label: 'English', + }, + es: { + value: 'es', + label: 'Spanish', + }, + }; + return ( { /> + {translate('preferencesPage.priorityMode')} @@ -91,9 +108,21 @@ const PreferencesPage = ({priorityMode, user, translate}) => { icon={() => } /> - + {priorityModes[priorityMode].description} + + + {translate('preferencesPage.language')} + + + Onyx.merge(ONYXKEYS.PREFERRED_LOCALE, locale)} + items={Object.values(locales)} + value={preferredLocale} + icon={() => } + /> + From 3294d9517e2860dfcf6e4ff16badaded0314a261 Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Sat, 12 Jun 2021 14:13:54 +0800 Subject: [PATCH 16/60] Added language selector in the preferences page --- src/pages/settings/PreferencesPage.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/settings/PreferencesPage.js b/src/pages/settings/PreferencesPage.js index 53af9f6698f4..0c6b7d13eca1 100755 --- a/src/pages/settings/PreferencesPage.js +++ b/src/pages/settings/PreferencesPage.js @@ -57,7 +57,7 @@ const PreferencesPage = ({ }, }; - const locales = { + const localesToLanguages = { default: { value: 'en', label: 'English', @@ -118,7 +118,7 @@ const PreferencesPage = ({ Onyx.merge(ONYXKEYS.PREFERRED_LOCALE, locale)} - items={Object.values(locales)} + items={Object.values(localesToLanguages)} value={preferredLocale} icon={() => } /> From 845786dfbdc78efdf21b30bdf02d6dbff43a063f Mon Sep 17 00:00:00 2001 From: Jasper Huang Date: Sat, 12 Jun 2021 14:20:21 +0800 Subject: [PATCH 17/60] Remove whitespace --- src/pages/settings/PreferencesPage.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/pages/settings/PreferencesPage.js b/src/pages/settings/PreferencesPage.js index 0c6b7d13eca1..a07b6b4fd2e7 100755 --- a/src/pages/settings/PreferencesPage.js +++ b/src/pages/settings/PreferencesPage.js @@ -94,7 +94,6 @@ const PreferencesPage = ({ /> - {translate('preferencesPage.priorityMode')} @@ -111,7 +110,6 @@ const PreferencesPage = ({ {priorityModes[priorityMode].description} - {translate('preferencesPage.language')} From dcc7a50e46c3a304a25fadeeb06214cb19e16d6b Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Sat, 12 Jun 2021 11:20:51 +0300 Subject: [PATCH 18/60] undo new onyx key, use IOU --- src/ONYXKEYS.js | 3 --- src/components/ReportTransaction.js | 21 ++++++++++++--------- src/libs/actions/IOU.js | 10 +++++++--- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index a1c0685be7f0..d7fcd65074f3 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -87,9 +87,6 @@ export default { // Indicates which locale should be used PREFERRED_LOCALE: 'preferredLocale', - // List of transactions that are in progress of being rejected - REJECT_IN_PROGRESS: 'rejectInProgress', - // User's Expensify Wallet USER_WALLET: 'userWallet', diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index 37235e43f336..2527bbc3b1c7 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -34,7 +34,9 @@ const propTypes = { /** List of transactionIDs in process of rejection */ /* eslint-disable-next-line react/no-unused-prop-types, react/require-default-props */ - rejectInProgress: PropTypes.arrayOf(PropTypes.string), + iou: PropTypes.shape({ + transactionsBeingRejected: PropTypes.arrayOf(PropTypes.string), + }), }; const defaultProps = { @@ -54,19 +56,20 @@ class ReportTransaction extends Component { chatReportID: this.props.chatReportID, transactionID: this.props.action.originalMessage.IOUTransactionID, comment: '', - rejectedIDs: this.props.rejectInProgress, + iou: this.props.iou, }); } - isRejected(rejectedIDs, transactionID) { - if (!rejectedIDs) { + isRejected() { + const IOUTransactionID = lodashGet(this.props.action, 'originalMessage.IOUTransactionID', ''); + const transactionsBeingRejected = lodashGet(this.props, 'iou.transactionsBeingRejected', []); + if (!transactionsBeingRejected || !transactionsBeingRejected.length) { return false; } - return rejectedIDs.includes(transactionID.toString()); + return transactionsBeingRejected.includes(IOUTransactionID.toString()); } render() { - const rejectedIDs = lodashGet(this.props, 'rejectInProgress', []); return ( { - this.isRejected(rejectedIDs, this.props.action.originalMessage.IOUTransactionID) + this.isRejected() ? ( console.error(`Error rejecting transaction: ${error}`)) .finally(() => { const withoutCurrentID = rejectedIDs.filter(id => id !== transactionID); - Onyx.set(ONYXKEYS.REJECT_IN_PROGRESS, withoutCurrentID); + Onyx.set(ONYXKEYS.IOU, {...iou, transactionsBeingRejected: withoutCurrentID}); }); } From d8978ad7614c654648ca4a3f1e0a10db6156d09d Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Sat, 12 Jun 2021 12:10:14 +0300 Subject: [PATCH 19/60] cleanup IOU.js --- src/libs/actions/IOU.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 8ddc6b5ac37c..cb1a9fdc1e48 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -132,14 +132,14 @@ function createIOUSplit(params) { * @param {Number} params.chatReportID * @param {String} params.transactionID * @param {String} params.comment - * @param {Object} params.rejectedIDs + * @param {Object} params.iou */ function rejectTransaction({ reportID, chatReportID, transactionID, comment, iou, }) { - const rejectedIDs = lodashGet(iou, 'transactionsBeingRejected', []); + const transactionsBeingRejected = lodashGet(iou, 'transactionsBeingRejected', []); Onyx.merge(ONYXKEYS.IOU, { - transactionsBeingRejected: [...rejectedIDs, transactionID], + transactionsBeingRejected: [...transactionsBeingRejected, transactionID], }); API.RejectTransaction({ reportID, @@ -161,7 +161,7 @@ function rejectTransaction({ }) .catch(error => console.error(`Error rejecting transaction: ${error}`)) .finally(() => { - const withoutCurrentID = rejectedIDs.filter(id => id !== transactionID); + const withoutCurrentID = transactionsBeingRejected.filter(id => id !== transactionID); Onyx.set(ONYXKEYS.IOU, {...iou, transactionsBeingRejected: withoutCurrentID}); }); } From 5848d1a96f9ee76f1c92097f98067ad1422721eb Mon Sep 17 00:00:00 2001 From: Rushat Gabhane Date: Mon, 14 Jun 2021 13:17:51 +0300 Subject: [PATCH 20/60] rm unnecessary toString --- src/components/ReportTransaction.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportTransaction.js b/src/components/ReportTransaction.js index 2527bbc3b1c7..8b83a8300d5c 100644 --- a/src/components/ReportTransaction.js +++ b/src/components/ReportTransaction.js @@ -66,7 +66,7 @@ class ReportTransaction extends Component { if (!transactionsBeingRejected || !transactionsBeingRejected.length) { return false; } - return transactionsBeingRejected.includes(IOUTransactionID.toString()); + return transactionsBeingRejected.includes(IOUTransactionID); } render() { From 33b4a16cdad9f553d595e94c790de0ab0efdc545 Mon Sep 17 00:00:00 2001 From: Nikki Wines Date: Mon, 14 Jun 2021 12:53:38 -0700 Subject: [PATCH 21/60] base level view for RequestorStep --- src/CONST.js | 13 ++ src/languages/en.js | 14 ++ .../ReimbursementAccountPage.js | 2 +- .../ReimbursementAccount/RequestorStep.js | 175 +++++++++++++++++- 4 files changed, 200 insertions(+), 4 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index 0d090cd7fe61..bedf70640170 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -47,6 +47,19 @@ const CONST = { IBAN: /^[A-Za-z0-9]{2,30}$/, SWIFT_BIC: /^[A-Za-z0-9]{8,11}$/, }, + STATES: [ + 'AK', 'AL', 'AR', 'AZ', 'CA', + 'CO', 'CT', 'DC', 'DE', 'FL', + 'GA', 'GU', 'HI', 'IA', 'ID', + 'IL', 'IN', 'KS', 'KY', 'LA', + 'MA', 'MD', 'ME', 'MI', 'MN', + 'MO', 'MS', 'MT', 'NC', 'ND', + 'NE', 'NH', 'NJ', 'NM', 'NV', + 'NY', 'OH', 'OK', 'OR', 'PA', + 'PR', 'RI', 'SC', 'SD', 'TN', + 'TX', 'UT', 'VA', 'VI', 'VT', + 'WA', 'WI', 'WV', 'WY', + ], }, BETAS: { ALL: 'all', diff --git a/src/languages/en.js b/src/languages/en.js index fea831a19833..4a314d497708 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -275,6 +275,20 @@ export default { iAcceptThe: 'I accept the ', hasPhoneLoginError: 'To add a verified bank account please ensure your primary login is a valid email and try again. You can add your phone number as a secondary login.', hasBeenThrottledError: ({fromNow}) => `For security reasons, we're taking a break from bank account setup so you can double-check your company information. Please try again ${fromNow}. Sorry!`, + financialRegulations: 'Financial regulation and bank rules require us to validate the identity of any individual setting up bank accounts on behalf of a company. ', + learnMore: 'Learn More', + isMyDataSafe: 'Is my data safe?', + onFidoConditions: 'By continuing with the request to add this bank account, you confirm that you have read, understand and accept ', + onFidoFacialScan: 'Onfido’s Facial Scan Policy and Release', + personalAddress: 'Your Personal Address (PO Boxes not allowed)', + street: 'Street', + city: 'City', + state: 'State', + zipCode: 'Zip Code', + dob: 'Date of Birth', + ssn: 'SSN (Last 4)', + ssnPlaceholder: 'Last 4 Digits', + isAuthorized: 'I am authorized to use my company bank account for business spend', }, addPersonalBankAccountPage: { enterPassword: 'Enter password', diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js index 4435525e47fd..60eb2c7f8d25 100644 --- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js +++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js @@ -102,7 +102,7 @@ class ReimbursementAccountPage extends React.Component { // We grab the currentStep from the achData to determine which view to display. The SetupWithdrawalAccount flow // allows us to continue the flow from various points depending on where the user left off. - const currentStep = this.props.reimbursementAccount.achData.currentStep; + const currentStep = CONST.BANK_ACCOUNT.STEP.REQUESTOR; //this.props.reimbursementAccount.achData.currentStep; return ( {currentStep === CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT && ( diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index 350e3b58471c..dc1b508e9feb 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -1,5 +1,174 @@ import React from 'react'; -import {View} from 'react-native'; +import {View, TextInput} from 'react-native'; +import styles from '../../styles/styles'; +import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; +import HeaderWithCloseButton from '../../components/HeaderWithCloseButton'; +import CONST from '../../CONST'; +import TextLink from '../../components/TextLink'; +import Navigation from '../../libs/Navigation/Navigation'; +import Icon from '../../components/Icon'; +import TextInputWithLabel from '../../components/TextInputWithLabel'; +import CheckboxWithLabel from '../../components/CheckboxWithLabel'; +import Text from '../../components/Text'; +import Picker from '../../components/Picker'; +import {DownArrow} from '../../components/Icon/Expensicons'; +import BankAccount from '../../libs/models/BankAccount'; -const RequestorStep = () => ; -export default RequestorStep; +const propTypes = { + ...withLocalizePropTypes, +}; + +class RequestorStep extends React.Component { + constructor(props) { + super(props); + + this.toggleAuthorization = this.toggleAuthorization.bind(this); + + this.state = { + firstName: '', + lastName: '', + street: '', + city: '', + state: '', + zipCode: '', + dob: '', + ssn: '', + }; + } + + toggleAuthorization() { + this.setState(prevState => ({ + isAuthorized: !prevState.isAuthorized, + })); + } + + render() { + return ( + + BankAccount.goToWithdrawalStepID(CONST.BANK_ACCOUNT.STEP.REQUESTOR)} + onCloseButtonPress={Navigation.dismissModal} + /> + + + {this.props.translate('bankAccount.financialRegulations')} + + {`${this.props.translate('bankAccount.learnMore')}`} + + {' | '} + + {`${this.props.translate('bankAccount.isMyDataSafe')}`} + + + + {this.props.translate('bankAccount.onFidoConditions')} + + {`${this.props.translate('bankAccount.onFidoFacialScan')}`} + + {', '} + + {`${this.props.translate('common.privacyPolicy')}`} + + {` ${this.props.translate('common.and')} `} + + {`${this.props.translate('common.termsOfService')}`} + + + + + this.setState({firstName})} + /> + + + this.setState({lastName})} + /> + + + + this.setState({street})} + /> + this.setState({city})} + /> + + + this.setState({state})} + items={CONST.BANK_ACCOUNT.STATES.map(state => ({value: state, label: state}))} + placeholder={{ + value: '', + label: this.props.translate('bankAccount.state'), + }} + value={this.state.state} + icon={() => } + /> + + + this.setState({zipCode})} + /> + + + + + this.setState({dob})} + /> + + + this.setState({ssn})} + /> + + ( + + + {this.props.translate('bankAccount.isAuthorized')} + + + )} + /> + + + ); + } +} + +RequestorStep.propTypes = propTypes; + +export default withLocalize(RequestorStep); From 8da5ea0cc2838745aa9ddbfdff40882746d00fcd Mon Sep 17 00:00:00 2001 From: Nikki Wines Date: Mon, 14 Jun 2021 17:25:59 -0700 Subject: [PATCH 22/60] stylistic update for the requestor step --- src/languages/en.js | 14 +- .../ReimbursementAccountPage.js | 2 +- .../ReimbursementAccount/RequestorStep.js | 173 ++++++++++-------- 3 files changed, 101 insertions(+), 88 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index 4a314d497708..ba4b81ba64e1 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -280,14 +280,12 @@ export default { isMyDataSafe: 'Is my data safe?', onFidoConditions: 'By continuing with the request to add this bank account, you confirm that you have read, understand and accept ', onFidoFacialScan: 'Onfido’s Facial Scan Policy and Release', - personalAddress: 'Your Personal Address (PO Boxes not allowed)', - street: 'Street', - city: 'City', - state: 'State', - zipCode: 'Zip Code', - dob: 'Date of Birth', - ssn: 'SSN (Last 4)', - ssnPlaceholder: 'Last 4 Digits', + requestorAddressStreet: 'Your Personal Address', + requestorAddressCity: 'City', + requestorAddressState: 'State', + requestorAddressZipCode: 'Zip Code', + dob: 'Date of Birth (YYYY-MM-DD)', + ssnLast4: 'Last 4 Digits of SSN', isAuthorized: 'I am authorized to use my company bank account for business spend', }, addPersonalBankAccountPage: { diff --git a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js index 60eb2c7f8d25..8c2facaf4d9a 100644 --- a/src/pages/ReimbursementAccount/ReimbursementAccountPage.js +++ b/src/pages/ReimbursementAccount/ReimbursementAccountPage.js @@ -102,7 +102,7 @@ class ReimbursementAccountPage extends React.Component { // We grab the currentStep from the achData to determine which view to display. The SetupWithdrawalAccount flow // allows us to continue the flow from various points depending on where the user left off. - const currentStep = CONST.BANK_ACCOUNT.STEP.REQUESTOR; //this.props.reimbursementAccount.achData.currentStep; + const currentStep = CONST.BANK_ACCOUNT.STEP.REQUESTOR; // this.props.reimbursementAccount.achData.currentStep; return ( {currentStep === CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT && ( diff --git a/src/pages/ReimbursementAccount/RequestorStep.js b/src/pages/ReimbursementAccount/RequestorStep.js index dc1b508e9feb..e18c494d4e7a 100644 --- a/src/pages/ReimbursementAccount/RequestorStep.js +++ b/src/pages/ReimbursementAccount/RequestorStep.js @@ -1,4 +1,5 @@ import React from 'react'; +import _ from 'underscore'; import {View, TextInput} from 'react-native'; import styles from '../../styles/styles'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; @@ -7,12 +8,12 @@ import CONST from '../../CONST'; import TextLink from '../../components/TextLink'; import Navigation from '../../libs/Navigation/Navigation'; import Icon from '../../components/Icon'; -import TextInputWithLabel from '../../components/TextInputWithLabel'; import CheckboxWithLabel from '../../components/CheckboxWithLabel'; import Text from '../../components/Text'; import Picker from '../../components/Picker'; import {DownArrow} from '../../components/Icon/Expensicons'; import BankAccount from '../../libs/models/BankAccount'; +import Button from '../../components/Button'; const propTypes = { ...withLocalizePropTypes, @@ -27,12 +28,13 @@ class RequestorStep extends React.Component { this.state = { firstName: '', lastName: '', - street: '', - city: '', - state: '', - zipCode: '', + requestorAddressStreet: '', + requestorAddressCity: '', + requestorAddressState: '', + requestorAddressZipCode: '', dob: '', - ssn: '', + ssnLast4: '', + isAuthorized: false, }; } @@ -42,7 +44,19 @@ class RequestorStep extends React.Component { })); } + + /** + * Submits the form for the Requestor Step + */ + submit() { + if (!this.state.isAuthorized) { + console.error('Must be authorized for company spend before proceeding'); + } + } + render() { + // Whether or not the form has been completely filled out + const unfilledFormValues = _.filter(this.state, value => value === '' || value === false); return ( BankAccount.goToWithdrawalStepID(CONST.BANK_ACCOUNT.STEP.REQUESTOR)} onCloseButtonPress={Navigation.dismissModal} /> - - - {this.props.translate('bankAccount.financialRegulations')} - - {`${this.props.translate('bankAccount.learnMore')}`} - - {' | '} - - {`${this.props.translate('bankAccount.isMyDataSafe')}`} - - - - {this.props.translate('bankAccount.onFidoConditions')} - - {`${this.props.translate('bankAccount.onFidoFacialScan')}`} - - {', '} - - {`${this.props.translate('common.privacyPolicy')}`} - - {` ${this.props.translate('common.and')} `} - - {`${this.props.translate('common.termsOfService')}`} - - - + + - this.setState({firstName})} /> - this.setState({lastName})} /> - this.setState({street})} + this.setState({dob})} + /> + this.setState({ssnLast4})} /> this.setState({city})} + style={[styles.textInput, styles.mb4]} + placeholder={this.props.translate('bankAccount.requestorAddressStreet')} + value={this.state.requestorAddressStreet} + onChangeText={requestorAddressStreet => this.setState({requestorAddressStreet})} /> - + + this.setState({requestorAddressCity})} + /> + + this.setState({state})} + onChange={requestorAddressState => this.setState({requestorAddressState})} items={CONST.BANK_ACCOUNT.STATES.map(state => ({value: state, label: state}))} placeholder={{ value: '', - label: this.props.translate('bankAccount.state'), + label: this.props.translate('bankAccount.requestorAddressState'), }} - value={this.state.state} + value={this.state.requestorAddressState} icon={() => } /> - - this.setState({zipCode})} - /> - - - - this.setState({dob})} - /> - - - this.setState({ssn})} + this.setState({requestorAddressZipCode})} /> )} /> + + {this.props.translate('bankAccount.financialRegulations')} + {/* eslint-disable-next-line max-len */} + + {`${this.props.translate('bankAccount.learnMore')}`} + + {' | '} + {/* eslint-disable-next-line max-len */} + + {`${this.props.translate('bankAccount.isMyDataSafe')}`} + + + + {this.props.translate('bankAccount.onFidoConditions')} + + {`${this.props.translate('bankAccount.onFidoFacialScan')}`} + + {', '} + + {`${this.props.translate('common.privacyPolicy')}`} + + {` ${this.props.translate('common.and')} `} + + {`${this.props.translate('common.termsOfService')}`} + + +