diff --git a/src/CONST.ts b/src/CONST.ts
index 43921d9a4457..3d69c83c5c22 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -963,6 +963,7 @@ const CONST = {
GUIDES_DOMAIN: 'team.expensify.com',
HELP: 'help@expensify.com',
INTEGRATION_TESTING_CREDS: 'integrationtestingcreds@expensify.com',
+ NOTIFICATIONS: 'notifications@expensify.com',
PAYROLL: 'payroll@expensify.com',
QA: 'qa@expensify.com',
QA_TRAVIS: 'qa+travisreceipts@expensify.com',
@@ -982,6 +983,7 @@ const CONST = {
FIRST_RESPONDER: Number(Config?.EXPENSIFY_ACCOUNT_ID_FIRST_RESPONDER ?? 9375152),
HELP: Number(Config?.EXPENSIFY_ACCOUNT_ID_HELP ?? -1),
INTEGRATION_TESTING_CREDS: Number(Config?.EXPENSIFY_ACCOUNT_ID_INTEGRATION_TESTING_CREDS ?? -1),
+ NOTIFICATIONS: Number(Config?.EXPENSIFY_ACCOUNT_ID_NOTIFICATIONS ?? 11665625),
PAYROLL: Number(Config?.EXPENSIFY_ACCOUNT_ID_PAYROLL ?? 9679724),
QA: Number(Config?.EXPENSIFY_ACCOUNT_ID_QA ?? 3126513),
QA_TRAVIS: Number(Config?.EXPENSIFY_ACCOUNT_ID_QA_TRAVIS ?? 8595733),
@@ -1408,6 +1410,7 @@ const CONST = {
this.EMAIL.FIRST_RESPONDER,
this.EMAIL.HELP,
this.EMAIL.INTEGRATION_TESTING_CREDS,
+ this.EMAIL.NOTIFICATIONS,
this.EMAIL.PAYROLL,
this.EMAIL.QA,
this.EMAIL.QA_TRAVIS,
diff --git a/src/components/FormSubmit/formSubmitPropTypes.js b/src/components/FormSubmit/formSubmitPropTypes.js
deleted file mode 100644
index 306b3544cc11..000000000000
--- a/src/components/FormSubmit/formSubmitPropTypes.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import PropTypes from 'prop-types';
-import stylePropTypes from '@styles/stylePropTypes';
-
-const propTypes = {
- /** A reference forwarded to the inner View */
- innerRef: PropTypes.oneOfType([
- PropTypes.func,
- // eslint-disable-next-line react/forbid-prop-types
- PropTypes.shape({current: PropTypes.any}),
- ]),
-
- /* A function to execute when form is submitted with ENTER */
- onSubmit: PropTypes.func.isRequired,
-
- /** Children to wrap with FormSubmit. */
- children: PropTypes.node.isRequired,
-
- /** Container styles */
- style: stylePropTypes,
-};
-
-const defaultProps = {
- innerRef: undefined,
- style: [],
-};
-
-export {propTypes, defaultProps};
diff --git a/src/components/FormSubmit/index.native.js b/src/components/FormSubmit/index.native.js
deleted file mode 100644
index 29a8678695d5..000000000000
--- a/src/components/FormSubmit/index.native.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from 'react';
-import {View} from 'react-native';
-import * as formSubmitPropTypes from './formSubmitPropTypes';
-
-const FormSubmit = React.forwardRef((props, ref) => (
-
- {props.children}
-
-));
-
-FormSubmit.propTypes = formSubmitPropTypes.propTypes;
-FormSubmit.defaultProps = formSubmitPropTypes.defaultProps;
-FormSubmit.displayName = 'FormSubmit';
-
-export default FormSubmit;
diff --git a/src/components/FormSubmit/index.native.tsx b/src/components/FormSubmit/index.native.tsx
new file mode 100644
index 000000000000..22bf5353949d
--- /dev/null
+++ b/src/components/FormSubmit/index.native.tsx
@@ -0,0 +1,18 @@
+import React from 'react';
+import {View} from 'react-native';
+import {FormSubmitProps, FormSubmitRef} from './types';
+
+function FormSubmit({style, children}: FormSubmitProps, ref: FormSubmitRef) {
+ return (
+
+ {children}
+
+ );
+}
+
+FormSubmit.displayName = 'FormSubmit';
+
+export default React.forwardRef(FormSubmit);
diff --git a/src/components/FormSubmit/index.js b/src/components/FormSubmit/index.tsx
similarity index 65%
rename from src/components/FormSubmit/index.js
rename to src/components/FormSubmit/index.tsx
index a4e9e960291c..ef3f3c39bbaa 100644
--- a/src/components/FormSubmit/index.js
+++ b/src/components/FormSubmit/index.tsx
@@ -1,23 +1,23 @@
-import lodashGet from 'lodash/get';
-import React, {useEffect} from 'react';
+import React, {KeyboardEvent, useEffect} from 'react';
import {View} from 'react-native';
import * as ComponentUtils from '@libs/ComponentUtils';
import isEnterWhileComposition from '@libs/KeyboardShortcut/isEnterWhileComposition';
import CONST from '@src/CONST';
-import * as formSubmitPropTypes from './formSubmitPropTypes';
+import {FormSubmitProps, FormSubmitRef} from './types';
-function FormSubmit({innerRef, children, onSubmit, style}) {
+function FormSubmit({children, onSubmit, style}: FormSubmitProps, ref: FormSubmitRef) {
/**
* Calls the submit callback when ENTER is pressed on a form element.
- * @param {Object} event
*/
- const submitForm = (event) => {
+ const submitForm = (event: KeyboardEvent) => {
// ENTER is pressed with modifier key or during text composition, do not submit the form
if (event.shiftKey || event.key !== CONST.KEYBOARD_SHORTCUTS.ENTER.shortcutKey || isEnterWhileComposition(event)) {
return;
}
- const tagName = lodashGet(event, 'target.tagName', '');
+ const eventTarget = event.target as HTMLElement;
+
+ const tagName = eventTarget?.tagName ?? '';
// ENTER is pressed on INPUT or SELECT element, call the submit callback.
if (tagName === 'INPUT' || tagName === 'SELECT') {
@@ -26,22 +26,30 @@ function FormSubmit({innerRef, children, onSubmit, style}) {
}
// Pressing Enter on TEXTAREA element adds a new line. When `dataset.submitOnEnter` prop is passed, call the submit callback.
- if (tagName === 'TEXTAREA' && lodashGet(event, 'target.dataset.submitOnEnter', 'false') === 'true') {
+ if (tagName === 'TEXTAREA' && (eventTarget?.dataset?.submitOnEnter ?? 'false') === 'true') {
event.preventDefault();
onSubmit();
return;
}
// ENTER is pressed on checkbox element, call the submit callback.
- if (lodashGet(event, 'target.role') === 'checkbox') {
+ if (eventTarget?.role === 'checkbox') {
onSubmit();
}
};
- const preventDefaultFormBehavior = (e) => e.preventDefault();
+ const preventDefaultFormBehavior = (e: SubmitEvent) => e.preventDefault();
useEffect(() => {
- const form = innerRef.current;
+ if (!(ref && 'current' in ref)) {
+ return;
+ }
+
+ const form = ref.current as HTMLFormElement | null;
+
+ if (!form) {
+ return;
+ }
// Prevent the browser from applying its own validation, which affects the email input
form.setAttribute('novalidate', '');
@@ -55,7 +63,7 @@ function FormSubmit({innerRef, children, onSubmit, style}) {
form.removeEventListener('submit', preventDefaultFormBehavior);
};
- }, [innerRef]);
+ }, [ref]);
return (
// React-native-web prevents event bubbling on TextInput for key presses
@@ -63,7 +71,7 @@ function FormSubmit({innerRef, children, onSubmit, style}) {
// Thus use capture phase.
@@ -72,17 +80,6 @@ function FormSubmit({innerRef, children, onSubmit, style}) {
);
}
-FormSubmit.propTypes = formSubmitPropTypes.propTypes;
-FormSubmit.defaultProps = formSubmitPropTypes.defaultProps;
-
-const FormSubmitWithRef = React.forwardRef((props, ref) => (
-
-));
-
-FormSubmitWithRef.displayName = 'FormSubmitWithRef';
+FormSubmit.displayName = 'FormSubmitWithRef';
-export default FormSubmitWithRef;
+export default React.forwardRef(FormSubmit);
diff --git a/src/components/FormSubmit/types.ts b/src/components/FormSubmit/types.ts
new file mode 100644
index 000000000000..20910647ecb8
--- /dev/null
+++ b/src/components/FormSubmit/types.ts
@@ -0,0 +1,12 @@
+import React, {ForwardedRef} from 'react';
+import {StyleProp, View, ViewStyle} from 'react-native';
+
+type FormSubmitProps = {
+ children: React.ReactNode;
+ onSubmit: () => void;
+ style?: StyleProp;
+};
+
+type FormSubmitRef = ForwardedRef;
+
+export type {FormSubmitProps, FormSubmitRef};
diff --git a/src/libs/KeyboardShortcut/isEnterWhileComposition.ts b/src/libs/KeyboardShortcut/isEnterWhileComposition.ts
index 51e198f1c2d1..a752f8a24811 100644
--- a/src/libs/KeyboardShortcut/isEnterWhileComposition.ts
+++ b/src/libs/KeyboardShortcut/isEnterWhileComposition.ts
@@ -1,3 +1,4 @@
+import React from 'react';
import {NativeSyntheticEvent} from 'react-native';
import * as Browser from '@libs/Browser';
import CONST from '@src/CONST';
@@ -6,7 +7,7 @@ import CONST from '@src/CONST';
* Check if the Enter key was pressed during IME confirmation (i.e. while the text is being composed).
* See {@link https://en.wikipedia.org/wiki/Input_method}
*/
-const isEnterWhileComposition = (event: KeyboardEvent): boolean => {
+const isEnterWhileComposition = (event: KeyboardEvent | React.KeyboardEvent): boolean => {
// if on mobile chrome, the enter key event is never fired when the enter key is pressed while composition.
if (Browser.isMobileChrome()) {
return false;
diff --git a/src/libs/OptionsListUtils.js b/src/libs/OptionsListUtils.js
index 5fed34cc8180..ddd3fd6e4f87 100644
--- a/src/libs/OptionsListUtils.js
+++ b/src/libs/OptionsListUtils.js
@@ -1218,7 +1218,7 @@ function getOptions(
}
// Exclude the current user from the personal details list
- const optionsToExclude = [{login: currentUserLogin}];
+ const optionsToExclude = [{login: currentUserLogin}, {login: CONST.EMAIL.NOTIFICATIONS}];
// If we're including selected options from the search results, we only want to exclude them if the search input is empty
// This is because on certain pages, we show the selected options at the top when the search input is empty
@@ -1240,6 +1240,11 @@ function getOptions(
break;
}
+ // Skip notifications@expensify.com
+ if (reportOption.login === CONST.EMAIL.NOTIFICATIONS) {
+ continue;
+ }
+
const isCurrentUserOwnedPolicyExpenseChatThatCouldShow =
reportOption.isPolicyExpenseChat && reportOption.ownerAccountID === currentUserAccountID && includeOwnedWorkspaceChats && !reportOption.isArchivedRoom;
diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts
index bac1736f07f7..70fd41937fa0 100644
--- a/src/libs/ReportUtils.ts
+++ b/src/libs/ReportUtils.ts
@@ -3430,6 +3430,8 @@ function shouldReportBeInOptionList(
report?.reportName === undefined ||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
report?.isHidden ||
+ // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
+ report?.participantAccountIDs?.includes(CONST.ACCOUNT_ID.NOTIFICATIONS) ||
(report?.participantAccountIDs?.length === 0 &&
!isChatThread(report) &&
!isPublicRoom(report) &&
diff --git a/src/pages/home/report/ReportActionItemSingle.js b/src/pages/home/report/ReportActionItemSingle.js
index c50f868cae99..39bce4bf067a 100644
--- a/src/pages/home/report/ReportActionItemSingle.js
+++ b/src/pages/home/report/ReportActionItemSingle.js
@@ -156,7 +156,9 @@ function ReportActionItemSingle(props) {
}, [isWorkspaceActor, reportID, actorAccountID, props.action.delegateAccountID, iouReportID, displayAllActors]);
const shouldDisableDetailPage = useMemo(
- () => !isWorkspaceActor && ReportUtils.isOptimisticPersonalDetail(props.action.delegateAccountID ? props.action.delegateAccountID : actorAccountID),
+ () =>
+ actorAccountID === CONST.ACCOUNT_ID.NOTIFICATIONS ||
+ (!isWorkspaceActor && ReportUtils.isOptimisticPersonalDetail(props.action.delegateAccountID ? props.action.delegateAccountID : actorAccountID)),
[props.action, isWorkspaceActor, actorAccountID],
);
diff --git a/src/pages/iou/WaypointEditor.js b/src/pages/iou/WaypointEditor.js
index f50ae766ac88..7d5362251715 100644
--- a/src/pages/iou/WaypointEditor.js
+++ b/src/pages/iou/WaypointEditor.js
@@ -2,13 +2,13 @@ import {useNavigation} from '@react-navigation/native';
import lodashGet from 'lodash/get';
import PropTypes from 'prop-types';
import React, {useMemo, useRef, useState} from 'react';
-import {View} from 'react-native';
import {withOnyx} from 'react-native-onyx';
import _ from 'underscore';
import AddressSearch from '@components/AddressSearch';
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import ConfirmModal from '@components/ConfirmModal';
-import Form from '@components/Form';
+import FormProvider from '@components/Form/FormProvider';
+import InputWrapper from '@components/Form/InputWrapper';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
import * as Expensicons from '@components/Icon/Expensicons';
import ScreenWrapper from '@components/ScreenWrapper';
@@ -209,7 +209,7 @@ function WaypointEditor({route: {params: {iouType = '', transactionID = '', wayp
cancelText={translate('common.cancel')}
danger
/>
-
+ (textInput.current = e)}
+ hint={!isOffline ? 'distance.errors.selectSuggestedAddress' : ''}
+ containerStyles={[styles.mt3]}
+ label={translate('distance.address')}
+ defaultValue={waypointAddress}
+ onPress={selectWaypoint}
+ maxInputLength={CONST.FORM_CHARACTER_LIMIT}
+ renamedInputKeys={{
+ address: `waypoint${waypointIndex}`,
+ city: null,
+ country: null,
+ street: null,
+ street2: null,
+ zipCode: null,
+ lat: null,
+ lng: null,
+ state: null,
+ }}
+ predefinedPlaces={recentWaypoints}
+ resultTypes=""
+ />
+
);