Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/components/AutoEmailLink.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React from 'react';
import PropTypes from 'prop-types';
import _ from 'underscore';
import {CONST} from 'expensify-common/lib/CONST';
import Text from './Text';
import TextLink from './TextLink';
import styles from '../styles/styles';

const propTypes = {
text: PropTypes.string.isRequired,
style: PropTypes.oneOfType([PropTypes.arrayOf(PropTypes.object), PropTypes.object]),
};

const defaultProps = {
style: [],
};

/*
* This is a "utility component", that does this:
* - Checks if a text contains any email. If it does, render it as a mailto: link
* - Else just render it inside `Text` component
*/

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NAB: Remove this blank space

const AutoEmailLink = (props) => (
<Text style={props.style}>
{_.map(props.text.split(CONST.REG_EXP.EXTRACT_EMAIL), (str, index) => {
if (CONST.REG_EXP.EMAIL.test(str)) {
return (
<TextLink
key={`${index}-${str}`}
href={`mailto:${str}`}
style={styles.link}
>
{str}
</TextLink>
);
}

return (
<Text
style={props.style}
key={`${index}-${str}`}
>
{str}
</Text>
);
})}
</Text>
);

AutoEmailLink.displayName = 'AutoEmailLink';
AutoEmailLink.propTypes = propTypes;
AutoEmailLink.defaultProps = defaultProps;
export default AutoEmailLink;
6 changes: 5 additions & 1 deletion src/components/BlockingViews/BlockingView.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Text from '../Text';
import themeColors from '../../styles/themes/default';
import TextLink from '../TextLink';
import Navigation from '../../libs/Navigation/Navigation';
import AutoEmailLink from '../AutoEmailLink';

const propTypes = {
/** Expensicon for the page */
Expand Down Expand Up @@ -56,7 +57,10 @@ const BlockingView = (props) => (
height={props.iconHeight}
/>
<Text style={[styles.notFoundTextHeader]}>{props.title}</Text>
<Text style={[styles.textAlignCenter]}>{props.subtitle}</Text>
<AutoEmailLink

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@allroundexperts what is the need for this change?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The message contains an email which needs to be shown as a link.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pardon me for my ignorance, but can you please share the context of why this was needed? I cannot find it in the issue comments?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Neither I can find the screenshots/test steps related to that.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mananjadhav If you look at the English translation message, it contains concierge email address. We need a way to show it as a hyperlink.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool. Thanks for clarifying.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on the comment, I think it would be better to add a description at the top of the file.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Handled.

style={[styles.textAlignCenter]}
text={props.subtitle}
/>
{props.shouldShowLink ? (
<TextLink
onPress={props.onLinkPress}
Expand Down
1 change: 1 addition & 0 deletions src/languages/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -1073,6 +1073,7 @@ export default {
growlMessageOnDeleteError: 'This workspace cannot be deleted right now because reports are actively being processed',
unavailable: 'Unavailable workspace',
memberNotFound: 'Member not found. To invite a new member to the workspace, please use the Invite button above.',
notAuthorized: `You do not have access to this page. Are you trying to join the workspace? Please reach out to the owner of this workspace so they can add you as a member! Something else? Reach out to ${CONST.EMAIL.CONCIERGE}`,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you trying to join the workspace? Please reach out to the owner of this workspace so they can add you as a member!

@youssef-lr @sonialiap Looking at the test steps, if the user B is already a part of the workspace, does this statement make sense?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay this could be a generic message, that shows up even for the user who is not a part of the workspace, we can keep it as is.

goToRoom: ({roomName}) => `Go to ${roomName} room`,
},
emptyWorkspace: {
Expand Down
1 change: 1 addition & 0 deletions src/languages/es.js
Original file line number Diff line number Diff line change
Expand Up @@ -1078,6 +1078,7 @@ export default {
growlMessageOnDeleteError: 'No se puede eliminar el espacio de trabajo porque tiene informes que están siendo procesados',
unavailable: 'Espacio de trabajo no disponible',
memberNotFound: 'Miembro no encontrado. Para invitar a un nuevo miembro al espacio de trabajo, por favor, utiliza el botón Invitar que está arriba.',
notAuthorized: `No tienes acceso a esta página. ¿Estás tratando de unirte al espacio de trabajo? Comunícate con el propietario de este espacio de trabajo para que pueda agregarte como miembro. ¿Necesitas algo más? Comunícate con ${CONST.EMAIL.CONCIERGE}`,
goToRoom: ({roomName}) => `Ir a la sala ${roomName}`,
},
emptyWorkspace: {
Expand Down
3 changes: 2 additions & 1 deletion src/pages/workspace/WorkspaceInitialPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,9 @@ const WorkspaceInitialPage = (props) => {
<ScreenWrapper includeSafeAreaPaddingBottom={false}>
{({safeAreaPaddingBottomStyle}) => (
<FullPageNotFoundView
shouldShow={_.isEmpty(policy)}
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)}
shouldShow={_.isEmpty(props.policy) || !Policy.isPolicyOwner(props.policy)}
subtitleKey={_.isEmpty(props.policy) ? undefined : 'workspace.common.notAuthorized'}
>
<HeaderWithBackButton
title={props.translate('workspace.common.workspace')}
Expand Down
4 changes: 3 additions & 1 deletion src/pages/workspace/WorkspacePageWithSections.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import lodashGet from 'lodash/get';
import _ from 'underscore';
import styles from '../../styles/styles';
import Navigation from '../../libs/Navigation/Navigation';
import * as Policy from '../../libs/actions/Policy';
import compose from '../../libs/compose';
import ROUTES from '../../ROUTES';
import HeaderWithBackButton from '../../components/HeaderWithBackButton';
Expand Down Expand Up @@ -115,8 +116,9 @@ class WorkspacePageWithSections extends React.Component {
shouldEnablePickerAvoiding={false}
>
<FullPageNotFoundView
shouldShow={_.isEmpty(this.props.policy)}
onBackButtonPress={() => Navigation.goBack(ROUTES.SETTINGS_WORKSPACES)}
shouldShow={_.isEmpty(this.props.policy) || !Policy.isPolicyOwner(this.props.policy)}
subtitleKey={_.isEmpty(this.props.policy) ? undefined : 'workspace.common.notAuthorized'}
>
<HeaderWithBackButton
title={this.props.headerText}
Expand Down