Skip to content

Commit

Permalink
Merge branch 'main' of github.com:Expensify/App into luke-full-page-o…
Browse files Browse the repository at this point in the history
…ffline-view
  • Loading branch information
Luke Donahue committed May 27, 2022
2 parents 560cee9 + 1d58296 commit 4329ace
Show file tree
Hide file tree
Showing 17 changed files with 266 additions and 168 deletions.
55 changes: 8 additions & 47 deletions src/components/ArchivedReportFooter.js
Original file line number Diff line number Diff line change
@@ -1,37 +1,24 @@
import lodashGet from 'lodash/get';
import React from 'react';
import PropTypes from 'prop-types';
import {withOnyx} from 'react-native-onyx';
import CONST from '../CONST';
import Banner from './Banner';
import withLocalize, {withLocalizePropTypes} from './withLocalize';
import compose from '../libs/compose';
import personalDetailsPropType from '../pages/personalDetailsPropType';
import ONYXKEYS from '../ONYXKEYS';
import * as ReportUtils from '../libs/ReportUtils';
import reportActionPropTypes from '../pages/home/report/reportActionPropTypes';

const propTypes = {
/** The reason this report was archived */
reportClosedAction: PropTypes.shape({
/** Message attached to the report closed action */
originalMessage: PropTypes.shape({
/** The reason the report was closed */
reason: PropTypes.string.isRequired,

/** (For accountMerged reason only), the email of the previous owner of this report. */
oldLogin: PropTypes.string,

/** (For accountMerged reason only), the email of the account the previous owner was merged into */
newLogin: PropTypes.string,
}).isRequired,
}),

/** The archived report */
report: PropTypes.shape({
/** The policy this report is attached to */
policyID: PropTypes.string,
/** The email of the owner of the report */
ownerEmail: PropTypes.string,
}).isRequired,

/** Array of report actions for this report */
reportActions: PropTypes.objectOf(PropTypes.shape(reportActionPropTypes)).isRequired,

/** Personal details of all users */
personalDetails: PropTypes.objectOf(personalDetailsPropType).isRequired,

Expand All @@ -44,40 +31,14 @@ const propTypes = {
...withLocalizePropTypes,
};

const defaultProps = {
reportClosedAction: {
originalMessage: {
reason: CONST.REPORT.ARCHIVE_REASON.DEFAULT,
},
},
};

const ArchivedReportFooter = (props) => {
const archiveReason = lodashGet(props.reportClosedAction, 'originalMessage.reason', CONST.REPORT.ARCHIVE_REASON.DEFAULT);
let displayName = lodashGet(props.personalDetails, `${props.report.ownerEmail}.displayName`, props.report.ownerEmail);

let oldDisplayName;
if (archiveReason === CONST.REPORT.ARCHIVE_REASON.ACCOUNT_MERGED) {
const newLogin = props.reportClosedAction.originalMessage.newLogin;
const oldLogin = props.reportClosedAction.originalMessage.oldLogin;
displayName = lodashGet(props.personalDetails, `${newLogin}.displayName`, newLogin);
oldDisplayName = lodashGet(props.personalDetails, `${oldLogin}.displayName`, oldLogin);
}

const archivedText = ReportUtils.getArchivedText(props.report, props.reportActions, props.personalDetails, props.policies);
return (
<Banner
text={props.translate(`reportArchiveReasons.${archiveReason}`, {
displayName: `<strong>${displayName}</strong>`,
oldDisplayName: `<strong>${oldDisplayName}</strong>`,
policyName: `<strong>${ReportUtils.getPolicyName(props.report, props.policies)}</strong>`,
})}
shouldRenderHTML={archiveReason !== CONST.REPORT.ARCHIVE_REASON.DEFAULT}
/>
<Banner html={archivedText} />
);
};

ArchivedReportFooter.propTypes = propTypes;
ArchivedReportFooter.defaultProps = defaultProps;
ArchivedReportFooter.displayName = 'ArchivedReportFooter';

export default compose(
Expand Down
19 changes: 3 additions & 16 deletions src/components/Banner.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,13 @@ import Hoverable from './Hoverable';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
import RenderHTML from './RenderHTML';
import Text from './Text';
import styles from '../styles/styles';
import * as StyleUtils from '../styles/StyleUtils';
import getButtonState from '../libs/getButtonState';

const propTypes = {
/** Text to display in the banner. */
text: PropTypes.string.isRequired,

/** Should this component render the text as HTML? */
shouldRenderHTML: PropTypes.bool,
};

const defaultProps = {
shouldRenderHTML: false,
/** HTML to display in the banner. */
html: PropTypes.string.isRequired,
};

const Banner = props => (
Expand All @@ -39,18 +31,13 @@ const Banner = props => (
fill={StyleUtils.getIconFillColor(getButtonState(isHovered))}
/>
</View>
{
props.shouldRenderHTML
? <RenderHTML html={props.text} />
: <Text>{props.text}</Text>
}
<RenderHTML html={props.html} />
</View>
)}
</Hoverable>
);

Banner.propTypes = propTypes;
Banner.defaultProps = defaultProps;
Banner.displayName = 'Banner';

export default memo(Banner);
39 changes: 39 additions & 0 deletions src/components/ExceededCommentLength.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import React from 'react';
import PropTypes from 'prop-types';
import _ from 'underscore';
import CONST from '../CONST';
import Text from './Text';
import styles from '../styles/styles';
import stylePropTypes from '../styles/stylePropTypes';

const propTypes = {
/** The current length of the comment */
commentLength: PropTypes.number.isRequired,

/** Additional style props */
style: stylePropTypes,
};

const defaultProps = {
style: [],
};

const ExceededCommentLength = (props) => {
if (props.commentLength <= CONST.MAX_COMMENT_LENGTH) {
return null;
}

const additionalStyles = _.isArray(props.style) ? props.style : [props.style];

return (
<Text style={[styles.textMicro, styles.textDanger, ...additionalStyles]}>
{`${props.commentLength}/${CONST.MAX_COMMENT_LENGTH}`}
</Text>
);
};

ExceededCommentLength.propTypes = propTypes;
ExceededCommentLength.defaultProps = defaultProps;
ExceededCommentLength.displayName = 'ExceededCommentLength';

export default ExceededCommentLength;
4 changes: 2 additions & 2 deletions src/components/InlineSystemMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from 'react';
import {View} from 'react-native';
import PropTypes from 'prop-types';
import styles from '../styles/styles';
import theme from '../styles/themes/default';
import Text from './Text';
import * as Expensicons from './Icon/Expensicons';
import colors from '../styles/colors';
import Icon from './Icon';

const propTypes = {
Expand All @@ -18,7 +18,7 @@ const InlineSystemMessage = (props) => {
}
return (
<View style={[styles.flexRow, styles.alignItemsCenter]}>
<Icon src={Expensicons.Exclamation} fill={colors.red} />
<Icon src={Expensicons.Exclamation} fill={theme.badgeDangerBG} />
<Text style={[styles.inlineSystemMessage]}>{props.message}</Text>
</View>
);
Expand Down
57 changes: 57 additions & 0 deletions src/components/OfflineIndicator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import React from 'react';
import {View} from 'react-native';
import _ from 'underscore';
import {withNetwork} from './OnyxProvider';
import networkPropTypes from './networkPropTypes';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
import variables from '../styles/variables';
import Text from './Text';
import styles from '../styles/styles';
import compose from '../libs/compose';
import withLocalize, {withLocalizePropTypes} from './withLocalize';
import stylePropTypes from '../styles/stylePropTypes';

const propTypes = {
/** Information about the network */
network: networkPropTypes.isRequired,

/** Additional style props */
style: stylePropTypes,

...withLocalizePropTypes,
};

const defaultProps = {
style: [],
};

const OfflineIndicator = (props) => {
if (!props.network.isOffline) {
return null;
}

const additionalStyles = _.isArray(props.style) ? props.style : [props.style];

return (
<View style={[styles.flexRow, ...additionalStyles]}>
<Icon
src={Expensicons.Offline}
width={variables.iconSizeExtraSmall}
height={variables.iconSizeExtraSmall}
/>
<Text style={[styles.ml2, styles.chatItemComposeSecondaryRowSubText]}>
{props.translate('reportActionCompose.youAppearToBeOffline')}
</Text>
</View>
);
};

OfflineIndicator.propTypes = propTypes;
OfflineIndicator.defaultProps = defaultProps;
OfflineIndicator.displayName = 'OfflineIndicator';

export default compose(
withLocalize,
withNetwork(),
)(OfflineIndicator);
51 changes: 31 additions & 20 deletions src/components/ReportWelcomeText.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import ONYXKEYS from '../ONYXKEYS';
import Navigation from '../libs/Navigation/Navigation';
import ROUTES from '../ROUTES';
import Tooltip from './Tooltip';
import RenderHTML from './RenderHTML';

const personalDetailsPropTypes = PropTypes.shape({
/** The login of the person (either email or phone number) */
Expand All @@ -32,7 +33,7 @@ const propTypes = {

/* Onyx Props */

/** All of the personal details for everyone */
/** All the personal details for everyone */
personalDetails: PropTypes.objectOf(personalDetailsPropTypes).isRequired,

/** The policies which the user has access to and which the report could be tied to */
Expand All @@ -52,6 +53,8 @@ const ReportWelcomeText = (props) => {
const isPolicyExpenseChat = ReportUtils.isPolicyExpenseChat(props.report);
const isChatRoom = ReportUtils.isChatRoom(props.report);
const isDefault = !(isChatRoom || isPolicyExpenseChat);
const isArchivedRoom = ReportUtils.isArchivedRoom(props.report);
const reportArchivedText = ReportUtils.getArchivedText(props.report, props.reportActions, props.personalDetails, props.policies);
const participants = lodashGet(props.report, 'participants', []);
const isMultipleParticipant = participants.length > 1;
const displayNamesWithTooltips = ReportUtils.getDisplayNamesWithTooltips(
Expand All @@ -62,25 +65,29 @@ const ReportWelcomeText = (props) => {
return (
<Text style={[styles.mt3, styles.mw100, styles.textAlignCenter]}>
{isPolicyExpenseChat && (
<>
{/* Add align center style individually because of limited style inheritance in React Native https://reactnative.dev/docs/text#limited-style-inheritance */}
<Text style={styles.textAlignCenter}>
{props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartOne')}
</Text>
<Text style={[styles.textStrong]}>
{/* Use the policyExpenseChat owner's first name or their email if it's undefined or an empty string */}
{lodashGet(props.personalDetails, [props.report.ownerEmail, 'firstName']) || props.report.ownerEmail}
</Text>
<Text>
{props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartTwo')}
</Text>
<Text style={[styles.textStrong]}>
{ReportUtils.getPolicyName(props.report, props.policies)}
</Text>
<Text>
{props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartThree')}
</Text>
</>
isArchivedRoom
? <RenderHTML html={reportArchivedText} />
: (
<>
{/* Add align center style individually because of limited style inheritance in React Native https://reactnative.dev/docs/text#limited-style-inheritance */}
<Text style={styles.textAlignCenter}>
{props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartOne')}
</Text>
<Text style={[styles.textStrong]}>
{/* Use the policyExpenseChat owner's first name or their email if it's undefined or an empty string */}
{lodashGet(props.personalDetails, [props.report.ownerEmail, 'firstName']) || props.report.ownerEmail}
</Text>
<Text>
{props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartTwo')}
</Text>
<Text style={[styles.textStrong]}>
{ReportUtils.getPolicyName(props.report, props.policies)}
</Text>
<Text>
{props.translate('reportActionsView.beginningOfChatHistoryPolicyExpenseChatPartThree')}
</Text>
</>
)
)}
{isChatRoom && (
<>
Expand Down Expand Up @@ -136,5 +143,9 @@ export default compose(
policies: {
key: ONYXKEYS.COLLECTION.POLICY,
},
reportActions: {
key: props => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${props.report.reportID}`,
canEvict: false,
},
}),
)(ReportWelcomeText);
38 changes: 38 additions & 0 deletions src/libs/ReportUtils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import _ from 'underscore';
import Str from 'expensify-common/lib/str';
import lodashGet from 'lodash/get';
import lodashFindLast from 'lodash/findLast';
import Onyx from 'react-native-onyx';
import ONYXKEYS from '../ONYXKEYS';
import CONST from '../CONST';
Expand Down Expand Up @@ -502,6 +503,42 @@ function navigateToDetailsPage(report) {
Navigation.navigate(ROUTES.getReportParticipantsRoute(report.reportID));
}

/**
* Get the text explaining why a report was archived.
*
* @param {Object} report
* @param {Object} reportActions
* @param {Object} personalDetails
* @param {Object} policies
* @returns {String|null}
*/
function getArchivedText(report, reportActions, personalDetails, policies) {
if (!isArchivedRoom(report)) {
return Localize.translateLocal(`reportArchiveReasons.${CONST.REPORT.ARCHIVE_REASON.DEFAULT}`);
}

const reportClosedAction = lodashFindLast(reportActions, action => action.actionName === CONST.REPORT.ACTIONS.TYPE.CLOSED);
if (!reportClosedAction) {
return Localize.translateLocal(`reportArchiveReasons.${CONST.REPORT.ARCHIVE_REASON.DEFAULT}`);
}

const archiveReason = lodashGet(reportClosedAction, 'originalMessage.reason', CONST.REPORT.ARCHIVE_REASON.DEFAULT);
let displayName = lodashGet(personalDetails, `${report.ownerEmail}.displayName`, report.ownerEmail);
let oldDisplayName;
if (archiveReason === CONST.REPORT.ARCHIVE_REASON.ACCOUNT_MERGED) {
const newLogin = reportClosedAction.originalMessage.newLogin;
const oldLogin = reportClosedAction.originalMessage.oldLogin;
displayName = lodashGet(personalDetails, `${newLogin}.displayName`, newLogin);
oldDisplayName = lodashGet(personalDetails, `${oldLogin}.displayName`, oldLogin);
}

return Localize.translateLocal(`reportArchiveReasons.${archiveReason}`, {
displayName: `<strong>${displayName}</strong>`,
oldDisplayName: `<strong>${oldDisplayName}</strong>`,
policyName: `<strong>${getPolicyName(report, policies)}</strong>`,
});
}

export {
getReportParticipantsTitle,
isReportMessageAttachment,
Expand Down Expand Up @@ -529,4 +566,5 @@ export {
getDisplayNamesWithTooltips,
getReportName,
navigateToDetailsPage,
getArchivedText,
};
Loading

0 comments on commit 4329ace

Please sign in to comment.