From ecdafb4c738a908c38e48d852ccba16f38680642 Mon Sep 17 00:00:00 2001 From: Rocio Perez-Cano Date: Tue, 9 May 2023 18:57:52 +0200 Subject: [PATCH 01/18] Add MenuItemWithTopDescription --- src/pages/ReportSettingsPage.js | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/pages/ReportSettingsPage.js b/src/pages/ReportSettingsPage.js index dfb5c19f92ff..3cc1f666ba11 100644 --- a/src/pages/ReportSettingsPage.js +++ b/src/pages/ReportSettingsPage.js @@ -25,6 +25,8 @@ import reportPropTypes from './reportPropTypes'; import withReportOrNotFound from './home/report/withReportOrNotFound'; import Form from '../components/Form'; import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView'; +import MenuItemWithTopDescription from "../components/MenuItemWithTopDescription"; +import ROUTES from "../ROUTES"; const propTypes = { /** Route params */ @@ -145,7 +147,7 @@ class ReportSettingsPage extends Component { render() { const shouldShowRoomName = !ReportUtils.isPolicyExpenseChat(this.props.report); const linkedWorkspace = _.find(this.props.policies, policy => policy && policy.id === this.props.report.policyID); - const shouldDisableRename = this.shouldDisableRename(linkedWorkspace); + const shouldDisableRenameOrWelcomeMessage = this.shouldDisableRename(linkedWorkspace); return ( @@ -161,9 +163,9 @@ class ReportSettingsPage extends Component { submitButtonText={this.props.translate('common.save')} style={[styles.mh5, styles.mt5, styles.flexGrow1]} validate={this.validate} - onSubmit={values => !shouldDisableRename && this.updatePolicyRoomName(values)} + onSubmit={values => !shouldDisableRenameOrWelcomeMessage && this.updatePolicyRoomName(values)} scrollContextEnabled - isSubmitButtonVisible={shouldShowRoomName && !shouldDisableRename} + isSubmitButtonVisible={shouldShowRoomName && !shouldDisableRenameOrWelcomeMessage} enabledWhenOffline > @@ -195,7 +197,7 @@ class ReportSettingsPage extends Component { > - {shouldDisableRename ? ( + {shouldDisableRenameOrWelcomeMessage ? ( {this.props.translate('newRoomPage.roomName')} @@ -216,6 +218,14 @@ class ReportSettingsPage extends Component { )} + {!shouldDisableRenameOrWelcomeMessage && ( + Navigation.navigate(ROUTES.SETTINGS_PRIORITY_MODE)} + /> + )} {Boolean(linkedWorkspace) && ( From 258cac78813fd7602a35fd0b6ef77d00dc53c312 Mon Sep 17 00:00:00 2001 From: Rocio Perez-Cano Date: Wed, 10 May 2023 13:05:59 +0200 Subject: [PATCH 02/18] Move menu itel to room menu instead --- src/CONST.js | 1 + src/languages/en.js | 4 ++++ src/languages/es.js | 4 ++++ src/pages/ReportDetailsPage.js | 10 ++++++++++ src/pages/ReportSettingsPage.js | 21 +++++++-------------- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/CONST.js b/src/CONST.js index abca3e1a5838..6c25c4234081 100755 --- a/src/CONST.js +++ b/src/CONST.js @@ -1089,6 +1089,7 @@ const CONST = { MEMBERS: 'member', SETTINGS: 'settings', LEAVE_ROOM: 'leaveRoom', + WELCOME_MESSAGE: 'welcomeMessage', }, FOOTER: { diff --git a/src/languages/en.js b/src/languages/en.js index 3b48f890b05d..2ef49dd60bb1 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -572,6 +572,10 @@ export default { }, }, }, + welcomeMessagePage: { + welcomeMessage: 'Welcome message', + explainerText: 'Choose whether to show all chats by default sorted with most recent with pinned items at the top, or #focus on unread pinned items, sorted alphabetically.', + }, languagePage: { language: 'Language', languages: { diff --git a/src/languages/es.js b/src/languages/es.js index 1898baf8aced..97a36f6c359e 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -571,6 +571,10 @@ export default { }, }, }, + welcomeMessagePage: { + welcomeMessage: 'Mensaje de bienvenida', + explainerText: 'Choose whether to show all chats by default sorted with most recent with pinned items at the top, or #focus on unread pinned items, sorted alphabetically.', + }, languagePage: { language: 'Idioma', languages: { diff --git a/src/pages/ReportDetailsPage.js b/src/pages/ReportDetailsPage.js index 8dc81875fa6d..f7e8636639ea 100644 --- a/src/pages/ReportDetailsPage.js +++ b/src/pages/ReportDetailsPage.js @@ -82,7 +82,17 @@ class ReportDetailsPage extends Component { }); } + // We only want policy owners and admins to be able to modify the welcome message. const policy = this.props.policies[`${ONYXKEYS.COLLECTION.POLICY}${this.props.report.policyID}`]; + if (!ReportUtils.isArchivedRoom(this.props.report) && (Policy.isPolicyOwner(policy) && policy.role === CONST.POLICY.ROLE.ADMIN)) { + menuItems.push({ + key: CONST.REPORT_DETAILS_MENU_ITEM.WELCOME_MESSAGE, + translationKey: 'welcomeMessagePage.welcomeMessage', + icon: Expensicons.ChatBubble, + action: () => { Navigation.navigate(ROUTES.getReportSettingsRoute(this.props.report.reportID)); }, + }); + } + if (ReportUtils.isUserCreatedPolicyRoom(this.props.report) || ReportUtils.canLeaveRoom(this.props.report, !_.isEmpty(policy))) { menuItems.push({ key: CONST.REPORT_DETAILS_MENU_ITEM.LEAVE_ROOM, diff --git a/src/pages/ReportSettingsPage.js b/src/pages/ReportSettingsPage.js index 3cc1f666ba11..43aa8b55f353 100644 --- a/src/pages/ReportSettingsPage.js +++ b/src/pages/ReportSettingsPage.js @@ -25,8 +25,9 @@ import reportPropTypes from './reportPropTypes'; import withReportOrNotFound from './home/report/withReportOrNotFound'; import Form from '../components/Form'; import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView'; -import MenuItemWithTopDescription from "../components/MenuItemWithTopDescription"; -import ROUTES from "../ROUTES"; +import ROUTES from '../ROUTES'; +import MenuItem from '../components/MenuItem'; +import * as Expensicons from '../components/Icon/Expensicons'; const propTypes = { /** Route params */ @@ -147,7 +148,7 @@ class ReportSettingsPage extends Component { render() { const shouldShowRoomName = !ReportUtils.isPolicyExpenseChat(this.props.report); const linkedWorkspace = _.find(this.props.policies, policy => policy && policy.id === this.props.report.policyID); - const shouldDisableRenameOrWelcomeMessage = this.shouldDisableRename(linkedWorkspace); + const shouldDisableRename = this.shouldDisableRename(linkedWorkspace); return ( @@ -163,9 +164,9 @@ class ReportSettingsPage extends Component { submitButtonText={this.props.translate('common.save')} style={[styles.mh5, styles.mt5, styles.flexGrow1]} validate={this.validate} - onSubmit={values => !shouldDisableRenameOrWelcomeMessage && this.updatePolicyRoomName(values)} + onSubmit={values => !shouldDisableRename && this.updatePolicyRoomName(values)} scrollContextEnabled - isSubmitButtonVisible={shouldShowRoomName && !shouldDisableRenameOrWelcomeMessage} + isSubmitButtonVisible={shouldShowRoomName && !shouldDisableRename} enabledWhenOffline > @@ -197,7 +198,7 @@ class ReportSettingsPage extends Component { > - {shouldDisableRenameOrWelcomeMessage ? ( + {shouldDisableRename ? ( {this.props.translate('newRoomPage.roomName')} @@ -218,14 +219,6 @@ class ReportSettingsPage extends Component { )} - {!shouldDisableRenameOrWelcomeMessage && ( - Navigation.navigate(ROUTES.SETTINGS_PRIORITY_MODE)} - /> - )} {Boolean(linkedWorkspace) && ( From b43148e7d9d57cb71fa6584353eab407bdf982af Mon Sep 17 00:00:00 2001 From: Rocio Perez-Cano Date: Wed, 10 May 2023 13:24:36 +0200 Subject: [PATCH 03/18] Add new route --- src/ROUTES.js | 2 + .../Navigation/AppNavigator/AuthScreens.js | 6 ++ .../AppNavigator/ModalStackNavigators.js | 9 +++ src/libs/Navigation/linkingConfig.js | 5 ++ src/pages/ReportDetailsPage.js | 2 +- src/pages/ReportSettingsPage.js | 3 - src/pages/ReportWelcomeMessagePage.js | 71 +++++++++++++++++++ 7 files changed, 94 insertions(+), 4 deletions(-) create mode 100644 src/pages/ReportWelcomeMessagePage.js diff --git a/src/ROUTES.js b/src/ROUTES.js index b4ae96eb5967..5d84e9cc83da 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -115,6 +115,8 @@ export default { getReportDetailsRoute: reportID => `r/${reportID}/details`, REPORT_SETTINGS: 'r/:reportID/settings', getReportSettingsRoute: reportID => `r/${reportID}/settings`, + REPORT_WELCOME_MESSAGE: 'r/:reportID/welcomeMessage', + getReportWelcomeMessageRoute: reportID => `r/${reportID}/welcomeMessage`, TRANSITION_FROM_OLD_DOT: 'transition', VALIDATE_LOGIN: 'v/:accountID/:validateCode', GET_ASSISTANCE: 'get-assistance/:taskID', diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js index 99752b462c77..5e792b485ab6 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.js +++ b/src/libs/Navigation/AppNavigator/AuthScreens.js @@ -287,6 +287,12 @@ class AuthScreens extends React.Component { component={ModalStackNavigators.ReportSettingsModalStackNavigator} listeners={modalScreenListeners} /> + { + const ReportWelcomeMessagePage = require('../../../pages/ReportWelcomeMessagePage').default; + return ReportWelcomeMessagePage; + }, + name: 'Report_WelcomeMessage_Root', +}]); + const ReportParticipantsModalStackNavigator = createModalStackNavigator([ { getComponent: () => { @@ -610,6 +618,7 @@ export { ReportDetailsModalStackNavigator, TaskModalStackNavigator, ReportSettingsModalStackNavigator, + ReportWelcomeMessageModalStackNavigator, ReportParticipantsModalStackNavigator, SearchModalStackNavigator, NewGroupModalStackNavigator, diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index 9ce9c763a4d1..fada9e3279d2 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -200,6 +200,11 @@ export default { Report_Settings_Root: ROUTES.REPORT_SETTINGS, }, }, + Report_WelcomeMessage: { + screens: { + Report_WelcomeMessage_Root: ROUTES.REPORT_WELCOME_MESSAGE, + }, + }, NewGroup: { screens: { NewGroup_Root: ROUTES.NEW_GROUP, diff --git a/src/pages/ReportDetailsPage.js b/src/pages/ReportDetailsPage.js index f7e8636639ea..29c1caf3c039 100644 --- a/src/pages/ReportDetailsPage.js +++ b/src/pages/ReportDetailsPage.js @@ -89,7 +89,7 @@ class ReportDetailsPage extends Component { key: CONST.REPORT_DETAILS_MENU_ITEM.WELCOME_MESSAGE, translationKey: 'welcomeMessagePage.welcomeMessage', icon: Expensicons.ChatBubble, - action: () => { Navigation.navigate(ROUTES.getReportSettingsRoute(this.props.report.reportID)); }, + action: () => { Navigation.navigate(ROUTES.getReportWelcomeMessageRoute(this.props.report.reportID)); }, }); } diff --git a/src/pages/ReportSettingsPage.js b/src/pages/ReportSettingsPage.js index 43aa8b55f353..dfb5c19f92ff 100644 --- a/src/pages/ReportSettingsPage.js +++ b/src/pages/ReportSettingsPage.js @@ -25,9 +25,6 @@ import reportPropTypes from './reportPropTypes'; import withReportOrNotFound from './home/report/withReportOrNotFound'; import Form from '../components/Form'; import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView'; -import ROUTES from '../ROUTES'; -import MenuItem from '../components/MenuItem'; -import * as Expensicons from '../components/Icon/Expensicons'; const propTypes = { /** Route params */ diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js new file mode 100644 index 000000000000..c669fd031930 --- /dev/null +++ b/src/pages/ReportWelcomeMessagePage.js @@ -0,0 +1,71 @@ +import React, {Component} from 'react'; +import PropTypes from 'prop-types'; +import {withOnyx} from 'react-native-onyx'; +import _ from 'underscore'; +import {ScrollView} from 'react-native'; +import compose from '../libs/compose'; +import withLocalize, {withLocalizePropTypes} from '../components/withLocalize'; +import ONYXKEYS from '../ONYXKEYS'; +import ScreenWrapper from '../components/ScreenWrapper'; +import Navigation from '../libs/Navigation/Navigation'; +import HeaderWithCloseButton from '../components/HeaderWithCloseButton'; +import styles from '../styles/styles'; +import reportPropTypes from './reportPropTypes'; +import withReportOrNotFound from './home/report/withReportOrNotFound'; +import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView'; + +const propTypes = { + ...withLocalizePropTypes, + + /** The report currently being looked at */ + report: reportPropTypes.isRequired, + + /** The policies which the user has access to and which the report could be tied to */ + policies: PropTypes.shape({ + /** Name of the policy */ + name: PropTypes.string, + }), + + /** Route params */ + route: PropTypes.shape({ + params: PropTypes.shape({ + /** Report ID passed via route r/:reportID/details */ + reportID: PropTypes.string, + }), + }).isRequired, +}; + +const defaultProps = { + policies: {}, +}; + +class ReportWelcomeMessagePage extends Component { + render() { + return ( + + + Navigation.goBack()} + onCloseButtonPress={() => Navigation.dismissModal()} + /> + + Example + + + + ); + } +} + +ReportWelcomeMessagePage.propTypes = propTypes; +ReportWelcomeMessagePage.defaultProps = defaultProps; +export default compose( + withLocalize, + withReportOrNotFound, + withOnyx({ + policies: { + key: ONYXKEYS.COLLECTION.POLICY, + }, + }), +)(ReportWelcomeMessagePage); From 44fc179e9c7970e05c5f32ded8aa030155ef23c4 Mon Sep 17 00:00:00 2001 From: Rocio Perez-Cano Date: Wed, 10 May 2023 13:40:29 +0200 Subject: [PATCH 04/18] use hooks --- src/languages/en.js | 2 +- src/languages/es.js | 2 +- src/pages/ReportWelcomeMessagePage.js | 48 +++++++++++++++++---------- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/src/languages/en.js b/src/languages/en.js index 2ef49dd60bb1..8e57cc99f8c9 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -574,7 +574,7 @@ export default { }, welcomeMessagePage: { welcomeMessage: 'Welcome message', - explainerText: 'Choose whether to show all chats by default sorted with most recent with pinned items at the top, or #focus on unread pinned items, sorted alphabetically.', + explainerText: 'Set a custom welcome message that will be sent users when they join this room.', }, languagePage: { language: 'Language', diff --git a/src/languages/es.js b/src/languages/es.js index 97a36f6c359e..486329e7aa92 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -573,7 +573,7 @@ export default { }, welcomeMessagePage: { welcomeMessage: 'Mensaje de bienvenida', - explainerText: 'Choose whether to show all chats by default sorted with most recent with pinned items at the top, or #focus on unread pinned items, sorted alphabetically.', + explainerText: 'Set a custom welcome message that will be sent users when they join this room.', }, languagePage: { language: 'Idioma', diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js index c669fd031930..9334d4fc8312 100644 --- a/src/pages/ReportWelcomeMessagePage.js +++ b/src/pages/ReportWelcomeMessagePage.js @@ -1,4 +1,6 @@ -import React, {Component} from 'react'; +import React, { + useCallback, useMemo, useRef, useState, +} from 'react'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; @@ -39,23 +41,33 @@ const defaultProps = { policies: {}, }; -class ReportWelcomeMessagePage extends Component { - render() { - return ( - - - Navigation.goBack()} - onCloseButtonPress={() => Navigation.dismissModal()} - /> - - Example - - - - ); - } +function ReportWelcomeMessagePage(props) { + const [welcomeMessage, setWelcomeMessage] = useState(''); + + const handleWelcomeMessageChange = useCallback((value) => { + setWelcomeMessage(value); + }, []); + + const submitForm = useCallback(() => { + // TODO: Save welcome message + }, [welcomeMessage]); + + return ( + + + Navigation.goBack()} + onCloseButtonPress={() => Navigation.dismissModal()} + /> + + + {props.translate('welcomeMessagePage.explainerText')} + + + + + ); } ReportWelcomeMessagePage.propTypes = propTypes; From 86f683defc2fe3e035ad8dd01c428e1be8a14bef Mon Sep 17 00:00:00 2001 From: Rocio Perez-Cano Date: Wed, 10 May 2023 13:50:58 +0200 Subject: [PATCH 05/18] Add elements to return --- src/pages/ReportWelcomeMessagePage.js | 35 ++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/src/pages/ReportWelcomeMessagePage.js b/src/pages/ReportWelcomeMessagePage.js index 9334d4fc8312..89a66ef658e2 100644 --- a/src/pages/ReportWelcomeMessagePage.js +++ b/src/pages/ReportWelcomeMessagePage.js @@ -1,10 +1,10 @@ import React, { - useCallback, useMemo, useRef, useState, + useCallback, useRef, useState, } from 'react'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; -import {ScrollView} from 'react-native'; +import {ScrollView, TextInput, View} from 'react-native'; import compose from '../libs/compose'; import withLocalize, {withLocalizePropTypes} from '../components/withLocalize'; import ONYXKEYS from '../ONYXKEYS'; @@ -15,6 +15,8 @@ import styles from '../styles/styles'; import reportPropTypes from './reportPropTypes'; import withReportOrNotFound from './home/report/withReportOrNotFound'; import FullPageNotFoundView from '../components/BlockingViews/FullPageNotFoundView'; +import FixedFooter from '../components/FixedFooter'; +import Button from '../components/Button'; const propTypes = { ...withLocalizePropTypes, @@ -43,6 +45,7 @@ const defaultProps = { function ReportWelcomeMessagePage(props) { const [welcomeMessage, setWelcomeMessage] = useState(''); + const welcomeMessageInputRef = useRef(null); const handleWelcomeMessageChange = useCallback((value) => { setWelcomeMessage(value); @@ -53,7 +56,14 @@ function ReportWelcomeMessagePage(props) { }, [welcomeMessage]); return ( - + { + if (!welcomeMessageInputRef.current) { + return; + } + welcomeMessageInputRef.current.focus(); + }} + > {props.translate('welcomeMessagePage.explainerText')} + + + + +