From 8958fede56bc0847e5980748dba1a87c9b06670c Mon Sep 17 00:00:00 2001 From: Abdul Rahuman Date: Fri, 24 Mar 2023 20:10:04 +0530 Subject: [PATCH 01/23] Implementing Invite message page --- src/ONYXKEYS.js | 1 + src/ROUTES.js | 2 + src/components/Form.js | 5 + src/components/MenuItem.js | 6 +- src/components/MultipleAvatars.js | 66 +++++- src/components/menuItemPropTypes.js | 3 + src/languages/en.js | 9 +- src/languages/es.js | 9 +- .../AppNavigator/ModalStackNavigators.js | 7 + src/libs/Navigation/linkingConfig.js | 3 + src/libs/actions/Policy.js | 5 + src/pages/settings/InitialSettingsPage.js | 2 + .../workspace/WorkspaceInviteMessagePage.js | 211 ++++++++++++++++++ src/pages/workspace/WorkspaceInvitePage.js | 64 +----- src/styles/StyleUtils.js | 32 +++ src/styles/styles.js | 38 ---- 16 files changed, 353 insertions(+), 110 deletions(-) create mode 100644 src/pages/workspace/WorkspaceInviteMessagePage.js diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index 42a4a2d651be..dc58aa6543c8 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -110,6 +110,7 @@ export default { POLICY: 'policy_', REPORT_IS_COMPOSER_FULL_SIZE: 'reportIsComposerFullSize_', POLICY_MEMBER_LIST: 'policyMemberList_', + WORKSPACE_INVITE_MEMBERS_DRAFT: 'workspaceInviteMembersDraft_', DOWNLOAD: 'download_', }, diff --git a/src/ROUTES.js b/src/ROUTES.js index 2cbe87a4361e..989f9420d694 100644 --- a/src/ROUTES.js +++ b/src/ROUTES.js @@ -114,6 +114,7 @@ export default { WORKSPACE_NEW: 'workspace/new', WORKSPACE_INITIAL: 'workspace/:policyID', WORKSPACE_INVITE: 'workspace/:policyID/invite', + WORKSPACE_INVITE_MESSAGE: 'workspace/:policyID/invite-message', WORKSPACE_SETTINGS: 'workspace/:policyID/settings', WORKSPACE_CARD: 'workspace/:policyID/card', WORKSPACE_REIMBURSE: 'workspace/:policyID/reimburse', @@ -124,6 +125,7 @@ export default { WORKSPACE_NEW_ROOM: 'workspace/new-room', getWorkspaceInitialRoute: policyID => `workspace/${policyID}`, getWorkspaceInviteRoute: policyID => `workspace/${policyID}/invite`, + getWorkspaceInviteMessageRoute: policyID => `workspace/${policyID}/invite-message`, getWorkspaceSettingsRoute: policyID => `workspace/${policyID}/settings`, getWorkspaceCardRoute: policyID => `workspace/${policyID}/card`, getWorkspaceReimburseRoute: policyID => `workspace/${policyID}/reimburse`, diff --git a/src/components/Form.js b/src/components/Form.js index 116179b46d4a..63889f9b203d 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -77,6 +77,9 @@ const propTypes = { /** Container styles */ style: stylePropTypes, + /** Custom content to display in the footer after submit button */ + footerContent: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), + ...withLocalizePropTypes, }; @@ -91,6 +94,7 @@ const defaultProps = { isSubmitActionDangerous: false, scrollToOverflowEnabled: false, scrollContextEnabled: false, + footerContent: null, style: [], }; @@ -335,6 +339,7 @@ class Form extends React.Component { disablePressOnEnter /> )} + {this.props.footerContent} ); diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index 2942f250ce83..19063a9e52ba 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -67,6 +67,8 @@ const MenuItem = (props) => { styles.lineHeightNormal, ], props.style); + const fallbackAvatarSize = (props.viewMode === CONST.OPTION_MODE.COMPACT) ? CONST.AVATAR_SIZE.SMALL : CONST.AVATAR_SIZE.DEFAULT; + return ( { @@ -175,12 +177,12 @@ const MenuItem = (props) => { )} {!_.isEmpty(props.floatRightAvatars) && ( - + diff --git a/src/components/MultipleAvatars.js b/src/components/MultipleAvatars.js index 6e30a2579a25..735525461675 100644 --- a/src/components/MultipleAvatars.js +++ b/src/components/MultipleAvatars.js @@ -55,13 +55,12 @@ const defaultProps = { }; const MultipleAvatars = (props) => { - const avatarContainerStyles = props.size === CONST.AVATAR_SIZE.SMALL ? styles.emptyAvatarSmall : styles.emptyAvatar; + let avatarContainerStyles = props.size === CONST.AVATAR_SIZE.SMALL ? styles.emptyAvatarSmall : styles.emptyAvatar; const singleAvatarStyles = props.size === CONST.AVATAR_SIZE.SMALL ? styles.singleAvatarSmall : styles.singleAvatar; const secondAvatarStyles = [ props.size === CONST.AVATAR_SIZE.SMALL ? styles.secondAvatarSmall : styles.secondAvatar, ...props.secondAvatarStyle, ]; - const horizontalStyles = [styles.horizontalStackedAvatar4, styles.horizontalStackedAvatar3, styles.horizontalStackedAvatar2, styles.horizontalStackedAvatar1]; if (!props.icons.length) { return null; @@ -83,6 +82,32 @@ const MultipleAvatars = (props) => { ); } + const oneAvatarSize = StyleUtils.getAvatarStyle(props.size); + const oneAvatarBorderWidth = StyleUtils.getAvatarBorderSize(props.size); + const overlapSize = oneAvatarSize.width / 3; + + if (props.shouldStackHorizontally) { + let width; + + // Height of one avatar + border space + const height = oneAvatarSize.height + (2 * oneAvatarBorderWidth); + if (props.icons.length > 4) { + // Width of overlapping avatars + border space + width = (oneAvatarSize.width * 3) + (oneAvatarBorderWidth * 8); + } else { + // one avatar width + overlaping avatar sizes + border space + width = oneAvatarSize.width + (overlapSize * 2 * (props.icons.length - 1)) + (oneAvatarBorderWidth * (props.icons.length * 2)); + } + avatarContainerStyles = StyleUtils.combineStyles([ + styles.alignItemsCenter, + styles.flexRow, + { + width, + height, + }, + ]); + } + return ( {props.shouldStackHorizontally ? ( @@ -91,13 +116,19 @@ const MultipleAvatars = (props) => { _.map([...props.icons].splice(0, 4).reverse(), (icon, index) => ( @@ -114,12 +145,29 @@ const MultipleAvatars = (props) => { // Set overlay background color with RGBA value so that the text will not inherit opacity StyleUtils.getBackgroundColorWithOpacityStyle(themeColors.overlay, variables.overlayOpacity), styles.horizontalStackedAvatar4Overlay, - StyleUtils.getAvatarBorderRadius(props.size, props.icons[3].type), + { + borderWidth: oneAvatarBorderWidth, borderRadius: oneAvatarSize.width, left: -((oneAvatarSize.width * 2) + (oneAvatarBorderWidth * 2)), zIndex: 6, + }, + (props.icons[3].type === CONST.ICON_TYPE_WORKSPACE ? StyleUtils.getAvatarBorderRadius(props.size, props.icons[3].type) : {}), ]} > - - {`+${props.icons.length - 4}`} - + + + {`+${props.icons.length - 4}`} + + )} diff --git a/src/components/menuItemPropTypes.js b/src/components/menuItemPropTypes.js index 9f3b40a55b43..a66e031dd5b4 100644 --- a/src/components/menuItemPropTypes.js +++ b/src/components/menuItemPropTypes.js @@ -1,4 +1,5 @@ import PropTypes from 'prop-types'; +import _ from 'underscore'; import CONST from '../CONST'; import stylePropTypes from '../styles/stylePropTypes'; import avatarPropTypes from './avatarPropTypes'; @@ -85,6 +86,8 @@ const propTypes = { /** Prop to identify if we should load avatars vertically instead of diagonally */ shouldStackHorizontally: PropTypes.bool, + + avatarSize: PropTypes.oneOf(_.values(CONST.AVATAR_SIZE)), }; export default propTypes; diff --git a/src/languages/en.js b/src/languages/en.js index 765be98ed4dc..042f36239a9a 100755 --- a/src/languages/en.js +++ b/src/languages/en.js @@ -1013,11 +1013,16 @@ export default { }, invite: { invitePeople: 'Invite new members', - personalMessagePrompt: 'Add a personal message (optional)', genericFailureMessage: 'An error occurred inviting the user to the workspace, please try again.', - welcomeNote: ({workspaceName}) => `You have been invited to ${workspaceName || 'a workspace'}! Download the Expensify mobile app at use.expensify.com/download to start tracking your expenses.`, pleaseEnterValidLogin: `Please ensure the email or phone number is valid (e.g. ${CONST.EXAMPLE_PHONE_NUMBER}).`, }, + inviteMessage: { + inviteMessageTitle: 'Add message', + inviteMessagePrompt: 'Make your invitation extra special by adding a message below', + personalMessagePrompt: 'Message', + genericFailureMessage: 'An error occurred inviting the user to the workspace, please try again.', + welcomeNote: ({workspaceName}) => `You have been invited to ${workspaceName || 'a workspace'}! Download the Expensify mobile app at use.expensify.com/download to start tracking your expenses.`, + }, editor: { nameInputLabel: 'Name', nameInputHelpText: 'This is the name you will see on your workspace.', diff --git a/src/languages/es.js b/src/languages/es.js index f7012c3d6654..dc9b3c703591 100644 --- a/src/languages/es.js +++ b/src/languages/es.js @@ -1014,11 +1014,16 @@ export default { }, invite: { invitePeople: 'Invitar nuevos miembros', - personalMessagePrompt: 'Agregar un mensaje personal (Opcional)', genericFailureMessage: 'Se produjo un error al invitar al usuario al espacio de trabajo. Vuelva a intentarlo..', - welcomeNote: ({workspaceName}) => `¡Has sido invitado a ${workspaceName}! Descargue la aplicación móvil Expensify en use.expensify.com/download para comenzar a rastrear sus gastos.`, pleaseEnterValidLogin: `Asegúrese de que el correo electrónico o el número de teléfono sean válidos (p. ej. ${CONST.EXAMPLE_PHONE_NUMBER}).`, }, + inviteMessage: { + inviteMessageTitle: 'Añadir un mensaje', + inviteMessagePrompt: 'Añadir un mensaje para hacer tu invitación destacar', + personalMessagePrompt: 'Mensaje', + genericFailureMessage: 'Se produjo un error al invitar al usuario al espacio de trabajo. Vuelva a intentarlo..', + welcomeNote: ({workspaceName}) => `¡Has sido invitado a ${workspaceName}! Descargue la aplicación móvil Expensify en use.expensify.com/download para comenzar a rastrear sus gastos.`, + }, editor: { nameInputLabel: 'Nombre', nameInputHelpText: 'Este es el nombre que verás en tu espacio de trabajo.', diff --git a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js index 405ea6c6c332..aa5ad473a659 100644 --- a/src/libs/Navigation/AppNavigator/ModalStackNavigators.js +++ b/src/libs/Navigation/AppNavigator/ModalStackNavigators.js @@ -455,6 +455,13 @@ const SettingsModalStackNavigator = createModalStackNavigator([ }, name: 'Workspace_Invite', }, + { + getComponent: () => { + const WorkspaceInviteMessagePage = require('../../../pages/workspace/WorkspaceInviteMessagePage').default; + return WorkspaceInviteMessagePage; + }, + name: 'Workspace_Invite_Message', + }, { getComponent: () => { const WorkspaceNewRoomPage = require('../../../pages/workspace/WorkspaceNewRoomPage').default; diff --git a/src/libs/Navigation/linkingConfig.js b/src/libs/Navigation/linkingConfig.js index 080b8d148cff..abfd7c71cf3e 100644 --- a/src/libs/Navigation/linkingConfig.js +++ b/src/libs/Navigation/linkingConfig.js @@ -170,6 +170,9 @@ export default { Workspace_Invite: { path: ROUTES.WORKSPACE_INVITE, }, + Workspace_Invite_Message: { + path: ROUTES.WORKSPACE_INVITE_MESSAGE, + }, Workspace_NewRoom: { path: ROUTES.WORKSPACE_NEW_ROOM, }, diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index f1cbb66cbdeb..d82381eeccaf 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -1011,6 +1011,10 @@ function openWorkspaceInvitePage(policyID, clientMemberEmails) { }); } +function setWorkspaceInviteMembersDraft(policyID, memberEmails) { + Onyx.set(`${ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MEMBERS_DRAFT}${policyID}`, memberEmails); +} + /** * * @param {String} reportID @@ -1070,6 +1074,7 @@ export { openWorkspaceMembersPage, openWorkspaceInvitePage, removeWorkspace, + setWorkspaceInviteMembersDraft, isPolicyOwner, leaveRoom, }; diff --git a/src/pages/settings/InitialSettingsPage.js b/src/pages/settings/InitialSettingsPage.js index 1fe9a18a8260..7c1184434eba 100755 --- a/src/pages/settings/InitialSettingsPage.js +++ b/src/pages/settings/InitialSettingsPage.js @@ -160,6 +160,7 @@ class InitialSettingsPage extends React.Component { action: () => { Navigation.navigate(ROUTES.SETTINGS_WORKSPACES); }, floatRightAvatars: policiesAvatars, shouldStackHorizontally: true, + avatarSize: CONST.AVATAR_SIZE.SMALLER, brickRoadIndicator: policyBrickRoadIndicator, }, { @@ -224,6 +225,7 @@ class InitialSettingsPage extends React.Component { brickRoadIndicator={item.brickRoadIndicator} floatRightAvatars={item.floatRightAvatars} shouldStackHorizontally={item.shouldStackHorizontally} + avatarSize={item.avatarSize} /> ); } diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.js b/src/pages/workspace/WorkspaceInviteMessagePage.js new file mode 100644 index 000000000000..ca1a6cf852db --- /dev/null +++ b/src/pages/workspace/WorkspaceInviteMessagePage.js @@ -0,0 +1,211 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import {Pressable, View} from 'react-native'; +import {withOnyx} from 'react-native-onyx'; +import _ from 'underscore'; +import Str from 'expensify-common/lib/str'; +import lodashGet from 'lodash/get'; +import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; +import ScreenWrapper from '../../components/ScreenWrapper'; +import HeaderWithCloseButton from '../../components/HeaderWithCloseButton'; +import Navigation from '../../libs/Navigation/Navigation'; +import styles from '../../styles/styles'; +import compose from '../../libs/compose'; +import ONYXKEYS from '../../ONYXKEYS'; +import * as Policy from '../../libs/actions/Policy'; +import TextInput from '../../components/TextInput'; +import MultipleAvatars from '../../components/MultipleAvatars'; +import CONST from '../../CONST'; +import * as Link from '../../libs/actions/Link'; +import Text from '../../components/Text'; +import withPolicy, {policyPropTypes, policyDefaultProps} from './withPolicy'; +import * as ReportUtils from '../../libs/ReportUtils'; +import ROUTES from '../../ROUTES'; +import * as Localize from '../../libs/Localize'; +import Form from '../../components/Form'; + +const personalDetailsPropTypes = PropTypes.shape({ + /** The login of the person (either email or phone number) */ + login: PropTypes.string.isRequired, + + /** The URL of the person's avatar (there should already be a default avatar if + the person doesn't have their own avatar uploaded yet) */ + avatar: PropTypes.string.isRequired, + + /** This is either the user's full name, or their login if full name is an empty string */ + displayName: PropTypes.string.isRequired, +}); + +const propTypes = { + + /** All of the personal details for everyone */ + personalDetails: PropTypes.objectOf(personalDetailsPropTypes).isRequired, + + invitedMembersDraft: PropTypes.arrayOf(PropTypes.string).isRequired, + + /** URL Route params */ + route: PropTypes.shape({ + /** Params from the URL path */ + params: PropTypes.shape({ + /** policyID passed via route: /workspace/:policyID/invite-message */ + policyID: PropTypes.string, + }), + }).isRequired, + + ...policyPropTypes, + ...withLocalizePropTypes, +}; + +const defaultProps = policyDefaultProps; + +class WorkspaceInviteMessagePage extends React.Component { + constructor(props) { + super(props); + + this.onSubmit = this.onSubmit.bind(this); + this.validate = this.validate.bind(this); + this.openPrivacyURL = this.openPrivacyURL.bind(this); + this.state = { + welcomeNote: this.getWelcomeNote(), + }; + } + + componentDidUpdate(prevProps) { + if ( + !(prevProps.preferredLocale !== this.props.preferredLocale + && this.state.welcomeNote === Localize.translate(prevProps.preferredLocale, 'workspace.inviteMessage.welcomeNote', {workspaceName: this.props.policy.name}) + ) + ) { + return; + } + this.setState({welcomeNote: this.getWelcomeNote()}); + } + + onSubmit() { + const filteredLogins = _.uniq(_.compact(_.map(this.props.invitedMembersDraft, login => login.toLowerCase().trim()))); + Policy.addMembersToWorkspace(filteredLogins, this.state.welcomeNote || this.getWelcomeNote(), this.props.route.params.policyID); + Navigation.navigate(ROUTES.getWorkspaceMembersRoute(this.props.route.params.policyID)); + } + + getAvatars() { + const filteredPersonalDetails = _.pick(this.props.personalDetails, this.props.invitedMembersDraft); + return _.map(filteredPersonalDetails, personalDetail => ({ + source: ReportUtils.getAvatar(personalDetail.avatar, personalDetail.login), + type: CONST.ICON_TYPE_AVATAR, + name: personalDetail.login, + })); + } + + getWelcomeNote() { + return this.props.translate('workspace.inviteMessage.welcomeNote', { + workspaceName: this.props.policy.name, + }); + } + + getAvatarTooltips() { + const filteredPersonalDetails = _.pick(this.props.personalDetails, this.props.invitedMembersDraft); + return _.map(filteredPersonalDetails, personalDetail => Str.removeSMSDomain(personalDetail.login)); + } + + openPrivacyURL(e) { + e.preventDefault(); + Link.openExternalLink(CONST.PRIVACY_URL); + } + + /** + * @returns {Boolean} + */ + validate() { + // No validation required as the invite message is optional + return {}; + } + + render() { + const policyName = lodashGet(this.props.policy, 'name'); + + return ( + + Navigation.dismissModal()} + onBackButtonPress={() => Navigation.goBack()} + /> +
+ + + {this.props.translate('common.privacy')} + + + + ) + } + > + + + + + + {this.props.translate('workspace.inviteMessage.inviteMessagePrompt')} + + + + this.setState({welcomeNote: text})} + /> + +
+
+ ); + } +} + +WorkspaceInviteMessagePage.propTypes = propTypes; +WorkspaceInviteMessagePage.defaultProps = defaultProps; + +export default compose( + withLocalize, + withPolicy, + withOnyx({ + personalDetails: { + key: ONYXKEYS.PERSONAL_DETAILS, + }, + invitedMembersDraft: { + key: ({route}) => `${ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MEMBERS_DRAFT}${route.params.policyID.toString()}`, + }, + }), +)(WorkspaceInviteMessagePage); diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js index e1fbdbeda817..8c61b3952371 100644 --- a/src/pages/workspace/WorkspaceInvitePage.js +++ b/src/pages/workspace/WorkspaceInvitePage.js @@ -1,6 +1,6 @@ import React from 'react'; import PropTypes from 'prop-types'; -import {Pressable, View} from 'react-native'; +import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; import lodashGet from 'lodash/get'; @@ -12,7 +12,6 @@ import styles from '../../styles/styles'; import compose from '../../libs/compose'; import ONYXKEYS from '../../ONYXKEYS'; import * as Policy from '../../libs/actions/Policy'; -import TextInput from '../../components/TextInput'; import FormAlertWithSubmitButton from '../../components/FormAlertWithSubmitButton'; import FormSubmit from '../../components/FormSubmit'; import OptionsSelector from '../../components/OptionsSelector'; @@ -20,13 +19,11 @@ import * as OptionsListUtils from '../../libs/OptionsListUtils'; import CONST from '../../CONST'; import FullScreenLoadingIndicator from '../../components/FullscreenLoadingIndicator'; import * as Link from '../../libs/actions/Link'; -import Text from '../../components/Text'; import withPolicy, {policyPropTypes, policyDefaultProps} from './withPolicy'; import {withNetwork} from '../../components/OnyxProvider'; import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; import networkPropTypes from '../../components/networkPropTypes'; import ROUTES from '../../ROUTES'; -import * as Localize from '../../libs/Localize'; const personalDetailsPropTypes = PropTypes.shape({ /** The login of the person (either email or phone number) */ @@ -92,7 +89,6 @@ class WorkspaceInvitePage extends React.Component { personalDetails, selectedOptions: [], userToInvite, - welcomeNote: this.getWelcomeNote(), shouldDisableButton: false, }; } @@ -105,13 +101,6 @@ class WorkspaceInvitePage extends React.Component { } componentDidUpdate(prevProps) { - if ( - prevProps.preferredLocale !== this.props.preferredLocale - && this.state.welcomeNote === Localize.translate(prevProps.preferredLocale, 'workspace.invite.welcomeNote', {workspaceName: this.props.policy.name}) - ) { - this.setState({welcomeNote: this.getWelcomeNote()}); - } - const isReconnecting = prevProps.network.isOffline && !this.props.network.isOffline; if (!isReconnecting) { return; @@ -131,17 +120,6 @@ class WorkspaceInvitePage extends React.Component { return [...CONST.EXPENSIFY_EMAILS, ...usersToExclude]; } - /** - * Gets the welcome note default text - * - * @returns {Object} - */ - getWelcomeNote() { - return this.props.translate('workspace.invite.welcomeNote', { - workspaceName: this.props.policy.name, - }); - } - /** * @returns {Boolean} */ @@ -268,13 +246,10 @@ class WorkspaceInvitePage extends React.Component { if (!this.validate()) { return; } - - this.setState({shouldDisableButton: true}, () => { - const logins = _.map(this.state.selectedOptions, option => option.login); - const filteredLogins = _.uniq(_.compact(_.map(logins, login => login.toLowerCase().trim()))); - Policy.addMembersToWorkspace(filteredLogins, this.state.welcomeNote, this.props.route.params.policyID); - Navigation.goBack(); - }); + const logins = _.map(this.state.selectedOptions, option => option.login); + const filteredLogins = _.uniq(_.compact(_.map(logins, login => login.toLowerCase().trim()))); + Policy.setWorkspaceInviteMembersDraft(this.props.route.params.policyID, filteredLogins); + Navigation.navigate(ROUTES.getWorkspaceInviteMessageRoute(this.props.route.params.policyID)); } /** @@ -338,41 +313,16 @@ class WorkspaceInvitePage extends React.Component { )}
- - this.setState({welcomeNote: text})} - /> - - - - - {this.props.translate('common.privacy')} - - - diff --git a/src/styles/StyleUtils.js b/src/styles/StyleUtils.js index 17893cb94c85..49897c4a11c4 100644 --- a/src/styles/StyleUtils.js +++ b/src/styles/StyleUtils.js @@ -80,6 +80,36 @@ function getAvatarStyle(size) { }; } +function getAvatarExtraFontSize(size) { + const AVATAR_SIZES = { + [CONST.AVATAR_SIZE.DEFAULT]: variables.fontSizeNormal, + [CONST.AVATAR_SIZE.SMALL_SUBSCRIPT]: variables.fontSizeExtraSmall, + [CONST.AVATAR_SIZE.MID_SUBSCRIPT]: variables.fontSizeExtraSmall, + [CONST.AVATAR_SIZE.SUBSCRIPT]: variables.fontSizeExtraSmall, + [CONST.AVATAR_SIZE.SMALL]: variables.fontSizeSmall, + [CONST.AVATAR_SIZE.SMALLER]: variables.fontSizeExtraSmall, + [CONST.AVATAR_SIZE.LARGE]: variables.fontSizeXLarge, + [CONST.AVATAR_SIZE.MEDIUM]: variables.fontSizeMedium, + [CONST.AVATAR_SIZE.LARGE_BORDERED]: variables.fontSizeXLarge, + }; + return AVATAR_SIZES[size]; +} + +function getAvatarBorderSize(size) { + const AVATAR_SIZES = { + [CONST.AVATAR_SIZE.DEFAULT]: 3, + [CONST.AVATAR_SIZE.SMALL_SUBSCRIPT]: 2, + [CONST.AVATAR_SIZE.MID_SUBSCRIPT]: 2, + [CONST.AVATAR_SIZE.SUBSCRIPT]: 2, + [CONST.AVATAR_SIZE.SMALL]: 3, + [CONST.AVATAR_SIZE.SMALLER]: 2, + [CONST.AVATAR_SIZE.LARGE]: 4, + [CONST.AVATAR_SIZE.MEDIUM]: 3, + [CONST.AVATAR_SIZE.LARGE_BORDERED]: 4, + }; + return AVATAR_SIZES[size]; +} + /** * Return the border radius for an avatar * @@ -930,6 +960,8 @@ export { getAvatarSize, getAvatarStyle, getAvatarBorderStyle, + getAvatarExtraFontSize, + getAvatarBorderSize, getErrorPageContainerStyle, getSafeAreaPadding, getSafeAreaMargins, diff --git a/src/styles/styles.js b/src/styles/styles.js index 14a2b992eba0..3baf34f7dbee 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1673,14 +1673,6 @@ const styles = { borderRadius: 24, }, - horizontalStackedAvatar: { - height: 28, - width: 28, - backgroundColor: themeColors.appBG, - paddingTop: 2, - alignItems: 'center', - }, - singleSubscript: { height: variables.iconSizeNormal, width: variables.iconSizeNormal, @@ -1812,38 +1804,8 @@ const styles = { width: variables.avatarSizeSmall, }, - horizontalStackedAvatar1: { - left: -19, - top: -79, - zIndex: 2, - }, - - horizontalStackedAvatar2: { - left: 1, - top: -51, - zIndex: 3, - }, - - horizontalStackedAvatar3: { - left: 21, - top: -23, - zIndex: 4, - }, - - horizontalStackedAvatar4: { - top: 5, - left: 41, - zIndex: 5, - }, - horizontalStackedAvatar4Overlay: { - top: -107, - left: 41, - height: 28, - width: 28, - borderWidth: 2, borderStyle: 'solid', - zIndex: 6, }, modalViewContainer: { From 8455cf4d60fe9817f2a647a6371665ea5958eda0 Mon Sep 17 00:00:00 2001 From: Abdul Rahuman Date: Fri, 24 Mar 2023 21:28:38 +0530 Subject: [PATCH 02/23] Merge changes --- src/components/MultipleAvatars.js | 2 +- src/styles/StyleUtils.js | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/MultipleAvatars.js b/src/components/MultipleAvatars.js index 735525461675..afff5b3f8a2e 100644 --- a/src/components/MultipleAvatars.js +++ b/src/components/MultipleAvatars.js @@ -83,7 +83,7 @@ const MultipleAvatars = (props) => { } const oneAvatarSize = StyleUtils.getAvatarStyle(props.size); - const oneAvatarBorderWidth = StyleUtils.getAvatarBorderSize(props.size); + const oneAvatarBorderWidth = StyleUtils.getAvatarBorderWidth(props.size); const overlapSize = oneAvatarSize.width / 3; if (props.shouldStackHorizontally) { diff --git a/src/styles/StyleUtils.js b/src/styles/StyleUtils.js index 49897c4a11c4..6b7d3f23d9f5 100644 --- a/src/styles/StyleUtils.js +++ b/src/styles/StyleUtils.js @@ -95,7 +95,7 @@ function getAvatarExtraFontSize(size) { return AVATAR_SIZES[size]; } -function getAvatarBorderSize(size) { +function getAvatarBorderWidth(size) { const AVATAR_SIZES = { [CONST.AVATAR_SIZE.DEFAULT]: 3, [CONST.AVATAR_SIZE.SMALL_SUBSCRIPT]: 2, @@ -959,6 +959,8 @@ function getDirectionStyle(direction) { export { getAvatarSize, getAvatarStyle, + getAvatarExtraFontSize, + getAvatarBorderWidth, getAvatarBorderStyle, getAvatarExtraFontSize, getAvatarBorderSize, From b3f2a1f0cd157328bd4b29f2e9d17fb1665f6002 Mon Sep 17 00:00:00 2001 From: Abdul Rahuman Date: Fri, 24 Mar 2023 21:35:38 +0530 Subject: [PATCH 03/23] Fixing issues --- src/styles/StyleUtils.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/styles/StyleUtils.js b/src/styles/StyleUtils.js index 6b7d3f23d9f5..7823f2849df4 100644 --- a/src/styles/StyleUtils.js +++ b/src/styles/StyleUtils.js @@ -962,8 +962,6 @@ export { getAvatarExtraFontSize, getAvatarBorderWidth, getAvatarBorderStyle, - getAvatarExtraFontSize, - getAvatarBorderSize, getErrorPageContainerStyle, getSafeAreaPadding, getSafeAreaMargins, From 8eb8cf9f458d590a35a865a3143eb1fdc9dfe916 Mon Sep 17 00:00:00 2001 From: Abdul Rahuman Date: Fri, 24 Mar 2023 22:31:43 +0530 Subject: [PATCH 04/23] Fixing lint failures --- src/pages/workspace/WorkspaceInviteMessagePage.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.js b/src/pages/workspace/WorkspaceInviteMessagePage.js index ca1a6cf852db..2bb16c5278e8 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.js +++ b/src/pages/workspace/WorkspaceInviteMessagePage.js @@ -39,9 +39,9 @@ const personalDetailsPropTypes = PropTypes.shape({ const propTypes = { /** All of the personal details for everyone */ - personalDetails: PropTypes.objectOf(personalDetailsPropTypes).isRequired, + personalDetails: PropTypes.objectOf(personalDetailsPropTypes), - invitedMembersDraft: PropTypes.arrayOf(PropTypes.string).isRequired, + invitedMembersDraft: PropTypes.arrayOf(PropTypes.string), /** URL Route params */ route: PropTypes.shape({ @@ -56,7 +56,11 @@ const propTypes = { ...withLocalizePropTypes, }; -const defaultProps = policyDefaultProps; +const defaultProps = { + ...policyDefaultProps, + personalDetails: {}, + invitedMembersDraft: [], +}; class WorkspaceInviteMessagePage extends React.Component { constructor(props) { From c6926f1d0e07248f89d362f829f4a9dc6a302e5f Mon Sep 17 00:00:00 2001 From: Abdul Rahuman Date: Sat, 25 Mar 2023 12:31:11 +0530 Subject: [PATCH 05/23] Fixing regression --- src/components/MenuItem.js | 2 +- src/pages/workspace/WorkspaceInviteMessagePage.js | 14 ++++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index 19063a9e52ba..fbaa4c71d90b 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -182,7 +182,7 @@ const MenuItem = (props) => { isHovered={hovered} isPressed={pressed} icons={props.floatRightAvatars} - size={props.avatarSize ? props.avatarSize : fallbackAvatarSize} + size={props.avatarSize || fallbackAvatarSize} fallbackIcon={defaultWorkspaceAvatars.WorkspaceBuilding} shouldStackHorizontally={props.shouldStackHorizontally} /> diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.js b/src/pages/workspace/WorkspaceInviteMessagePage.js index 2bb16c5278e8..4202ca792f29 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.js +++ b/src/pages/workspace/WorkspaceInviteMessagePage.js @@ -92,12 +92,14 @@ class WorkspaceInviteMessagePage extends React.Component { } getAvatars() { - const filteredPersonalDetails = _.pick(this.props.personalDetails, this.props.invitedMembersDraft); - return _.map(filteredPersonalDetails, personalDetail => ({ - source: ReportUtils.getAvatar(personalDetail.avatar, personalDetail.login), - type: CONST.ICON_TYPE_AVATAR, - name: personalDetail.login, - })); + return _.map(this.props.invitedMembersDraft, (memberlogin) => { + const userPersonalDetail = lodashGet(this.props.personalDetails, memberlogin, {login: memberlogin, avatar: ''}); + return { + source: ReportUtils.getAvatar(userPersonalDetail.avatar, userPersonalDetail.login), + type: CONST.ICON_TYPE_AVATAR, + name: userPersonalDetail.login, + }; + }); } getWelcomeNote() { From 4f8fc62d4bfeef5b082ccfc8a74de943ca80473e Mon Sep 17 00:00:00 2001 From: Abdul Rahuman Date: Sat, 25 Mar 2023 13:08:27 +0530 Subject: [PATCH 06/23] Resolving calculation comment --- src/components/MultipleAvatars.js | 8 ++------ src/styles/StyleUtils.js | 20 ++++++++++++++++++++ 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/components/MultipleAvatars.js b/src/components/MultipleAvatars.js index afff5b3f8a2e..23b5e499d3ce 100644 --- a/src/components/MultipleAvatars.js +++ b/src/components/MultipleAvatars.js @@ -119,9 +119,7 @@ const MultipleAvatars = (props) => { style={[styles.justifyContentCenter, styles.alignItemsCenter, StyleUtils.getHorizontalStackedAvatarBorderStyle(props.isHovered, props.isPressed), - { - left: -(overlapSize * index), borderRadius: oneAvatarSize.width, borderWidth: oneAvatarBorderWidth, zIndex: index + 2, - }, + StyleUtils.getHorizontalStackedAvatarStyle(index, overlapSize, oneAvatarBorderWidth, oneAvatarSize.width), (icon.type === CONST.ICON_TYPE_WORKSPACE ? StyleUtils.getAvatarBorderRadius(props.size, icon.type) : {}), ]} > @@ -145,9 +143,7 @@ const MultipleAvatars = (props) => { // Set overlay background color with RGBA value so that the text will not inherit opacity StyleUtils.getBackgroundColorWithOpacityStyle(themeColors.overlay, variables.overlayOpacity), styles.horizontalStackedAvatar4Overlay, - { - borderWidth: oneAvatarBorderWidth, borderRadius: oneAvatarSize.width, left: -((oneAvatarSize.width * 2) + (oneAvatarBorderWidth * 2)), zIndex: 6, - }, + StyleUtils.getHorizontalStackedOverlayAvatarStyle(oneAvatarSize, oneAvatarBorderWidth), (props.icons[3].type === CONST.ICON_TYPE_WORKSPACE ? StyleUtils.getAvatarBorderRadius(props.size, props.icons[3].type) : {}), ]} > diff --git a/src/styles/StyleUtils.js b/src/styles/StyleUtils.js index 7823f2849df4..7f774145a6e2 100644 --- a/src/styles/StyleUtils.js +++ b/src/styles/StyleUtils.js @@ -768,6 +768,24 @@ function getHorizontalStackedAvatarBorderStyle(isHovered, isPressed) { }; } +function getHorizontalStackedAvatarStyle(index, overlapSize, borderWidth, borderRadius) { + return { + left: -(overlapSize * index), + borderRadius, + borderWidth, + zIndex: index + 2, + }; +} + +function getHorizontalStackedOverlayAvatarStyle(oneAvatarSize, oneAvatarBorderWidth) { + return { + borderWidth: oneAvatarBorderWidth, + borderRadius: oneAvatarSize.width, + left: -((oneAvatarSize.width * 2) + (oneAvatarBorderWidth * 2)), + zIndex: 6, + }; +} + /** * @param {Number} safeAreaPaddingBottom * @returns {Object} @@ -996,6 +1014,8 @@ export { getMinimumHeight, fade, getHorizontalStackedAvatarBorderStyle, + getHorizontalStackedAvatarStyle, + getHorizontalStackedOverlayAvatarStyle, getReportWelcomeBackgroundImageStyle, getReportWelcomeTopMarginStyle, getReportWelcomeContainerStyle, From cd795e10ec0a0ed811ad05c6a6f280def406a8be Mon Sep 17 00:00:00 2001 From: Abdul Rahuman Date: Sat, 25 Mar 2023 13:26:27 +0530 Subject: [PATCH 07/23] Fixing future comments --- src/ONYXKEYS.js | 1 + src/pages/workspace/WorkspaceInviteMessagePage.js | 15 +++------------ src/pages/workspace/WorkspaceInvitePage.js | 6 +++++- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js index dc58aa6543c8..63fb45033de0 100755 --- a/src/ONYXKEYS.js +++ b/src/ONYXKEYS.js @@ -183,6 +183,7 @@ export default { PROFILE_SETTINGS_FORM: 'profileSettingsForm', DISPLAY_NAME_FORM: 'displayNameForm', LEGAL_NAME_FORM: 'legalNameForm', + WORKSPACE_INVITE_MESSAGE_FORM: 'workspaceInviteMessageForm', DATE_OF_BIRTH_FORM: 'dateOfBirthForm', HOME_ADDRESS_FORM: 'homeAddressForm', NEW_ROOM_FORM: 'newRoomForm', diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.js b/src/pages/workspace/WorkspaceInviteMessagePage.js index 4202ca792f29..094a220fe018 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.js +++ b/src/pages/workspace/WorkspaceInviteMessagePage.js @@ -86,8 +86,7 @@ class WorkspaceInviteMessagePage extends React.Component { } onSubmit() { - const filteredLogins = _.uniq(_.compact(_.map(this.props.invitedMembersDraft, login => login.toLowerCase().trim()))); - Policy.addMembersToWorkspace(filteredLogins, this.state.welcomeNote || this.getWelcomeNote(), this.props.route.params.policyID); + Policy.addMembersToWorkspace(this.props.invitedMembersDraft, this.state.welcomeNote || this.getWelcomeNote(), this.props.route.params.policyID); Navigation.navigate(ROUTES.getWorkspaceMembersRoute(this.props.route.params.policyID)); } @@ -118,14 +117,6 @@ class WorkspaceInviteMessagePage extends React.Component { Link.openExternalLink(CONST.PRIVACY_URL); } - /** - * @returns {Boolean} - */ - validate() { - // No validation required as the invite message is optional - return {}; - } - render() { const policyName = lodashGet(this.props.policy, 'name'); @@ -142,8 +133,8 @@ class WorkspaceInviteMessagePage extends React.Component { />
{}} onSubmit={this.onSubmit} submitButtonText={this.props.translate('common.save')} enabledWhenOffline diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js index 8c61b3952371..ae33789fff0b 100644 --- a/src/pages/workspace/WorkspaceInvitePage.js +++ b/src/pages/workspace/WorkspaceInvitePage.js @@ -247,7 +247,11 @@ class WorkspaceInvitePage extends React.Component { return; } const logins = _.map(this.state.selectedOptions, option => option.login); - const filteredLogins = _.uniq(_.compact(_.map(logins, login => login.toLowerCase().trim()))); + const filteredLogins = _.chain(logins) + .map(login => login.toLowerCase().trim()) + .compact() + .uniq() + .value(); Policy.setWorkspaceInviteMembersDraft(this.props.route.params.policyID, filteredLogins); Navigation.navigate(ROUTES.getWorkspaceInviteMessageRoute(this.props.route.params.policyID)); } From b9157482d78b12cb70c74f646cb623bfd5f500f8 Mon Sep 17 00:00:00 2001 From: Abdul Rahuman Date: Sat, 25 Mar 2023 14:31:12 +0530 Subject: [PATCH 08/23] adding JSDocs --- .../workspace/WorkspaceInviteMessagePage.js | 8 +++++-- src/styles/StyleUtils.js | 24 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.js b/src/pages/workspace/WorkspaceInviteMessagePage.js index 094a220fe018..afbdc05a08bb 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.js +++ b/src/pages/workspace/WorkspaceInviteMessagePage.js @@ -112,8 +112,12 @@ class WorkspaceInviteMessagePage extends React.Component { return _.map(filteredPersonalDetails, personalDetail => Str.removeSMSDomain(personalDetail.login)); } - openPrivacyURL(e) { - e.preventDefault(); + /** + * Opens privacy url as an external link + * @param {Object} event + */ + openPrivacyURL(event) { + event.preventDefault(); Link.openExternalLink(CONST.PRIVACY_URL); } diff --git a/src/styles/StyleUtils.js b/src/styles/StyleUtils.js index 7f774145a6e2..055a2339bbed 100644 --- a/src/styles/StyleUtils.js +++ b/src/styles/StyleUtils.js @@ -80,6 +80,11 @@ function getAvatarStyle(size) { }; } +/** + * Get Font size of '+1' text on avatar overlay + * @param {String} size + * @returns {Number} + */ function getAvatarExtraFontSize(size) { const AVATAR_SIZES = { [CONST.AVATAR_SIZE.DEFAULT]: variables.fontSizeNormal, @@ -95,6 +100,11 @@ function getAvatarExtraFontSize(size) { return AVATAR_SIZES[size]; } +/** + * Get Bordersize of Avatar based on avatar size + * @param {String} size + * @returns {Number} + */ function getAvatarBorderWidth(size) { const AVATAR_SIZES = { [CONST.AVATAR_SIZE.DEFAULT]: 3, @@ -768,6 +778,14 @@ function getHorizontalStackedAvatarBorderStyle(isHovered, isPressed) { }; } +/** + * Get computed avatar styles based on position and border size + * @param {Number} index + * @param {Number} overlapSize + * @param {Number} borderWidth + * @param {Number} borderRadius + * @returns {Object} + */ function getHorizontalStackedAvatarStyle(index, overlapSize, borderWidth, borderRadius) { return { left: -(overlapSize * index), @@ -777,6 +795,12 @@ function getHorizontalStackedAvatarStyle(index, overlapSize, borderWidth, border }; } +/** + * Get computed avatar styles of '+1' overlay based on size + * @param {Object} oneAvatarSize + * @param {Numer} oneAvatarBorderWidth + * @returns {Object} + */ function getHorizontalStackedOverlayAvatarStyle(oneAvatarSize, oneAvatarBorderWidth) { return { borderWidth: oneAvatarBorderWidth, From da2352ed669a0da92a5bdebc6f26af49cedccd3f Mon Sep 17 00:00:00 2001 From: Abdul Rahuman Date: Sat, 25 Mar 2023 14:46:26 +0530 Subject: [PATCH 09/23] Fixing errors --- src/pages/workspace/WorkspaceInviteMessagePage.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.js b/src/pages/workspace/WorkspaceInviteMessagePage.js index afbdc05a08bb..58e9597c5547 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.js +++ b/src/pages/workspace/WorkspaceInviteMessagePage.js @@ -67,7 +67,6 @@ class WorkspaceInviteMessagePage extends React.Component { super(props); this.onSubmit = this.onSubmit.bind(this); - this.validate = this.validate.bind(this); this.openPrivacyURL = this.openPrivacyURL.bind(this); this.state = { welcomeNote: this.getWelcomeNote(), @@ -138,7 +137,7 @@ class WorkspaceInviteMessagePage extends React.Component { {}} + validate={() => ({})} onSubmit={this.onSubmit} submitButtonText={this.props.translate('common.save')} enabledWhenOffline From df8e7c0621c6acfc1268cbb705b9695f24c7fb76 Mon Sep 17 00:00:00 2001 From: Abdul Rahuman Date: Tue, 28 Mar 2023 20:27:56 +0530 Subject: [PATCH 10/23] Fixing PR style comments --- src/components/MenuItem.js | 1 + src/components/MultipleAvatars.js | 2 +- src/pages/workspace/WorkspaceInviteMessagePage.js | 6 ++++-- src/pages/workspace/WorkspaceInvitePage.js | 2 +- src/styles/StyleUtils.js | 1 + src/styles/styles.js | 4 ---- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/components/MenuItem.js b/src/components/MenuItem.js index fbaa4c71d90b..c05c9fd294eb 100644 --- a/src/components/MenuItem.js +++ b/src/components/MenuItem.js @@ -50,6 +50,7 @@ const defaultProps = { brickRoadIndicator: '', floatRightAvatars: [], shouldStackHorizontally: false, + avatarSize: undefined, }; const MenuItem = (props) => { diff --git a/src/components/MultipleAvatars.js b/src/components/MultipleAvatars.js index 23b5e499d3ce..af02ba397fbd 100644 --- a/src/components/MultipleAvatars.js +++ b/src/components/MultipleAvatars.js @@ -113,7 +113,7 @@ const MultipleAvatars = (props) => { {props.shouldStackHorizontally ? ( <> { - _.map([...props.icons].splice(0, 4).reverse(), (icon, index) => ( + _.map([...props.icons].splice(0, 4), (icon, index) => ( ({})} onSubmit={this.onSubmit} - submitButtonText={this.props.translate('common.save')} + submitButtonText={this.props.translate('common.invite')} enabledWhenOffline footerContent={ ( @@ -147,7 +149,7 @@ class WorkspaceInviteMessagePage extends React.Component { onPress={this.openPrivacyURL} accessibilityRole="link" href={CONST.PRIVACY_URL} - style={[styles.mh5, styles.mb3, styles.alignSelfStart]} + style={[styles.mb5, styles.alignSelfStart]} > diff --git a/src/pages/workspace/WorkspaceInvitePage.js b/src/pages/workspace/WorkspaceInvitePage.js index ae33789fff0b..10519571740c 100644 --- a/src/pages/workspace/WorkspaceInvitePage.js +++ b/src/pages/workspace/WorkspaceInvitePage.js @@ -323,7 +323,7 @@ class WorkspaceInvitePage extends React.Component { buttonText={this.props.translate('common.next')} onSubmit={this.inviteUser} message={this.props.policy.alertMessage} - containerStyles={[styles.flexReset, styles.mb0, styles.flexGrow0, styles.flexShrink0, styles.flexBasisAuto, styles.mb3]} + containerStyles={[styles.flexReset, styles.flexGrow0, styles.flexShrink0, styles.flexBasisAuto, styles.mb5]} enabledWhenOffline disablePressOnEnter /> diff --git a/src/styles/StyleUtils.js b/src/styles/StyleUtils.js index 055a2339bbed..bf270a50d9c8 100644 --- a/src/styles/StyleUtils.js +++ b/src/styles/StyleUtils.js @@ -807,6 +807,7 @@ function getHorizontalStackedOverlayAvatarStyle(oneAvatarSize, oneAvatarBorderWi borderRadius: oneAvatarSize.width, left: -((oneAvatarSize.width * 2) + (oneAvatarBorderWidth * 2)), zIndex: 6, + borderStyle: 'solid', }; } diff --git a/src/styles/styles.js b/src/styles/styles.js index 3baf34f7dbee..9538aed8a2ba 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -1804,10 +1804,6 @@ const styles = { width: variables.avatarSizeSmall, }, - horizontalStackedAvatar4Overlay: { - borderStyle: 'solid', - }, - modalViewContainer: { alignItems: 'center', flex: 1, From fabd9af9c1ab788cbfb8a548d85cff48dbe21737 Mon Sep 17 00:00:00 2001 From: Abdul Rahuman Date: Tue, 4 Apr 2023 11:29:05 +0530 Subject: [PATCH 11/23] Reseting draft after submit --- src/pages/workspace/WorkspaceInviteMessagePage.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.js b/src/pages/workspace/WorkspaceInviteMessagePage.js index 5774af4480e1..107ec9db81b9 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.js +++ b/src/pages/workspace/WorkspaceInviteMessagePage.js @@ -86,6 +86,7 @@ class WorkspaceInviteMessagePage extends React.Component { onSubmit() { Policy.addMembersToWorkspace(this.props.invitedMembersDraft, this.state.welcomeNote || this.getWelcomeNote(), this.props.route.params.policyID); + Policy.setWorkspaceInviteMembersDraft(this.props.route.params.policyID, []); Navigation.navigate(ROUTES.getWorkspaceMembersRoute(this.props.route.params.policyID)); } From e9992b73d386e9ca366c18cd0a265616878bce6f Mon Sep 17 00:00:00 2001 From: Abdul Rahuman Date: Wed, 19 Apr 2023 14:43:34 +0530 Subject: [PATCH 12/23] Fixing privacy link to move along with the submit button --- src/components/Form.js | 2 +- src/components/FormAlertWithSubmitButton.js | 48 +++++++++++-------- .../workspace/WorkspaceInviteMessagePage.js | 2 +- 3 files changed, 31 insertions(+), 21 deletions(-) diff --git a/src/components/Form.js b/src/components/Form.js index 15f16aa6e696..f808bde1f0f5 100644 --- a/src/components/Form.js +++ b/src/components/Form.js @@ -343,6 +343,7 @@ class Form extends React.Component { isLoading={this.props.formState.isLoading} message={_.isEmpty(this.props.formState.errorFields) ? this.getErrorMessage() : null} onSubmit={this.submit} + footerContent={this.props.footerContent} onFixTheErrorsLinkPressed={() => { const errors = !_.isEmpty(this.state.errors) ? this.state.errors : this.props.formState.errorFields; const focusKey = _.find(_.keys(this.inputRefs), key => _.keys(errors).includes(key)); @@ -372,7 +373,6 @@ class Form extends React.Component { disablePressOnEnter /> )} - {this.props.footerContent} ); diff --git a/src/components/FormAlertWithSubmitButton.js b/src/components/FormAlertWithSubmitButton.js index 2ff4f0b94b55..6f8c91617de8 100644 --- a/src/components/FormAlertWithSubmitButton.js +++ b/src/components/FormAlertWithSubmitButton.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'; import styles from '../styles/styles'; import Button from './Button'; import FormAlertWrapper from './FormAlertWrapper'; +import {View} from 'react-native'; const propTypes = { /** Text for the button */ @@ -41,6 +42,9 @@ const propTypes = { /** Whether the form submit action is dangerous */ isSubmitActionDangerous: PropTypes.bool, + + /** Custom content to display in the footer after submit button */ + footerContent: PropTypes.oneOfType([PropTypes.func, PropTypes.node]), }; const defaultProps = { @@ -53,6 +57,7 @@ const defaultProps = { enabledWhenOffline: false, disablePressOnEnter: false, isSubmitActionDangerous: false, + footerContent: null, }; const FormAlertWithSubmitButton = props => ( @@ -63,25 +68,30 @@ const FormAlertWithSubmitButton = props => ( message={props.message} onFixTheErrorsLinkPressed={props.onFixTheErrorsLinkPressed} > - {isOffline => ((isOffline && !props.enabledWhenOffline) ? ( -