From 58e9005bf13b402b28093c689e92dc224fc0288b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Horus=20Lugo=20L=C3=B3pez?= Date: Thu, 29 Jul 2021 11:38:01 +0200 Subject: [PATCH 01/18] Add edit button for workspace name --- src/components/AvatarWithImagePicker.js | 2 +- src/pages/workspace/WorkspaceSidebar.js | 33 ++++++++++++++++--------- src/styles/styles.js | 11 ++++++++- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/components/AvatarWithImagePicker.js b/src/components/AvatarWithImagePicker.js index 219203bb57f87..2b9e56a0495af 100644 --- a/src/components/AvatarWithImagePicker.js +++ b/src/components/AvatarWithImagePicker.js @@ -114,7 +114,7 @@ class AvatarWithImagePicker extends React.Component { {({openPicker}) => ( <> this.setState({isMenuVisible: true})} > diff --git a/src/pages/workspace/WorkspaceSidebar.js b/src/pages/workspace/WorkspaceSidebar.js index e5f3df1609c7a..c7bd0d4810091 100644 --- a/src/pages/workspace/WorkspaceSidebar.js +++ b/src/pages/workspace/WorkspaceSidebar.js @@ -1,6 +1,6 @@ import _ from 'underscore'; import React from 'react'; -import {View, ScrollView} from 'react-native'; +import {View, ScrollView, Pressable} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; @@ -13,6 +13,7 @@ import { Users, ExpensifyCard, Workspace, + Pencil, } from '../../components/Icon/Expensicons'; import ScreenWrapper from '../../components/ScreenWrapper'; import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; @@ -105,17 +106,27 @@ const WorkspaceSidebar = ({translate, isSmallScreenWidth, policy}) => { }} onImageRemoved={() => setAvatarURL(policy.id)} /> - - {policy.name} - + + {policy.name} + + alert('edit')} + > + + + {menuItems.map(item => ( diff --git a/src/styles/styles.js b/src/styles/styles.js index 8726d33b2a4e6..7880590cdbc80 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1790,14 +1790,23 @@ const styles = { borderColor: themeColors.textReversed, borderRadius: 16, borderWidth: 3, - bottom: -4, color: themeColors.textReversed, height: 32, + width: 32, justifyContent: 'center', padding: 4, + }, + + smallAvatarEditIcon: { position: 'absolute', right: -4, width: 32, + bottom: -4, + }, + + smallNameEditIcon: { + position: 'absolute', + right: -36, }, workspaceCard: { From 529b62e5e918eb57930e8db0eac45656091ec905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Horus=20Lugo=20L=C3=B3pez?= Date: Thu, 29 Jul 2021 13:01:20 +0200 Subject: [PATCH 02/18] Add WorkspaceNameEditor modal --- src/ROUTES.js | 2 + .../Navigation/AppNavigator/AuthScreens.js | 7 ++ .../AppNavigator/ModalStackNavigators.js | 7 ++ src/libs/Navigation/linkingConfig.js | 6 ++ .../workspace/WorkspaceNameEditorPage.js | 95 +++++++++++++++++++ src/pages/workspace/WorkspaceSidebar.js | 4 +- 6 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 src/pages/workspace/WorkspaceNameEditorPage.js diff --git a/src/ROUTES.js b/src/ROUTES.js index bbe1883d441e0..9b02df08f339b 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -80,6 +80,8 @@ export default { getWorkspaceInviteRoute: policyID => `workspace/${policyID}/invite`, WORKSPACE_INVITE: 'workspace/:policyID/invite', REQUEST_CALL: 'request-call', + getWorkspaceNameEditorRoute: policyID => `workspace/${policyID}/edit-name`, + WORKSPACE_NAME_EDITOR: 'workspace/:policyID/edit-name', /** * @param {String} route diff --git a/src/libs/Navigation/AppNavigator/AuthScreens.js b/src/libs/Navigation/AppNavigator/AuthScreens.js index 028ff82ea4438..b5598d01c847c 100644 --- a/src/libs/Navigation/AppNavigator/AuthScreens.js +++ b/src/libs/Navigation/AppNavigator/AuthScreens.js @@ -58,6 +58,7 @@ import { WorkspaceInviteModalStackNavigator, RequestCallModalStackNavigator, ReportDetailsModalStackNavigator, + WorkspaceNameEditorNavigator, } from './ModalStackNavigators'; import SCREENS from '../../../SCREENS'; import Timers from '../../Timers'; @@ -408,6 +409,12 @@ class AuthScreens extends React.Component { component={IOUSendModalStackNavigator} listeners={modalScreenListeners} /> + ); } diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 326dc6ed11ad0..80758b1d654d5 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -28,6 +28,7 @@ import ReimbursementAccountPage from '../../../pages/ReimbursementAccount/Reimbu import NewWorkspacePage from '../../../pages/workspace/NewWorkspacePage'; import RequestCallPage from '../../../pages/RequestCallPage'; import ReportDetailsPage from '../../../pages/ReportDetailsPage'; +import WorkspaceNameEditorPage from '../../../pages/workspace/WorkspaceNameEditorPage'; const defaultSubRouteOptions = { cardStyle: styles.navigationScreenCardStyle, @@ -197,6 +198,11 @@ const RequestCallModalStackNavigator = createModalStackNavigator([{ name: 'RequestCall_Root', }]); +const WorkspaceNameEditorNavigator = createModalStackNavigator([{ + Component: WorkspaceNameEditorPage, + name: 'WorkspaceNameEditor_Root', +}]); + export { IOUBillStackNavigator, IOURequestModalStackNavigator, @@ -215,4 +221,5 @@ export { NewWorkspaceStackNavigator, WorkspaceInviteModalStackNavigator, RequestCallModalStackNavigator, + WorkspaceNameEditorNavigator, }; diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index cf3c57b07ac6b..0ca70ae46075e 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -157,6 +157,12 @@ export default { }, }, + WorkspaceNameEditor: { + screens: { + WorkspaceNameEditor_Root: ROUTES.WORKSPACE_NAME_EDITOR, + }, + }, + RequestCall: { screens: { RequestCall_Root: ROUTES.REQUEST_CALL, diff --git a/src/pages/workspace/WorkspaceNameEditorPage.js b/src/pages/workspace/WorkspaceNameEditorPage.js new file mode 100644 index 0000000000000..2c2c8f81df93e --- /dev/null +++ b/src/pages/workspace/WorkspaceNameEditorPage.js @@ -0,0 +1,95 @@ +import React from 'react'; +import {View} from 'react-native'; +import {withOnyx} from 'react-native-onyx'; +import PropTypes from 'prop-types'; +import ONYXKEYS from '../../ONYXKEYS'; +import HeaderWithCloseButton from '../../components/HeaderWithCloseButton'; +import ScreenWrapper from '../../components/ScreenWrapper'; +import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; +import Navigation from '../../libs/Navigation/Navigation'; +import Permissions from '../../libs/Permissions'; +import styles from '../../styles/styles'; +import WorkspaceDefaultAvatar from '../../../assets/images/workspace-default-avatar.svg'; +import TextInputWithLabel from '../../components/TextInputWithLabel'; +import Button from '../../components/Button'; +import Text from '../../components/Text'; +import compose from '../../libs/compose'; +import {create} from '../../libs/actions/Policy'; +import defaultTheme from '../../styles/themes/default'; + +const propTypes = { + /** List of betas */ + betas: PropTypes.arrayOf(PropTypes.string), + + ...withLocalizePropTypes, +}; +const defaultProps = { + betas: [], +}; + +class WorkspaceNameEditorPage extends React.Component { + constructor(props) { + super(props); + + this.state = { + name: '', + }; + + this.submit = this.submit.bind(this); + } + + submit() { + const name = this.state.name.trim(); + create(name); + } + + render() { + if (!Permissions.canUseFreePlan(this.props.betas)) { + console.debug('Not showing new workspace page because user is not on free plan beta'); + return ; + } + + return ( + + + + + + + + this.setState({name})} + onSubmitEditting={this.submit} + /> + {this.props.translate('workspace.new.helpText')} + + +