diff --git a/__mocks__/react-native-safe-area-context.js b/__mocks__/react-native-safe-area-context.js index f17c34cf326e..4b4af7841c2c 100644 --- a/__mocks__/react-native-safe-area-context.js +++ b/__mocks__/react-native-safe-area-context.js @@ -9,15 +9,17 @@ const insets = { }; function withSafeAreaInsets(WrappedComponent) { - const WithSafeAreaInsets = (props) => ( - - ); + function WithSafeAreaInsets(props) { + return ( + + ); + } return forwardRef((props, ref) => ( CFBundleVersion - 1.3.27.0 + 1.3.27.6 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index c64cafa77d58..98de86749f65 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.3.27.0 + 1.3.27.6 diff --git a/package-lock.json b/package-lock.json index cef8bc2ba52a..40dd6287e4a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.3.27-0", + "version": "1.3.27-6", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.3.27-0", + "version": "1.3.27-6", "hasInstallScript": true, "license": "MIT", "dependencies": { @@ -146,7 +146,7 @@ "electron": "22.3.7", "electron-builder": "24.4.0", "eslint": "^7.6.0", - "eslint-config-expensify": "^2.0.36", + "eslint-config-expensify": "^2.0.38", "eslint-config-prettier": "^8.8.0", "eslint-plugin-jest": "^24.1.0", "eslint-plugin-jsx-a11y": "^6.6.1", @@ -22536,9 +22536,9 @@ } }, "node_modules/eslint-config-expensify": { - "version": "2.0.36", - "resolved": "https://registry.npmjs.org/eslint-config-expensify/-/eslint-config-expensify-2.0.36.tgz", - "integrity": "sha512-8tQsyWhPUFRGJYCucTJd2FFVOOUQfsxGlGynVncCKgI96fmkagurhAu/zteszW0Ora6gAf7BkIuW6z6ZKKBdjg==", + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/eslint-config-expensify/-/eslint-config-expensify-2.0.38.tgz", + "integrity": "sha512-jAlrYSjkDV8YESUUPcaTjUM8Fgru+37FS+Hq6zzcRR0FbA5bLiOPguhJHo77XpYh5N+PEf4wrpgsS04sjdgDPg==", "dev": true, "dependencies": { "@lwc/eslint-plugin-lwc": "^0.11.0", @@ -58390,9 +58390,9 @@ } }, "eslint-config-expensify": { - "version": "2.0.36", - "resolved": "https://registry.npmjs.org/eslint-config-expensify/-/eslint-config-expensify-2.0.36.tgz", - "integrity": "sha512-8tQsyWhPUFRGJYCucTJd2FFVOOUQfsxGlGynVncCKgI96fmkagurhAu/zteszW0Ora6gAf7BkIuW6z6ZKKBdjg==", + "version": "2.0.38", + "resolved": "https://registry.npmjs.org/eslint-config-expensify/-/eslint-config-expensify-2.0.38.tgz", + "integrity": "sha512-jAlrYSjkDV8YESUUPcaTjUM8Fgru+37FS+Hq6zzcRR0FbA5bLiOPguhJHo77XpYh5N+PEf4wrpgsS04sjdgDPg==", "dev": true, "requires": { "@lwc/eslint-plugin-lwc": "^0.11.0", diff --git a/package.json b/package.json index 4462f9d7ad68..a15c21698ecf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.3.27-0", + "version": "1.3.27-6", "author": "Expensify, Inc.", "homepage": "https://new.expensify.com", "description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.", @@ -182,7 +182,7 @@ "electron": "22.3.7", "electron-builder": "24.4.0", "eslint": "^7.6.0", - "eslint-config-expensify": "^2.0.36", + "eslint-config-expensify": "^2.0.38", "eslint-config-prettier": "^8.8.0", "eslint-plugin-jest": "^24.1.0", "eslint-plugin-jsx-a11y": "^6.6.1", diff --git a/src/App.js b/src/App.js index 2b47d8ddcd28..af27b3a6f854 100644 --- a/src/App.js +++ b/src/App.js @@ -33,29 +33,31 @@ LogBox.ignoreLogs([ const fill = {flex: 1}; -const App = () => ( - - - - - - - - -); +function App() { + return ( + + + + + + + + + ); +} App.displayName = 'App'; diff --git a/src/components/AddPaymentMethodMenu.js b/src/components/AddPaymentMethodMenu.js index 2581bde85b4e..e5f6bf946f16 100644 --- a/src/components/AddPaymentMethodMenu.js +++ b/src/components/AddPaymentMethodMenu.js @@ -43,41 +43,43 @@ const defaultProps = { betas: [], }; -const AddPaymentMethodMenu = (props) => ( - { - props.onItemSelected(CONST.PAYMENT_METHODS.BANK_ACCOUNT); +function AddPaymentMethodMenu(props) { + return ( + { + props.onItemSelected(CONST.PAYMENT_METHODS.BANK_ACCOUNT); + }, }, - }, - ...(Permissions.canUseWallet(props.betas) - ? [ - { - text: props.translate('common.debitCard'), - icon: Expensicons.CreditCard, - onSelected: () => props.onItemSelected(CONST.PAYMENT_METHODS.DEBIT_CARD), - }, - ] - : []), - ...(props.shouldShowPaypal && !props.payPalMeData.description - ? [ - { - text: props.translate('common.payPalMe'), - icon: Expensicons.PayPal, - onSelected: () => props.onItemSelected(CONST.PAYMENT_METHODS.PAYPAL), - }, - ] - : []), - ]} - /> -); + ...(Permissions.canUseWallet(props.betas) + ? [ + { + text: props.translate('common.debitCard'), + icon: Expensicons.CreditCard, + onSelected: () => props.onItemSelected(CONST.PAYMENT_METHODS.DEBIT_CARD), + }, + ] + : []), + ...(props.shouldShowPaypal && !props.payPalMeData.description + ? [ + { + text: props.translate('common.payPalMe'), + icon: Expensicons.PayPal, + onSelected: () => props.onItemSelected(CONST.PAYMENT_METHODS.PAYPAL), + }, + ] + : []), + ]} + /> + ); +} AddPaymentMethodMenu.propTypes = propTypes; AddPaymentMethodMenu.defaultProps = defaultProps; diff --git a/src/components/AddressSearch/index.js b/src/components/AddressSearch/index.js index 5219c5b4855f..9699eb9aab94 100644 --- a/src/components/AddressSearch/index.js +++ b/src/components/AddressSearch/index.js @@ -91,7 +91,7 @@ const defaultProps = { // Do not convert to class component! It's been tried before and presents more challenges than it's worth. // Relevant thread: https://expensify.slack.com/archives/C03TQ48KC/p1634088400387400 // Reference: https://github.com/FaridSafi/react-native-google-places-autocomplete/issues/609#issuecomment-886133839 -const AddressSearch = (props) => { +function AddressSearch(props) { const [displayListViewBorder, setDisplayListViewBorder] = useState(false); const containerRef = useRef(); const query = useMemo( @@ -291,7 +291,7 @@ const AddressSearch = (props) => { ); -}; +} AddressSearch.propTypes = propTypes; AddressSearch.defaultProps = defaultProps; diff --git a/src/components/AnchorForAttachmentsOnly/BaseAnchorForAttachmentsOnly.js b/src/components/AnchorForAttachmentsOnly/BaseAnchorForAttachmentsOnly.js index 03f293d12f71..f20f798768c2 100644 --- a/src/components/AnchorForAttachmentsOnly/BaseAnchorForAttachmentsOnly.js +++ b/src/components/AnchorForAttachmentsOnly/BaseAnchorForAttachmentsOnly.js @@ -34,7 +34,7 @@ const defaultProps = { ...anchorForAttachmentsOnlyDefaultProps, }; -const BaseAnchorForAttachmentsOnly = (props) => { +function BaseAnchorForAttachmentsOnly(props) { const sourceURL = props.source; const sourceURLWithAuth = addEncryptedAuthTokenToURL(sourceURL); const sourceID = (sourceURL.match(CONST.REGEX.ATTACHMENT_ID) || [])[1]; @@ -70,7 +70,7 @@ const BaseAnchorForAttachmentsOnly = (props) => { )} ); -}; +} BaseAnchorForAttachmentsOnly.displayName = 'BaseAnchorForAttachmentsOnly'; BaseAnchorForAttachmentsOnly.propTypes = propTypes; diff --git a/src/components/AnchorForAttachmentsOnly/index.js b/src/components/AnchorForAttachmentsOnly/index.js index d4d607d3cc65..1a58aa4b3ae1 100644 --- a/src/components/AnchorForAttachmentsOnly/index.js +++ b/src/components/AnchorForAttachmentsOnly/index.js @@ -4,14 +4,16 @@ import BaseAnchorForAttachmentsOnly from './BaseAnchorForAttachmentsOnly'; import * as DeviceCapabilities from '../../libs/DeviceCapabilities'; import ControlSelection from '../../libs/ControlSelection'; -const AnchorForAttachmentsOnly = (props) => ( - DeviceCapabilities.canUseTouchScreen() && ControlSelection.block()} - onPressOut={() => ControlSelection.unblock()} - /> -); +function AnchorForAttachmentsOnly(props) { + return ( + DeviceCapabilities.canUseTouchScreen() && ControlSelection.block()} + onPressOut={() => ControlSelection.unblock()} + /> + ); +} AnchorForAttachmentsOnly.propTypes = anchorForAttachmentsOnlyPropTypes.propTypes; AnchorForAttachmentsOnly.defaultProps = anchorForAttachmentsOnlyPropTypes.defaultProps; diff --git a/src/components/AnchorForAttachmentsOnly/index.native.js b/src/components/AnchorForAttachmentsOnly/index.native.js index 4fcdd2e6cff3..f27aad641186 100644 --- a/src/components/AnchorForAttachmentsOnly/index.native.js +++ b/src/components/AnchorForAttachmentsOnly/index.native.js @@ -3,13 +3,15 @@ import * as anchorForAttachmentsOnlyPropTypes from './anchorForAttachmentsOnlyPr import BaseAnchorForAttachmentsOnly from './BaseAnchorForAttachmentsOnly'; import styles from '../../styles/styles'; -const AnchorForAttachmentsOnly = (props) => ( - -); +function AnchorForAttachmentsOnly(props) { + return ( + + ); +} AnchorForAttachmentsOnly.propTypes = anchorForAttachmentsOnlyPropTypes.propTypes; AnchorForAttachmentsOnly.defaultProps = anchorForAttachmentsOnlyPropTypes.defaultProps; diff --git a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.js b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.js index 1f95ead89a4c..191af3613e1f 100644 --- a/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.js +++ b/src/components/AnchorForCommentsOnly/BaseAnchorForCommentsOnly.js @@ -11,7 +11,6 @@ import * as ContextMenuActions from '../../pages/home/report/ContextMenu/Context import Tooltip from '../Tooltip'; import * as DeviceCapabilities from '../../libs/DeviceCapabilities'; import styles from '../../styles/styles'; -import * as StyleUtils from '../../styles/StyleUtils'; import withWindowDimensions, {windowDimensionsPropTypes} from '../withWindowDimensions'; import {propTypes as anchorForCommentsOnlyPropTypes, defaultProps as anchorForCommentsOnlyDefaultProps} from './anchorForCommentsOnlyPropTypes'; @@ -39,7 +38,7 @@ const defaultProps = { /* * This is a default anchor component for regular links. */ -const BaseAnchorForCommentsOnly = (props) => { +function BaseAnchorForCommentsOnly(props) { let linkRef; const rest = _.omit(props, _.keys(propTypes)); const linkProps = {}; @@ -54,7 +53,6 @@ const BaseAnchorForCommentsOnly = (props) => { return ( { ReportActionContextMenu.showContextMenu( isEmail ? ContextMenuActions.CONTEXT_MENU_TYPES.EMAIL : ContextMenuActions.CONTEXT_MENU_TYPES.LINK, @@ -87,7 +85,7 @@ const BaseAnchorForCommentsOnly = (props) => { ); -}; +} BaseAnchorForCommentsOnly.propTypes = propTypes; BaseAnchorForCommentsOnly.defaultProps = defaultProps; diff --git a/src/components/AnchorForCommentsOnly/index.js b/src/components/AnchorForCommentsOnly/index.js index 1ea73d5a648d..9ded866b7cdf 100644 --- a/src/components/AnchorForCommentsOnly/index.js +++ b/src/components/AnchorForCommentsOnly/index.js @@ -1,17 +1,23 @@ import React from 'react'; +import {View} from 'react-native'; import * as anchorForCommentsOnlyPropTypes from './anchorForCommentsOnlyPropTypes'; import BaseAnchorForCommentsOnly from './BaseAnchorForCommentsOnly'; import * as DeviceCapabilities from '../../libs/DeviceCapabilities'; import ControlSelection from '../../libs/ControlSelection'; +import styles from '../../styles/styles'; -const AnchorForCommentsOnly = (props) => ( - DeviceCapabilities.canUseTouchScreen() && ControlSelection.block()} - onPressOut={() => ControlSelection.unblock()} - /> -); +function AnchorForCommentsOnly(props) { + return ( + + DeviceCapabilities.canUseTouchScreen() && ControlSelection.block()} + onPressOut={() => ControlSelection.unblock()} + /> + + ); +} AnchorForCommentsOnly.propTypes = anchorForCommentsOnlyPropTypes.propTypes; AnchorForCommentsOnly.defaultProps = anchorForCommentsOnlyPropTypes.defaultProps; diff --git a/src/components/AnchorForCommentsOnly/index.native.js b/src/components/AnchorForCommentsOnly/index.native.js index 21b922f52794..69211b75e855 100644 --- a/src/components/AnchorForCommentsOnly/index.native.js +++ b/src/components/AnchorForCommentsOnly/index.native.js @@ -6,7 +6,7 @@ import * as anchorForCommentsOnlyPropTypes from './anchorForCommentsOnlyPropType import BaseAnchorForCommentsOnly from './BaseAnchorForCommentsOnly'; // eslint-disable-next-line react/jsx-props-no-spreading -const AnchorForCommentsOnly = (props) => { +function AnchorForCommentsOnly(props) { const onPress = () => (_.isFunction(props.onPress) ? props.onPress() : Linking.openURL(props.href)); return ( @@ -16,7 +16,7 @@ const AnchorForCommentsOnly = (props) => { onPress={onPress} /> ); -}; +} AnchorForCommentsOnly.propTypes = anchorForCommentsOnlyPropTypes.propTypes; AnchorForCommentsOnly.defaultProps = anchorForCommentsOnlyPropTypes.defaultProps; diff --git a/src/components/AnimatedStep.js b/src/components/AnimatedStep.js index 0cd7261eb501..dce06cb33760 100644 --- a/src/components/AnimatedStep.js +++ b/src/components/AnimatedStep.js @@ -21,7 +21,7 @@ const defaultProps = { style: [], }; -const AnimatedStep = (props) => { +function AnimatedStep(props) { function getAnimationStyle(direction) { let animationStyle; @@ -43,7 +43,7 @@ const AnimatedStep = (props) => { {props.children} ); -}; +} AnimatedStep.propTypes = propTypes; AnimatedStep.defaultProps = defaultProps; diff --git a/src/components/AnonymousReportFooter.js b/src/components/AnonymousReportFooter.js index 2b92c20d127c..08a4a04e64dd 100644 --- a/src/components/AnonymousReportFooter.js +++ b/src/components/AnonymousReportFooter.js @@ -23,33 +23,35 @@ const defaultProps = { report: {}, }; -const AnonymousReportFooter = (props) => ( - - - - - - - - - - {props.translate('anonymousReportFooter.logoTagline')} - - - - )} ); } @@ -327,6 +329,11 @@ function ReportActionItem(props) { return ( <> {children} + {!_.isEmpty(props.action.linkMetadata) && ( + + !_.isEmpty(item))} /> + + )} {hasReactions && ( { +function ReportActionItemCreated(props) { if (!ReportUtils.isChatReport(props.report)) { return null; } @@ -75,7 +75,7 @@ const ReportActionItemCreated = (props) => { ); -}; +} ReportActionItemCreated.defaultProps = defaultProps; ReportActionItemCreated.propTypes = propTypes; diff --git a/src/pages/home/report/ReportActionItemDate.js b/src/pages/home/report/ReportActionItemDate.js index e49445fdefaf..0e6af2e95636 100644 --- a/src/pages/home/report/ReportActionItemDate.js +++ b/src/pages/home/report/ReportActionItemDate.js @@ -12,7 +12,9 @@ const propTypes = { ...withLocalizePropTypes, }; -const ReportActionItemDate = (props) => {props.datetimeToCalendarTime(props.created)}; +function ReportActionItemDate(props) { + return {props.datetimeToCalendarTime(props.created)}; +} ReportActionItemDate.propTypes = propTypes; ReportActionItemDate.displayName = 'ReportActionItemDate'; diff --git a/src/pages/home/report/ReportActionItemDraft.js b/src/pages/home/report/ReportActionItemDraft.js index e1663ed13bc4..b3b66994fb9c 100644 --- a/src/pages/home/report/ReportActionItemDraft.js +++ b/src/pages/home/report/ReportActionItemDraft.js @@ -8,11 +8,13 @@ const propTypes = { children: PropTypes.node.isRequired, }; -const ReportActionItemDraft = (props) => ( - - {props.children} - -); +function ReportActionItemDraft(props) { + return ( + + {props.children} + + ); +} ReportActionItemDraft.propTypes = propTypes; ReportActionItemDraft.displayName = 'ReportActionItemDraft'; diff --git a/src/pages/home/report/ReportActionItemFragment.js b/src/pages/home/report/ReportActionItemFragment.js index 07b00590306e..edcf0167f711 100644 --- a/src/pages/home/report/ReportActionItemFragment.js +++ b/src/pages/home/report/ReportActionItemFragment.js @@ -77,7 +77,7 @@ const defaultProps = { style: [], }; -const ReportActionItemFragment = (props) => { +function ReportActionItemFragment(props) { switch (props.fragment.type) { case 'COMMENT': { // If this is an attachment placeholder, return the placeholder component @@ -124,7 +124,7 @@ const ReportActionItemFragment = (props) => { selectable={!DeviceCapabilities.canUseTouchScreen() || !props.isSmallScreenWidth} style={[containsOnlyEmojis ? styles.onlyEmojisText : undefined, styles.ltr, ...props.style]} > - {convertToLTR(Str.htmlDecode(text))} + {convertToLTR(text)} {Boolean(props.fragment.isEdited) && ( { default: return props.fragment.text; } -}; +} ReportActionItemFragment.propTypes = propTypes; ReportActionItemFragment.defaultProps = defaultProps; diff --git a/src/pages/home/report/ReportActionItemGrouped.js b/src/pages/home/report/ReportActionItemGrouped.js index ea8458340204..e60bf01835f8 100644 --- a/src/pages/home/report/ReportActionItemGrouped.js +++ b/src/pages/home/report/ReportActionItemGrouped.js @@ -16,11 +16,13 @@ const defaultProps = { wrapperStyles: [styles.chatItem], }; -const ReportActionItemGrouped = (props) => ( - - {props.children} - -); +function ReportActionItemGrouped(props) { + return ( + + {props.children} + + ); +} ReportActionItemGrouped.propTypes = propTypes; ReportActionItemGrouped.defaultProps = defaultProps; diff --git a/src/pages/home/report/ReportActionItemMessage.js b/src/pages/home/report/ReportActionItemMessage.js index fef1bb0377c9..e6bcdffe1e8d 100644 --- a/src/pages/home/report/ReportActionItemMessage.js +++ b/src/pages/home/report/ReportActionItemMessage.js @@ -28,28 +28,30 @@ const defaultProps = { isHidden: false, }; -const ReportActionItemMessage = (props) => ( - - {!props.isHidden ? ( - _.map(_.compact(props.action.previousMessage || props.action.message), (fragment, index) => ( - - )) - ) : ( - {props.translate('moderation.flaggedContent')} - )} - -); +function ReportActionItemMessage(props) { + return ( + + {!props.isHidden ? ( + _.map(_.compact(props.action.previousMessage || props.action.message), (fragment, index) => ( + + )) + ) : ( + {props.translate('moderation.flaggedContent')} + )} + + ); +} ReportActionItemMessage.propTypes = propTypes; ReportActionItemMessage.defaultProps = defaultProps; diff --git a/src/pages/home/report/ReportActionItemMessageEdit.js b/src/pages/home/report/ReportActionItemMessageEdit.js index 0e4c602e674f..d6242d3f2886 100644 --- a/src/pages/home/report/ReportActionItemMessageEdit.js +++ b/src/pages/home/report/ReportActionItemMessageEdit.js @@ -283,6 +283,7 @@ class ReportActionItemMessageEdit extends React.Component { {(hovered) => ( { +function ReportActionItemParentAction(props) { const parentReportAction = props.parentReportActions[`${props.report.parentReportActionID}`]; // In case of transaction threads, we do not want to render the parent report action. @@ -74,7 +74,7 @@ const ReportActionItemParentAction = (props) => { {!props.shouldHideThreadDividerLine && } ); -}; +} ReportActionItemParentAction.defaultProps = defaultProps; ReportActionItemParentAction.propTypes = propTypes; diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js index 84a89bf7475f..e6f7cbc95410 100644 --- a/src/pages/home/report/ReportActionItemSingle.js +++ b/src/pages/home/report/ReportActionItemSingle.js @@ -65,7 +65,7 @@ const showUserDetails = (accountID) => { Navigation.navigate(ROUTES.getProfileRoute(accountID)); }; -const ReportActionItemSingle = (props) => { +function ReportActionItemSingle(props) { const actorEmail = props.action.actorEmail.replace(CONST.REGEX.MERGED_ACCOUNT_PREFIX, ''); const {accountID, avatar, displayName, pendingFields} = props.personalDetails[actorEmail] || {}; const avatarSource = UserUtils.getAvatar(avatar, actorEmail); @@ -138,7 +138,7 @@ const ReportActionItemSingle = (props) => { ); -}; +} ReportActionItemSingle.propTypes = propTypes; ReportActionItemSingle.defaultProps = defaultProps; diff --git a/src/pages/home/report/ReportActionItemThread.js b/src/pages/home/report/ReportActionItemThread.js index 41cbf8c96d89..835c31cf4df4 100644 --- a/src/pages/home/report/ReportActionItemThread.js +++ b/src/pages/home/report/ReportActionItemThread.js @@ -1,5 +1,5 @@ import React from 'react'; -import {View, Pressable, Text} from 'react-native'; +import {View, Text} from 'react-native'; import PropTypes from 'prop-types'; import styles from '../../../styles/styles'; import * as Report from '../../../libs/actions/Report'; @@ -9,6 +9,7 @@ import CONST from '../../../CONST'; import avatarPropTypes from '../../../components/avatarPropTypes'; import MultipleAvatars from '../../../components/MultipleAvatars'; import compose from '../../../libs/compose'; +import PressableWithoutFeedback from '../../../components/Pressable/PressableWithoutFeedback'; const propTypes = { /** List of participant icons for the thread */ @@ -30,7 +31,7 @@ const propTypes = { ...windowDimensionsPropTypes, }; -const ReportActionItemThread = (props) => { +function ReportActionItemThread(props) { const numberOfRepliesText = props.numberOfReplies > CONST.MAX_THREAD_REPLIES_PREVIEW ? `${CONST.MAX_THREAD_REPLIES_PREVIEW}+` : `${props.numberOfReplies}`; const replyText = props.numberOfReplies === 1 ? props.translate('threads.reply') : props.translate('threads.replies'); @@ -38,10 +39,12 @@ const ReportActionItemThread = (props) => { return ( - { Report.navigateToAndOpenChildReport(props.childReportID); }} + accessibilityRole="button" + accessibilityLabel={`${props.numberOfReplies} ${replyText}`} > { >{`${props.translate('threads.lastReply')} ${timeStamp}`} - + ); -}; +} ReportActionItemThread.propTypes = propTypes; ReportActionItemThread.displayName = 'ReportActionItemThread'; diff --git a/src/pages/home/report/ReportActionsList.js b/src/pages/home/report/ReportActionsList.js index edbfcc7eee47..367f81895fd0 100644 --- a/src/pages/home/report/ReportActionsList.js +++ b/src/pages/home/report/ReportActionsList.js @@ -77,7 +77,7 @@ function keyExtractor(item) { return item.reportActionID; } -const ReportActionsList = (props) => { +function ReportActionsList(props) { const opacity = useSharedValue(0); const animatedStyles = useAnimatedStyle(() => ({ opacity: opacity.value, @@ -191,7 +191,7 @@ const ReportActionsList = (props) => { /> ); -}; +} ReportActionsList.propTypes = propTypes; ReportActionsList.defaultProps = defaultProps; diff --git a/src/pages/home/report/ReportDropUI.js b/src/pages/home/report/ReportDropUI.js index 87e0696cb71f..f59d0a31135d 100644 --- a/src/pages/home/report/ReportDropUI.js +++ b/src/pages/home/report/ReportDropUI.js @@ -12,21 +12,23 @@ const propTypes = { ...withLocalizePropTypes, }; -const ReportDropUI = (props) => ( - - - - - {props.translate('reportActionCompose.dropToUpload')} - -); +function ReportDropUI(props) { + return ( + + + + + {props.translate('reportActionCompose.dropToUpload')} + + ); +} ReportDropUI.displayName = 'ReportDropUI'; ReportDropUI.propTypes = propTypes; diff --git a/src/pages/home/sidebar/SidebarScreen/index.js b/src/pages/home/sidebar/SidebarScreen/index.js index e93c20ad9815..20eb62d0ddd6 100755 --- a/src/pages/home/sidebar/SidebarScreen/index.js +++ b/src/pages/home/sidebar/SidebarScreen/index.js @@ -5,7 +5,7 @@ import FloatingActionButtonAndPopover from './FloatingActionButtonAndPopover'; import FreezeWrapper from '../../../../libs/Navigation/FreezeWrapper'; import withWindowDimensions from '../../../../components/withWindowDimensions'; -const SidebarScreen = (props) => { +function SidebarScreen(props) { const popoverModal = useRef(null); /** @@ -36,7 +36,7 @@ const SidebarScreen = (props) => { ); -}; +} SidebarScreen.propTypes = sidebarPropTypes; SidebarScreen.displayName = 'SidebarScreen'; diff --git a/src/pages/home/sidebar/SidebarScreen/index.native.js b/src/pages/home/sidebar/SidebarScreen/index.native.js index 971ea8d8f816..8ed41233bdb5 100755 --- a/src/pages/home/sidebar/SidebarScreen/index.native.js +++ b/src/pages/home/sidebar/SidebarScreen/index.native.js @@ -5,16 +5,18 @@ import FloatingActionButtonAndPopover from './FloatingActionButtonAndPopover'; import FreezeWrapper from '../../../../libs/Navigation/FreezeWrapper'; import withWindowDimensions from '../../../../components/withWindowDimensions'; -const SidebarScreen = (props) => ( - - - - - -); +function SidebarScreen(props) { + return ( + + + + + + ); +} SidebarScreen.propTypes = sidebarPropTypes; SidebarScreen.displayName = 'SidebarScreen'; diff --git a/src/pages/iou/IOUBillPage.js b/src/pages/iou/IOUBillPage.js index 433dd1697b0b..a3a9d4932bd4 100644 --- a/src/pages/iou/IOUBillPage.js +++ b/src/pages/iou/IOUBillPage.js @@ -1,12 +1,14 @@ import React from 'react'; import MoneyRequestModal from './MoneyRequestModal'; -const IOUBillPage = (props) => ( - -); +function IOUBillPage(props) { + return ( + + ); +} IOUBillPage.displayName = 'IOUBillPage'; export default IOUBillPage; diff --git a/src/pages/iou/IOURequestPage.js b/src/pages/iou/IOURequestPage.js index 86b1e1a4dab9..8311e188c666 100644 --- a/src/pages/iou/IOURequestPage.js +++ b/src/pages/iou/IOURequestPage.js @@ -1,7 +1,9 @@ import React from 'react'; import MoneyRequestModal from './MoneyRequestModal'; -// eslint-disable-next-line react/jsx-props-no-spreading -const IOURequestPage = (props) => ; +function IOURequestPage(props) { + // eslint-disable-next-line react/jsx-props-no-spreading + return ; +} IOURequestPage.displayName = 'IOURequestPage'; export default IOURequestPage; diff --git a/src/pages/iou/IOUSendPage.js b/src/pages/iou/IOUSendPage.js index 19af6d44dea6..e53fd273a2f2 100644 --- a/src/pages/iou/IOUSendPage.js +++ b/src/pages/iou/IOUSendPage.js @@ -2,12 +2,14 @@ import React from 'react'; import CONST from '../../CONST'; import MoneyRequestModal from './MoneyRequestModal'; -const IOUSendPage = (props) => ( - -); +function IOUSendPage(props) { + return ( + + ); +} IOUSendPage.displayName = 'IOUSendPage'; export default IOUSendPage; diff --git a/src/pages/iou/MoneyRequestModal.js b/src/pages/iou/MoneyRequestModal.js index 729a4ed27227..8b08c36359b5 100644 --- a/src/pages/iou/MoneyRequestModal.js +++ b/src/pages/iou/MoneyRequestModal.js @@ -95,7 +95,7 @@ const Steps = { MoneyRequestConfirm: 'moneyRequest.confirm', }; -const MoneyRequestModal = (props) => { +function MoneyRequestModal(props) { // Skip MoneyRequestParticipants step if participants are passed in const reportParticipants = lodashGet(props, 'report.participants', []); const steps = useMemo( @@ -394,7 +394,7 @@ const MoneyRequestModal = (props) => { )} ); -}; +} MoneyRequestModal.displayName = 'MoneyRequestModal'; MoneyRequestModal.propTypes = propTypes; diff --git a/src/pages/iou/SplitBillDetailsPage.js b/src/pages/iou/SplitBillDetailsPage.js index d4e5cc85d3fb..f892e57c3e06 100644 --- a/src/pages/iou/SplitBillDetailsPage.js +++ b/src/pages/iou/SplitBillDetailsPage.js @@ -62,7 +62,7 @@ function getReportID(route) { return route.params.reportID.toString(); } -const SplitBillDetailsPage = (props) => { +function SplitBillDetailsPage(props) { const reportAction = props.reportActions[`${props.route.params.reportActionID.toString()}`]; const personalDetails = OptionsListUtils.getPersonalDetailsForLogins(reportAction.originalMessage.participants, props.personalDetails); const participants = OptionsListUtils.getParticipantsOptions(reportAction.originalMessage, personalDetails); @@ -97,7 +97,7 @@ const SplitBillDetailsPage = (props) => { ); -}; +} SplitBillDetailsPage.propTypes = propTypes; SplitBillDetailsPage.defaultProps = defaultProps; diff --git a/src/pages/iou/steps/MoneyRequestConfirmPage.js b/src/pages/iou/steps/MoneyRequestConfirmPage.js index daa5af83bbd6..8ed80aab7bcd 100644 --- a/src/pages/iou/steps/MoneyRequestConfirmPage.js +++ b/src/pages/iou/steps/MoneyRequestConfirmPage.js @@ -54,22 +54,24 @@ const defaultProps = { }, }; -const MoneyRequestConfirmPage = (props) => ( - -); +function MoneyRequestConfirmPage(props) { + return ( + + ); +} MoneyRequestConfirmPage.displayName = 'MoneyRequestConfirmPage'; MoneyRequestConfirmPage.propTypes = propTypes; diff --git a/src/pages/settings/AboutPage/AboutPage.js b/src/pages/settings/AboutPage/AboutPage.js index 8ec8ea447f0b..0b5074bfc0ce 100644 --- a/src/pages/settings/AboutPage/AboutPage.js +++ b/src/pages/settings/AboutPage/AboutPage.js @@ -28,7 +28,7 @@ const propTypes = { ...windowDimensionsPropTypes, }; -const AboutPage = (props) => { +function AboutPage(props) { let popoverAnchor; const menuItems = [ { @@ -136,7 +136,7 @@ const AboutPage = (props) => { )} ); -}; +} AboutPage.propTypes = propTypes; AboutPage.displayName = 'AboutPage'; diff --git a/src/pages/settings/AppDownloadLinks.js b/src/pages/settings/AppDownloadLinks.js index 3c42e4901616..c6c8035e5477 100644 --- a/src/pages/settings/AppDownloadLinks.js +++ b/src/pages/settings/AppDownloadLinks.js @@ -21,7 +21,7 @@ const propTypes = { ...windowDimensionsPropTypes, }; -const AppDownloadLinksPage = (props) => { +function AppDownloadLinksPage(props) { let popoverAnchor; const menuItems = [ @@ -80,7 +80,7 @@ const AppDownloadLinksPage = (props) => { ); -}; +} AppDownloadLinksPage.propTypes = propTypes; AppDownloadLinksPage.displayName = 'AppDownloadLinksPage'; diff --git a/src/pages/settings/NewPasswordForm.js b/src/pages/settings/NewPasswordForm.js index a2f02972dcad..224b0d5a0892 100644 --- a/src/pages/settings/NewPasswordForm.js +++ b/src/pages/settings/NewPasswordForm.js @@ -21,7 +21,7 @@ const propTypes = { ...withLocalizePropTypes, }; -const NewPasswordForm = (props) => { +function NewPasswordForm(props) { const [passwordHintError, setPasswordHintError] = useState(false); const isValidPassword = () => props.password.match(CONST.PASSWORD_COMPLEXITY_REGEX_STRING); @@ -61,7 +61,7 @@ const NewPasswordForm = (props) => { {props.translate('setPasswordPage.newPasswordPrompt')} ); -}; +} NewPasswordForm.propTypes = propTypes; NewPasswordForm.displayName = 'NewPasswordForm'; diff --git a/src/pages/settings/Payments/AddPayPalMePage.js b/src/pages/settings/Payments/AddPayPalMePage.js index cbb437ea00e6..ec5476a9162e 100644 --- a/src/pages/settings/Payments/AddPayPalMePage.js +++ b/src/pages/settings/Payments/AddPayPalMePage.js @@ -21,7 +21,7 @@ import * as Expensicons from '../../../components/Icon/Expensicons'; import variables from '../../../styles/variables'; import PressableWithoutFeedback from '../../../components/Pressable/PressableWithoutFeedback'; -const AddPayPalMePage = (props) => { +function AddPayPalMePage(props) { const [payPalMeUsername, setPayPalMeUsername] = useState(''); const [payPalMeUsernameError, setPayPalMeUsernameError] = useState(false); const payPalMeInput = useRef(null); @@ -107,7 +107,7 @@ const AddPayPalMePage = (props) => { ); -}; +} AddPayPalMePage.propTypes = {...withLocalizePropTypes}; AddPayPalMePage.displayName = 'AddPayPalMePage'; diff --git a/src/pages/settings/Payments/ChooseTransferAccountPage.js b/src/pages/settings/Payments/ChooseTransferAccountPage.js index 224b727bf4e5..0443401a62f1 100644 --- a/src/pages/settings/Payments/ChooseTransferAccountPage.js +++ b/src/pages/settings/Payments/ChooseTransferAccountPage.js @@ -28,7 +28,7 @@ const defaultProps = { walletTransfer: {}, }; -const ChooseTransferAccountPage = (props) => { +function ChooseTransferAccountPage(props) { /** * Go back to transfer balance screen with the selected bank account set * @param {Object} event Click event object @@ -77,7 +77,7 @@ const ChooseTransferAccountPage = (props) => { /> ); -}; +} ChooseTransferAccountPage.propTypes = propTypes; ChooseTransferAccountPage.defaultProps = defaultProps; diff --git a/src/pages/settings/Payments/PaymentsPage/index.js b/src/pages/settings/Payments/PaymentsPage/index.js index c22511e4f160..df81f1f1b39b 100644 --- a/src/pages/settings/Payments/PaymentsPage/index.js +++ b/src/pages/settings/Payments/PaymentsPage/index.js @@ -1,7 +1,9 @@ import React from 'react'; import BasePaymentsPage from './BasePaymentsPage'; -const PaymentsPage = () => ; +function PaymentsPage() { + return ; +} PaymentsPage.displayName = 'PaymentsPage'; diff --git a/src/pages/settings/Preferences/LanguagePage.js b/src/pages/settings/Preferences/LanguagePage.js index 23f36e6e44e3..e449b43b22b7 100644 --- a/src/pages/settings/Preferences/LanguagePage.js +++ b/src/pages/settings/Preferences/LanguagePage.js @@ -21,7 +21,7 @@ const propTypes = { preferredLocale: PropTypes.string.isRequired, }; -const LanguagePage = (props) => { +function LanguagePage(props) { const localesToLanguages = _.map(props.translate('languagePage.languages'), (language, key) => ({ value: key, text: language.label, @@ -55,7 +55,7 @@ const LanguagePage = (props) => { /> ); -}; +} LanguagePage.displayName = 'LanguagePage'; LanguagePage.propTypes = propTypes; diff --git a/src/pages/settings/Preferences/PreferencesPage.js b/src/pages/settings/Preferences/PreferencesPage.js index 8cf39f23f9f8..81b129439e96 100755 --- a/src/pages/settings/Preferences/PreferencesPage.js +++ b/src/pages/settings/Preferences/PreferencesPage.js @@ -42,7 +42,7 @@ const defaultProps = { user: {}, }; -const PreferencesPage = (props) => { +function PreferencesPage(props) { const priorityModes = props.translate('priorityModePage.priorityModes'); const languages = props.translate('languagePage.languages'); @@ -96,7 +96,7 @@ const PreferencesPage = (props) => { ); -}; +} PreferencesPage.propTypes = propTypes; PreferencesPage.defaultProps = defaultProps; diff --git a/src/pages/settings/Preferences/PriorityModePage.js b/src/pages/settings/Preferences/PriorityModePage.js index e044d906e862..cf48e63d015d 100644 --- a/src/pages/settings/Preferences/PriorityModePage.js +++ b/src/pages/settings/Preferences/PriorityModePage.js @@ -29,7 +29,7 @@ const defaultProps = { priorityMode: CONST.PRIORITY_MODE.DEFAULT, }; -const PriorityModePage = (props) => { +function PriorityModePage(props) { const priorityModes = _.map(props.translate('priorityModePage.priorityModes'), (mode, key) => ({ value: key, text: mode.label, @@ -68,7 +68,7 @@ const PriorityModePage = (props) => { /> ); -}; +} PriorityModePage.displayName = 'PriorityModePage'; PriorityModePage.propTypes = propTypes; diff --git a/src/pages/settings/Profile/Contacts/ContactMethodsPage.js b/src/pages/settings/Profile/Contacts/ContactMethodsPage.js index aa27771beeec..3100af19c4e9 100644 --- a/src/pages/settings/Profile/Contacts/ContactMethodsPage.js +++ b/src/pages/settings/Profile/Contacts/ContactMethodsPage.js @@ -58,7 +58,7 @@ const defaultProps = { }, }; -const ContactMethodsPage = (props) => { +function ContactMethodsPage(props) { const loginNames = _.keys(props.loginList); // Sort the login names by placing the one corresponding to the default contact method as the first item before displaying the contact methods. @@ -139,7 +139,7 @@ const ContactMethodsPage = (props) => { ); -}; +} ContactMethodsPage.propTypes = propTypes; ContactMethodsPage.defaultProps = defaultProps; diff --git a/src/pages/settings/Profile/Contacts/ValidateCodeForm/index.android.js b/src/pages/settings/Profile/Contacts/ValidateCodeForm/index.android.js index 8128b2077012..30c5517b8375 100644 --- a/src/pages/settings/Profile/Contacts/ValidateCodeForm/index.android.js +++ b/src/pages/settings/Profile/Contacts/ValidateCodeForm/index.android.js @@ -1,13 +1,15 @@ import React from 'react'; import BaseValidateCodeForm from './BaseValidateCodeForm'; -const ValidateCodeForm = (props) => ( - -); +function ValidateCodeForm(props) { + return ( + + ); +} ValidateCodeForm.displayName = 'ValidateCodeForm'; diff --git a/src/pages/settings/Profile/Contacts/ValidateCodeForm/index.js b/src/pages/settings/Profile/Contacts/ValidateCodeForm/index.js index 80691a931185..6ef0c91b6d37 100644 --- a/src/pages/settings/Profile/Contacts/ValidateCodeForm/index.js +++ b/src/pages/settings/Profile/Contacts/ValidateCodeForm/index.js @@ -1,13 +1,15 @@ import React from 'react'; import BaseValidateCodeForm from './BaseValidateCodeForm'; -const ValidateCodeForm = (props) => ( - -); +function ValidateCodeForm(props) { + return ( + + ); +} ValidateCodeForm.displayName = 'ValidateCodeForm'; diff --git a/src/pages/settings/Profile/PersonalDetails/DateOfBirthPage.js b/src/pages/settings/Profile/PersonalDetails/DateOfBirthPage.js index cd1ed1ac0895..77413ae1e596 100644 --- a/src/pages/settings/Profile/PersonalDetails/DateOfBirthPage.js +++ b/src/pages/settings/Profile/PersonalDetails/DateOfBirthPage.js @@ -34,7 +34,7 @@ const defaultProps = { }, }; -const DateOfBirthPage = ({translate, route, privatePersonalDetails}) => { +function DateOfBirthPage({translate, route, privatePersonalDetails}) { /** * The year should be set on the route when navigating back from the year picker * This lets us pass the selected year without having to overwrite the value in Onyx @@ -93,7 +93,7 @@ const DateOfBirthPage = ({translate, route, privatePersonalDetails}) => { ); -}; +} DateOfBirthPage.propTypes = propTypes; DateOfBirthPage.defaultProps = defaultProps; diff --git a/src/pages/settings/Profile/PersonalDetails/PersonalDetailsInitialPage.js b/src/pages/settings/Profile/PersonalDetails/PersonalDetailsInitialPage.js index e8eb26e120a7..a466d2091de1 100644 --- a/src/pages/settings/Profile/PersonalDetails/PersonalDetailsInitialPage.js +++ b/src/pages/settings/Profile/PersonalDetails/PersonalDetailsInitialPage.js @@ -53,7 +53,7 @@ const defaultProps = { }, }; -const PersonalDetailsInitialPage = (props) => { +function PersonalDetailsInitialPage(props) { useEffect(() => { if (props.network.isOffline) { return; @@ -120,7 +120,7 @@ const PersonalDetailsInitialPage = (props) => { ); -}; +} PersonalDetailsInitialPage.propTypes = propTypes; PersonalDetailsInitialPage.defaultProps = defaultProps; diff --git a/src/pages/settings/Profile/ProfilePage.js b/src/pages/settings/Profile/ProfilePage.js index 9d0a83855be0..562b862a7fc6 100755 --- a/src/pages/settings/Profile/ProfilePage.js +++ b/src/pages/settings/Profile/ProfilePage.js @@ -45,7 +45,7 @@ const defaultProps = { ...withCurrentUserPersonalDetailsDefaultProps, }; -const ProfilePage = (props) => { +function ProfilePage(props) { const getPronouns = () => { let pronounsKey = lodashGet(props.currentUserPersonalDetails, 'pronouns', ''); if (pronounsKey.startsWith(CONST.PRONOUNS.PREFIX)) { @@ -121,7 +121,7 @@ const ProfilePage = (props) => { ); -}; +} ProfilePage.propTypes = propTypes; ProfilePage.defaultProps = defaultProps; diff --git a/src/pages/settings/Profile/TimezoneInitialPage.js b/src/pages/settings/Profile/TimezoneInitialPage.js index d23131305054..7dfc9fb6f9de 100644 --- a/src/pages/settings/Profile/TimezoneInitialPage.js +++ b/src/pages/settings/Profile/TimezoneInitialPage.js @@ -25,7 +25,7 @@ const defaultProps = { ...withCurrentUserPersonalDetailsDefaultProps, }; -const TimezoneInitialPage = (props) => { +function TimezoneInitialPage(props) { const timezone = lodashGet(props.currentUserPersonalDetails, 'timezone', CONST.DEFAULT_TIME_ZONE); /** @@ -69,7 +69,7 @@ const TimezoneInitialPage = (props) => { ); -}; +} TimezoneInitialPage.propTypes = propTypes; TimezoneInitialPage.defaultProps = defaultProps; diff --git a/src/pages/settings/Report/NotificationPreferencePage.js b/src/pages/settings/Report/NotificationPreferencePage.js index 331ea4fe9988..915a32180ad8 100644 --- a/src/pages/settings/Report/NotificationPreferencePage.js +++ b/src/pages/settings/Report/NotificationPreferencePage.js @@ -22,7 +22,7 @@ const propTypes = { }; const greenCheckmark = {src: Expensicons.Checkmark, color: themeColors.success}; -const NotificationPreferencePage = (props) => { +function NotificationPreferencePage(props) { const notificationPreferenceOptions = _.map(props.translate('notificationPreferencesPage.notificationPreferences'), (preference, key) => ({ value: key, text: preference, @@ -56,7 +56,7 @@ const NotificationPreferencePage = (props) => { /> ); -}; +} NotificationPreferencePage.displayName = 'NotificationPreferencePage'; NotificationPreferencePage.propTypes = propTypes; diff --git a/src/pages/settings/Report/RoomNamePage.js b/src/pages/settings/Report/RoomNamePage.js index 89baaca72c79..b4bf1d0c5566 100644 --- a/src/pages/settings/Report/RoomNamePage.js +++ b/src/pages/settings/Report/RoomNamePage.js @@ -32,7 +32,7 @@ const defaultProps = { reports: {}, }; -const RoomNamePage = (props) => { +function RoomNamePage(props) { const report = props.report; const reports = props.reports; const translate = props.translate; @@ -89,7 +89,7 @@ const RoomNamePage = (props) => { ); -}; +} RoomNamePage.propTypes = propTypes; RoomNamePage.defaultProps = defaultProps; diff --git a/src/pages/settings/Report/WriteCapabilityPage.js b/src/pages/settings/Report/WriteCapabilityPage.js index b71b80673da9..381d21785564 100644 --- a/src/pages/settings/Report/WriteCapabilityPage.js +++ b/src/pages/settings/Report/WriteCapabilityPage.js @@ -23,7 +23,7 @@ const propTypes = { }; const greenCheckmark = {src: Expensicons.Checkmark, color: themeColors.success}; -const WriteCapabilityPage = (props) => { +function WriteCapabilityPage(props) { const writeCapabilityOptions = _.map(CONST.REPORT.WRITE_CAPABILITIES, (value) => ({ value, text: props.translate(`writeCapabilityPage.writeCapability.${value}`), @@ -58,7 +58,7 @@ const WriteCapabilityPage = (props) => { /> ); -}; +} WriteCapabilityPage.displayName = 'WriteCapabilityPage'; WriteCapabilityPage.propTypes = propTypes; diff --git a/src/pages/settings/Security/TwoFactorAuth/TwoFactorAuthForm/index.android.js b/src/pages/settings/Security/TwoFactorAuth/TwoFactorAuthForm/index.android.js index 925f6d429fa1..ea0d5e257e2f 100644 --- a/src/pages/settings/Security/TwoFactorAuth/TwoFactorAuthForm/index.android.js +++ b/src/pages/settings/Security/TwoFactorAuth/TwoFactorAuthForm/index.android.js @@ -1,7 +1,9 @@ import React from 'react'; import BaseTwoFactorAuthForm from './BaseTwoFactorAuthForm'; -const TwoFactorAuthForm = () => ; +function TwoFactorAuthForm() { + return ; +} TwoFactorAuthForm.displayName = 'TwoFactorAuthForm'; diff --git a/src/pages/settings/Security/TwoFactorAuth/TwoFactorAuthForm/index.js b/src/pages/settings/Security/TwoFactorAuth/TwoFactorAuthForm/index.js index c204978554ff..c52e65facd6d 100644 --- a/src/pages/settings/Security/TwoFactorAuth/TwoFactorAuthForm/index.js +++ b/src/pages/settings/Security/TwoFactorAuth/TwoFactorAuthForm/index.js @@ -1,7 +1,9 @@ import React from 'react'; import BaseTwoFactorAuthForm from './BaseTwoFactorAuthForm'; -const TwoFactorAuthForm = () => ; +function TwoFactorAuthForm() { + return ; +} TwoFactorAuthForm.displayName = 'TwoFactorAuthForm'; diff --git a/src/pages/signin/ChangeExpensifyLoginLink.js b/src/pages/signin/ChangeExpensifyLoginLink.js index 0ea56a176af2..3419454d611b 100755 --- a/src/pages/signin/ChangeExpensifyLoginLink.js +++ b/src/pages/signin/ChangeExpensifyLoginLink.js @@ -29,22 +29,24 @@ const defaultProps = { }, }; -const ChangeExpensifyLoginLink = (props) => ( - - {!_.isEmpty(props.credentials.login) && {props.translate('loginForm.notYou', {user: props.formatPhoneNumber(props.credentials.login)})}} - - - {props.translate('common.goBack')} - {'.'} - - - -); +function ChangeExpensifyLoginLink(props) { + return ( + + {!_.isEmpty(props.credentials.login) && {props.translate('loginForm.notYou', {user: props.formatPhoneNumber(props.credentials.login)})}} + + + {props.translate('common.goBack')} + {'.'} + + + + ); +} ChangeExpensifyLoginLink.propTypes = propTypes; ChangeExpensifyLoginLink.defaultProps = defaultProps; diff --git a/src/pages/signin/Licenses.js b/src/pages/signin/Licenses.js index a734579090e4..e3f1026c1e9f 100644 --- a/src/pages/signin/Licenses.js +++ b/src/pages/signin/Licenses.js @@ -9,25 +9,27 @@ import LocalePicker from '../../components/LocalePicker'; const currentYear = new Date().getFullYear(); -const Licenses = (props) => ( - <> - {`© ${currentYear} Expensify`} - - {props.translate('termsOfUse.phrase5')} - - {' '} - {props.translate('termsOfUse.phrase6')} - - . - - - - - -); +function Licenses(props) { + return ( + <> + {`© ${currentYear} Expensify`} + + {props.translate('termsOfUse.phrase5')} + + {' '} + {props.translate('termsOfUse.phrase6')} + + . + + + + + + ); +} Licenses.propTypes = {...withLocalizePropTypes}; Licenses.displayName = 'Licenses'; diff --git a/src/pages/signin/ResendValidationForm.js b/src/pages/signin/ResendValidationForm.js index 993ed7d76478..091e386fb100 100755 --- a/src/pages/signin/ResendValidationForm.js +++ b/src/pages/signin/ResendValidationForm.js @@ -49,7 +49,7 @@ const defaultProps = { account: {}, }; -const ResendValidationForm = (props) => { +function ResendValidationForm(props) { const isSMSLogin = Str.isSMSLogin(props.credentials.login); // replacing spaces with "hard spaces" to prevent breaking the number @@ -113,7 +113,7 @@ const ResendValidationForm = (props) => { ); -}; +} ResendValidationForm.propTypes = propTypes; ResendValidationForm.defaultProps = defaultProps; diff --git a/src/pages/signin/SignInHeroCopy.js b/src/pages/signin/SignInHeroCopy.js index c06985526a42..204876c25398 100644 --- a/src/pages/signin/SignInHeroCopy.js +++ b/src/pages/signin/SignInHeroCopy.js @@ -13,20 +13,22 @@ const propTypes = { ...withLocalizePropTypes, }; -const SignInHeroCopy = (props) => ( - - - {props.translate('login.hero.header')} - - {props.translate('login.hero.body')} - -); +function SignInHeroCopy(props) { + return ( + + + {props.translate('login.hero.header')} + + {props.translate('login.hero.body')} + + ); +} SignInHeroCopy.displayName = 'SignInHeroCopy'; SignInHeroCopy.propTypes = propTypes; diff --git a/src/pages/signin/SignInHeroImage.js b/src/pages/signin/SignInHeroImage.js index 24f1895ed5e0..9785a66a4003 100644 --- a/src/pages/signin/SignInHeroImage.js +++ b/src/pages/signin/SignInHeroImage.js @@ -9,7 +9,7 @@ const propTypes = { ...windowDimensionsPropTypes, }; -const SignInHeroImage = (props) => { +function SignInHeroImage(props) { let imageSize; if (props.isSmallScreenWidth) { imageSize = { @@ -36,7 +36,7 @@ const SignInHeroImage = (props) => { style={[styles.alignSelfCenter, imageSize]} /> ); -}; +} SignInHeroImage.displayName = 'SignInHeroImage'; SignInHeroImage.propTypes = propTypes; diff --git a/src/pages/signin/SignInPage.js b/src/pages/signin/SignInPage.js index dcfc7b67a56a..a875c25359b0 100644 --- a/src/pages/signin/SignInPage.js +++ b/src/pages/signin/SignInPage.js @@ -1,27 +1,30 @@ -import React, {useEffect} from 'react'; -import {View} from 'react-native'; +import React, {Component} from 'react'; import PropTypes from 'prop-types'; import {withOnyx} from 'react-native-onyx'; +import {View} from 'react-native'; +import lodashGet from 'lodash/get'; import Str from 'expensify-common/lib/str'; -import {useSafeAreaInsets} from 'react-native-safe-area-context'; +import {withSafeAreaInsets} from 'react-native-safe-area-context'; import ONYXKEYS from '../../ONYXKEYS'; import styles from '../../styles/styles'; +import compose from '../../libs/compose'; import SignInPageLayout from './SignInPageLayout'; import LoginForm from './LoginForm'; import PasswordForm from './PasswordForm'; import ValidateCodeForm from './ValidateCodeForm'; import ResendValidationForm from './ResendValidationForm'; +import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize'; import Performance from '../../libs/Performance'; import * as App from '../../libs/actions/App'; +import Permissions from '../../libs/Permissions'; import UnlinkLoginForm from './UnlinkLoginForm'; +import withWindowDimensions, {windowDimensionsPropTypes} from '../../components/withWindowDimensions'; import * as Localize from '../../libs/Localize'; -import useLocalize from '../../hooks/useLocalize'; -import usePermissions from '../../hooks/usePermissions'; -import useWindowDimensions from '../../hooks/useWindowDimensions'; -import Log from '../../libs/Log'; import * as StyleUtils from '../../styles/StyleUtils'; const propTypes = { + /* Onyx Props */ + /** The details about the account that the user is signing in with */ account: PropTypes.shape({ /** Error to display when there is an account error returned */ @@ -32,149 +35,153 @@ const propTypes = { /** The primaryLogin associated with the account */ primaryLogin: PropTypes.string, - - /** Has the user pressed the forgot password button? */ - forgotPassword: PropTypes.bool, - - /** Does this account require 2FA? */ - requiresTwoFactorAuth: PropTypes.bool, }), + /** List of betas available to current user */ + betas: PropTypes.arrayOf(PropTypes.string), + /** The credentials of the person signing in */ credentials: PropTypes.shape({ login: PropTypes.string, password: PropTypes.string, twoFactorAuthCode: PropTypes.string, - validateCode: PropTypes.string, }), + + ...withLocalizePropTypes, + + ...windowDimensionsPropTypes, }; const defaultProps = { account: {}, + betas: [], credentials: {}, }; -/** - * @param {Boolean} hasLogin - * @param {Boolean} hasPassword - * @param {Boolean} hasValidateCode - * @param {Boolean} isPrimaryLogin - * @param {Boolean} isAccountValidated - * @param {Boolean} didForgetPassword - * @param {Boolean} canUsePasswordlessLogins - * @returns {Object} - */ -function getRenderOptions({hasLogin, hasPassword, hasValidateCode, isPrimaryLogin, isAccountValidated, didForgetPassword, canUsePasswordlessLogins}) { - const shouldShowLoginForm = !hasLogin && !hasValidateCode; - const isUnvalidatedSecondaryLogin = hasLogin && !isPrimaryLogin && !isAccountValidated; - const shouldShowPasswordForm = hasLogin && isAccountValidated && !hasPassword && !didForgetPassword && !isUnvalidatedSecondaryLogin && !canUsePasswordlessLogins; - const shouldShowValidateCodeForm = (hasLogin || hasValidateCode) && !isUnvalidatedSecondaryLogin && canUsePasswordlessLogins; - const shouldShowResendValidationForm = hasLogin && (!isAccountValidated || didForgetPassword) && !isUnvalidatedSecondaryLogin && !canUsePasswordlessLogins; - const shouldShowWelcomeHeader = shouldShowLoginForm || shouldShowPasswordForm || shouldShowValidateCodeForm || isUnvalidatedSecondaryLogin; - const shouldShowWelcomeText = shouldShowLoginForm || shouldShowPasswordForm || shouldShowValidateCodeForm; - return { - shouldShowLoginForm, - shouldShowUnlinkLoginForm: isUnvalidatedSecondaryLogin, - shouldShowPasswordForm, - shouldShowValidateCodeForm, - shouldShowResendValidationForm, - shouldShowWelcomeHeader, - shouldShowWelcomeText, - }; -} - -function SignInPage({account, credentials}) { - const {translate, formatPhoneNumber} = useLocalize(); - const {canUsePasswordlessLogins} = usePermissions(); - const {isSmallScreenWidth} = useWindowDimensions(); - const safeAreaInsets = useSafeAreaInsets(); +class SignInPage extends Component { + componentDidMount() { + Performance.measureTTI(); - useEffect(() => Performance.measureTTI(), []); - useEffect(() => { App.setLocale(Localize.getDevicePreferredLocale()); - }, []); - - const { - shouldShowLoginForm, - shouldShowUnlinkLoginForm, - shouldShowPasswordForm, - shouldShowValidateCodeForm, - shouldShowResendValidationForm, - shouldShowWelcomeHeader, - shouldShowWelcomeText, - } = getRenderOptions({ - hasLogin: Boolean(credentials.login), - hasPassword: Boolean(credentials.password), - hasValidateCode: Boolean(credentials.validateCode), - isPrimaryLogin: account.primaryLogin && account.primaryLogin === credentials.login, - isAccountValidated: Boolean(account.validated), - didForgetPassword: Boolean(account.forgotPassword), - canUsePasswordlessLogins, - }); - - let welcomeHeader; - let welcomeText; - if (shouldShowValidateCodeForm) { - if (account.requiresTwoFactorAuth) { - // We will only know this after a user signs in successfully, without their 2FA code - welcomeHeader = isSmallScreenWidth ? '' : translate('welcomeText.welcomeBack'); - welcomeText = translate('validateCodeForm.enterAuthenticatorCode'); - } else { - const userLogin = Str.removeSMSDomain(credentials.login || ''); - - // replacing spaces with "hard spaces" to prevent breaking the number - const userLoginToDisplay = Str.isSMSLogin(userLogin) ? formatPhoneNumber(userLogin).replace(/ /g, '\u00A0') : userLogin; - if (account.validated) { - welcomeHeader = isSmallScreenWidth ? '' : translate('welcomeText.welcomeBack'); - welcomeText = isSmallScreenWidth - ? `${translate('welcomeText.welcomeBack')} ${translate('welcomeText.welcomeEnterMagicCode', {login: userLoginToDisplay})}` - : translate('welcomeText.welcomeEnterMagicCode', {login: userLoginToDisplay}); + } + + render() { + // Show the login form if + // - A login has not been entered yet + // - AND a validateCode has not been cached with sign in link + const showLoginForm = !this.props.credentials.login && !this.props.credentials.validateCode; + + // Show the unlink form if + // - A login has been entered + // - AND the login is not the primary login + // - AND the login is not validated + const showUnlinkLoginForm = + Boolean(this.props.credentials.login && this.props.account.primaryLogin) && this.props.account.primaryLogin !== this.props.credentials.login && !this.props.account.validated; + + // Show the old password form if + // - A login has been entered + // - AND an account exists and is validated for this login + // - AND a password hasn't been entered yet + // - AND haven't forgotten password + // - AND the login isn't an unvalidated secondary login + // - AND the user is NOT on the passwordless beta + const showPasswordForm = + Boolean(this.props.credentials.login) && + this.props.account.validated && + !this.props.credentials.password && + !this.props.account.forgotPassword && + !showUnlinkLoginForm && + !Permissions.canUsePasswordlessLogins(this.props.betas); + + // Show the new magic code / validate code form if + // - A login has been entered or a validateCode has been cached from sign in link + // - AND the login isn't an unvalidated secondary login + // - AND the user is on the 'passwordless' beta + const showValidateCodeForm = + Boolean(this.props.credentials.login || this.props.credentials.validateCode) && !showUnlinkLoginForm && Permissions.canUsePasswordlessLogins(this.props.betas); + + // Show the resend validation link form if + // - A login has been entered + // - AND is not validated or password is forgotten + // - AND the login isn't an unvalidated secondary login + // - AND user is not on 'passwordless' beta + const showResendValidationForm = + Boolean(this.props.credentials.login) && + (!this.props.account.validated || this.props.account.forgotPassword) && + !showUnlinkLoginForm && + !Permissions.canUsePasswordlessLogins(this.props.betas); + + let welcomeHeader = ''; + let welcomeText = ''; + if (showValidateCodeForm) { + if (this.props.account.requiresTwoFactorAuth) { + // We will only know this after a user signs in successfully, without their 2FA code + welcomeHeader = this.props.isSmallScreenWidth ? '' : this.props.translate('welcomeText.welcomeBack'); + welcomeText = this.props.translate('validateCodeForm.enterAuthenticatorCode'); } else { - welcomeHeader = isSmallScreenWidth ? '' : translate('welcomeText.welcome'); - welcomeText = isSmallScreenWidth - ? `${translate('welcomeText.welcome')} ${translate('welcomeText.newFaceEnterMagicCode', {login: userLoginToDisplay})}` - : translate('welcomeText.newFaceEnterMagicCode', {login: userLoginToDisplay}); + const userLogin = Str.removeSMSDomain(lodashGet(this.props, 'credentials.login', '')); + + // replacing spaces with "hard spaces" to prevent breaking the number + const userLoginToDisplay = Str.isSMSLogin(userLogin) ? this.props.formatPhoneNumber(userLogin).replace(/ /g, '\u00A0') : userLogin; + if (this.props.account.validated) { + welcomeHeader = this.props.isSmallScreenWidth ? '' : this.props.translate('welcomeText.welcomeBack'); + welcomeText = this.props.isSmallScreenWidth + ? `${this.props.translate('welcomeText.welcomeBack')} ${this.props.translate('welcomeText.welcomeEnterMagicCode', {login: userLoginToDisplay})}` + : this.props.translate('welcomeText.welcomeEnterMagicCode', {login: userLoginToDisplay}); + } else { + welcomeHeader = this.props.isSmallScreenWidth ? '' : this.props.translate('welcomeText.welcome'); + welcomeText = this.props.isSmallScreenWidth + ? `${this.props.translate('welcomeText.welcome')} ${this.props.translate('welcomeText.newFaceEnterMagicCode', {login: userLoginToDisplay})}` + : this.props.translate('welcomeText.newFaceEnterMagicCode', {login: userLoginToDisplay}); + } } + } else if (showPasswordForm) { + welcomeHeader = this.props.isSmallScreenWidth ? '' : this.props.translate('welcomeText.welcomeBack'); + welcomeText = this.props.isSmallScreenWidth + ? `${this.props.translate('welcomeText.welcomeBack')} ${this.props.translate('welcomeText.enterPassword')}` + : this.props.translate('welcomeText.enterPassword'); + } else if (showUnlinkLoginForm) { + welcomeHeader = this.props.isSmallScreenWidth ? this.props.translate('login.hero.header') : this.props.translate('welcomeText.welcomeBack'); + } else if (!showResendValidationForm) { + welcomeHeader = this.props.isSmallScreenWidth ? this.props.translate('login.hero.header') : this.props.translate('welcomeText.getStarted'); + welcomeText = this.props.isSmallScreenWidth ? this.props.translate('welcomeText.getStarted') : ''; } - } else if (shouldShowPasswordForm) { - welcomeHeader = isSmallScreenWidth ? '' : translate('welcomeText.welcomeBack'); - welcomeText = isSmallScreenWidth ? `${translate('welcomeText.welcomeBack')} ${translate('welcomeText.enterPassword')}` : translate('welcomeText.enterPassword'); - } else if (shouldShowUnlinkLoginForm) { - welcomeHeader = isSmallScreenWidth ? translate('login.hero.header') : translate('welcomeText.welcomeBack'); - } else if (!shouldShowResendValidationForm) { - welcomeHeader = isSmallScreenWidth ? translate('login.hero.header') : translate('welcomeText.getStarted'); - welcomeText = isSmallScreenWidth ? translate('welcomeText.getStarted') : ''; - } else { - Log.warn('SignInPage in unexpected state!'); - } - return ( - - - {/* LoginForm and PasswordForm must use the isVisible prop. This keeps them mounted, but visually hidden + return ( + // There is an issue SafeAreaView on Android where wrong insets flicker on app start. + // Can be removed once https://github.com/th3rdwave/react-native-safe-area-context/issues/364 is resolved. + + + {/* LoginForm and PasswordForm must use the isVisible prop. This keeps them mounted, but visually hidden so that password managers can access the values. Conditionally rendering these components will break this feature. */} - - {shouldShowValidateCodeForm ? : } - {shouldShowResendValidationForm && } - {shouldShowUnlinkLoginForm && } - - - ); + + {showValidateCodeForm ? : } + {showResendValidationForm && } + {showUnlinkLoginForm && } + + + ); + } } SignInPage.propTypes = propTypes; SignInPage.defaultProps = defaultProps; -SignInPage.displayName = 'SignInPage'; -export default withOnyx({ - account: {key: ONYXKEYS.ACCOUNT}, - credentials: {key: ONYXKEYS.CREDENTIALS}, -})(SignInPage); +export default compose( + withSafeAreaInsets, + withLocalize, + withWindowDimensions, + withOnyx({ + account: {key: ONYXKEYS.ACCOUNT}, + betas: {key: ONYXKEYS.BETAS}, + credentials: {key: ONYXKEYS.CREDENTIALS}, + }), +)(SignInPage); diff --git a/src/pages/signin/SignInPageHero.js b/src/pages/signin/SignInPageHero.js index 5475c75c36b6..3af7a8fb1a1e 100644 --- a/src/pages/signin/SignInPageHero.js +++ b/src/pages/signin/SignInPageHero.js @@ -11,23 +11,25 @@ const propTypes = { ...windowDimensionsPropTypes, }; -const SignInPageHero = (props) => ( - - - - +function SignInPageHero(props) { + return ( + + + + + - -); + ); +} SignInPageHero.displayName = 'SignInPageHero'; SignInPageHero.propTypes = propTypes; diff --git a/src/pages/signin/SignInPageLayout/Footer.js b/src/pages/signin/SignInPageLayout/Footer.js index fb58f5292dd6..a37654fe41ff 100644 --- a/src/pages/signin/SignInPageLayout/Footer.js +++ b/src/pages/signin/SignInPageLayout/Footer.js @@ -149,7 +149,7 @@ const columns = ({scrollPageToTop}) => [ }, ]; -const Footer = (props) => { +function Footer(props) { const isVertical = props.isSmallScreenWidth; const imageDirection = isVertical ? styles.flexRow : styles.flexColumn; const imageStyle = isVertical ? styles.pr0 : styles.alignSelfCenter; @@ -218,7 +218,7 @@ const Footer = (props) => { ); -}; +} Footer.propTypes = propTypes; Footer.displayName = 'Footer'; diff --git a/src/pages/signin/SignInPageLayout/SignInPageContent.js b/src/pages/signin/SignInPageLayout/SignInPageContent.js index a1fc645fb19d..bcadeaa6558f 100755 --- a/src/pages/signin/SignInPageLayout/SignInPageContent.js +++ b/src/pages/signin/SignInPageLayout/SignInPageContent.js @@ -36,54 +36,56 @@ const propTypes = { ...windowDimensionsPropTypes, }; -const SignInPageContent = (props) => ( - - - {/* This empty view creates margin on the top of the sign in form which will shrink and grow depending on if the keyboard is open or not */} - +function SignInPageContent(props) { + return ( + + + {/* This empty view creates margin on the top of the sign in form which will shrink and grow depending on if the keyboard is open or not */} + - - - - + + + + + + + {props.shouldShowWelcomeHeader && props.welcomeHeader ? ( + + {props.welcomeHeader} + + ) : null} + {props.shouldShowWelcomeText && props.welcomeText ? ( + {props.welcomeText} + ) : null} + + {props.children} + + + - - {props.shouldShowWelcomeHeader && props.welcomeHeader ? ( - - {props.welcomeHeader} - - ) : null} - {props.shouldShowWelcomeText && props.welcomeText ? ( - {props.welcomeText} - ) : null} - - {props.children} - - - + {props.isSmallScreenWidth ? ( + + + + ) : null} - {props.isSmallScreenWidth ? ( - - - - ) : null} - - -); + + ); +} SignInPageContent.propTypes = propTypes; SignInPageContent.displayName = 'SignInPageContent'; diff --git a/src/pages/signin/SignInPageLayout/SignInPageGraphics.js b/src/pages/signin/SignInPageLayout/SignInPageGraphics.js index 5448b8024a7c..67f9dd62f7ec 100644 --- a/src/pages/signin/SignInPageLayout/SignInPageGraphics.js +++ b/src/pages/signin/SignInPageLayout/SignInPageGraphics.js @@ -12,22 +12,24 @@ const propTypes = { ...windowDimensionsPropTypes, }; -const SignInPageGraphics = (props) => ( - { - Link.openExternalLink(backgroundStyle.redirectUri); - }} - disabled={_.isEmpty(backgroundStyle.redirectUri)} - > - - -); +function SignInPageGraphics(props) { + return ( + { + Link.openExternalLink(backgroundStyle.redirectUri); + }} + disabled={_.isEmpty(backgroundStyle.redirectUri)} + > + + + ); +} SignInPageGraphics.displayName = 'SignInPageGraphics'; SignInPageGraphics.propTypes = propTypes; diff --git a/src/pages/signin/SignInPageLayout/index.js b/src/pages/signin/SignInPageLayout/index.js index 9466077f488e..954f8b2ebb8a 100644 --- a/src/pages/signin/SignInPageLayout/index.js +++ b/src/pages/signin/SignInPageLayout/index.js @@ -37,7 +37,7 @@ const propTypes = { ...windowDimensionsPropTypes, }; -const SignInPageLayout = (props) => { +function SignInPageLayout(props) { const scrollViewRef = useRef(); let containerStyles = [styles.flex1, styles.signInPageInner]; let contentContainerStyles = [styles.flex1, styles.flexRow]; @@ -133,7 +133,7 @@ const SignInPageLayout = (props) => { )} ); -}; +} SignInPageLayout.propTypes = propTypes; SignInPageLayout.displayName = 'SignInPageLayout'; diff --git a/src/pages/signin/Socials.js b/src/pages/signin/Socials.js index 83c89e5fd617..52c21890c381 100644 --- a/src/pages/signin/Socials.js +++ b/src/pages/signin/Socials.js @@ -34,29 +34,31 @@ const socialsList = [ }, ]; -const Socials = () => ( - - {_.map(socialsList, (social) => ( - - {(hovered) => ( - - - - - - )} - - ))} - -); +function Socials() { + return ( + + {_.map(socialsList, (social) => ( + + {(hovered) => ( + + + + + + )} + + ))} + + ); +} Socials.displayName = 'Socials'; diff --git a/src/pages/signin/Terms.js b/src/pages/signin/Terms.js index 0cd23d780812..15f7c17a2889 100644 --- a/src/pages/signin/Terms.js +++ b/src/pages/signin/Terms.js @@ -7,27 +7,29 @@ import withLocalize, {withLocalizePropTypes} from '../../components/withLocalize const linkStyles = [styles.textExtraSmallSupporting, styles.link]; -const Terms = (props) => ( - - {props.translate('termsOfUse.phrase1')} - - {' '} - {props.translate('termsOfUse.phrase2')}{' '} - - {props.translate('termsOfUse.phrase3')} - - {' '} - {props.translate('termsOfUse.phrase4')} - - {'. '} - -); +function Terms(props) { + return ( + + {props.translate('termsOfUse.phrase1')} + + {' '} + {props.translate('termsOfUse.phrase2')}{' '} + + {props.translate('termsOfUse.phrase3')} + + {' '} + {props.translate('termsOfUse.phrase4')} + + {'. '} + + ); +} Terms.propTypes = {...withLocalizePropTypes}; Terms.displayName = 'Terms'; diff --git a/src/pages/signin/UnlinkLoginForm.js b/src/pages/signin/UnlinkLoginForm.js index adf44aeb1d8b..6807ba74c6f9 100644 --- a/src/pages/signin/UnlinkLoginForm.js +++ b/src/pages/signin/UnlinkLoginForm.js @@ -50,9 +50,9 @@ const defaultProps = { credentials: {}, }; -const UnlinkLoginForm = (props) => { - const primaryLogin = Str.isSMSLogin(props.account.primaryLogin || '') ? Str.removeSMSDomain(props.account.primaryLogin || '') : props.account.primaryLogin; - const secondaryLogin = Str.isSMSLogin(props.credentials.login || '') ? Str.removeSMSDomain(props.credentials.login || '') : props.credentials.login; +function UnlinkLoginForm(props) { + const primaryLogin = Str.isSMSLogin(props.account.primaryLogin) ? Str.removeSMSDomain(props.account.primaryLogin) : props.account.primaryLogin; + const secondaryLogin = Str.isSMSLogin(props.credentials.login) ? Str.removeSMSDomain(props.credentials.login) : props.credentials.login; return ( <> @@ -95,7 +95,7 @@ const UnlinkLoginForm = (props) => { ); -}; +} UnlinkLoginForm.propTypes = propTypes; UnlinkLoginForm.defaultProps = defaultProps; diff --git a/src/pages/signin/ValidateCodeForm/index.android.js b/src/pages/signin/ValidateCodeForm/index.android.js index 4058ee49a7b9..e0258121fad0 100644 --- a/src/pages/signin/ValidateCodeForm/index.android.js +++ b/src/pages/signin/ValidateCodeForm/index.android.js @@ -9,12 +9,14 @@ const defaultProps = { const propTypes = { isVisible: PropTypes.bool, }; -const ValidateCodeForm = (props) => ( - -); +function ValidateCodeForm(props) { + return ( + + ); +} ValidateCodeForm.displayName = 'ValidateCodeForm'; ValidateCodeForm.propTypes = propTypes; diff --git a/src/pages/signin/ValidateCodeForm/index.js b/src/pages/signin/ValidateCodeForm/index.js index 21122d391ffa..e60c30bff359 100644 --- a/src/pages/signin/ValidateCodeForm/index.js +++ b/src/pages/signin/ValidateCodeForm/index.js @@ -9,12 +9,14 @@ const defaultProps = { const propTypes = { isVisible: PropTypes.bool, }; -const ValidateCodeForm = (props) => ( - -); +function ValidateCodeForm(props) { + return ( + + ); +} ValidateCodeForm.displayName = 'ValidateCodeForm'; ValidateCodeForm.propTypes = propTypes; diff --git a/src/pages/tasks/NewTaskDescriptionPage.js b/src/pages/tasks/NewTaskDescriptionPage.js index cb0bfd8c2871..e18615a34ffe 100644 --- a/src/pages/tasks/NewTaskDescriptionPage.js +++ b/src/pages/tasks/NewTaskDescriptionPage.js @@ -1,4 +1,4 @@ -import React, {useRef} from 'react'; +import React, {useEffect, useRef, useState} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import PropTypes from 'prop-types'; @@ -35,9 +35,20 @@ const defaultProps = { }, }; -const NewTaskDescriptionPage = (props) => { +function NewTaskDescriptionPage(props) { const inputRef = useRef(null); + // The selection will be used to place the cursor at the end if there is prior text in the text input area + const [selection, setSelection] = useState({start: 0, end: 0}); + + // eslint-disable-next-line rulesdir/prefer-early-return + useEffect(() => { + if (props.task.description) { + const length = props.task.description.length; + setSelection({start: length, end: length}); + } + }, [props.task.description]); + // On submit, we want to call the assignTask function and wait to validate // the response const onSubmit = (values) => { @@ -78,12 +89,19 @@ const NewTaskDescriptionPage = (props) => { inputID="taskDescription" label={props.translate('newTaskPage.descriptionOptional')} ref={(el) => (inputRef.current = el)} + autoGrowHeight + containerStyles={[styles.autoGrowHeightMultilineInput]} + textAlignVertical="top" + selection={selection} + onSelectionChange={(e) => { + setSelection(e.nativeEvent.selection); + }} /> ); -}; +} NewTaskDescriptionPage.displayName = 'NewTaskDescriptionPage'; NewTaskDescriptionPage.propTypes = propTypes; diff --git a/src/pages/tasks/NewTaskDetailsPage.js b/src/pages/tasks/NewTaskDetailsPage.js index 383134c434bb..eaad83fd4a84 100644 --- a/src/pages/tasks/NewTaskDetailsPage.js +++ b/src/pages/tasks/NewTaskDetailsPage.js @@ -34,7 +34,7 @@ const defaultProps = { task: {}, }; -const NewTaskPage = (props) => { +function NewTaskPage(props) { const inputRef = useRef(); const [taskTitle, setTaskTitle] = useState(props.task.title); const [taskDescription, setTaskDescription] = useState(props.task.description || ''); @@ -102,6 +102,9 @@ const NewTaskPage = (props) => { setTaskDescription(value)} /> @@ -109,7 +112,7 @@ const NewTaskPage = (props) => { ); -}; +} NewTaskPage.displayName = 'NewTaskPage'; NewTaskPage.propTypes = propTypes; diff --git a/src/pages/tasks/NewTaskPage.js b/src/pages/tasks/NewTaskPage.js index ad936b900c1e..4a53921ce8f6 100644 --- a/src/pages/tasks/NewTaskPage.js +++ b/src/pages/tasks/NewTaskPage.js @@ -66,7 +66,7 @@ const defaultProps = { session: {}, }; -const NewTaskPage = (props) => { +function NewTaskPage(props) { const [assignee, setAssignee] = React.useState({}); const [shareDestination, setShareDestination] = React.useState({}); const [errorMessage, setErrorMessage] = React.useState(''); @@ -86,6 +86,12 @@ const NewTaskPage = (props) => { setAssignee(displayDetails); } + // If we don't have an assignee and we are creating a task from a report + // this allows us to auto assign a participant of the report. + if (!props.task.assignee && props.task.parentReportID) { + TaskUtils.setAssigneeValueWithParentReportID(props.task.parentReportID); + } + // We only set the parentReportID if we are creating a task from a report // this allows us to go ahead and set that report as the share destination // and disable the share destination selector @@ -178,7 +184,7 @@ const NewTaskPage = (props) => { ); -}; +} NewTaskPage.displayName = 'NewTaskPage'; NewTaskPage.propTypes = propTypes; diff --git a/src/pages/tasks/NewTaskTitlePage.js b/src/pages/tasks/NewTaskTitlePage.js index 82e5b14a9e3e..1e232b637de3 100644 --- a/src/pages/tasks/NewTaskTitlePage.js +++ b/src/pages/tasks/NewTaskTitlePage.js @@ -36,7 +36,7 @@ const defaultProps = { }, }; -const NewTaskTitlePage = (props) => { +function NewTaskTitlePage(props) { const inputRef = useRef(null); /** @@ -101,7 +101,7 @@ const NewTaskTitlePage = (props) => { ); -}; +} NewTaskTitlePage.displayName = 'NewTaskTitlePage'; NewTaskTitlePage.propTypes = propTypes; diff --git a/src/pages/tasks/TaskAssigneeSelectorModal.js b/src/pages/tasks/TaskAssigneeSelectorModal.js index e95f6143f904..e1d5a4b5a599 100644 --- a/src/pages/tasks/TaskAssigneeSelectorModal.js +++ b/src/pages/tasks/TaskAssigneeSelectorModal.js @@ -69,7 +69,7 @@ const defaultProps = { task: {}, }; -const TaskAssigneeSelectorModal = (props) => { +function TaskAssigneeSelectorModal(props) { const [searchValue, setSearchValue] = useState(''); const [headerMessage, setHeaderMessage] = useState(''); const [filteredRecentReports, setFilteredRecentReports] = useState([]); @@ -216,7 +216,7 @@ const TaskAssigneeSelectorModal = (props) => { )} ); -}; +} TaskAssigneeSelectorModal.displayName = 'TaskAssigneeSelectorModal'; TaskAssigneeSelectorModal.propTypes = propTypes; diff --git a/src/pages/tasks/TaskDescriptionPage.js b/src/pages/tasks/TaskDescriptionPage.js index 747d7f44c83f..760209cbc597 100644 --- a/src/pages/tasks/TaskDescriptionPage.js +++ b/src/pages/tasks/TaskDescriptionPage.js @@ -1,4 +1,4 @@ -import React, {useCallback, useRef} from 'react'; +import React, {useCallback, useEffect, useRef, useState} from 'react'; import PropTypes from 'prop-types'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; @@ -48,6 +48,17 @@ function TaskDescriptionPage(props) { const inputRef = useRef(null); + // Same as NewtaskDescriptionPage, use the selection to place the cursor correctly if there is prior text + const [selection, setSelection] = useState({start: 0, end: 0}); + + // eslint-disable-next-line rulesdir/prefer-early-return + useEffect(() => { + if (props.task.report && props.task.report.description) { + const length = props.task.report.description.length; + setSelection({start: length, end: length}); + } + }, [props.task.report]); + return ( (inputRef.current = el)} + autoGrowHeight + containerStyles={[styles.autoGrowHeightMultilineInput]} + textAlignVertical="top" + selection={selection} + onSelectionChange={(e) => { + setSelection(e.nativeEvent.selection); + }} /> diff --git a/src/pages/tasks/TaskShareDestinationSelectorModal.js b/src/pages/tasks/TaskShareDestinationSelectorModal.js index ed4fadd906d9..2073ca92a233 100644 --- a/src/pages/tasks/TaskShareDestinationSelectorModal.js +++ b/src/pages/tasks/TaskShareDestinationSelectorModal.js @@ -41,7 +41,7 @@ const defaultProps = { reports: {}, }; -const TaskShareDestinationSelectorModal = (props) => { +function TaskShareDestinationSelectorModal(props) { const [searchValue, setSearchValue] = useState(''); const [headerMessage, setHeaderMessage] = useState(''); const [filteredRecentReports, setFilteredRecentReports] = useState([]); @@ -169,7 +169,7 @@ const TaskShareDestinationSelectorModal = (props) => { )} ); -}; +} TaskShareDestinationSelectorModal.displayName = 'TaskShareDestinationSelectorModal'; TaskShareDestinationSelectorModal.propTypes = propTypes; diff --git a/src/pages/workspace/WorkspaceInitialPage.js b/src/pages/workspace/WorkspaceInitialPage.js index e08ee256ca3c..7ced21b0e833 100644 --- a/src/pages/workspace/WorkspaceInitialPage.js +++ b/src/pages/workspace/WorkspaceInitialPage.js @@ -64,7 +64,7 @@ function dismissError(policyID) { Policy.removeWorkspace(policyID); } -const WorkspaceInitialPage = (props) => { +function WorkspaceInitialPage(props) { const policy = props.policy; const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const hasPolicyCreationError = Boolean(policy.pendingAction === CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD && policy.errors); @@ -256,7 +256,7 @@ const WorkspaceInitialPage = (props) => { )} ); -}; +} WorkspaceInitialPage.propTypes = propTypes; WorkspaceInitialPage.defaultProps = defaultProps; diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.js b/src/pages/workspace/WorkspaceInviteMessagePage.js index eb53319ffd38..617af9a1fd54 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.js +++ b/src/pages/workspace/WorkspaceInviteMessagePage.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'; @@ -24,6 +24,7 @@ import ROUTES from '../../ROUTES'; import * as Localize from '../../libs/Localize'; import Form from '../../components/Form'; import FullPageNotFoundView from '../../components/BlockingViews/FullPageNotFoundView'; +import PressableWithoutFeedback from '../../components/Pressable/PressableWithoutFeedback'; const personalDetailsPropTypes = PropTypes.shape({ /** The login of the person (either email or phone number) */ @@ -163,16 +164,17 @@ class WorkspaceInviteMessagePage extends React.Component { submitButtonText={this.props.translate('common.invite')} enabledWhenOffline footerContent={ - {this.props.translate('common.privacy')} - + } > @@ -195,7 +197,7 @@ class WorkspaceInviteMessagePage extends React.Component { autoCorrect={false} autoGrowHeight textAlignVertical="top" - containerStyles={[styles.workspaceInviteWelcome]} + containerStyles={[styles.autoGrowHeightMultilineInput]} defaultValue={this.state.welcomeNote} value={this.state.welcomeNote} onChangeText={(text) => this.setState({welcomeNote: text})} diff --git a/src/pages/workspace/WorkspaceResetBankAccountModal.js b/src/pages/workspace/WorkspaceResetBankAccountModal.js index 56d1fad3b1f8..d790a2503185 100644 --- a/src/pages/workspace/WorkspaceResetBankAccountModal.js +++ b/src/pages/workspace/WorkspaceResetBankAccountModal.js @@ -15,7 +15,7 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceResetBankAccountModal = (props) => { +function WorkspaceResetBankAccountModal(props) { const achData = lodashGet(props.reimbursementAccount, 'achData') || {}; const isInOpenState = achData.state === BankAccount.STATE.OPEN; const bankAccountID = achData.bankAccountID; @@ -44,7 +44,7 @@ const WorkspaceResetBankAccountModal = (props) => { isVisible /> ); -}; +} WorkspaceResetBankAccountModal.displayName = 'WorkspaceResetBankAccountModal'; WorkspaceResetBankAccountModal.propTypes = propTypes; diff --git a/src/pages/workspace/bills/WorkspaceBillsFirstSection.js b/src/pages/workspace/bills/WorkspaceBillsFirstSection.js index 12cfa47aee11..b0fc0e99c8f9 100644 --- a/src/pages/workspace/bills/WorkspaceBillsFirstSection.js +++ b/src/pages/workspace/bills/WorkspaceBillsFirstSection.js @@ -40,7 +40,7 @@ const defaultProps = { user: {}, }; -const WorkspaceBillsFirstSection = (props) => { +function WorkspaceBillsFirstSection(props) { const emailDomain = Str.extractEmailDomain(props.session.email); const manageYourBillsUrl = `reports?policyID=${props.policyID}&from=all&type=bill&showStates=Open,Processing,Approved,Reimbursed,Archived&isAdvancedFilterMode=true`; return ( @@ -78,7 +78,7 @@ const WorkspaceBillsFirstSection = (props) => { ); -}; +} WorkspaceBillsFirstSection.propTypes = propTypes; WorkspaceBillsFirstSection.defaultProps = defaultProps; diff --git a/src/pages/workspace/bills/WorkspaceBillsNoVBAView.js b/src/pages/workspace/bills/WorkspaceBillsNoVBAView.js index 5022eb0c170c..e99d157a4733 100644 --- a/src/pages/workspace/bills/WorkspaceBillsNoVBAView.js +++ b/src/pages/workspace/bills/WorkspaceBillsNoVBAView.js @@ -18,31 +18,33 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceBillsNoVBAView = (props) => ( - <> - +function WorkspaceBillsNoVBAView(props) { + return ( + <> + -
- - {props.translate('workspace.bills.unlockNoVBACopy')} - -
- -); +
+ + {props.translate('workspace.bills.unlockNoVBACopy')} + +
+ + ); +} WorkspaceBillsNoVBAView.propTypes = propTypes; WorkspaceBillsNoVBAView.displayName = 'WorkspaceBillsNoVBAView'; diff --git a/src/pages/workspace/bills/WorkspaceBillsPage.js b/src/pages/workspace/bills/WorkspaceBillsPage.js index 713db314a2c7..5cb590895e0d 100644 --- a/src/pages/workspace/bills/WorkspaceBillsPage.js +++ b/src/pages/workspace/bills/WorkspaceBillsPage.js @@ -19,21 +19,23 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceBillsPage = (props) => ( - - {(hasVBA, policyID) => ( - <> - {!hasVBA && } - {hasVBA && } - - )} - -); +function WorkspaceBillsPage(props) { + return ( + + {(hasVBA, policyID) => ( + <> + {!hasVBA && } + {hasVBA && } + + )} + + ); +} WorkspaceBillsPage.propTypes = propTypes; WorkspaceBillsPage.displayName = 'WorkspaceBillsPage'; diff --git a/src/pages/workspace/bills/WorkspaceBillsVBAView.js b/src/pages/workspace/bills/WorkspaceBillsVBAView.js index dcb625777c7d..c35b3400e7d1 100644 --- a/src/pages/workspace/bills/WorkspaceBillsVBAView.js +++ b/src/pages/workspace/bills/WorkspaceBillsVBAView.js @@ -17,7 +17,7 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceBillsVBAView = (props) => { +function WorkspaceBillsVBAView(props) { const reportsUrl = `reports?policyID=${props.policyID}&from=all&type=bill&showStates=Processing,Approved&isAdvancedFilterMode=true`; return ( @@ -45,7 +45,7 @@ const WorkspaceBillsVBAView = (props) => { ); -}; +} WorkspaceBillsVBAView.propTypes = propTypes; WorkspaceBillsVBAView.displayName = 'WorkspaceBillsVBAView'; diff --git a/src/pages/workspace/card/WorkspaceCardNoVBAView.js b/src/pages/workspace/card/WorkspaceCardNoVBAView.js index ed7ecea68d66..da93946a6191 100644 --- a/src/pages/workspace/card/WorkspaceCardNoVBAView.js +++ b/src/pages/workspace/card/WorkspaceCardNoVBAView.js @@ -18,35 +18,37 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceCardNoVBAView = (props) => ( -
- - {props.translate('workspace.card.noVBACopy')} - +function WorkspaceCardNoVBAView(props) { + return ( +
+ + {props.translate('workspace.card.noVBACopy')} + - -
-); + +
+ ); +} WorkspaceCardNoVBAView.propTypes = propTypes; WorkspaceCardNoVBAView.displayName = 'WorkspaceCardNoVBAView'; diff --git a/src/pages/workspace/card/WorkspaceCardPage.js b/src/pages/workspace/card/WorkspaceCardPage.js index 1b2e0915eb56..2f5527c49cf0 100644 --- a/src/pages/workspace/card/WorkspaceCardPage.js +++ b/src/pages/workspace/card/WorkspaceCardPage.js @@ -20,24 +20,26 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceCardPage = (props) => ( - - {(hasVBA, policyID, isUsingECard) => ( - <> - {!hasVBA && } +function WorkspaceCardPage(props) { + return ( + + {(hasVBA, policyID, isUsingECard) => ( + <> + {!hasVBA && } - {hasVBA && !isUsingECard && } + {hasVBA && !isUsingECard && } - {hasVBA && isUsingECard && } - - )} - -); + {hasVBA && isUsingECard && } + + )} + + ); +} WorkspaceCardPage.propTypes = propTypes; WorkspaceCardPage.displayName = 'WorkspaceCardPage'; diff --git a/src/pages/workspace/card/WorkspaceCardVBANoECardView.js b/src/pages/workspace/card/WorkspaceCardVBANoECardView.js index d68d3099fc53..5c93b8858de4 100644 --- a/src/pages/workspace/card/WorkspaceCardVBANoECardView.js +++ b/src/pages/workspace/card/WorkspaceCardVBANoECardView.js @@ -26,38 +26,40 @@ const defaultProps = { user: {}, }; -const WorkspaceCardVBANoECardView = (props) => ( - <> -
- - +
+ + + +
- {Boolean(props.user.isCheckingDomain) && {props.translate('workspace.card.checkingDomain')}} - -); +
+ {Boolean(props.user.isCheckingDomain) && {props.translate('workspace.card.checkingDomain')}} + + ); +} WorkspaceCardVBANoECardView.propTypes = propTypes; WorkspaceCardVBANoECardView.defaultProps = defaultProps; diff --git a/src/pages/workspace/card/WorkspaceCardVBAWithECardView.js b/src/pages/workspace/card/WorkspaceCardVBAWithECardView.js index 4c1213800bac..7f9971f00c1b 100644 --- a/src/pages/workspace/card/WorkspaceCardVBAWithECardView.js +++ b/src/pages/workspace/card/WorkspaceCardVBAWithECardView.js @@ -19,7 +19,7 @@ const MENU_LINKS = { SETTLEMENT_FREQUENCY: encodeURI('domain_companycards?param={"section":"configureSettings"}'), }; -const WorkspaceCardVBAWithECardView = (props) => { +function WorkspaceCardVBAWithECardView(props) { const menuItems = [ { title: props.translate('workspace.common.issueAndManageCards'), @@ -72,7 +72,7 @@ const WorkspaceCardVBAWithECardView = (props) => { ); -}; +} WorkspaceCardVBAWithECardView.propTypes = propTypes; WorkspaceCardVBAWithECardView.displayName = 'WorkspaceCardVBAWithECardView'; diff --git a/src/pages/workspace/invoices/WorkspaceInvoicesFirstSection.js b/src/pages/workspace/invoices/WorkspaceInvoicesFirstSection.js index 45d28325d913..7c47476e1c7b 100644 --- a/src/pages/workspace/invoices/WorkspaceInvoicesFirstSection.js +++ b/src/pages/workspace/invoices/WorkspaceInvoicesFirstSection.js @@ -16,7 +16,7 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceInvoicesFirstSection = (props) => { +function WorkspaceInvoicesFirstSection(props) { const sendInvoiceUrl = encodeURI('reports?param={"createInvoice":true}'); const viewAllInvoicesUrl = `reports?policyID=${props.policyID}&from=all&type=invoice&showStates=Open,Processing,Approved,Reimbursed,Archived&isAdvancedFilterMode=true`; @@ -51,7 +51,7 @@ const WorkspaceInvoicesFirstSection = (props) => { ); -}; +} WorkspaceInvoicesFirstSection.propTypes = propTypes; WorkspaceInvoicesFirstSection.displayName = 'WorkspaceInvoicesFirstSection'; diff --git a/src/pages/workspace/invoices/WorkspaceInvoicesNoVBAView.js b/src/pages/workspace/invoices/WorkspaceInvoicesNoVBAView.js index 291011f5502b..c37e739c3b97 100644 --- a/src/pages/workspace/invoices/WorkspaceInvoicesNoVBAView.js +++ b/src/pages/workspace/invoices/WorkspaceInvoicesNoVBAView.js @@ -18,31 +18,33 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceInvoicesNoVBAView = (props) => ( - <> - +function WorkspaceInvoicesNoVBAView(props) { + return ( + <> + -
- - {props.translate('workspace.invoices.unlockNoVBACopy')} - -
- -); +
+ + {props.translate('workspace.invoices.unlockNoVBACopy')} + +
+ + ); +} WorkspaceInvoicesNoVBAView.propTypes = propTypes; WorkspaceInvoicesNoVBAView.displayName = 'WorkspaceInvoicesNoVBAView'; diff --git a/src/pages/workspace/invoices/WorkspaceInvoicesPage.js b/src/pages/workspace/invoices/WorkspaceInvoicesPage.js index 4273f8a6513a..bfc1988211ce 100644 --- a/src/pages/workspace/invoices/WorkspaceInvoicesPage.js +++ b/src/pages/workspace/invoices/WorkspaceInvoicesPage.js @@ -19,21 +19,23 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceInvoicesPage = (props) => ( - - {(hasVBA, policyID) => ( - <> - {!hasVBA && } - {hasVBA && } - - )} - -); +function WorkspaceInvoicesPage(props) { + return ( + + {(hasVBA, policyID) => ( + <> + {!hasVBA && } + {hasVBA && } + + )} + + ); +} WorkspaceInvoicesPage.propTypes = propTypes; WorkspaceInvoicesPage.displayName = 'WorkspaceInvoicesPage'; diff --git a/src/pages/workspace/invoices/WorkspaceInvoicesVBAView.js b/src/pages/workspace/invoices/WorkspaceInvoicesVBAView.js index c4f50bb9d49d..0f7dd8b340fc 100644 --- a/src/pages/workspace/invoices/WorkspaceInvoicesVBAView.js +++ b/src/pages/workspace/invoices/WorkspaceInvoicesVBAView.js @@ -17,7 +17,7 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceInvoicesVBAView = (props) => { +function WorkspaceInvoicesVBAView(props) { const viewUnpaidInvoicesUrl = `reports?policyID=${props.policyID}&from=all&type=invoice&showStates=Processing&isAdvancedFilterMode=true`; return ( @@ -45,7 +45,7 @@ const WorkspaceInvoicesVBAView = (props) => { ); -}; +} WorkspaceInvoicesVBAView.propTypes = propTypes; WorkspaceInvoicesVBAView.displayName = 'WorkspaceInvoicesVBAView'; diff --git a/src/pages/workspace/reimburse/WorkspaceReimbursePage.js b/src/pages/workspace/reimburse/WorkspaceReimbursePage.js index 61056569f8fa..9d1495c2a11f 100644 --- a/src/pages/workspace/reimburse/WorkspaceReimbursePage.js +++ b/src/pages/workspace/reimburse/WorkspaceReimbursePage.js @@ -21,17 +21,19 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceReimbursePage = (props) => ( - - {() => } - -); +function WorkspaceReimbursePage(props) { + return ( + + {() => } + + ); +} WorkspaceReimbursePage.propTypes = propTypes; WorkspaceReimbursePage.displayName = 'WorkspaceReimbursePage'; diff --git a/src/pages/workspace/travel/WorkspaceTravelNoVBAView.js b/src/pages/workspace/travel/WorkspaceTravelNoVBAView.js index 33758f9ecebf..8716ee930206 100644 --- a/src/pages/workspace/travel/WorkspaceTravelNoVBAView.js +++ b/src/pages/workspace/travel/WorkspaceTravelNoVBAView.js @@ -17,28 +17,30 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceTravelNoVBAView = (props) => ( - <> -
- - {props.translate('workspace.travel.noVBACopy')} - -
- -); +function WorkspaceTravelNoVBAView(props) { + return ( + <> +
+ + {props.translate('workspace.travel.noVBACopy')} + +
+ + ); +} WorkspaceTravelNoVBAView.propTypes = propTypes; WorkspaceTravelNoVBAView.displayName = 'WorkspaceTravelNoVBAView'; diff --git a/src/pages/workspace/travel/WorkspaceTravelPage.js b/src/pages/workspace/travel/WorkspaceTravelPage.js index 1fc0e196aa20..8f8a174a5876 100644 --- a/src/pages/workspace/travel/WorkspaceTravelPage.js +++ b/src/pages/workspace/travel/WorkspaceTravelPage.js @@ -19,21 +19,23 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceTravelPage = (props) => ( - - {(hasVBA, policyID) => ( - <> - {!hasVBA && } - {hasVBA && } - - )} - -); +function WorkspaceTravelPage(props) { + return ( + + {(hasVBA, policyID) => ( + <> + {!hasVBA && } + {hasVBA && } + + )} + + ); +} WorkspaceTravelPage.propTypes = propTypes; WorkspaceTravelPage.displayName = 'WorkspaceTravelPage'; diff --git a/src/pages/workspace/travel/WorkspaceTravelVBAView.js b/src/pages/workspace/travel/WorkspaceTravelVBAView.js index 527783dcb209..8156b0334b3d 100644 --- a/src/pages/workspace/travel/WorkspaceTravelVBAView.js +++ b/src/pages/workspace/travel/WorkspaceTravelVBAView.js @@ -14,45 +14,47 @@ const propTypes = { ...withLocalizePropTypes, }; -const WorkspaceTravelVBAView = (props) => ( -
Link.openOldDotLink('domain_companycards'), - icon: Expensicons.ExpensifyCard, - shouldShowRightIcon: true, - iconRight: Expensicons.NewWindow, - wrapperStyle: [styles.cardMenuItem], - link: () => Link.buildOldDotURL('domain_companycards'), - }, - { - title: props.translate('workspace.travel.bookTravelWithConcierge'), - onPress: () => { - Report.navigateToConciergeChat(); +function WorkspaceTravelVBAView(props) { + return ( +
Link.openOldDotLink('domain_companycards'), + icon: Expensicons.ExpensifyCard, + shouldShowRightIcon: true, + iconRight: Expensicons.NewWindow, + wrapperStyle: [styles.cardMenuItem], + link: () => Link.buildOldDotURL('domain_companycards'), }, - icon: Expensicons.Concierge, - shouldShowRightIcon: true, - wrapperStyle: [styles.cardMenuItem], - }, - { - title: props.translate('requestorStep.learnMore'), - onPress: () => Link.openExternalLink(CONST.CONCIERGE_TRAVEL_URL), - icon: Expensicons.Info, - shouldShowRightIcon: true, - iconRight: Expensicons.NewWindow, - wrapperStyle: [styles.cardMenuItem], - link: CONST.CONCIERGE_TRAVEL_URL, - }, - ]} - > - - {props.translate('workspace.travel.VBACopy')} - -
-); + { + title: props.translate('workspace.travel.bookTravelWithConcierge'), + onPress: () => { + Report.navigateToConciergeChat(); + }, + icon: Expensicons.Concierge, + shouldShowRightIcon: true, + wrapperStyle: [styles.cardMenuItem], + }, + { + title: props.translate('requestorStep.learnMore'), + onPress: () => Link.openExternalLink(CONST.CONCIERGE_TRAVEL_URL), + icon: Expensicons.Info, + shouldShowRightIcon: true, + iconRight: Expensicons.NewWindow, + wrapperStyle: [styles.cardMenuItem], + link: CONST.CONCIERGE_TRAVEL_URL, + }, + ]} + > + + {props.translate('workspace.travel.VBACopy')} + +
+ ); +} WorkspaceTravelVBAView.propTypes = propTypes; WorkspaceTravelVBAView.displayName = 'WorkspaceTravelVBAView'; diff --git a/src/pages/workspace/withPolicy.js b/src/pages/workspace/withPolicy.js index 4458cc45ece9..17a7f0efc72d 100644 --- a/src/pages/workspace/withPolicy.js +++ b/src/pages/workspace/withPolicy.js @@ -84,7 +84,7 @@ export default function (WrappedComponent) { ...policyDefaultProps, }; - const WithPolicy = (props) => { + function WithPolicy(props) { const currentRoute = _.last(useNavigationState((state) => state.routes || [])); const policyID = getPolicyIDFromRoute(currentRoute); @@ -100,7 +100,7 @@ export default function (WrappedComponent) { ref={props.forwardedRef} /> ); - }; + } WithPolicy.propTypes = propTypes; WithPolicy.defaultProps = defaultProps; diff --git a/src/pages/workspace/withPolicyAndFullscreenLoading.js b/src/pages/workspace/withPolicyAndFullscreenLoading.js index 1d5cc395c80e..29f1424a26f6 100644 --- a/src/pages/workspace/withPolicyAndFullscreenLoading.js +++ b/src/pages/workspace/withPolicyAndFullscreenLoading.js @@ -26,7 +26,7 @@ export default function (WrappedComponent) { ...policyDefaultProps, }; - const WithPolicyAndFullscreenLoading = (props) => { + function WithPolicyAndFullscreenLoading(props) { if (props.isLoadingReportData && _.isEmpty(props.policy)) { return ; } @@ -39,7 +39,7 @@ export default function (WrappedComponent) { ref={props.forwardedRef} /> ); - }; + } WithPolicyAndFullscreenLoading.propTypes = propTypes; WithPolicyAndFullscreenLoading.defaultProps = defaultProps; diff --git a/src/stories/AddressSearch.stories.js b/src/stories/AddressSearch.stories.js index b6d8fc4e6aa3..35f7e3a07596 100644 --- a/src/stories/AddressSearch.stories.js +++ b/src/stories/AddressSearch.stories.js @@ -15,7 +15,7 @@ export default { }, }; -const Template = (args) => { +function Template(args) { const [value, setValue] = useState(''); return ( { {...args} /> ); -}; +} // Arguments can be passed to the component by binding // See: https://storybook.js.org/docs/react/writing-stories/introduction#using-args diff --git a/src/stories/Banner.stories.js b/src/stories/Banner.stories.js index 82a63885ae69..c7c27cb52352 100644 --- a/src/stories/Banner.stories.js +++ b/src/stories/Banner.stories.js @@ -11,8 +11,10 @@ const story = { component: Banner, }; -// eslint-disable-next-line react/jsx-props-no-spreading -const Template = (args) => ; +function Template(args) { + // eslint-disable-next-line react/jsx-props-no-spreading + return ; +} // Arguments can be passed to the component by binding // See: https://storybook.js.org/docs/react/writing-stories/introduction#using-args diff --git a/src/stories/Button.stories.js b/src/stories/Button.stories.js index d1baf311c1fd..52212e673f0f 100644 --- a/src/stories/Button.stories.js +++ b/src/stories/Button.stories.js @@ -11,14 +11,16 @@ const story = { component: Button, }; -// eslint-disable-next-line react/jsx-props-no-spreading -const Template = (args) =>