From 755f2f8149b7aca2d53be59637ae7e09565981da Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Tue, 27 Sep 2022 18:01:21 -0600 Subject: [PATCH 01/14] add onyxkey and banner --- src/ONYXKEYS.js | 3 +++ src/pages/home/ReportScreen.js | 11 +++++++++++ 2 files changed, 14 insertions(+) diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index ab94c4dff47c..1caa4f2c1942 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -5,6 +5,9 @@ export default { // Holds information about the users account that is logging in ACCOUNT: 'account', + // Holds the reportID for the report between the user and their account manager + ACCOUNT_MANAGER_REPORT_ID: 'accountManagerReportID', + // Boolean flag only true when first set NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER: 'isFirstTimeNewExpensifyUser', diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 09085ae3f7a0..e60722013dc1 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -30,6 +30,8 @@ import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/ import OfflineIndicator from '../../components/OfflineIndicator'; import OfflineWithFeedback from '../../components/OfflineWithFeedback'; import withDrawerState, {withDrawerPropTypes} from '../../components/withDrawerState'; +import Banner from '../../components/Banner'; +import withLocalize from '../../components/withLocalize'; const propTypes = { /** Navigation route context info provided by react navigation */ @@ -246,6 +248,11 @@ class ReportScreen extends React.Component { reportID={reportID} onNavigationMenuButtonClicked={() => Navigation.navigate(ROUTES.HOME)} /> + {this.props.accountManagerReportID && ( + + )} Date: Wed, 28 Sep 2022 13:02:11 -0600 Subject: [PATCH 02/14] add shouldShowIcon prop to Banner --- src/components/ArchivedReportFooter.js | 1 + src/components/Banner.js | 18 ++++++++++++------ src/pages/home/ReportScreen.js | 10 +++++----- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/src/components/ArchivedReportFooter.js b/src/components/ArchivedReportFooter.js index bcb204c98369..4bd5175db750 100644 --- a/src/components/ArchivedReportFooter.js +++ b/src/components/ArchivedReportFooter.js @@ -72,6 +72,7 @@ const ArchivedReportFooter = (props) => { policyName: `${ReportUtils.getPolicyName(props.report, props.policies)}`, })} shouldRenderHTML={archiveReason !== CONST.REPORT.ARCHIVE_REASON.DEFAULT} + shouldShowIcon /> ); }; diff --git a/src/components/Banner.js b/src/components/Banner.js index 87808c22af24..5b30b741b32e 100644 --- a/src/components/Banner.js +++ b/src/components/Banner.js @@ -14,12 +14,16 @@ const propTypes = { /** Text to display in the banner. */ text: PropTypes.string.isRequired, + /** Should this component render the left-aligned exclamation icon? */ + shouldShowIcon: PropTypes.bool, + /** Should this component render the text as HTML? */ shouldRenderHTML: PropTypes.bool, }; const defaultProps = { shouldRenderHTML: false, + shouldShowIcon: false, }; const Banner = props => ( @@ -34,12 +38,14 @@ const Banner = props => ( styles.breakAll, ]} > - - - + {props.shouldShowIcon && ( + + + + )} { props.shouldRenderHTML ? diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index e60722013dc1..cf506ef278f8 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -248,12 +248,12 @@ class ReportScreen extends React.Component { reportID={reportID} onNavigationMenuButtonClicked={() => Navigation.navigate(ROUTES.HOME)} /> - {this.props.accountManagerReportID && ( - - )} + {this.props.accountManagerReportID && ReportUtils.isConciergeChatReport() && ( + + )} Date: Wed, 28 Sep 2022 13:18:43 -0600 Subject: [PATCH 03/14] add close button --- src/components/Banner.js | 31 +++++++++++++++++++++++++++++-- src/pages/home/ReportScreen.js | 5 +++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/components/Banner.js b/src/components/Banner.js index 5b30b741b32e..389f351096d2 100644 --- a/src/components/Banner.js +++ b/src/components/Banner.js @@ -1,6 +1,7 @@ import React, {memo} from 'react'; import PropTypes from 'prop-types'; -import {View} from 'react-native'; +import {View, Pressable} from 'react-native'; +import compose from '../libs/compose'; import Hoverable from './Hoverable'; import Icon from './Icon'; import * as Expensicons from './Icon/Expensicons'; @@ -9,6 +10,8 @@ import Text from './Text'; import styles from '../styles/styles'; import * as StyleUtils from '../styles/StyleUtils'; import getButtonState from '../libs/getButtonState'; +import Tooltip from './Tooltip'; +import withLocalize, {withLocalizePropTypes} from './withLocalize'; const propTypes = { /** Text to display in the banner. */ @@ -17,13 +20,22 @@ const propTypes = { /** Should this component render the left-aligned exclamation icon? */ shouldShowIcon: PropTypes.bool, + /** Should this component render a close button? */ + shouldShowCloseButton: PropTypes.bool, + /** Should this component render the text as HTML? */ shouldRenderHTML: PropTypes.bool, + + onClose: PropTypes.func, + + ...withLocalizePropTypes, }; const defaultProps = { shouldRenderHTML: false, shouldShowIcon: false, + shouldShowCloseButton: false, + onClose: () => {}, }; const Banner = props => ( @@ -51,6 +63,18 @@ const Banner = props => ( ? : {props.text} } + {props.shouldShowCloseButton && ( + + + + + + )} )} @@ -60,4 +84,7 @@ Banner.propTypes = propTypes; Banner.defaultProps = defaultProps; Banner.displayName = 'Banner'; -export default memo(Banner); +export default compose( + withLocalize, + memo, +)(Banner); diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index cf506ef278f8..97df899e54c2 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -249,11 +249,12 @@ class ReportScreen extends React.Component { onNavigationMenuButtonClicked={() => Navigation.navigate(ROUTES.HOME)} /> - {this.props.accountManagerReportID && ReportUtils.isConciergeChatReport() && ( + {/* {this.props.accountManagerReportID && ReportUtils.isConciergeChatReport() && ( */} - )} + {/* )} */} Date: Wed, 28 Sep 2022 13:19:36 -0600 Subject: [PATCH 04/14] add comment --- src/components/Banner.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/Banner.js b/src/components/Banner.js index 389f351096d2..e3e985190994 100644 --- a/src/components/Banner.js +++ b/src/components/Banner.js @@ -26,6 +26,7 @@ const propTypes = { /** Should this component render the text as HTML? */ shouldRenderHTML: PropTypes.bool, + /** Callback called when the close button is pressed */ onClose: PropTypes.func, ...withLocalizePropTypes, From dd00d29b36f1152e07fb8b3e2dadfc1f16d0e382 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Wed, 28 Sep 2022 13:23:48 -0600 Subject: [PATCH 05/14] add Pressable --- src/components/Banner.js | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/components/Banner.js b/src/components/Banner.js index e3e985190994..ca4095f81819 100644 --- a/src/components/Banner.js +++ b/src/components/Banner.js @@ -29,6 +29,9 @@ const propTypes = { /** Callback called when the close button is pressed */ onClose: PropTypes.func, + /** Callback called when the message is pressed */ + onPress: PropTypes.func, + ...withLocalizePropTypes, }; @@ -37,6 +40,7 @@ const defaultProps = { shouldShowIcon: false, shouldShowCloseButton: false, onClose: () => {}, + onPress: () => {}, }; const Banner = props => ( @@ -59,11 +63,15 @@ const Banner = props => ( /> )} - { - props.shouldRenderHTML - ? - : {props.text} - } + + { + props.shouldRenderHTML + ? + : {props.text} + } + {props.shouldShowCloseButton && ( Date: Wed, 28 Sep 2022 13:27:32 -0600 Subject: [PATCH 06/14] add view for styles --- src/components/Banner.js | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/components/Banner.js b/src/components/Banner.js index ca4095f81819..6efbe3bb769b 100644 --- a/src/components/Banner.js +++ b/src/components/Banner.js @@ -53,25 +53,28 @@ const Banner = props => ( styles.borderRadiusNormal, isHovered ? styles.activeComponentBG : styles.hoveredComponentBG, styles.breakAll, + styles.justifyContentBetween, ]} > - {props.shouldShowIcon && ( - - - - )} - - { - props.shouldRenderHTML - ? - : {props.text} - } - + + {props.shouldShowIcon && ( + + + + )} + + { + props.shouldRenderHTML + ? + : {props.text} + } + + {props.shouldShowCloseButton && ( Date: Wed, 28 Sep 2022 14:38:57 -0600 Subject: [PATCH 07/14] add styles --- src/components/Banner.js | 19 ++++++++++++------- src/pages/home/ReportScreen.js | 4 ++++ src/styles/styles.js | 4 ++++ 3 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/components/Banner.js b/src/components/Banner.js index 6efbe3bb769b..69a15e008b8f 100644 --- a/src/components/Banner.js +++ b/src/components/Banner.js @@ -32,6 +32,12 @@ const propTypes = { /** Callback called when the message is pressed */ onPress: PropTypes.func, + // eslint-disable-next-line react/forbid-prop-types + containerStyles: PropTypes.arrayOf(PropTypes.object), + + // eslint-disable-next-line react/forbid-prop-types + textStyles: PropTypes.arrayOf(PropTypes.object), + ...withLocalizePropTypes, }; @@ -41,6 +47,8 @@ const defaultProps = { shouldShowCloseButton: false, onClose: () => {}, onPress: () => {}, + containerStyles: [], + textStyles: [], }; const Banner = props => ( @@ -53,10 +61,10 @@ const Banner = props => ( styles.borderRadiusNormal, isHovered ? styles.activeComponentBG : styles.hoveredComponentBG, styles.breakAll, - styles.justifyContentBetween, + ...props.containerStyles, ]} > - + {props.shouldShowIcon && ( ( /> )} - + { props.shouldRenderHTML ? - : {props.text} + : {props.text} } @@ -79,7 +85,6 @@ const Banner = props => ( diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 97df899e54c2..178f3967ce67 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -6,6 +6,7 @@ import lodashGet from 'lodash/get'; import _ from 'underscore'; import lodashFindLast from 'lodash/findLast'; import styles from '../../styles/styles'; +import colors from '../../styles/colors'; import ScreenWrapper from '../../components/ScreenWrapper'; import HeaderView from './HeaderView'; import Navigation from '../../libs/Navigation/Navigation'; @@ -251,8 +252,11 @@ class ReportScreen extends React.Component { {/* {this.props.accountManagerReportID && ReportUtils.isConciergeChatReport() && ( */} {/* )} */} Date: Wed, 28 Sep 2022 15:04:35 -0600 Subject: [PATCH 08/14] add callbacks --- src/pages/home/ReportScreen.js | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 178f3967ce67..be426c98f6f2 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -6,7 +6,6 @@ import lodashGet from 'lodash/get'; import _ from 'underscore'; import lodashFindLast from 'lodash/findLast'; import styles from '../../styles/styles'; -import colors from '../../styles/colors'; import ScreenWrapper from '../../components/ScreenWrapper'; import HeaderView from './HeaderView'; import Navigation from '../../libs/Navigation/Navigation'; @@ -126,11 +125,14 @@ class ReportScreen extends React.Component { this.onSubmitComment = this.onSubmitComment.bind(this); this.updateViewportOffsetTop = this.updateViewportOffsetTop.bind(this); + this.chatWithAccountManager = this.chatWithAccountManager.bind(this); + this.dismissBanner = this.dismissBanner.bind(this); this.removeViewportResizeListener = () => {}; this.state = { skeletonViewContainerHeight: 0, viewportOffsetTop: 0, + isBannerVisible: true, }; } @@ -205,6 +207,14 @@ class ReportScreen extends React.Component { this.setState({viewportOffsetTop}); } + dismissBanner() { + this.setState({isBannerVisible: false}); + } + + chatWithAccountManager() { + Navigation.navigate(ROUTES.getReportRoute(this.props.accountManagerReportID)); + } + render() { if (!this.props.isSidebarLoaded) { return null; @@ -250,15 +260,16 @@ class ReportScreen extends React.Component { onNavigationMenuButtonClicked={() => Navigation.navigate(ROUTES.HOME)} /> - {/* {this.props.accountManagerReportID && ReportUtils.isConciergeChatReport() && ( */} + {this.props.accountManagerReportID && ReportUtils.isConciergeChatReport(this.props.report) && this.state.isBannerVisible && ( - {/* )} */} + )} Date: Wed, 28 Sep 2022 15:21:58 -0600 Subject: [PATCH 09/14] add copy translations --- src/languages/en.js | 1 + src/languages/es.js | 1 + src/pages/home/ReportScreen.js | 4 ++-- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index fb5108f4bcdd..ea103feb3335 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -211,6 +211,7 @@ export default { beginningOfChatHistoryPolicyExpenseChatPartOne: 'Collaboration between ', beginningOfChatHistoryPolicyExpenseChatPartTwo: ' and ', beginningOfChatHistoryPolicyExpenseChatPartThree: ' starts here! šŸŽ‰ This is the place to chat, request money and settle up.', + chatWithAccountManager: 'Chat with your Account Manager here', }, newMessages: 'New messages', reportTypingIndicator: { diff --git a/src/languages/es.js b/src/languages/es.js index 326191616cc4..3a69f61ae9d9 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -211,6 +211,7 @@ export default { beginningOfChatHistoryPolicyExpenseChatPartOne: 'Ā”La colaboraciĆ³n entre ', beginningOfChatHistoryPolicyExpenseChatPartTwo: ' y ', beginningOfChatHistoryPolicyExpenseChatPartThree: ' empieza aquĆ­! :tada: Este es el lugar donde chatear, pedir dinero y pagar.', + chatWithAccountManager: 'Chatea con tu Gerente de Cuenta aquĆ­', }, newMessages: 'Mensajes nuevos', reportTypingIndicator: { diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index be426c98f6f2..626a9de31c0f 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -260,11 +260,11 @@ class ReportScreen extends React.Component { onNavigationMenuButtonClicked={() => Navigation.navigate(ROUTES.HOME)} /> - {this.props.accountManagerReportID && ReportUtils.isConciergeChatReport(this.props.report) && this.state.isBannerVisible && ( + {ReportUtils.isConciergeChatReport(this.props.report) && this.state.isBannerVisible && ( Date: Wed, 28 Sep 2022 15:24:40 -0600 Subject: [PATCH 10/14] add conditional --- src/pages/home/ReportScreen.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 626a9de31c0f..d52db32f27e4 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -260,7 +260,7 @@ class ReportScreen extends React.Component { onNavigationMenuButtonClicked={() => Navigation.navigate(ROUTES.HOME)} /> - {ReportUtils.isConciergeChatReport(this.props.report) && this.state.isBannerVisible && ( + {this.props.accountManagerReportID && ReportUtils.isConciergeChatReport(this.props.report) && this.state.isBannerVisible && ( Date: Wed, 28 Sep 2022 17:27:25 -0600 Subject: [PATCH 11/14] rm pressable, add styles --- src/components/Banner.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/components/Banner.js b/src/components/Banner.js index 69a15e008b8f..3b5a8d66e3aa 100644 --- a/src/components/Banner.js +++ b/src/components/Banner.js @@ -64,7 +64,7 @@ const Banner = props => ( ...props.containerStyles, ]} > - + {props.shouldShowIcon && ( ( /> )} - - { - props.shouldRenderHTML - ? - : {props.text} - } - + { + props.shouldRenderHTML + ? + : {props.text} + } {props.shouldShowCloseButton && ( From 281bd482f39d51fd7acd4ebf29ea67bb82a5e35d Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 29 Sep 2022 12:00:21 -0600 Subject: [PATCH 12/14] update copy --- src/languages/en.js | 2 +- src/languages/es.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index ea103feb3335..3c06709612eb 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -211,7 +211,7 @@ export default { beginningOfChatHistoryPolicyExpenseChatPartOne: 'Collaboration between ', beginningOfChatHistoryPolicyExpenseChatPartTwo: ' and ', beginningOfChatHistoryPolicyExpenseChatPartThree: ' starts here! šŸŽ‰ This is the place to chat, request money and settle up.', - chatWithAccountManager: 'Chat with your Account Manager here', + chatWithAccountManager: 'Chat with your account manager here', }, newMessages: 'New messages', reportTypingIndicator: { diff --git a/src/languages/es.js b/src/languages/es.js index 3a69f61ae9d9..a57107ac3fe8 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -211,7 +211,7 @@ export default { beginningOfChatHistoryPolicyExpenseChatPartOne: 'Ā”La colaboraciĆ³n entre ', beginningOfChatHistoryPolicyExpenseChatPartTwo: ' y ', beginningOfChatHistoryPolicyExpenseChatPartThree: ' empieza aquĆ­! :tada: Este es el lugar donde chatear, pedir dinero y pagar.', - chatWithAccountManager: 'Chatea con tu Gerente de Cuenta aquĆ­', + chatWithAccountManager: 'Chatea con tu gestor de cuenta aquĆ­', }, newMessages: 'Mensajes nuevos', reportTypingIndicator: { From 01638f8ff18ab1dc1eae994e174b9659baff91fb Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 29 Sep 2022 12:13:14 -0600 Subject: [PATCH 13/14] add logic to keep drawer closed --- src/libs/Navigation/DeprecatedCustomActions.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/libs/Navigation/DeprecatedCustomActions.js b/src/libs/Navigation/DeprecatedCustomActions.js index 1c192d60f93e..a7765d91cd2e 100644 --- a/src/libs/Navigation/DeprecatedCustomActions.js +++ b/src/libs/Navigation/DeprecatedCustomActions.js @@ -104,14 +104,21 @@ function pushDrawerRoute(route) { // Force drawer to close // https://github.com/react-navigation/react-navigation/blob/94ab791cae5061455f036cd3f6bc7fa63167e7c7/packages/routers/src/DrawerRouter.tsx#L142 - const hasDrawerhistory = _.find(state.history || [], h => h.type === 'drawer'); - if (!hasDrawerhistory || currentState.type !== 'drawer') { + const drawerHistoryItem = _.find(state.history || [], h => h.type === 'drawer'); + const isDrawerClosed = drawerHistoryItem && drawerHistoryItem.status === 'closed'; + if (!drawerHistoryItem || currentState.type !== 'drawer') { history.push({ type: 'drawer', // If current state is not from drawer navigator then always use closed status to close the drawer status: currentState.type !== 'drawer' || currentState.default === 'open' ? 'closed' : 'open', }); + } else if (isDrawerClosed) { + // Keep the drawer closed if it's already closed + history.push({ + type: 'drawer', + status: 'closed', + }); } return CommonActions.reset({ From f953a4c79362ec6109b4d958555d8320405e2bf8 Mon Sep 17 00:00:00 2001 From: Carlos Martins Date: Thu, 29 Sep 2022 13:19:03 -0600 Subject: [PATCH 14/14] add comments on navigator changes --- src/libs/Navigation/DeprecatedCustomActions.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/Navigation/DeprecatedCustomActions.js b/src/libs/Navigation/DeprecatedCustomActions.js index a7765d91cd2e..eb10d9c2f827 100644 --- a/src/libs/Navigation/DeprecatedCustomActions.js +++ b/src/libs/Navigation/DeprecatedCustomActions.js @@ -102,15 +102,15 @@ function pushDrawerRoute(route) { const screenRoute = {type: 'route', name: newScreenName}; const history = _.map(state.history ? [...state.history] : [screenRoute], () => screenRoute); - // Force drawer to close - // https://github.com/react-navigation/react-navigation/blob/94ab791cae5061455f036cd3f6bc7fa63167e7c7/packages/routers/src/DrawerRouter.tsx#L142 const drawerHistoryItem = _.find(state.history || [], h => h.type === 'drawer'); const isDrawerClosed = drawerHistoryItem && drawerHistoryItem.status === 'closed'; if (!drawerHistoryItem || currentState.type !== 'drawer') { + // Add the drawer item to the navigation history to control if the drawer should be in open or closed state history.push({ type: 'drawer', - // If current state is not from drawer navigator then always use closed status to close the drawer + // If current state is not from drawer navigator then always force the drawer to close by using closed status + // https://github.com/react-navigation/react-navigation/blob/94ab791cae5061455f036cd3f6bc7fa63167e7c7/packages/routers/src/DrawerRouter.tsx#L142 status: currentState.type !== 'drawer' || currentState.default === 'open' ? 'closed' : 'open', }); } else if (isDrawerClosed) {