From d24c8f1b6c82de2cf89cc3657cc3aef9a290f7c7 Mon Sep 17 00:00:00 2001 From: Pedro Guerreiro Date: Thu, 14 Dec 2023 13:16:33 +0000 Subject: [PATCH 01/57] refactor(typescript): migrate loginwithshortlivedauthtoken --- src/libs/Navigation/types.ts | 5 +- ...s => LogInWithShortLivedAuthTokenPage.tsx} | 61 ++++++------------- 2 files changed, 23 insertions(+), 43 deletions(-) rename src/pages/{LogInWithShortLivedAuthTokenPage.js => LogInWithShortLivedAuthTokenPage.tsx} (64%) diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 94a07ddc6b73..1a7f017cf4d8 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -3,6 +3,7 @@ import {CommonActions, NavigationContainerRefWithCurrent, NavigationHelpers, Nav import {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; import NAVIGATORS from '@src/NAVIGATORS'; +import type {Route as Routes} from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; type NavigationRef = NavigationContainerRefWithCurrent; @@ -366,8 +367,10 @@ type PublicScreensParamList = { [SCREENS.TRANSITION_BETWEEN_APPS]: { shouldForceLogin: string; email: string; + error: string; shortLivedAuthToken: string; - exitTo: string; + shortLivedToken: string; + exitTo: Routes; }; [SCREENS.VALIDATE_LOGIN]: { accountID: string; diff --git a/src/pages/LogInWithShortLivedAuthTokenPage.js b/src/pages/LogInWithShortLivedAuthTokenPage.tsx similarity index 64% rename from src/pages/LogInWithShortLivedAuthTokenPage.js rename to src/pages/LogInWithShortLivedAuthTokenPage.tsx index 16d0c3909d62..c262b4d14658 100644 --- a/src/pages/LogInWithShortLivedAuthTokenPage.js +++ b/src/pages/LogInWithShortLivedAuthTokenPage.tsx @@ -1,8 +1,7 @@ -import lodashGet from 'lodash/get'; -import PropTypes from 'prop-types'; +import {StackScreenProps} from '@react-navigation/stack'; import React, {useEffect} from 'react'; import {View} from 'react-native'; -import {withOnyx} from 'react-native-onyx'; +import {OnyxEntry, withOnyx} from 'react-native-onyx'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -11,64 +10,44 @@ import Text from '@components/Text'; import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import Navigation from '@libs/Navigation/Navigation'; +import {PublicScreensParamList} from '@libs/Navigation/types'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import * as Session from '@userActions/Session'; import ONYXKEYS from '@src/ONYXKEYS'; +import SCREENS from '@src/SCREENS'; +import {Account} from '@src/types/onyx'; -const propTypes = { - /** The parameters needed to authenticate with a short-lived token are in the URL */ - route: PropTypes.shape({ - /** Each parameter passed via the URL */ - params: PropTypes.shape({ - /** Short-lived authToken to sign in a user */ - shortLivedAuthToken: PropTypes.string, - - /** Short-lived authToken to sign in as a user, if they are coming from the old mobile app */ - shortLivedToken: PropTypes.string, - - /** The email of the transitioning user */ - email: PropTypes.string, - }), - }).isRequired, - +type LogInWithShortLivedAuthTokenPageOnyxProps = { /** The details about the account that the user is signing in with */ - account: PropTypes.shape({ - /** Whether a sign is loading */ - isLoading: PropTypes.bool, - }), + account: OnyxEntry; }; -const defaultProps = { - account: { - isLoading: false, - }, -}; +type LogInWithShortLivedAuthTokenPageProps = LogInWithShortLivedAuthTokenPageOnyxProps & StackScreenProps; -function LogInWithShortLivedAuthTokenPage(props) { +function LogInWithShortLivedAuthTokenPage({route, account}: LogInWithShortLivedAuthTokenPageProps) { const theme = useTheme(); const styles = useThemeStyles(); const {translate} = useLocalize(); + const { + params: {email, shortLivedAuthToken, shortLivedToken, exitTo, error}, + } = route; useEffect(() => { - const email = lodashGet(props, 'route.params.email', ''); - // We have to check for both shortLivedAuthToken and shortLivedToken, as the old mobile app uses shortLivedToken, and is not being actively updated. - const shortLivedAuthToken = lodashGet(props, 'route.params.shortLivedAuthToken', '') || lodashGet(props, 'route.params.shortLivedToken', ''); + const token = shortLivedAuthToken || shortLivedToken; // Try to authenticate using the shortLivedToken if we're not already trying to load the accounts - if (shortLivedAuthToken && !props.account.isLoading) { - Session.signInWithShortLivedAuthToken(email, shortLivedAuthToken); + if (token && !account?.isLoading) { + Session.signInWithShortLivedAuthToken(email, token); return; } // If an error is returned as part of the route, ensure we set it in the onyxData for the account - const error = lodashGet(props, 'route.params.error', ''); if (error) { Session.setAccountError(error); } - const exitTo = lodashGet(props, 'route.params.exitTo', ''); if (exitTo) { Navigation.isNavigationReady().then(() => { Navigation.navigate(exitTo); @@ -76,9 +55,9 @@ function LogInWithShortLivedAuthTokenPage(props) { } // The only dependencies of the effect are based on props.route // eslint-disable-next-line react-hooks/exhaustive-deps - }, [props.route]); + }, [route]); - if (props.account.isLoading) { + if (account?.isLoading) { return ; } @@ -94,7 +73,7 @@ function LogInWithShortLivedAuthTokenPage(props) { {translate('deeplinkWrapper.launching')} - + {translate('deeplinkWrapper.expired')}{' '} { @@ -119,10 +98,8 @@ function LogInWithShortLivedAuthTokenPage(props) { ); } -LogInWithShortLivedAuthTokenPage.propTypes = propTypes; -LogInWithShortLivedAuthTokenPage.defaultProps = defaultProps; LogInWithShortLivedAuthTokenPage.displayName = 'LogInWithShortLivedAuthTokenPage'; -export default withOnyx({ +export default withOnyx({ account: {key: ONYXKEYS.ACCOUNT}, })(LogInWithShortLivedAuthTokenPage); From 7052b2212499ff4c689207fd482c0c09fac044f3 Mon Sep 17 00:00:00 2001 From: Pedro Guerreiro Date: Thu, 14 Dec 2023 15:00:00 +0000 Subject: [PATCH 02/57] refactor(typescript): apply pull request feedback --- src/libs/Navigation/types.ts | 11 +++++------ src/pages/LogInWithShortLivedAuthTokenPage.tsx | 10 +++++----- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/src/libs/Navigation/types.ts b/src/libs/Navigation/types.ts index 1a7f017cf4d8..84e838cad4ed 100644 --- a/src/libs/Navigation/types.ts +++ b/src/libs/Navigation/types.ts @@ -365,12 +365,11 @@ type RightModalNavigatorParamList = { type PublicScreensParamList = { [SCREENS.HOME]: undefined; [SCREENS.TRANSITION_BETWEEN_APPS]: { - shouldForceLogin: string; - email: string; - error: string; - shortLivedAuthToken: string; - shortLivedToken: string; - exitTo: Routes; + email?: string; + error?: string; + shortLivedAuthToken?: string; + shortLivedToken?: string; + exitTo?: Routes; }; [SCREENS.VALIDATE_LOGIN]: { accountID: string; diff --git a/src/pages/LogInWithShortLivedAuthTokenPage.tsx b/src/pages/LogInWithShortLivedAuthTokenPage.tsx index c262b4d14658..bee93f9db915 100644 --- a/src/pages/LogInWithShortLivedAuthTokenPage.tsx +++ b/src/pages/LogInWithShortLivedAuthTokenPage.tsx @@ -10,13 +10,13 @@ import Text from '@components/Text'; import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import Navigation from '@libs/Navigation/Navigation'; -import {PublicScreensParamList} from '@libs/Navigation/types'; +import type {PublicScreensParamList} from '@libs/Navigation/types'; import useTheme from '@styles/themes/useTheme'; import useThemeStyles from '@styles/useThemeStyles'; import * as Session from '@userActions/Session'; import ONYXKEYS from '@src/ONYXKEYS'; import SCREENS from '@src/SCREENS'; -import {Account} from '@src/types/onyx'; +import type {Account} from '@src/types/onyx'; type LogInWithShortLivedAuthTokenPageOnyxProps = { /** The details about the account that the user is signing in with */ @@ -35,10 +35,10 @@ function LogInWithShortLivedAuthTokenPage({route, account}: LogInWithShortLivedA useEffect(() => { // We have to check for both shortLivedAuthToken and shortLivedToken, as the old mobile app uses shortLivedToken, and is not being actively updated. - const token = shortLivedAuthToken || shortLivedToken; + const token = shortLivedAuthToken ?? shortLivedToken; // Try to authenticate using the shortLivedToken if we're not already trying to load the accounts - if (token && !account?.isLoading) { + if (email && token && !account?.isLoading) { Session.signInWithShortLivedAuthToken(email, token); return; } @@ -73,7 +73,7 @@ function LogInWithShortLivedAuthTokenPage({route, account}: LogInWithShortLivedA {translate('deeplinkWrapper.launching')} - + {translate('deeplinkWrapper.expired')}{' '} { From 7a8e43e3f1bf0be2e2a1b4827b573d42e02b26ce Mon Sep 17 00:00:00 2001 From: Pedro Guerreiro Date: Mon, 18 Dec 2023 18:18:48 +0000 Subject: [PATCH 03/57] refactor: apply pull request feedback --- src/pages/LogInWithShortLivedAuthTokenPage.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/pages/LogInWithShortLivedAuthTokenPage.tsx b/src/pages/LogInWithShortLivedAuthTokenPage.tsx index 2bf59bd76af7..5e95f31d1d6c 100644 --- a/src/pages/LogInWithShortLivedAuthTokenPage.tsx +++ b/src/pages/LogInWithShortLivedAuthTokenPage.tsx @@ -29,16 +29,14 @@ function LogInWithShortLivedAuthTokenPage({route, account}: LogInWithShortLivedA const theme = useTheme(); const styles = useThemeStyles(); const {translate} = useLocalize(); - const { - params: {email, shortLivedAuthToken, shortLivedToken, exitTo, error}, - } = route; + const {email = '', shortLivedAuthToken = '', shortLivedToken = '', exitTo, error} = route?.params ?? {}; useEffect(() => { // We have to check for both shortLivedAuthToken and shortLivedToken, as the old mobile app uses shortLivedToken, and is not being actively updated. - const token = shortLivedAuthToken ?? shortLivedToken; + const token = shortLivedAuthToken || shortLivedToken; // Try to authenticate using the shortLivedToken if we're not already trying to load the accounts - if (email && token && !account?.isLoading) { + if (token && !account?.isLoading) { Session.signInWithShortLivedAuthToken(email, token); return; } From e30aef2cef323c939996368409d8a6db404e5c56 Mon Sep 17 00:00:00 2001 From: tienifr Date: Wed, 20 Dec 2023 17:30:52 +0700 Subject: [PATCH 04/57] fix: plaid iframe transparent background --- web/index.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/web/index.html b/web/index.html index 967873fe586c..7c02614d17b2 100644 --- a/web/index.html +++ b/web/index.html @@ -96,6 +96,11 @@ caret-color: #ffffff; } + /* Customize Plaid iframe */ + [id^="plaid-link-iframe"] { + color-scheme: dark !important; + } + /* Prevent autofill from overlapping with the input label in Chrome */ div:has(input:-webkit-autofill, input[chrome-autofilled]) > label { transform: translateY(var(--active-label-translate-y)) scale(var(--active-label-scale)) !important; From 8810934caddf3cb2ba995a6bb5307dd9741585b7 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Thu, 21 Dec 2023 09:45:53 +0500 Subject: [PATCH 05/57] feat: add report field menu items --- src/components/OfflineWithFeedback.tsx | 2 +- .../ReportActionItem/MoneyReportView.tsx | 37 +++++++++++++++++-- src/libs/ReportUtils.ts | 18 ++++++++- src/pages/home/report/ReportActionItem.js | 9 ++++- src/pages/reportPropTypes.js | 3 ++ 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/components/OfflineWithFeedback.tsx b/src/components/OfflineWithFeedback.tsx index 5fcf1fe7442b..4522595826af 100644 --- a/src/components/OfflineWithFeedback.tsx +++ b/src/components/OfflineWithFeedback.tsx @@ -18,7 +18,7 @@ import MessagesRow from './MessagesRow'; type OfflineWithFeedbackProps = ChildrenProps & { /** The type of action that's pending */ - pendingAction: OnyxCommon.PendingAction; + pendingAction?: OnyxCommon.PendingAction; /** Determine whether to hide the component's children if deletion is pending */ shouldHideOnDelete?: boolean; diff --git a/src/components/ReportActionItem/MoneyReportView.tsx b/src/components/ReportActionItem/MoneyReportView.tsx index 36daa037fd78..2ffbda4d347b 100644 --- a/src/components/ReportActionItem/MoneyReportView.tsx +++ b/src/components/ReportActionItem/MoneyReportView.tsx @@ -1,8 +1,10 @@ -import React from 'react'; +import React, { useMemo } from 'react'; import {StyleProp, TextStyle, View} from 'react-native'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import SpacerView from '@components/SpacerView'; +import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useStyleUtils from '@hooks/useStyleUtils'; @@ -13,22 +15,27 @@ import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as ReportUtils from '@libs/ReportUtils'; import AnimatedEmptyStateBackground from '@pages/home/report/AnimatedEmptyStateBackground'; import variables from '@styles/variables'; -import type {Report} from '@src/types/onyx'; +import type {PolicyReportField, Report} from '@src/types/onyx'; +import usePermissions from '@hooks/usePermissions'; type MoneyReportViewProps = { /** The report currently being looked at */ report: Report; + /** Policy report fields */ + policyReportFields: PolicyReportField[]; + /** Whether we should display the horizontal rule below the component */ shouldShowHorizontalRule: boolean; }; -function MoneyReportView({report, shouldShowHorizontalRule}: MoneyReportViewProps) { +function MoneyReportView({report, policyReportFields, shouldShowHorizontalRule}: MoneyReportViewProps) { const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); const {isSmallScreenWidth} = useWindowDimensions(); + const {canUseReportFields} = usePermissions(); const isSettled = ReportUtils.isSettled(report.reportID); const {totalDisplaySpend, nonReimbursableSpend, reimbursableSpend} = ReportUtils.getMoneyRequestSpendBreakdown(report); @@ -45,10 +52,34 @@ function MoneyReportView({report, shouldShowHorizontalRule}: MoneyReportViewProp StyleUtils.getColorStyle(theme.textSupporting), ]; + const sortedPolicyReportFields = useMemo(() => policyReportFields.sort(({orderWeight: firstOrderWeight}, {orderWeight: secondOrderWeight}) => firstOrderWeight - secondOrderWeight), [policyReportFields]); + return ( + {canUseReportFields && sortedPolicyReportFields.map((reportField) => { + const title = ReportUtils.getReportFieldTitle(report, reportField); + return ( + + {}} + shouldShowRightIcon + disabled={false} + wrapperStyle={[styles.pv2, styles.taskDescriptionMenuItem]} + shouldGreyOutWhenDisabled={false} + numberOfLinesTitle={0} + interactive + shouldStackHorizontally={false} + onSecondaryInteraction={() => {}} + hoverAndPressStyle={false} + titleWithTooltips={[]} + /> + + ); + })} , reportField: PolicyReportField) { + const value = report?.reportFields?.[reportField.fieldID] ?? reportField.defaultValue; + + if (reportField.type !== 'formula') { + return value; + } + + return value.replaceAll(/{report:([a-zA-Z]+)}/g, (match, property) => { + if (report && property in report) { + return report[property as keyof Report]?.toString() ?? match; + } + return match; + }); +} + export { getReportParticipantsTitle, isReportMessageAttachment, @@ -4343,6 +4358,7 @@ export { canEditWriteCapability, hasSmartscanError, shouldAutoFocusOnKeyPress, + getReportFieldTitle, }; export type {ExpenseOriginalMessage, OptionData, OptimisticChatReport}; diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index c81e47016dcc..84e573145b9a 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -620,6 +620,7 @@ function ReportActionItem(props) { @@ -765,6 +766,10 @@ export default compose( }, initialValue: {}, }, + policyReportFields: { + key: ({report}) => report && 'policyID' in report ? `${ONYXKEYS.COLLECTION.POLICY_REPORT_FIELDS}${report.policyID}` : undefined, + initialValue: [], + }, emojiReactions: { key: ({action}) => `${ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS}${action.reportActionID}`, initialValue: {}, @@ -800,6 +805,8 @@ export default compose( prevProps.shouldHideThreadDividerLine === nextProps.shouldHideThreadDividerLine && lodashGet(prevProps.report, 'total', 0) === lodashGet(nextProps.report, 'total', 0) && lodashGet(prevProps.report, 'nonReimbursableTotal', 0) === lodashGet(nextProps.report, 'nonReimbursableTotal', 0) && - prevProps.linkedReportActionID === nextProps.linkedReportActionID, + prevProps.linkedReportActionID === nextProps.linkedReportActionID && + _.isEqual(prevProps.policyReportFields, nextProps.policyReportFields) && + _.isEqual(prevProps.report.reportFields, nextProps.report.reportFields), ), ); diff --git a/src/pages/reportPropTypes.js b/src/pages/reportPropTypes.js index c89ea761f582..507965266ecc 100644 --- a/src/pages/reportPropTypes.js +++ b/src/pages/reportPropTypes.js @@ -67,4 +67,7 @@ export default PropTypes.shape({ /** Field-specific pending states for offline UI status */ pendingFields: PropTypes.objectOf(PropTypes.string), + + /** Custom fields attached to the report */ + reportFields: PropTypes.objectOf(PropTypes.string), }); From 54e7f76d9f5ede5acb255813a67e1c3f3f857fde Mon Sep 17 00:00:00 2001 From: Vit Horacek Date: Sun, 31 Dec 2023 15:49:13 +0100 Subject: [PATCH 06/57] Clean up the states and statuses in the app --- src/CONST.ts | 9 +--- .../ReportActionItem/TaskPreview.js | 4 +- src/libs/ReportUtils.ts | 31 ++++++------- src/libs/actions/IOU.js | 13 +++--- src/libs/actions/Policy.js | 10 ++--- src/libs/actions/Report.ts | 4 +- src/libs/actions/Task.js | 12 ++--- src/libs/actions/Welcome.ts | 2 +- src/pages/home/HeaderView.js | 2 +- src/pages/home/ReportScreen.js | 6 +-- tests/actions/IOUTest.js | 20 ++++----- tests/unit/ReportUtilsTest.js | 38 ++++++++-------- tests/unit/SidebarFilterTest.js | 28 ++++++------ tests/unit/SidebarOrderTest.js | 44 +++++++++---------- tests/unit/SidebarTest.js | 8 ++-- tests/utils/LHNTestUtils.js | 4 +- 16 files changed, 109 insertions(+), 126 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index abba27b0c33b..15cb361eb5db 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -626,18 +626,13 @@ const CONST = { ANNOUNCE: '#announce', ADMINS: '#admins', }, - STATE: { - OPEN: 'OPEN', - SUBMITTED: 'SUBMITTED', - PROCESSING: 'PROCESSING', - }, STATE_NUM: { OPEN: 0, PROCESSING: 1, - SUBMITTED: 2, + APPROVED: 2, BILLING: 3, }, - STATUS: { + STATUS_NUM: { OPEN: 0, SUBMITTED: 1, CLOSED: 2, diff --git a/src/components/ReportActionItem/TaskPreview.js b/src/components/ReportActionItem/TaskPreview.js index a7728045f407..578b41c713bc 100644 --- a/src/components/ReportActionItem/TaskPreview.js +++ b/src/components/ReportActionItem/TaskPreview.js @@ -90,8 +90,8 @@ function TaskPreview(props) { // Only the direct parent reportAction will contain details about the taskReport // Other linked reportActions will only contain the taskReportID and we will grab the details from there const isTaskCompleted = !_.isEmpty(props.taskReport) - ? props.taskReport.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.taskReport.statusNum === CONST.REPORT.STATUS.APPROVED - : props.action.childStateNum === CONST.REPORT.STATE_NUM.SUBMITTED && props.action.childStatusNum === CONST.REPORT.STATUS.APPROVED; + ? props.taskReport.stateNum === CONST.REPORT.STATE_NUM.APPROVED && props.taskReport.statusNum === CONST.REPORT.STATUS_NUM.APPROVED + : props.action.childStateNum === CONST.REPORT.STATE_NUM.APPROVED && props.action.childStatusNum === CONST.REPORT.STATUS_NUM.APPROVED; const taskTitle = _.escape(TaskUtils.getTaskTitle(props.taskReportID, props.action.childReportName)); const taskAssigneeAccountID = Task.getTaskAssigneeAccountID(props.taskReport) || props.action.childManagerAccountID; const assigneeLogin = lodashGet(personalDetails, [taskAssigneeAccountID, 'login'], ''); diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 24d0050997f7..99a3ec6d796a 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -529,14 +529,14 @@ function isCanceledTaskReport(report: OnyxEntry | EmptyObject = {}, pare * @param parentReportAction - The parent report action of the report (Used to check if the task has been canceled) */ function isOpenTaskReport(report: OnyxEntry, parentReportAction: OnyxEntry | EmptyObject = {}): boolean { - return isTaskReport(report) && !isCanceledTaskReport(report, parentReportAction) && report?.stateNum === CONST.REPORT.STATE_NUM.OPEN && report?.statusNum === CONST.REPORT.STATUS.OPEN; + return isTaskReport(report) && !isCanceledTaskReport(report, parentReportAction) && report?.stateNum === CONST.REPORT.STATE_NUM.OPEN && report?.statusNum === CONST.REPORT.STATUS_NUM.OPEN; } /** * Checks if a report is a completed task report. */ function isCompletedTaskReport(report: OnyxEntry): boolean { - return isTaskReport(report) && report?.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && report?.statusNum === CONST.REPORT.STATUS.APPROVED; + return isTaskReport(report) && report?.stateNum === CONST.REPORT.STATE_NUM.APPROVED && report?.statusNum === CONST.REPORT.STATUS_NUM.APPROVED; } /** @@ -550,14 +550,14 @@ function isReportManager(report: OnyxEntry): boolean { * Checks if the supplied report has been approved */ function isReportApproved(report: OnyxEntry | EmptyObject): boolean { - return report?.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && report?.statusNum === CONST.REPORT.STATUS.APPROVED; + return report?.stateNum === CONST.REPORT.STATE_NUM.APPROVED && report?.statusNum === CONST.REPORT.STATUS_NUM.APPROVED; } /** * Checks if the supplied report is an expense report in Open state and status. */ function isDraftExpenseReport(report: OnyxEntry): boolean { - return isExpenseReport(report) && report?.stateNum === CONST.REPORT.STATE_NUM.OPEN && report?.statusNum === CONST.REPORT.STATUS.OPEN; + return isExpenseReport(report) && report?.stateNum === CONST.REPORT.STATE_NUM.OPEN && report?.statusNum === CONST.REPORT.STATUS_NUM.OPEN; } /** @@ -588,11 +588,11 @@ function isSettled(reportID: string | undefined): boolean { // In case the payment is scheduled and we are waiting for the payee to set up their wallet, // consider the report as paid as well. - if (report.isWaitingOnBankAccount && report.statusNum === CONST.REPORT.STATUS.APPROVED) { + if (report.isWaitingOnBankAccount && report.statusNum === CONST.REPORT.STATUS_NUM.APPROVED) { return true; } - return report?.statusNum === CONST.REPORT.STATUS.REIMBURSED; + return report?.statusNum === CONST.REPORT.STATUS_NUM.REIMBURSED; } /** @@ -767,7 +767,7 @@ function isConciergeChatReport(report: OnyxEntry): boolean { * Returns true if report is still being processed */ function isProcessingReport(report: OnyxEntry): boolean { - return report?.stateNum === CONST.REPORT.STATE_NUM.PROCESSING && report?.statusNum === CONST.REPORT.STATUS.SUBMITTED; + return report?.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED && report?.statusNum === CONST.REPORT.STATUS_NUM.SUBMITTED; } /** @@ -873,7 +873,7 @@ function findLastAccessedReport( * Whether the provided report is an archived room */ function isArchivedRoom(report: OnyxEntry | EmptyObject): boolean { - return report?.statusNum === CONST.REPORT.STATUS.CLOSED && report?.stateNum === CONST.REPORT.STATE_NUM.SUBMITTED; + return report?.statusNum === CONST.REPORT.STATUS_NUM.CLOSED && report?.stateNum === CONST.REPORT.STATE_NUM.APPROVED; } /** @@ -2469,7 +2469,7 @@ function buildOptimisticTaskCommentReportAction(taskReportID: string, taskTitle: reportAction.reportAction.childType = CONST.REPORT.TYPE.TASK; reportAction.reportAction.childReportName = taskTitle; reportAction.reportAction.childManagerAccountID = taskAssigneeAccountID; - reportAction.reportAction.childStatusNum = CONST.REPORT.STATUS.OPEN; + reportAction.reportAction.childStatusNum = CONST.REPORT.STATUS_NUM.OPEN; reportAction.reportAction.childStateNum = CONST.REPORT.STATE_NUM.OPEN; return reportAction; @@ -2499,9 +2499,8 @@ function buildOptimisticIOUReport(payeeAccountID: number, payerAccountID: number ownerAccountID: payeeAccountID, participantAccountIDs: [payeeAccountID, payerAccountID], reportID: generateReportID(), - state: CONST.REPORT.STATE.SUBMITTED, - stateNum: isSendingMoney ? CONST.REPORT.STATE_NUM.SUBMITTED : CONST.REPORT.STATE_NUM.PROCESSING, - statusNum: isSendingMoney ? CONST.REPORT.STATUS.REIMBURSED : CONST.REPORT.STATE_NUM.PROCESSING, + stateNum: isSendingMoney ? CONST.REPORT.STATE_NUM.APPROVED : CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: isSendingMoney ? CONST.REPORT.STATUS_NUM.REIMBURSED : CONST.REPORT.STATE_NUM.SUBMITTED, total, // We don't translate reportName because the server response is always in English @@ -2534,9 +2533,8 @@ function buildOptimisticExpenseReport(chatReportID: string, policyID: string, pa const isFree = policy?.type === CONST.POLICY.TYPE.FREE; // Define the state and status of the report based on whether the policy is free or paid - const state = isFree ? CONST.REPORT.STATE.SUBMITTED : CONST.REPORT.STATE.OPEN; - const stateNum = isFree ? CONST.REPORT.STATE_NUM.PROCESSING : CONST.REPORT.STATE_NUM.OPEN; - const statusNum = isFree ? CONST.REPORT.STATUS.SUBMITTED : CONST.REPORT.STATUS.OPEN; + const stateNum = isFree ? CONST.REPORT.STATE_NUM.SUBMITTED : CONST.REPORT.STATE_NUM.OPEN; + const statusNum = isFree ? CONST.REPORT.STATUS_NUM.SUBMITTED : CONST.REPORT.STATUS_NUM.OPEN; return { reportID: generateReportID(), @@ -2548,7 +2546,6 @@ function buildOptimisticExpenseReport(chatReportID: string, policyID: string, pa // We don't translate reportName because the server response is always in English reportName: `${policyName} owes ${formattedTotal}`, - state, stateNum, statusNum, total: storedTotal, @@ -3248,7 +3245,7 @@ function buildOptimisticTaskReport( parentReportID, policyID, stateNum: CONST.REPORT.STATE_NUM.OPEN, - statusNum: CONST.REPORT.STATUS.OPEN, + statusNum: CONST.REPORT.STATUS_NUM.OPEN, notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS, lastVisibleActionCreated: DateUtils.getDBTime(), }; diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index ecae885392b9..2c1d6486ca67 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -2827,7 +2827,7 @@ function getPayMoneyRequestParams(chatReport, iouReport, recipient, paymentMetho lastMessageText: optimisticIOUReportAction.message[0].text, lastMessageHtml: optimisticIOUReportAction.message[0].html, hasOutstandingChildRequest: false, - statusNum: CONST.REPORT.STATUS.REIMBURSED, + statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED, }, }, { @@ -2965,8 +2965,8 @@ function approveMoneyRequest(expenseReport) { ...expenseReport, lastMessageText: optimisticApprovedReportAction.message[0].text, lastMessageHtml: optimisticApprovedReportAction.message[0].html, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, - statusNum: CONST.REPORT.STATUS.APPROVED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.APPROVED, }, }; const optimisticData = [optimisticIOUReportData, optimisticReportActionsData]; @@ -3038,9 +3038,8 @@ function submitReport(expenseReport) { ...expenseReport, lastMessageText: lodashGet(optimisticSubmittedReportAction, 'message.0.text', ''), lastMessageHtml: lodashGet(optimisticSubmittedReportAction, 'message.0.html', ''), - state: CONST.REPORT.STATE.SUBMITTED, - stateNum: CONST.REPORT.STATE_NUM.PROCESSING, - statusNum: CONST.REPORT.STATUS.SUBMITTED, + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }, }, ...(parentReport.reportID @@ -3084,7 +3083,7 @@ function submitReport(expenseReport) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, value: { - statusNum: CONST.REPORT.STATUS.OPEN, + statusNum: CONST.REPORT.STATUS_NUM.OPEN, stateNum: CONST.REPORT.STATE_NUM.OPEN, }, }, diff --git a/src/libs/actions/Policy.js b/src/libs/actions/Policy.js index f33e6637e2de..2aa583016957 100644 --- a/src/libs/actions/Policy.js +++ b/src/libs/actions/Policy.js @@ -172,8 +172,8 @@ function deleteWorkspace(policyID, reports, policyName) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${reportID}`, value: { - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, - statusNum: CONST.REPORT.STATUS.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, hasDraft: false, oldPolicyName: allPolicies[`${ONYXKEYS.COLLECTION.POLICY}${policyID}`].name, }, @@ -352,8 +352,8 @@ function removeMembers(accountIDs, policyID) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${report.reportID}`, value: { - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, oldPolicyName: policy.name, hasDraft: false, }, @@ -459,7 +459,7 @@ function createPolicyExpenseChats(policyID, invitedEmailsToAccountIDs, hasOutsta key: `${ONYXKEYS.COLLECTION.REPORT}${oldChat.reportID}`, value: { stateNum: CONST.REPORT.STATE_NUM.OPEN, - statusNum: CONST.REPORT.STATUS.OPEN, + statusNum: CONST.REPORT.STATUS_NUM.OPEN, }, }); return; diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 06c0316a40b5..701a68ec060a 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -2079,8 +2079,8 @@ function leaveRoom(reportID: string, isWorkspaceMemberLeavingWorkspaceRoom = fal } : { reportID: null, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, - statusNum: CONST.REPORT.STATUS.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, notificationPreference: CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, }, }, diff --git a/src/libs/actions/Task.js b/src/libs/actions/Task.js index 0fe6a528cda1..d6f1c920bbd0 100644 --- a/src/libs/actions/Task.js +++ b/src/libs/actions/Task.js @@ -238,8 +238,8 @@ function completeTask(taskReport) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`, value: { - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, - statusNum: CONST.REPORT.STATUS.APPROVED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.APPROVED, }, }, @@ -267,7 +267,7 @@ function completeTask(taskReport) { key: `${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`, value: { stateNum: CONST.REPORT.STATE_NUM.OPEN, - statusNum: CONST.REPORT.STATUS.OPEN, + statusNum: CONST.REPORT.STATUS_NUM.OPEN, }, }, { @@ -306,7 +306,7 @@ function reopenTask(taskReport) { key: `${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`, value: { stateNum: CONST.REPORT.STATE_NUM.OPEN, - statusNum: CONST.REPORT.STATUS.OPEN, + statusNum: CONST.REPORT.STATUS_NUM.OPEN, lastVisibleActionCreated: reopenedTaskReportAction.created, lastMessageText: message, lastActorAccountID: reopenedTaskReportAction.actorAccountID, @@ -336,8 +336,8 @@ function reopenTask(taskReport) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${taskReportID}`, value: { - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, - statusNum: CONST.REPORT.STATUS.APPROVED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.APPROVED, }, }, { diff --git a/src/libs/actions/Welcome.ts b/src/libs/actions/Welcome.ts index 02109804efb9..fdf68b72fc3f 100644 --- a/src/libs/actions/Welcome.ts +++ b/src/libs/actions/Welcome.ts @@ -131,7 +131,7 @@ function show({routes, showCreateMenu = () => {}, showPopoverMenu = () => false} const workspaceChatReport = Object.values(allReports ?? {}).find((report) => { if (report) { - return ReportUtils.isPolicyExpenseChat(report) && report.ownerAccountID === currentUserAccountID && report.statusNum !== CONST.REPORT.STATUS.CLOSED; + return ReportUtils.isPolicyExpenseChat(report) && report.ownerAccountID === currentUserAccountID && report.statusNum !== CONST.REPORT.STATUS_NUM.CLOSED; } return false; }); diff --git a/src/pages/home/HeaderView.js b/src/pages/home/HeaderView.js index d3ec573b5886..4d77fb90622f 100644 --- a/src/pages/home/HeaderView.js +++ b/src/pages/home/HeaderView.js @@ -132,7 +132,7 @@ function HeaderView(props) { } // Task is not closed - if (props.report.stateNum !== CONST.REPORT.STATE_NUM.SUBMITTED && props.report.statusNum !== CONST.REPORT.STATUS.CLOSED && canModifyTask) { + if (props.report.stateNum !== CONST.REPORT.STATE_NUM.APPROVED && props.report.statusNum !== CONST.REPORT.STATUS_NUM.CLOSED && canModifyTask) { threeDotMenuItems.push({ icon: Expensicons.Trashcan, text: translate('common.cancel'), diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 8e177e0c2e64..38ee1e81fc77 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -186,7 +186,7 @@ function ReportScreen({ // There are no reportActions at all to display and we are still in the process of loading the next set of actions. const isLoadingInitialReportActions = _.isEmpty(filteredReportActions) && reportMetadata.isLoadingInitialReportActions; - const isOptimisticDelete = lodashGet(report, 'statusNum') === CONST.REPORT.STATUS.CLOSED; + const isOptimisticDelete = lodashGet(report, 'statusNum') === CONST.REPORT.STATUS_NUM.CLOSED; const shouldHideReport = !ReportUtils.canAccessReport(report, policies, betas); @@ -358,8 +358,8 @@ function ReportScreen({ (prevOnyxReportID && prevOnyxReportID === routeReportID && !onyxReportID && - prevReport.statusNum === CONST.REPORT.STATUS.OPEN && - (report.statusNum === CONST.REPORT.STATUS.CLOSED || (!report.statusNum && !prevReport.parentReportID && prevReport.chatType === CONST.REPORT.CHAT_TYPE.POLICY_ROOM))) || + prevReport.statusNum === CONST.REPORT.STATUS_NUM.OPEN && + (report.statusNum === CONST.REPORT.STATUS_NUM.CLOSED || (!report.statusNum && !prevReport.parentReportID && prevReport.chatType === CONST.REPORT.CHAT_TYPE.POLICY_ROOM))) || ((ReportUtils.isMoneyRequest(prevReport) || ReportUtils.isMoneyRequestReport(prevReport)) && _.isEmpty(report)) ) { Navigation.dismissModal(); diff --git a/tests/actions/IOUTest.js b/tests/actions/IOUTest.js index 4d9ce42a08ce..492726b1865a 100644 --- a/tests/actions/IOUTest.js +++ b/tests/actions/IOUTest.js @@ -1237,9 +1237,8 @@ describe('actions/IOU', () => { expect(chatReport.pendingFields).toBeFalsy(); expect(iouReport.pendingFields).toBeFalsy(); - // expect(iouReport.status).toBe(CONST.REPORT.STATUS.SUBMITTED); - // expect(iouReport.stateNum).toBe(CONST.REPORT.STATE_NUM.SUBMITTED); - // expect(iouReport.state).toBe(CONST.REPORT.STATE.SUBMITTED); + // expect(iouReport.status).toBe(CONST.REPORT.STATUS_NUM.SUBMITTED); + // expect(iouReport.stateNum).toBe(CONST.REPORT.STATE_NUM.APPROVED); resolve(); }, @@ -1306,9 +1305,8 @@ describe('actions/IOU', () => { expect(chatReport.iouReportID).toBeFalsy(); - // expect(iouReport.status).toBe(CONST.REPORT.STATUS.REIMBURSED); - // expect(iouReport.state).toBe(CONST.REPORT.STATE.MANUALREIMBURSED); - // expect(iouReport.stateNum).toBe(CONST.REPORT.STATE_NUM.SUBMITTED); + // expect(iouReport.status).toBe(CONST.REPORT.STATUS_NUM.REIMBURSED); + // expect(iouReport.stateNum).toBe(CONST.REPORT.STATE_NUM.APPROVED); resolve(); }, @@ -1356,9 +1354,8 @@ describe('actions/IOU', () => { expect(chatReport.iouReportID).toBeFalsy(); - // expect(iouReport.status).toBe(CONST.REPORT.STATUS.REIMBURSED); - // expect(iouReport.state).toBe(CONST.REPORT.STATE.MANUALREIMBURSED); - // expect(iouReport.stateNum).toBe(CONST.REPORT.STATE_NUM.SUBMITTED); + // expect(iouReport.status).toBe(CONST.REPORT.STATUS_NUM.REIMBURSED); + // expect(iouReport.stateNum).toBe(CONST.REPORT.STATE_NUM.APPROVED); resolve(); }, @@ -1770,9 +1767,8 @@ describe('actions/IOU', () => { expect.objectContaining({ lastMessageHtml: `paid $${amount / 100}.00 with Expensify`, lastMessageText: `paid $${amount / 100}.00 with Expensify`, - state: CONST.REPORT.STATE.SUBMITTED, - statusNum: CONST.REPORT.STATUS.REIMBURSED, - stateNum: CONST.REPORT.STATE_NUM.PROCESSING, + statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED, + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, }), ); expect(updatedChatReport).toEqual( diff --git a/tests/unit/ReportUtilsTest.js b/tests/unit/ReportUtilsTest.js index d700aa4724f1..c9e8053e3146 100644 --- a/tests/unit/ReportUtilsTest.js +++ b/tests/unit/ReportUtilsTest.js @@ -149,8 +149,8 @@ describe('ReportUtils', () => { test('Archived', () => { const archivedAdminsRoom = { ...baseAdminsRoom, - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; expect(ReportUtils.getReportName(archivedAdminsRoom)).toBe('#admins (archived)'); @@ -172,8 +172,8 @@ describe('ReportUtils', () => { test('Archived', () => { const archivedPolicyRoom = { ...baseUserCreatedRoom, - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; expect(ReportUtils.getReportName(archivedPolicyRoom)).toBe('#VikingsChat (archived)'); @@ -213,8 +213,8 @@ describe('ReportUtils', () => { ownerAccountID: 1, policyID: policy.policyID, oldPolicyName: policy.name, - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; test('as member', () => { @@ -307,7 +307,7 @@ describe('ReportUtils', () => { managerID: currentUserAccountID, isUnreadWithMention: false, stateNum: CONST.REPORT.STATE_NUM.OPEN, - statusNum: CONST.REPORT.STATUS.OPEN, + statusNum: CONST.REPORT.STATUS_NUM.OPEN, }; expect(ReportUtils.requiresAttentionFromCurrentUser(report)).toBe(true); }); @@ -368,7 +368,7 @@ describe('ReportUtils', () => { const report = { ...LHNTestUtils.getFakeReport(), type: CONST.REPORT.TYPE.IOU, - statusNum: CONST.REPORT.STATUS.REIMBURSED, + statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED, }; const moneyRequestOptions = ReportUtils.getMoneyRequestOptions(report, {}, [currentUserAccountID]); expect(moneyRequestOptions.length).toBe(0); @@ -378,8 +378,8 @@ describe('ReportUtils', () => { const report = { ...LHNTestUtils.getFakeReport(), type: CONST.REPORT.TYPE.EXPENSE, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, - statusNum: CONST.REPORT.STATUS.APPROVED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, + statusNum: CONST.REPORT.STATUS_NUM.APPROVED, }; const moneyRequestOptions = ReportUtils.getMoneyRequestOptions(report, {}, [currentUserAccountID]); expect(moneyRequestOptions.length).toBe(0); @@ -389,7 +389,7 @@ describe('ReportUtils', () => { const report = { ...LHNTestUtils.getFakeReport(), type: CONST.REPORT.TYPE.EXPENSE, - statusNum: CONST.REPORT.STATUS.REIMBURSED, + statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED, }; const moneyRequestOptions = ReportUtils.getMoneyRequestOptions(report, {}, [currentUserAccountID]); expect(moneyRequestOptions.length).toBe(0); @@ -419,8 +419,8 @@ describe('ReportUtils', () => { const report = { ...LHNTestUtils.getFakeReport(), type: CONST.REPORT.TYPE.EXPENSE, - stateNum: CONST.REPORT.STATE_NUM.PROCESSING, - statusNum: CONST.REPORT.STATUS.SUBMITTED, + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, parentReportID: '101', }; const paidPolicy = { @@ -508,7 +508,7 @@ describe('ReportUtils', () => { ...LHNTestUtils.getFakeReport(), type: CONST.REPORT.TYPE.EXPENSE, stateNum: CONST.REPORT.STATE_NUM.OPEN, - statusNum: CONST.REPORT.STATUS.OPEN, + statusNum: CONST.REPORT.STATUS_NUM.OPEN, parentReportID: '103', }; const paidPolicy = { @@ -523,9 +523,8 @@ describe('ReportUtils', () => { const report = { ...LHNTestUtils.getFakeReport(), type: CONST.REPORT.TYPE.IOU, - state: CONST.REPORT.STATE.SUBMITTED, - stateNum: CONST.REPORT.STATE_NUM.PROCESSING, - statusNum: CONST.REPORT.STATUS.SUBMITTED, + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }; const moneyRequestOptions = ReportUtils.getMoneyRequestOptions(report, {}, [currentUserAccountID, participantsAccountIDs[0]]); expect(moneyRequestOptions.length).toBe(1); @@ -536,9 +535,8 @@ describe('ReportUtils', () => { const report = { ...LHNTestUtils.getFakeReport(), type: CONST.REPORT.TYPE.IOU, - state: CONST.REPORT.STATE.SUBMITTED, - stateNum: CONST.REPORT.STATE_NUM.PROCESSING, - statusNum: CONST.REPORT.STATUS.SUBMITTED, + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }; const moneyRequestOptions = ReportUtils.getMoneyRequestOptions(report, {}, [currentUserAccountID, participantsAccountIDs[0]]); expect(moneyRequestOptions.length).toBe(1); diff --git a/tests/unit/SidebarFilterTest.js b/tests/unit/SidebarFilterTest.js index dd2985ea34a8..35d91e291666 100644 --- a/tests/unit/SidebarFilterTest.js +++ b/tests/unit/SidebarFilterTest.js @@ -471,20 +471,20 @@ describe('Sidebar', () => { // Given an archived chat report, an archived default policy room, and an archived user created policy room const archivedReport = { ...LHNTestUtils.getFakeReport([1, 2]), - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; const archivedPolicyRoomReport = { ...LHNTestUtils.getFakeReport([1, 2]), chatType: CONST.REPORT.CHAT_TYPE.POLICY_ANNOUNCE, - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; const archivedUserCreatedPolicyRoomReport = { ...LHNTestUtils.getFakeReport([1, 2]), chatType: CONST.REPORT.CHAT_TYPE.POLICY_ROOM, - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; LHNTestUtils.getDefaultRenderedSidebarLinks(); @@ -695,8 +695,8 @@ describe('Sidebar', () => { const report = { ...LHNTestUtils.getFakeReport(), lastVisibleActionCreated: '2022-11-22 03:48:27.267', - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; // Given the user is in all betas @@ -746,8 +746,8 @@ describe('Sidebar', () => { // Given an archived report that has all comments read const report = { ...LHNTestUtils.getFakeReport(), - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; // Given the user is in all betas @@ -795,8 +795,8 @@ describe('Sidebar', () => { const report = { ...LHNTestUtils.getFakeReport(), isPinned: false, - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; // Given the user is in all betas @@ -840,8 +840,8 @@ describe('Sidebar', () => { // Given an archived report that is not the active report const report = { ...LHNTestUtils.getFakeReport(), - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; // Given the user is in all betas diff --git a/tests/unit/SidebarOrderTest.js b/tests/unit/SidebarOrderTest.js index 44d6dd57de91..a6b0f4dba60d 100644 --- a/tests/unit/SidebarOrderTest.js +++ b/tests/unit/SidebarOrderTest.js @@ -255,7 +255,7 @@ describe('Sidebar', () => { reportName: taskReportName, managerID: 2, stateNum: CONST.REPORT.STATE_NUM.OPEN, - statusNum: CONST.REPORT.STATUS.OPEN, + statusNum: CONST.REPORT.STATUS_NUM.OPEN, }; // Each report has at least one ADDCOMMENT action so should be rendered in the LNH @@ -313,8 +313,8 @@ describe('Sidebar', () => { total: 10000, currency: 'USD', chatReportID: report3.reportID, - stateNum: CONST.REPORT.STATE_NUM.PROCESSING, - statusNum: CONST.REPORT.STATUS.SUBMITTED, + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }; report3.iouReportID = iouReport.reportID; @@ -374,9 +374,8 @@ describe('Sidebar', () => { policyName: 'Workspace', total: -10000, currency: 'USD', - state: CONST.REPORT.STATE.SUBMITTED, - stateNum: CONST.REPORT.STATE_NUM.PROCESSING, - statusNum: CONST.REPORT.STATUS.SUBMITTED, + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, chatReportID: report3.reportID, parentReportID: report3.reportID, }; @@ -575,9 +574,8 @@ describe('Sidebar', () => { total: 10000, currency: 'USD', chatReportID: report3.reportID, - state: CONST.REPORT.STATE.SUBMITTED, - stateNum: CONST.REPORT.STATE_NUM.PROCESSING, - statusNum: CONST.REPORT.STATUS.SUBMITTED, + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }; report3.iouReportID = iouReport.reportID; const currentReportId = report2.reportID; @@ -740,8 +738,8 @@ describe('Sidebar', () => { const report1 = { ...LHNTestUtils.getFakeReport([1, 2]), chatType: CONST.REPORT.CHAT_TYPE.POLICY_ROOM, - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; const report2 = LHNTestUtils.getFakeReport([3, 4]); const report3 = LHNTestUtils.getFakeReport([5, 6]); @@ -837,8 +835,8 @@ describe('Sidebar', () => { const report1 = { ...LHNTestUtils.getFakeReport([1, 2], 3, true), chatType: CONST.REPORT.CHAT_TYPE.POLICY_ROOM, - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; const report2 = LHNTestUtils.getFakeReport([3, 4], 2, true); const report3 = LHNTestUtils.getFakeReport([5, 6], 1, true); @@ -914,8 +912,8 @@ describe('Sidebar', () => { total: 10000, currency: 'USD', chatReportID: report3.reportID, - stateNum: CONST.REPORT.STATE_NUM.PROCESSING, - statusNum: CONST.REPORT.STATUS.SUBMITTED, + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }; const iouReport2 = { ...LHNTestUtils.getFakeReport([9, 10]), @@ -926,8 +924,8 @@ describe('Sidebar', () => { total: 10000, currency: 'USD', chatReportID: report3.reportID, - stateNum: CONST.REPORT.STATE_NUM.PROCESSING, - statusNum: CONST.REPORT.STATUS.SUBMITTED, + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }; const iouReport3 = { ...LHNTestUtils.getFakeReport([11, 12]), @@ -938,8 +936,8 @@ describe('Sidebar', () => { total: 100000, currency: 'USD', chatReportID: report3.reportID, - stateNum: CONST.REPORT.STATE_NUM.PROCESSING, - statusNum: CONST.REPORT.STATUS.SUBMITTED, + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }; const iouReport4 = { ...LHNTestUtils.getFakeReport([11, 12]), @@ -950,8 +948,8 @@ describe('Sidebar', () => { total: 10000, currency: 'USD', chatReportID: report3.reportID, - stateNum: CONST.REPORT.STATE_NUM.PROCESSING, - statusNum: CONST.REPORT.STATUS.SUBMITTED, + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }; const iouReport5 = { ...LHNTestUtils.getFakeReport([11, 12]), @@ -962,8 +960,8 @@ describe('Sidebar', () => { total: 10000, currency: 'USD', chatReportID: report3.reportID, - stateNum: CONST.REPORT.STATE_NUM.PROCESSING, - statusNum: CONST.REPORT.STATUS.SUBMITTED, + stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.SUBMITTED, }; report1.iouReportID = iouReport1.reportID; diff --git a/tests/unit/SidebarTest.js b/tests/unit/SidebarTest.js index 106b2c3b69a9..09d3905fe86a 100644 --- a/tests/unit/SidebarTest.js +++ b/tests/unit/SidebarTest.js @@ -51,8 +51,8 @@ describe('Sidebar', () => { const report = { ...LHNTestUtils.getFakeReport(['email1@test.com', 'email2@test.com'], 3, true), chatType: CONST.REPORT.CHAT_TYPE.POLICY_ROOM, - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; // Given the user is in all betas @@ -86,8 +86,8 @@ describe('Sidebar', () => { ...LHNTestUtils.getFakeReport(['email1@test.com', 'email2@test.com'], 3, true), policyName: 'Vikings Policy', chatType: CONST.REPORT.CHAT_TYPE.POLICY_ROOM, - statusNum: CONST.REPORT.STATUS.CLOSED, - stateNum: CONST.REPORT.STATE_NUM.SUBMITTED, + statusNum: CONST.REPORT.STATUS_NUM.CLOSED, + stateNum: CONST.REPORT.STATE_NUM.APPROVED, }; const action = { ...LHNTestUtils.getFakeReportAction('email1@test.com', 3, true), diff --git a/tests/utils/LHNTestUtils.js b/tests/utils/LHNTestUtils.js index a80feae730c6..0507a671358a 100644 --- a/tests/utils/LHNTestUtils.js +++ b/tests/utils/LHNTestUtils.js @@ -209,8 +209,8 @@ function getAdvancedFakeReport(isArchived, isUserCreatedPolicyRoom, hasAddWorksp ...getFakeReport([1, 2], 0, isUnread), type: CONST.REPORT.TYPE.CHAT, chatType: isUserCreatedPolicyRoom ? CONST.REPORT.CHAT_TYPE.POLICY_ROOM : CONST.REPORT.CHAT_TYPE.POLICY_ADMINS, - statusNum: isArchived ? CONST.REPORT.STATUS.CLOSED : 0, - stateNum: isArchived ? CONST.REPORT.STATE_NUM.SUBMITTED : 0, + statusNum: isArchived ? CONST.REPORT.STATUS_NUM.CLOSED : 0, + stateNum: isArchived ? CONST.REPORT.STATE_NUM.APPROVED : 0, errorFields: hasAddWorkspaceError ? {addWorkspaceRoom: 'blah'} : null, isPinned, hasDraft, From b93661414bdaa7f0bb24da494a75b0c4777c1b56 Mon Sep 17 00:00:00 2001 From: Vit Horacek Date: Sun, 31 Dec 2023 15:57:34 +0100 Subject: [PATCH 07/57] remove the state from the Report type --- src/types/onyx/Report.ts | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/types/onyx/Report.ts b/src/types/onyx/Report.ts index b274025908f5..9db1de108885 100644 --- a/src/types/onyx/Report.ts +++ b/src/types/onyx/Report.ts @@ -83,9 +83,6 @@ type Report = { /** ID of the chat report */ chatReportID?: string; - /** The state of the report */ - state?: ValueOf; - /** The state that the report is currently in */ stateNum?: ValueOf; From 3877497f806050a569941170a219cc299ac79eb7 Mon Sep 17 00:00:00 2001 From: Vit Horacek Date: Sun, 31 Dec 2023 16:09:25 +0100 Subject: [PATCH 08/57] Prettier --- src/libs/ReportUtils.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 99a3ec6d796a..40101feb6d40 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -529,7 +529,9 @@ function isCanceledTaskReport(report: OnyxEntry | EmptyObject = {}, pare * @param parentReportAction - The parent report action of the report (Used to check if the task has been canceled) */ function isOpenTaskReport(report: OnyxEntry, parentReportAction: OnyxEntry | EmptyObject = {}): boolean { - return isTaskReport(report) && !isCanceledTaskReport(report, parentReportAction) && report?.stateNum === CONST.REPORT.STATE_NUM.OPEN && report?.statusNum === CONST.REPORT.STATUS_NUM.OPEN; + return ( + isTaskReport(report) && !isCanceledTaskReport(report, parentReportAction) && report?.stateNum === CONST.REPORT.STATE_NUM.OPEN && report?.statusNum === CONST.REPORT.STATUS_NUM.OPEN + ); } /** From a5d07180966c77bdd0d2e5d3e358d8a6911161c0 Mon Sep 17 00:00:00 2001 From: Vit Horacek Date: Sun, 31 Dec 2023 16:20:52 +0100 Subject: [PATCH 09/57] Fix the statenum const --- src/CONST.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CONST.ts b/src/CONST.ts index 15cb361eb5db..62e79ec62400 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -628,7 +628,7 @@ const CONST = { }, STATE_NUM: { OPEN: 0, - PROCESSING: 1, + SUBMITTED: 1, APPROVED: 2, BILLING: 3, }, From 02d8deb0c84212f158c95194067b7bd23cc5f52b Mon Sep 17 00:00:00 2001 From: Vit Horacek Date: Sun, 31 Dec 2023 16:29:07 +0100 Subject: [PATCH 10/57] Fix type issues --- src/libs/E2E/apiMocks/openApp.ts | 4 ++-- src/libs/ReportUtils.ts | 4 +--- src/types/onyx/Report.ts | 2 +- src/types/onyx/ReportAction.ts | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/libs/E2E/apiMocks/openApp.ts b/src/libs/E2E/apiMocks/openApp.ts index 42d13716407d..4c12a95a1db4 100644 --- a/src/libs/E2E/apiMocks/openApp.ts +++ b/src/libs/E2E/apiMocks/openApp.ts @@ -2043,10 +2043,10 @@ const openApp = (): Response => ({ managerID: 16, currency: 'USD', chatReportID: '98817646', - state: 'SUBMITTED', cachedTotal: '($1,473.11)', total: 147311, stateNum: 1, + statusNum: 1, }, report_4249286573496381: { reportID: '4249286573496381', @@ -2054,10 +2054,10 @@ const openApp = (): Response => ({ managerID: 21, currency: 'USD', chatReportID: '4867098979334014', - state: 'SUBMITTED', cachedTotal: '($212.78)', total: 21278, stateNum: 1, + statusNum: 1, }, }, }, diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 40101feb6d40..5c5fe45fc811 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -109,7 +109,6 @@ type OptimisticExpenseReport = Pick< | 'ownerAccountID' | 'currency' | 'reportName' - | 'state' | 'stateNum' | 'statusNum' | 'total' @@ -300,13 +299,12 @@ type OptimisticIOUReport = Pick< | 'ownerAccountID' | 'participantAccountIDs' | 'reportID' - | 'state' | 'stateNum' + | 'statusNum' | 'total' | 'reportName' | 'notificationPreference' | 'parentReportID' - | 'statusNum' | 'lastVisibleActionCreated' >; type DisplayNameWithTooltips = Array>; diff --git a/src/types/onyx/Report.ts b/src/types/onyx/Report.ts index 9db1de108885..607c303f1abb 100644 --- a/src/types/onyx/Report.ts +++ b/src/types/onyx/Report.ts @@ -87,7 +87,7 @@ type Report = { stateNum?: ValueOf; /** The status of the current report */ - statusNum?: ValueOf; + statusNum?: ValueOf; /** Which user role is capable of posting messages on the report */ writeCapability?: WriteCapability; diff --git a/src/types/onyx/ReportAction.ts b/src/types/onyx/ReportAction.ts index a881b63fbb95..df4248b90d09 100644 --- a/src/types/onyx/ReportAction.ts +++ b/src/types/onyx/ReportAction.ts @@ -148,7 +148,7 @@ type ReportActionBase = { childManagerAccountID?: number; /** The status of the child report */ - childStatusNum?: ValueOf; + childStatusNum?: ValueOf; /** Report action child status name */ childStateNum?: ValueOf; From 0b7592d8efb3242816eb5aebba4120dc22e9a131 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Tue, 2 Jan 2024 11:55:17 +0500 Subject: [PATCH 11/57] fix: lint issues --- src/CONST.ts | 2 + .../ReportActionItem/MoneyReportView.tsx | 61 +++++++++++-------- src/libs/ReportUtils.ts | 2 +- src/pages/home/report/ReportActionItem.js | 2 +- 4 files changed, 38 insertions(+), 29 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index abba27b0c33b..e0479869987b 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -1427,6 +1427,8 @@ const CONST = { INVISIBLE_CHARACTERS_GROUPS: /[\p{C}\p{Z}]/gu, OTHER_INVISIBLE_CHARACTERS: /[\u3164]/g, + + REPORT_FIELD_TITLE: /{report:([a-zA-Z]+)}/g, }, PRONOUNS: { diff --git a/src/components/ReportActionItem/MoneyReportView.tsx b/src/components/ReportActionItem/MoneyReportView.tsx index 2ffbda4d347b..9ad9e73244f3 100644 --- a/src/components/ReportActionItem/MoneyReportView.tsx +++ b/src/components/ReportActionItem/MoneyReportView.tsx @@ -1,12 +1,13 @@ -import React, { useMemo } from 'react'; +import React, {useMemo} from 'react'; import {StyleProp, TextStyle, View} from 'react-native'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; -import SpacerView from '@components/SpacerView'; -import OfflineWithFeedback from '@components/OfflineWithFeedback'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; +import OfflineWithFeedback from '@components/OfflineWithFeedback'; +import SpacerView from '@components/SpacerView'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; +import usePermissions from '@hooks/usePermissions'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -16,7 +17,6 @@ import * as ReportUtils from '@libs/ReportUtils'; import AnimatedEmptyStateBackground from '@pages/home/report/AnimatedEmptyStateBackground'; import variables from '@styles/variables'; import type {PolicyReportField, Report} from '@src/types/onyx'; -import usePermissions from '@hooks/usePermissions'; type MoneyReportViewProps = { /** The report currently being looked at */ @@ -52,34 +52,41 @@ function MoneyReportView({report, policyReportFields, shouldShowHorizontalRule}: StyleUtils.getColorStyle(theme.textSupporting), ]; - const sortedPolicyReportFields = useMemo(() => policyReportFields.sort(({orderWeight: firstOrderWeight}, {orderWeight: secondOrderWeight}) => firstOrderWeight - secondOrderWeight), [policyReportFields]); + const sortedPolicyReportFields = useMemo( + () => policyReportFields.sort(({orderWeight: firstOrderWeight}, {orderWeight: secondOrderWeight}) => firstOrderWeight - secondOrderWeight), + [policyReportFields], + ); return ( - {canUseReportFields && sortedPolicyReportFields.map((reportField) => { - const title = ReportUtils.getReportFieldTitle(report, reportField); - return ( - - {}} - shouldShowRightIcon - disabled={false} - wrapperStyle={[styles.pv2, styles.taskDescriptionMenuItem]} - shouldGreyOutWhenDisabled={false} - numberOfLinesTitle={0} - interactive - shouldStackHorizontally={false} - onSecondaryInteraction={() => {}} - hoverAndPressStyle={false} - titleWithTooltips={[]} - /> - - ); - })} + {canUseReportFields && + sortedPolicyReportFields.map((reportField) => { + const title = ReportUtils.getReportFieldTitle(report, reportField); + return ( + + {}} + shouldShowRightIcon + disabled={false} + wrapperStyle={[styles.pv2, styles.taskDescriptionMenuItem]} + shouldGreyOutWhenDisabled={false} + numberOfLinesTitle={0} + interactive + shouldStackHorizontally={false} + onSecondaryInteraction={() => {}} + hoverAndPressStyle={false} + titleWithTooltips={[]} + /> + + ); + })} , reportField: PolicyRepor return value; } - return value.replaceAll(/{report:([a-zA-Z]+)}/g, (match, property) => { + return value.replaceAll(CONST.REGEX.REPORT_FIELD_TITLE, (match, property) => { if (report && property in report) { return report[property as keyof Report]?.toString() ?? match; } diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 4e806faa1b47..a16ba6132ebc 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -761,7 +761,7 @@ export default compose( initialValue: {}, }, policyReportFields: { - key: ({report}) => report && 'policyID' in report ? `${ONYXKEYS.COLLECTION.POLICY_REPORT_FIELDS}${report.policyID}` : undefined, + key: ({report}) => (report && 'policyID' in report ? `${ONYXKEYS.COLLECTION.POLICY_REPORT_FIELDS}${report.policyID}` : undefined), initialValue: [], }, emojiReactions: { From a2508343aa10ec039299fbccf7aeab2c62014122 Mon Sep 17 00:00:00 2001 From: Jakub Butkiewicz Date: Tue, 2 Jan 2024 17:41:12 +0100 Subject: [PATCH 12/57] ref: migrate ReportAttachments page to Typescript --- ...rtAttachments.js => ReportAttachments.tsx} | 41 ++++++++++--------- 1 file changed, 21 insertions(+), 20 deletions(-) rename src/pages/home/report/{ReportAttachments.js => ReportAttachments.tsx} (55%) diff --git a/src/pages/home/report/ReportAttachments.js b/src/pages/home/report/ReportAttachments.tsx similarity index 55% rename from src/pages/home/report/ReportAttachments.js rename to src/pages/home/report/ReportAttachments.tsx index 8ecbb036a756..1558cc8a13c4 100644 --- a/src/pages/home/report/ReportAttachments.js +++ b/src/pages/home/report/ReportAttachments.tsx @@ -1,43 +1,45 @@ -import PropTypes from 'prop-types'; +import {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback} from 'react'; -import _ from 'underscore'; import AttachmentModal from '@components/AttachmentModal'; import ComposerFocusManager from '@libs/ComposerFocusManager'; import Navigation from '@libs/Navigation/Navigation'; +import {AuthScreensParamList} from '@libs/Navigation/types'; import * as ReportUtils from '@libs/ReportUtils'; import ROUTES from '@src/ROUTES'; +import SCREENS from '@src/SCREENS'; -const propTypes = { - /** Navigation route context info provided by react navigation */ - route: PropTypes.shape({ - /** Route specific parameters used on this screen */ - params: PropTypes.shape({ - /** The report ID which the attachment is associated with */ - reportID: PropTypes.string.isRequired, - /** The uri encoded source of the attachment */ - source: PropTypes.string.isRequired, - }).isRequired, - }).isRequired, +type Attachment = { + file: { + name: string; + }; + hasBeenFlagged: boolean; + isAuthTokenRequired: boolean; + isReceipt: boolean; + reportActionID: string; + source: string; }; -function ReportAttachments(props) { - const reportID = _.get(props, ['route', 'params', 'reportID']); +type ReportAttachmentsProps = StackScreenProps; + +function ReportAttachments({route}: ReportAttachmentsProps) { + const reportID = route.params?.reportID; const report = ReportUtils.getReport(reportID); // In native the imported images sources are of type number. Ref: https://reactnative.dev/docs/image#imagesource - const decodedSource = decodeURI(_.get(props, ['route', 'params', 'source'])); + const decodedSource = decodeURI(route.params.source); const source = Number(decodedSource) || decodedSource; const onCarouselAttachmentChange = useCallback( - (attachment) => { - const route = ROUTES.REPORT_ATTACHMENTS.getRoute(reportID, attachment.source); - Navigation.navigate(route); + (attachment: Attachment) => { + const routeToNavigate = ROUTES.REPORT_ATTACHMENTS.getRoute(reportID, attachment.source); + Navigation.navigate(routeToNavigate); }, [reportID], ); return ( Date: Wed, 3 Jan 2024 10:50:17 +0100 Subject: [PATCH 13/57] fix: seperate type --- src/pages/home/report/ReportAttachments.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/ReportAttachments.tsx b/src/pages/home/report/ReportAttachments.tsx index 1558cc8a13c4..cd8f809378cc 100644 --- a/src/pages/home/report/ReportAttachments.tsx +++ b/src/pages/home/report/ReportAttachments.tsx @@ -8,10 +8,12 @@ import * as ReportUtils from '@libs/ReportUtils'; import ROUTES from '@src/ROUTES'; import SCREENS from '@src/SCREENS'; +type File = { + name: string; +}; + type Attachment = { - file: { - name: string; - }; + file: File; hasBeenFlagged: boolean; isAuthTokenRequired: boolean; isReceipt: boolean; From 9bd8f5d7fde9b899b6007597d1864fe26ab37b42 Mon Sep 17 00:00:00 2001 From: Nikki Wines Date: Thu, 4 Jan 2024 16:29:47 -0500 Subject: [PATCH 14/57] add updatemoneyrequestdescription --- src/libs/actions/IOU.js | 16 ++++++++++++++++ src/pages/EditRequestPage.js | 19 +++++++++++-------- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 21997023fbc8..12ad2d007067 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -1069,6 +1069,21 @@ function updateMoneyRequestTag(transactionID, transactionThreadReportID, tag) { API.write('UpdateMoneyRequestTag', params, onyxData); } +/** + * Updates the description of a money request + * + * @param {String} transactionID + * @param {Number} transactionThreadReportID + * @param {String} comment + */ +function updateMoneyRequestDescription(transactionID, transactionThreadReportID, comment) { + const transactionChanges = { + comment, + }; + const {params, onyxData} = getUpdateMoneyRequestParams(transactionID, transactionThreadReportID, transactionChanges, true); + API.write('UpdateMoneyRequestDescription', params, onyxData); +} + /** * Edits an existing distance request * @@ -3510,6 +3525,7 @@ export { updateMoneyRequestDate, updateMoneyRequestTag, updateMoneyRequestAmountAndCurrency, + updateMoneyRequestDescription, replaceReceipt, detachReceipt, getIOUReportID, diff --git a/src/pages/EditRequestPage.js b/src/pages/EditRequestPage.js index 54c5202fb205..1d8b175ae23a 100644 --- a/src/pages/EditRequestPage.js +++ b/src/pages/EditRequestPage.js @@ -162,18 +162,21 @@ function EditRequestPage({report, route, parentReport, policyCategories, policyT [transactionTag, transaction.transactionID, report.reportID], ); + const saveComment = useCallback( + ({comment: newComment}) => { + // Update comment only if it has changed + if (newComment.trim() !== transactionDescription) { + IOU.updateMoneyRequestDescription(transaction.transactionID, report.reportID, newComment.trim()); + } + Navigation.dismissModal(); + } + ) + if (fieldToEdit === CONST.EDIT_REQUEST_FIELD.DESCRIPTION) { return ( { - // In case the comment hasn't been changed, do not make the API request. - if (transactionChanges.comment.trim() === transactionDescription) { - Navigation.dismissModal(); - return; - } - editMoneyRequest({comment: transactionChanges.comment.trim()}); - }} + onSubmit={saveComment} /> ); } From e5594e91c22840105889e065f27ca74f49106115 Mon Sep 17 00:00:00 2001 From: Nikki Wines Date: Thu, 4 Jan 2024 18:27:32 -0500 Subject: [PATCH 15/57] update comment --- src/libs/actions/IOU.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 12ad2d007067..d4ca15929675 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -1055,7 +1055,7 @@ function updateMoneyRequestDate(transactionID, transactionThreadReportID, val) { } /** - * Updates the created date of a money request + * Updates the tag of a money request * * @param {String} transactionID * @param {Number} transactionThreadReportID From fc886b72359680e01ae26e4836e0a6fb1af9bbc9 Mon Sep 17 00:00:00 2001 From: Nikki Wines Date: Thu, 4 Jan 2024 20:46:09 -0500 Subject: [PATCH 16/57] minor style and clarifications --- src/pages/EditRequestPage.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pages/EditRequestPage.js b/src/pages/EditRequestPage.js index 1d8b175ae23a..c351efcf1bdc 100644 --- a/src/pages/EditRequestPage.js +++ b/src/pages/EditRequestPage.js @@ -164,13 +164,13 @@ function EditRequestPage({report, route, parentReport, policyCategories, policyT const saveComment = useCallback( ({comment: newComment}) => { - // Update comment only if it has changed + // Only update comment if it has changed if (newComment.trim() !== transactionDescription) { IOU.updateMoneyRequestDescription(transaction.transactionID, report.reportID, newComment.trim()); } Navigation.dismissModal(); } - ) + ); if (fieldToEdit === CONST.EDIT_REQUEST_FIELD.DESCRIPTION) { return ( From 01b9f03ab67c38979f2c02b07bb91189675f2332 Mon Sep 17 00:00:00 2001 From: Nikki Wines Date: Fri, 5 Jan 2024 13:29:45 -0500 Subject: [PATCH 17/57] include dependencies for callback --- src/pages/EditRequestPage.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/pages/EditRequestPage.js b/src/pages/EditRequestPage.js index 1d8b175ae23a..4efbdeb7e841 100644 --- a/src/pages/EditRequestPage.js +++ b/src/pages/EditRequestPage.js @@ -169,8 +169,9 @@ function EditRequestPage({report, route, parentReport, policyCategories, policyT IOU.updateMoneyRequestDescription(transaction.transactionID, report.reportID, newComment.trim()); } Navigation.dismissModal(); - } - ) + }, + [transactionDescription, transaction.transactionID, report.reportID], + ); if (fieldToEdit === CONST.EDIT_REQUEST_FIELD.DESCRIPTION) { return ( From 26b8460a214b339d82fa099c21c9f10743f0be72 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Sat, 6 Jan 2024 02:27:43 +0500 Subject: [PATCH 18/57] fix: use policy report fields array --- src/pages/home/report/ReportActionItem.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionItem.js b/src/pages/home/report/ReportActionItem.js index 44c7e0f60ea6..93835416eeed 100644 --- a/src/pages/home/report/ReportActionItem.js +++ b/src/pages/home/report/ReportActionItem.js @@ -615,7 +615,7 @@ function ReportActionItem(props) { From 1b27f97cfba198d9820e7935132ae0ceb2328a8d Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Tue, 9 Jan 2024 14:58:16 +0700 Subject: [PATCH 19/57] fix duplicated in LHN when deleted members was invited --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 0d7658adf180..ddb03bcc334c 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -3551,7 +3551,7 @@ function getChatByParticipantsAndPolicy(newParticipantList: number[], policyID: if (!report?.participantAccountIDs) { return false; } - const sortedParticipanctsAccountIDs = report.parentReportActionIDs?.sort(); + const sortedParticipanctsAccountIDs = report.participantAccountIDs?.sort(); // Only return the room if it has all the participants and is not a policy room return report.policyID === policyID && lodashIsEqual(newParticipantList, sortedParticipanctsAccountIDs); }) ?? null From 3e2413ecfe28d49b9629102666817fe80a213067 Mon Sep 17 00:00:00 2001 From: Pedro Guerreiro Date: Tue, 9 Jan 2024 15:50:19 +0000 Subject: [PATCH 20/57] chore(typescript): add missing import type --- src/pages/LogInWithShortLivedAuthTokenPage.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/pages/LogInWithShortLivedAuthTokenPage.tsx b/src/pages/LogInWithShortLivedAuthTokenPage.tsx index 5e95f31d1d6c..c5f8a9c20d5b 100644 --- a/src/pages/LogInWithShortLivedAuthTokenPage.tsx +++ b/src/pages/LogInWithShortLivedAuthTokenPage.tsx @@ -1,7 +1,8 @@ -import {StackScreenProps} from '@react-navigation/stack'; +import type {StackScreenProps} from '@react-navigation/stack'; import React, {useEffect} from 'react'; import {View} from 'react-native'; -import {OnyxEntry, withOnyx} from 'react-native-onyx'; +import type {OnyxEntry} from 'react-native-onyx'; +import {withOnyx} from 'react-native-onyx'; import FullScreenLoadingIndicator from '@components/FullscreenLoadingIndicator'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -15,7 +16,7 @@ import Navigation from '@libs/Navigation/Navigation'; import type {PublicScreensParamList} from '@libs/Navigation/types'; import * as Session from '@userActions/Session'; import ONYXKEYS from '@src/ONYXKEYS'; -import SCREENS from '@src/SCREENS'; +import type SCREENS from '@src/SCREENS'; import type {Account} from '@src/types/onyx'; type LogInWithShortLivedAuthTokenPageOnyxProps = { From 68d981572bf20fb6c62cd22e65b559e03ea0e0b7 Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Tue, 9 Jan 2024 14:54:55 -0300 Subject: [PATCH 21/57] making requests not count scanning receipts --- src/components/ReportActionItem/ReportPreview.js | 2 +- src/languages/en.ts | 3 ++- src/languages/es.ts | 3 ++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/ReportActionItem/ReportPreview.js b/src/components/ReportActionItem/ReportPreview.js index 27447a10a32b..4d41b522f148 100644 --- a/src/components/ReportActionItem/ReportPreview.js +++ b/src/components/ReportActionItem/ReportPreview.js @@ -165,7 +165,7 @@ function ReportPreview(props) { const previewSubtitle = formattedMerchant || props.translate('iou.requestCount', { - count: numberOfRequests, + count: numberOfRequests - numberOfScanningReceipts, scanningReceipts: numberOfScanningReceipts, }); diff --git a/src/languages/en.ts b/src/languages/en.ts index 1e84c8ea46be..55d680273e80 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1,4 +1,5 @@ import {CONST as COMMON_CONST} from 'expensify-common/lib/CONST'; +import Str from 'expensify-common/lib/str'; import CONST from '@src/CONST'; import type { AddressLineParams, @@ -584,7 +585,7 @@ export default { receiptStatusText: "Only you can see this receipt when it's scanning. Check back later or enter the details now.", receiptScanningFailed: 'Receipt scanning failed. Enter the details manually.', transactionPendingText: 'It takes a few days from the date the card was used for the transaction to post.', - requestCount: ({count, scanningReceipts = 0}: RequestCountParams) => `${count} requests${scanningReceipts > 0 ? `, ${scanningReceipts} scanning` : ''}`, + requestCount: ({count, scanningReceipts = 0}: RequestCountParams) => `${count} ${Str.pluralize('request', 'requests', count)}${scanningReceipts > 0 ? `, ${scanningReceipts} scanning` : ''}`, deleteRequest: 'Delete request', deleteConfirmation: 'Are you sure that you want to delete this request?', settledExpensify: 'Paid', diff --git a/src/languages/es.ts b/src/languages/es.ts index eda992589f69..2802ec33b39b 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1,4 +1,5 @@ import CONST from '@src/CONST'; +import Str from 'expensify-common/lib/str'; import type { AddressLineParams, AlreadySignedInParams, @@ -577,7 +578,7 @@ export default { receiptStatusText: 'Solo tú puedes ver este recibo cuando se está escaneando. Vuelve más tarde o introduce los detalles ahora.', receiptScanningFailed: 'El escaneo de recibo ha fallado. Introduce los detalles manualmente.', transactionPendingText: 'La transacción tarda unos días en contabilizarse desde la fecha en que se utilizó la tarjeta.', - requestCount: ({count, scanningReceipts = 0}: RequestCountParams) => `${count} solicitudes${scanningReceipts > 0 ? `, ${scanningReceipts} escaneando` : ''}`, + requestCount: ({count, scanningReceipts = 0}: RequestCountParams) => `${count} ${Str.pluralize('solicitude', 'solicitudes', count)}${scanningReceipts > 0 ? `, ${scanningReceipts} escaneando` : ''}`, deleteRequest: 'Eliminar pedido', deleteConfirmation: '¿Estás seguro de que quieres eliminar este pedido?', settledExpensify: 'Pagado', From 36f6ef8e21fe0faceb3f5f957d1f060fe18b29ab Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Tue, 9 Jan 2024 18:10:20 -0300 Subject: [PATCH 22/57] making sure props.action gets update --- src/components/ReportActionItem/ReportPreview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/ReportPreview.js b/src/components/ReportActionItem/ReportPreview.js index 4d41b522f148..2a58369d0b63 100644 --- a/src/components/ReportActionItem/ReportPreview.js +++ b/src/components/ReportActionItem/ReportPreview.js @@ -241,7 +241,7 @@ function ReportPreview(props) { unsubscribeOnyxTransaction(); }; // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + }, [props.action]); const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicyExpenseChat(props.chatReport); const isPolicyAdmin = policyType !== CONST.POLICY.TYPE.PERSONAL && lodashGet(props.policy, 'role') === CONST.POLICY.ROLE.ADMIN; From 8cf72a7aebd0888fa28276d25e5ba6f81376dc80 Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Tue, 9 Jan 2024 19:14:53 -0300 Subject: [PATCH 23/57] moving reportpreview updates from useEffect to useMemo --- .../ReportActionItem/ReportPreview.js | 39 ++++++------------- src/languages/en.ts | 3 +- src/languages/es.ts | 5 ++- 3 files changed, 17 insertions(+), 30 deletions(-) diff --git a/src/components/ReportActionItem/ReportPreview.js b/src/components/ReportActionItem/ReportPreview.js index 2a58369d0b63..da3dd0f2b078 100644 --- a/src/components/ReportActionItem/ReportPreview.js +++ b/src/components/ReportActionItem/ReportPreview.js @@ -13,6 +13,7 @@ import refPropTypes from '@components/refPropTypes'; import SettlementButton from '@components/SettlementButton'; import {showContextMenuForReport} from '@components/ShowContextMenuContext'; import Text from '@components/Text'; +import transactionPropTypes from '@components/transactionPropTypes'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import useLocalize from '@hooks/useLocalize'; import useStyleUtils from '@hooks/useStyleUtils'; @@ -23,7 +24,6 @@ import ControlSelection from '@libs/ControlSelection'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import Navigation from '@libs/Navigation/Navigation'; -import onyxSubscribe from '@libs/onyxSubscribe'; import * as ReceiptUtils from '@libs/ReceiptUtils'; import * as ReportActionUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; @@ -107,6 +107,9 @@ const propTypes = { /** Whether a message is a whisper */ isWhisper: PropTypes.bool, + /** All the transactions, used to update ReportPreview label and status */ + transactions: PropTypes.objectOf(transactionPropTypes), + ...withLocalizePropTypes, }; @@ -123,6 +126,7 @@ const defaultProps = { policy: { isHarvestingEnabled: false, }, + transactions: {}, }; function ReportPreview(props) { @@ -131,10 +135,10 @@ function ReportPreview(props) { const {getLineHeightStyle} = useStyleUtils(); const {translate} = useLocalize(); - const [hasMissingSmartscanFields, sethasMissingSmartscanFields] = useState(false); - const [areAllRequestsBeingSmartScanned, setAreAllRequestsBeingSmartScanned] = useState(false); - const [hasOnlyDistanceRequests, setHasOnlyDistanceRequests] = useState(false); - const [hasNonReimbursableTransactions, setHasNonReimbursableTransactions] = useState(false); + const hasMissingSmartscanFields = useMemo(() => ReportUtils.hasMissingSmartscanFields(props.iouReportID), [props.transactions]); + const areAllRequestsBeingSmartScanned = useMemo(() => ReportUtils.areAllRequestsBeingSmartScanned(props.iouReportID, props.action), [props.transactions]); + const hasOnlyDistanceRequests = useMemo(() => ReportUtils.hasOnlyDistanceRequestTransactions(props.iouReportID), [props.transactions]); + const hasNonReimbursableTransactions = useMemo(() => ReportUtils.hasNonReimbursableTransactions(props.iouReportID), [props.transactions]); const managerID = props.iouReport.managerID || 0; const isCurrentUserManager = managerID === lodashGet(props.session, 'accountID'); @@ -221,28 +225,6 @@ function ReportPreview(props) { const bankAccountRoute = ReportUtils.getBankAccountRoute(props.chatReport); - useEffect(() => { - const unsubscribeOnyxTransaction = onyxSubscribe({ - key: ONYXKEYS.COLLECTION.TRANSACTION, - waitForCollectionCallback: true, - callback: (allTransactions) => { - if (_.isEmpty(allTransactions)) { - return; - } - - sethasMissingSmartscanFields(ReportUtils.hasMissingSmartscanFields(props.iouReportID)); - setAreAllRequestsBeingSmartScanned(ReportUtils.areAllRequestsBeingSmartScanned(props.iouReportID, props.action)); - setHasOnlyDistanceRequests(ReportUtils.hasOnlyDistanceRequestTransactions(props.iouReportID)); - setHasNonReimbursableTransactions(ReportUtils.hasNonReimbursableTransactions(props.iouReportID)); - }, - }); - - return () => { - unsubscribeOnyxTransaction(); - }; - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [props.action]); - const isPaidGroupPolicy = ReportUtils.isPaidGroupPolicyExpenseChat(props.chatReport); const isPolicyAdmin = policyType !== CONST.POLICY.TYPE.PERSONAL && lodashGet(props.policy, 'role') === CONST.POLICY.ROLE.ADMIN; const isPayer = isPaidGroupPolicy @@ -373,5 +355,8 @@ export default compose( session: { key: ONYXKEYS.SESSION, }, + transactions: { + key: ONYXKEYS.COLLECTION.TRANSACTION, + }, }), )(ReportPreview); diff --git a/src/languages/en.ts b/src/languages/en.ts index c1df0bddf358..7ff001a447e1 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -585,7 +585,8 @@ export default { receiptStatusText: "Only you can see this receipt when it's scanning. Check back later or enter the details now.", receiptScanningFailed: 'Receipt scanning failed. Enter the details manually.', transactionPendingText: 'It takes a few days from the date the card was used for the transaction to post.', - requestCount: ({count, scanningReceipts = 0}: RequestCountParams) => `${count} ${Str.pluralize('request', 'requests', count)}${scanningReceipts > 0 ? `, ${scanningReceipts} scanning` : ''}`, + requestCount: ({count, scanningReceipts = 0}: RequestCountParams) => + `${count} ${Str.pluralize('request', 'requests', count)}${scanningReceipts > 0 ? `, ${scanningReceipts} scanning` : ''}`, deleteRequest: 'Delete request', deleteConfirmation: 'Are you sure that you want to delete this request?', settledExpensify: 'Paid', diff --git a/src/languages/es.ts b/src/languages/es.ts index a32808a690a9..81b1df377499 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1,5 +1,5 @@ -import CONST from '@src/CONST'; import Str from 'expensify-common/lib/str'; +import CONST from '@src/CONST'; import type { AddressLineParams, AlreadySignedInParams, @@ -578,7 +578,8 @@ export default { receiptStatusText: 'Solo tú puedes ver este recibo cuando se está escaneando. Vuelve más tarde o introduce los detalles ahora.', receiptScanningFailed: 'El escaneo de recibo ha fallado. Introduce los detalles manualmente.', transactionPendingText: 'La transacción tarda unos días en contabilizarse desde la fecha en que se utilizó la tarjeta.', - requestCount: ({count, scanningReceipts = 0}: RequestCountParams) => `${count} ${Str.pluralize('solicitude', 'solicitudes', count)}${scanningReceipts > 0 ? `, ${scanningReceipts} escaneando` : ''}`, + requestCount: ({count, scanningReceipts = 0}: RequestCountParams) => + `${count} ${Str.pluralize('solicitude', 'solicitudes', count)}${scanningReceipts > 0 ? `, ${scanningReceipts} escaneando` : ''}`, deleteRequest: 'Eliminar pedido', deleteConfirmation: '¿Estás seguro de que quieres eliminar este pedido?', settledExpensify: 'Pagado', From fcd96fcf7796ac196f27d2215dfd6915bb62757a Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Tue, 9 Jan 2024 20:40:09 -0300 Subject: [PATCH 24/57] removing unused imports --- src/components/ReportActionItem/ReportPreview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/ReportPreview.js b/src/components/ReportActionItem/ReportPreview.js index da3dd0f2b078..ab234c2e8ec4 100644 --- a/src/components/ReportActionItem/ReportPreview.js +++ b/src/components/ReportActionItem/ReportPreview.js @@ -1,6 +1,6 @@ import lodashGet from 'lodash/get'; import PropTypes from 'prop-types'; -import React, {useEffect, useMemo, useState} from 'react'; +import React, {useMemo} from 'react'; import {View} from 'react-native'; import {withOnyx} from 'react-native-onyx'; import _ from 'underscore'; From e3cab9926b1ef6cccf128d723287c082cee7dc2f Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Tue, 9 Jan 2024 20:44:51 -0300 Subject: [PATCH 25/57] make use memo depend on every property needed --- src/components/ReportActionItem/ReportPreview.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/components/ReportActionItem/ReportPreview.js b/src/components/ReportActionItem/ReportPreview.js index ab234c2e8ec4..cbdb1d38d496 100644 --- a/src/components/ReportActionItem/ReportPreview.js +++ b/src/components/ReportActionItem/ReportPreview.js @@ -135,10 +135,14 @@ function ReportPreview(props) { const {getLineHeightStyle} = useStyleUtils(); const {translate} = useLocalize(); - const hasMissingSmartscanFields = useMemo(() => ReportUtils.hasMissingSmartscanFields(props.iouReportID), [props.transactions]); - const areAllRequestsBeingSmartScanned = useMemo(() => ReportUtils.areAllRequestsBeingSmartScanned(props.iouReportID, props.action), [props.transactions]); - const hasOnlyDistanceRequests = useMemo(() => ReportUtils.hasOnlyDistanceRequestTransactions(props.iouReportID), [props.transactions]); - const hasNonReimbursableTransactions = useMemo(() => ReportUtils.hasNonReimbursableTransactions(props.iouReportID), [props.transactions]); + const {hasMissingSmartscanFields, areAllRequestsBeingSmartScanned, hasOnlyDistanceRequests, hasNonReimbursableTransactions} = useMemo(() => { + return { + hasMissingSmartscanFields: ReportUtils.hasMissingSmartscanFields(props.iouReportID), + areAllRequestsBeingSmartScanned: ReportUtils.areAllRequestsBeingSmartScanned(props.iouReportID, props.action), + hasOnlyDistanceRequests: ReportUtils.hasOnlyDistanceRequestTransactions(props.iouReportID), + hasNonReimbursableTransactions: ReportUtils.hasNonReimbursableTransactions(props.iouReportID), + }; + }, [props.transactions, props.iouReportID, props.action]); const managerID = props.iouReport.managerID || 0; const isCurrentUserManager = managerID === lodashGet(props.session, 'accountID'); From afcd7597f51fe1cd3cb94aab8b739d17e68a2368 Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Tue, 9 Jan 2024 20:56:59 -0300 Subject: [PATCH 26/57] disabling exhaustive-deps lint --- src/components/ReportActionItem/ReportPreview.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/ReportActionItem/ReportPreview.js b/src/components/ReportActionItem/ReportPreview.js index cbdb1d38d496..30e4cb78ccf1 100644 --- a/src/components/ReportActionItem/ReportPreview.js +++ b/src/components/ReportActionItem/ReportPreview.js @@ -142,6 +142,7 @@ function ReportPreview(props) { hasOnlyDistanceRequests: ReportUtils.hasOnlyDistanceRequestTransactions(props.iouReportID), hasNonReimbursableTransactions: ReportUtils.hasNonReimbursableTransactions(props.iouReportID), }; + // eslint-disable-next-line react-hooks/exhaustive-deps -- we just want this to run when transactions get updated }, [props.transactions, props.iouReportID, props.action]); const managerID = props.iouReport.managerID || 0; From 81d19652c6e653ec271b0ef6c647b7846002de3a Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Tue, 9 Jan 2024 21:17:46 -0300 Subject: [PATCH 27/57] lint/prettier --- src/components/ReportActionItem/ReportPreview.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/components/ReportActionItem/ReportPreview.js b/src/components/ReportActionItem/ReportPreview.js index 30e4cb78ccf1..9c2e9916730c 100644 --- a/src/components/ReportActionItem/ReportPreview.js +++ b/src/components/ReportActionItem/ReportPreview.js @@ -135,15 +135,16 @@ function ReportPreview(props) { const {getLineHeightStyle} = useStyleUtils(); const {translate} = useLocalize(); - const {hasMissingSmartscanFields, areAllRequestsBeingSmartScanned, hasOnlyDistanceRequests, hasNonReimbursableTransactions} = useMemo(() => { - return { + const {hasMissingSmartscanFields, areAllRequestsBeingSmartScanned, hasOnlyDistanceRequests, hasNonReimbursableTransactions} = useMemo( + () => ({ hasMissingSmartscanFields: ReportUtils.hasMissingSmartscanFields(props.iouReportID), areAllRequestsBeingSmartScanned: ReportUtils.areAllRequestsBeingSmartScanned(props.iouReportID, props.action), hasOnlyDistanceRequests: ReportUtils.hasOnlyDistanceRequestTransactions(props.iouReportID), hasNonReimbursableTransactions: ReportUtils.hasNonReimbursableTransactions(props.iouReportID), - }; + }), // eslint-disable-next-line react-hooks/exhaustive-deps -- we just want this to run when transactions get updated - }, [props.transactions, props.iouReportID, props.action]); + [props.transactions, props.iouReportID, props.action], + ); const managerID = props.iouReport.managerID || 0; const isCurrentUserManager = managerID === lodashGet(props.session, 'accountID'); From 20371372d2cc7abcab47153c93c23a3f5169c31f Mon Sep 17 00:00:00 2001 From: Jakub Butkiewicz Date: Wed, 10 Jan 2024 08:31:12 +0100 Subject: [PATCH 28/57] fix: imports and removed optional chaining where it was not necessary --- src/pages/home/report/ReportAttachments.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/pages/home/report/ReportAttachments.tsx b/src/pages/home/report/ReportAttachments.tsx index cd8f809378cc..42ca51cabe0b 100644 --- a/src/pages/home/report/ReportAttachments.tsx +++ b/src/pages/home/report/ReportAttachments.tsx @@ -1,12 +1,12 @@ -import {StackScreenProps} from '@react-navigation/stack'; +import type {StackScreenProps} from '@react-navigation/stack'; import React, {useCallback} from 'react'; import AttachmentModal from '@components/AttachmentModal'; import ComposerFocusManager from '@libs/ComposerFocusManager'; import Navigation from '@libs/Navigation/Navigation'; -import {AuthScreensParamList} from '@libs/Navigation/types'; +import type {AuthScreensParamList} from '@libs/Navigation/types'; import * as ReportUtils from '@libs/ReportUtils'; import ROUTES from '@src/ROUTES'; -import SCREENS from '@src/SCREENS'; +import type SCREENS from '@src/SCREENS'; type File = { name: string; @@ -24,7 +24,7 @@ type Attachment = { type ReportAttachmentsProps = StackScreenProps; function ReportAttachments({route}: ReportAttachmentsProps) { - const reportID = route.params?.reportID; + const reportID = route.params.reportID; const report = ReportUtils.getReport(reportID); // In native the imported images sources are of type number. Ref: https://reactnative.dev/docs/image#imagesource From 1ca9b76e86363c4f723a838a4b1c696f0920cca6 Mon Sep 17 00:00:00 2001 From: Github Date: Tue, 9 Jan 2024 12:14:39 +0100 Subject: [PATCH 29/57] refactor some Reassure tests --- tests/perf-test/OptionsSelector.perf-test.js | 2 +- .../perf-test/ReportActionsUtils.perf-test.ts | 205 ++++++------- tests/perf-test/ReportUtils.perf-test.ts | 287 ++++++++---------- tests/perf-test/SidebarLinks.perf-test.js | 155 +++++----- tests/perf-test/SidebarUtils.perf-test.ts | 99 +++--- 5 files changed, 339 insertions(+), 409 deletions(-) diff --git a/tests/perf-test/OptionsSelector.perf-test.js b/tests/perf-test/OptionsSelector.perf-test.js index 557a0baf1ba4..3236a468b216 100644 --- a/tests/perf-test/OptionsSelector.perf-test.js +++ b/tests/perf-test/OptionsSelector.perf-test.js @@ -84,7 +84,7 @@ test('[OptionsSelector] should render 1 section', () => { measurePerformance(, {runs}); }); -test('[OptionsSelector] should render mutliple sections', () => { +test('[OptionsSelector] should render multiple sections', () => { const sections = generateSections(mutlipleSectionsConfig); measurePerformance(, {runs}); }); diff --git a/tests/perf-test/ReportActionsUtils.perf-test.ts b/tests/perf-test/ReportActionsUtils.perf-test.ts index ea3b48bacf47..2a96a5959942 100644 --- a/tests/perf-test/ReportActionsUtils.perf-test.ts +++ b/tests/perf-test/ReportActionsUtils.perf-test.ts @@ -9,18 +9,6 @@ import createCollection from '../utils/collections/createCollection'; import createRandomReportAction from '../utils/collections/reportActions'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; -beforeAll(() => - Onyx.init({ - keys: ONYXKEYS, - safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], - }), -); - -// Clear out Onyx after each test so that each test starts with a clean slate -afterEach(() => { - Onyx.clear(); -}); - const getMockedReportActionsMap = (reportsLength = 10, actionsPerReportLength = 100) => { const mockReportActions = Array.from({length: actionsPerReportLength}, (v, i) => { const reportActionKey = i + 1; @@ -49,120 +37,113 @@ const reportId = '1'; const runs = CONST.PERFORMANCE_TESTS.RUNS; -/** - * This function will be executed 20 times and the average time will be used on the comparison. - * It will fail based on the CI configuration around Reassure: - * @see /.github/workflows/reassurePerformanceTests.yml - * - * Max deviation on the duration is set to 20% at the time of writing. - * - * More on the measureFunction API: - * @see https://callstack.github.io/reassure/docs/api#measurefunction-function - */ -test('[ReportActionsUtils] getLastVisibleAction on 10k reportActions', async () => { - await Onyx.multiSet({ - ...mockedReportActionsMap, +describe('ReportActionsUtils', () => { + beforeAll(() => { + Onyx.init({ + keys: ONYXKEYS, + safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], + }); + + Onyx.multiSet({ + ...mockedReportActionsMap, + }); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId), {runs}); -}); + afterAll(() => { + Onyx.clear(); + }); -test('[ReportActionsUtils] getLastVisibleAction on 10k reportActions with actionsToMerge', async () => { - const parentReportActionId = '1'; - const fakeParentAction = reportActions[parentReportActionId]; - const actionsToMerge = { - [parentReportActionId]: { - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, - previousMessage: fakeParentAction.message, - message: [ - { - translationKey: '', - type: 'COMMENT', - html: '', - text: '', - isEdited: true, - isDeletedParentAction: true, - }, - ], - errors: null, - linkMetaData: [], - }, - } as unknown as ReportActions; - - await Onyx.multiSet({ - ...mockedReportActionsMap, + /** + * This function will be executed 20 times and the average time will be used on the comparison. + * It will fail based on the CI configuration around Reassure: + * @see /.github/workflows/reassurePerformanceTests.yml + * + * Max deviation on the duration is set to 20% at the time of writing. + * + * More on the measureFunction API: + * @see https://callstack.github.io/reassure/docs/api#measurefunction-function + */ + test('[ReportActionsUtils] getLastVisibleAction on 10k reportActions', async () => { + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId, actionsToMerge), {runs}); -}); -test('[ReportActionsUtils] getMostRecentIOURequestActionID on 10k ReportActions', async () => { - const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions); - await Onyx.multiSet({ - ...mockedReportActionsMap, + test('[ReportActionsUtils] getLastVisibleAction on 10k reportActions with actionsToMerge', async () => { + const parentReportActionId = '1'; + const fakeParentAction = reportActions[parentReportActionId]; + const actionsToMerge = { + [parentReportActionId]: { + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + previousMessage: fakeParentAction.message, + message: [ + { + translationKey: '', + type: 'COMMENT', + html: '', + text: '', + isEdited: true, + isDeletedParentAction: true, + }, + ], + errors: null, + linkMetaData: [], + }, + } as unknown as ReportActions; + + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId, actionsToMerge), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray), {runs}); -}); -test('[ReportActionsUtils] getLastVisibleMessage on 10k ReportActions', async () => { - await Onyx.multiSet({ - ...mockedReportActionsMap, + test('[ReportActionsUtils] getMostRecentIOURequestActionID on 10k ReportActions', async () => { + const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions); + + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId), {runs}); -}); -test('[ReportActionsUtils] getLastVisibleMessage on 10k ReportActions with actionsToMerge', async () => { - const parentReportActionId = '1'; - const fakeParentAction = reportActions[parentReportActionId]; - const actionsToMerge = { - [parentReportActionId]: { - pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, - previousMessage: fakeParentAction.message, - message: [ - { - translationKey: '', - type: 'COMMENT', - html: '', - text: '', - isEdited: true, - isDeletedParentAction: true, - }, - ], - errors: null, - linkMetaData: [], - }, - } as unknown as ReportActions; - - await Onyx.multiSet({ - ...mockedReportActionsMap, + test('[ReportActionsUtils] getLastVisibleMessage on 10k ReportActions', async () => { + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId, actionsToMerge), {runs}); -}); -test('[ReportActionsUtils] getSortedReportActionsForDisplay on 10k ReportActions', async () => { - await Onyx.multiSet({ - ...mockedReportActionsMap, + test('[ReportActionsUtils] getLastVisibleMessage on 10k ReportActions with actionsToMerge', async () => { + const parentReportActionId = '1'; + const fakeParentAction = reportActions[parentReportActionId]; + const actionsToMerge = { + [parentReportActionId]: { + pendingAction: CONST.RED_BRICK_ROAD_PENDING_ACTION.UPDATE, + previousMessage: fakeParentAction.message, + message: [ + { + translationKey: '', + type: 'COMMENT', + html: '', + text: '', + isEdited: true, + isDeletedParentAction: true, + }, + ], + errors: null, + linkMetaData: [], + }, + } as unknown as ReportActions; + + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId, actionsToMerge), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions), {runs}); -}); -test('[ReportActionsUtils] getLastClosedReportAction on 10k ReportActions', async () => { - await Onyx.multiSet({ - ...mockedReportActionsMap, + test('[ReportActionsUtils] getSortedReportActionsForDisplay on 10k ReportActions', async () => { + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions), {runs}); + }); + + test('[ReportActionsUtils] getLastClosedReportAction on 10k ReportActions', async () => { + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getLastClosedReportAction(reportActions), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastClosedReportAction(reportActions), {runs}); -}); -test('[ReportActionsUtils] getMostRecentReportActionLastModified', async () => { - await Onyx.multiSet({ - ...mockedReportActionsMap, + test('[ReportActionsUtils] getMostRecentReportActionLastModified', async () => { + await waitForBatchedUpdates(); + await measureFunction(() => ReportActionsUtils.getMostRecentReportActionLastModified(), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getMostRecentReportActionLastModified(), {runs}); }); diff --git a/tests/perf-test/ReportUtils.perf-test.ts b/tests/perf-test/ReportUtils.perf-test.ts index 62b911fb0417..30f874c669ab 100644 --- a/tests/perf-test/ReportUtils.perf-test.ts +++ b/tests/perf-test/ReportUtils.perf-test.ts @@ -13,19 +13,6 @@ import createRandomTransaction from '../utils/collections/transaction'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; const runs = CONST.PERFORMANCE_TESTS.RUNS; - -beforeAll(() => - Onyx.init({ - keys: ONYXKEYS, - safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], - }), -); - -// Clear out Onyx after each test so that each test starts with a clean state -afterEach(() => { - Onyx.clear(); -}); - const getMockedReports = (length = 500) => createCollection( (item) => `${ONYXKEYS.COLLECTION.REPORT}${item.reportID}`, @@ -50,195 +37,169 @@ const mockedReportsMap = getMockedReports(5000) as Record<`${typeof ONYXKEYS.COL const mockedPoliciesMap = getMockedPolicies(5000) as Record<`${typeof ONYXKEYS.COLLECTION.POLICY}`, Policy>; const participantAccountIDs = Array.from({length: 1000}, (v, i) => i + 1); -test('[ReportUtils] findLastAccessedReport on 2k reports and policies', async () => { - const ignoreDomainRooms = true; - const isFirstTimeNewExpensifyUser = true; - const reports = getMockedReports(2000); - const policies = getMockedPolicies(2000); - const openOnAdminRoom = true; - - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.findLastAccessedReport(reports, ignoreDomainRooms, policies, isFirstTimeNewExpensifyUser, openOnAdminRoom), {runs}); -}); +describe('ReportUtils', () => { + beforeAll(() => { + Onyx.init({ + keys: ONYXKEYS, + safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], + }); + + Onyx.multiSet({ + ...mockedPoliciesMap, + ...mockedReportsMap, + }); + }); -test('[ReportUtils] canDeleteReportAction on 5k reports and policies', async () => { - const reportID = '1'; + afterAll(() => { + Onyx.clear(); + }); - const reportAction = {...createRandomReportAction(1), actionName: CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT} as unknown as ReportAction; + test('[ReportUtils] findLastAccessedReport on 2k reports and policies', async () => { + const ignoreDomainRooms = true; + const isFirstTimeNewExpensifyUser = true; + const reports = getMockedReports(2000); + const policies = getMockedPolicies(2000); + const openOnAdminRoom = true; - await Onyx.multiSet({ - ...mockedPoliciesMap, - ...mockedReportsMap, + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.findLastAccessedReport(reports, ignoreDomainRooms, policies, isFirstTimeNewExpensifyUser, openOnAdminRoom), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.canDeleteReportAction(reportAction, reportID), {runs}); -}); + test('[ReportUtils] canDeleteReportAction on 5k reports and policies', async () => { + const reportID = '1'; + const reportAction = {...createRandomReportAction(1), actionName: CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT} as unknown as ReportAction; -test('[ReportUtils] getReportRecipientAccountID on 1k participants', async () => { - const report = {...createRandomReport(1), participantAccountIDs}; - const currentLoginAccountID = 1; - - await Onyx.multiSet({ - ...mockedReportsMap, + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.canDeleteReportAction(reportAction, reportID), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getReportRecipientAccountIDs(report, currentLoginAccountID), {runs}); -}); - -test('[ReportUtils] getIconsForParticipants on 1k participants', async () => { - const participants = Array.from({length: 1000}, (v, i) => i + 1); + test('[ReportUtils] getReportRecipientAccountID on 1k participants', async () => { + const report = {...createRandomReport(1), participantAccountIDs}; + const currentLoginAccountID = 1; - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getIconsForParticipants(participants, personalDetails), {runs}); -}); + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.getReportRecipientAccountIDs(report, currentLoginAccountID), {runs}); + }); -test('[ReportUtils] getIcons on 1k participants', async () => { - const report = {...createRandomReport(1), parentReportID: '1', parentReportActionID: '1', type: CONST.REPORT.TYPE.CHAT}; - const policy = createRandomPolicy(1); - const defaultIcon = null; - const defaultName = ''; - const defaultIconId = -1; + test('[ReportUtils] getIconsForParticipants on 1k participants', async () => { + const participants = Array.from({length: 1000}, (v, i) => i + 1); - await Onyx.multiSet({ - [ONYXKEYS.PERSONAL_DETAILS_LIST]: personalDetails, + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.getIconsForParticipants(participants, personalDetails), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getIcons(report, personalDetails, defaultIcon, defaultName, defaultIconId, policy), {runs}); -}); - -test('[ReportUtils] getDisplayNamesWithTooltips 1k participants', async () => { - const isMultipleParticipantReport = true; - const shouldFallbackToHidden = true; + test('[ReportUtils] getIcons on 1k participants', async () => { + const report = {...createRandomReport(1), parentReportID: '1', parentReportActionID: '1', type: CONST.REPORT.TYPE.CHAT}; + const policy = createRandomPolicy(1); + const defaultIcon = null; + const defaultName = ''; + const defaultIconId = -1; - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getDisplayNamesWithTooltips(personalDetails, isMultipleParticipantReport, shouldFallbackToHidden), {runs}); -}); + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.getIcons(report, personalDetails, defaultIcon, defaultName, defaultIconId, policy), {runs}); + }); -test('[ReportUtils] getReportPreviewMessage on 5k policies', async () => { - const reportAction = createRandomReportAction(1); - const report = createRandomReport(1); - const policy = createRandomPolicy(1); - const shouldConsiderReceiptBeingScanned = true; - const isPreviewMessageForParentChatReport = true; + test('[ReportUtils] getDisplayNamesWithTooltips 1k participants', async () => { + const isMultipleParticipantReport = true; + const shouldFallbackToHidden = true; - await Onyx.multiSet({ - ...mockedPoliciesMap, + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.getDisplayNamesWithTooltips(personalDetails, isMultipleParticipantReport, shouldFallbackToHidden), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getReportPreviewMessage(report, reportAction, shouldConsiderReceiptBeingScanned, isPreviewMessageForParentChatReport, policy), {runs}); -}); + test('[ReportUtils] getReportPreviewMessage on 5k policies', async () => { + const reportAction = createRandomReportAction(1); + const report = createRandomReport(1); + const policy = createRandomPolicy(1); + const shouldConsiderReceiptBeingScanned = true; + const isPreviewMessageForParentChatReport = true; -test('[ReportUtils] getReportName on 1k participants', async () => { - const report = {...createRandomReport(1), chatType: undefined, participantAccountIDs}; - const policy = createRandomPolicy(1); + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.getReportPreviewMessage(report, reportAction, shouldConsiderReceiptBeingScanned, isPreviewMessageForParentChatReport, policy), {runs}); + }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getReportName(report, policy), {runs}); -}); + test('[ReportUtils] getReportName on 1k participants', async () => { + const report = {...createRandomReport(1), chatType: undefined, participantAccountIDs}; + const policy = createRandomPolicy(1); -test('[ReportUtils] canShowReportRecipientLocalTime on 1k participants', async () => { - const report = {...createRandomReport(1), participantAccountIDs}; - const accountID = 1; - await Onyx.multiSet({ - ...mockedReportsMap, + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.getReportName(report, policy), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.canShowReportRecipientLocalTime(personalDetails, report, accountID), {runs}); -}); - -test('[ReportUtils] shouldReportBeInOptionList on 1k participant', async () => { - const report = {...createRandomReport(1), participantAccountIDs, type: CONST.REPORT.TYPE.CHAT}; - const currentReportId = '2'; - const isInGSDMode = true; - const betas = [CONST.BETAS.DEFAULT_ROOMS]; - const policies = getMockedPolicies(); + test('[ReportUtils] canShowReportRecipientLocalTime on 1k participants', async () => { + const report = {...createRandomReport(1), participantAccountIDs}; + const accountID = 1; - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.shouldReportBeInOptionList(report, currentReportId, isInGSDMode, betas, policies), {runs}); -}); + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.canShowReportRecipientLocalTime(personalDetails, report, accountID), {runs}); + }); -test('[ReportUtils] getWorkspaceIcon on 5k policies', async () => { - const report = createRandomReport(1); - const policy = createRandomPolicy(1); + test('[ReportUtils] shouldReportBeInOptionList on 1k participant', async () => { + const report = {...createRandomReport(1), participantAccountIDs, type: CONST.REPORT.TYPE.CHAT}; + const currentReportId = '2'; + const isInGSDMode = true; + const betas = [CONST.BETAS.DEFAULT_ROOMS]; + const policies = getMockedPolicies(); - await Onyx.multiSet({ - ...mockedPoliciesMap, + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.shouldReportBeInOptionList(report, currentReportId, isInGSDMode, betas, policies), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getWorkspaceIcon(report, policy), {runs}); -}); - -test('[ReportUtils] getMoneyRequestOptions on 1k participants', async () => { - const report = {...createRandomReport(1), type: CONST.REPORT.TYPE.CHAT, chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, isOwnPolicyExpenseChat: true}; - const policy = createRandomPolicy(1); - const reportParticipants = Array.from({length: 1000}, (v, i) => i + 1); + test('[ReportUtils] getWorkspaceIcon on 5k policies', async () => { + const report = createRandomReport(1); + const policy = createRandomPolicy(1); - await Onyx.multiSet({ - ...mockedPoliciesMap, + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.getWorkspaceIcon(report, policy), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getMoneyRequestOptions(report, policy, reportParticipants), {runs}); -}); - -test('[ReportUtils] getWorkspaceAvatar on 5k policies', async () => { - const report = createRandomReport(1); + test('[ReportUtils] getMoneyRequestOptions on 1k participants', async () => { + const report = {...createRandomReport(1), type: CONST.REPORT.TYPE.CHAT, chatType: CONST.REPORT.CHAT_TYPE.POLICY_EXPENSE_CHAT, isOwnPolicyExpenseChat: true}; + const policy = createRandomPolicy(1); + const reportParticipants = Array.from({length: 1000}, (v, i) => i + 1); - await Onyx.multiSet({ - ...mockedPoliciesMap, + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.getMoneyRequestOptions(report, policy, reportParticipants), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getWorkspaceAvatar(report), {runs}); -}); -test('[ReportUtils] getWorkspaceChat on 5k policies', async () => { - const policyID = '1'; - const accountsID = Array.from({length: 20}, (v, i) => i + 1); + test('[ReportUtils] getWorkspaceAvatar on 5k policies', async () => { + const report = createRandomReport(1); - await Onyx.multiSet({ - ...mockedReportsMap, + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.getWorkspaceAvatar(report), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getWorkspaceChats(policyID, accountsID), {runs}); -}); - -test('[ReportUtils] getTransactionDetails on 5k reports', async () => { - const transaction = createRandomTransaction(1); + test('[ReportUtils] getWorkspaceChat on 5k policies', async () => { + const policyID = '1'; + const accountsID = Array.from({length: 20}, (v, i) => i + 1); - await Onyx.multiSet({ - ...mockedReportsMap, + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.getWorkspaceChats(policyID, accountsID), {runs}); }); - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getTransactionDetails(transaction, 'yyyy-MM-dd'), {runs}); -}); + test('[ReportUtils] getTransactionDetails on 5k reports', async () => { + const transaction = createRandomTransaction(1); + + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.getTransactionDetails(transaction, 'yyyy-MM-dd'), {runs}); + }); -test('[ReportUtils] getIOUReportActionDisplayMessage on 5k policies', async () => { - const reportAction = { - ...createRandomReportAction(1), - actionName: CONST.REPORT.ACTIONS.TYPE.IOU, - originalMessage: { - IOUReportID: '1', - IOUTransactionID: '1', - amount: 100, - participantAccountID: 1, - currency: CONST.CURRENCY.USD, - type: CONST.IOU.REPORT_ACTION_TYPE.PAY, - paymentType: CONST.IOU.PAYMENT_TYPE.EXPENSIFY, - }, - }; - - await Onyx.multiSet({ - ...mockedPoliciesMap, - }); - - await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getIOUReportActionDisplayMessage(reportAction), {runs}); + test('[ReportUtils] getIOUReportActionDisplayMessage on 5k policies', async () => { + const reportAction = { + ...createRandomReportAction(1), + actionName: CONST.REPORT.ACTIONS.TYPE.IOU, + originalMessage: { + IOUReportID: '1', + IOUTransactionID: '1', + amount: 100, + participantAccountID: 1, + currency: CONST.CURRENCY.USD, + type: CONST.IOU.REPORT_ACTION_TYPE.PAY, + paymentType: CONST.IOU.PAYMENT_TYPE.EXPENSIFY, + }, + }; + + await waitForBatchedUpdates(); + await measureFunction(() => ReportUtils.getIOUReportActionDisplayMessage(reportAction), {runs}); + }); }); diff --git a/tests/perf-test/SidebarLinks.perf-test.js b/tests/perf-test/SidebarLinks.perf-test.js index 1f529b08e6b3..1bc674045c23 100644 --- a/tests/perf-test/SidebarLinks.perf-test.js +++ b/tests/perf-test/SidebarLinks.perf-test.js @@ -15,25 +15,6 @@ jest.mock('../../src/components/Icon/Expensicons'); jest.mock('@react-navigation/native'); -beforeAll(() => - Onyx.init({ - keys: ONYXKEYS, - safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], - registerStorageEventListener: () => {}, - }), -); - -// Initialize the network key for OfflineWithFeedback -beforeEach(() => { - wrapOnyxWithWaitForBatchedUpdates(Onyx); - return Onyx.merge(ONYXKEYS.NETWORK, {isOffline: false}); -}); - -// Clear out Onyx after each test so that each test starts with a clean slate -afterEach(() => { - Onyx.clear(); -}); - const getMockedReportsMap = (length = 100) => { const mockReports = Array.from({length}, (__, i) => { const reportID = i + 1; @@ -51,71 +32,81 @@ const mockedResponseMap = getMockedReportsMap(500); const runs = CONST.PERFORMANCE_TESTS.RUNS; -test('[SidebarLinks] should render Sidebar with 500 reports stored', () => { - const scenario = async () => { - // Query for the sidebar - await screen.findByTestId('lhn-options-list'); - /** - * Query for display names of participants [1, 2]. - * This will ensure that the sidebar renders a list of items. - */ - await screen.findAllByText('One, Two'); - }; - - return waitForBatchedUpdates() - .then(() => - Onyx.multiSet({ - [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT, - [ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails, - [ONYXKEYS.BETAS]: [CONST.BETAS.DEFAULT_ROOMS], - [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.GSD, - [ONYXKEYS.IS_LOADING_REPORT_DATA]: false, - ...mockedResponseMap, - }), - ) - .then(() => measurePerformance(, {scenario, runs})); -}); +describe('SidebarLinks', () => { + beforeAll(() => { + Onyx.init({ + keys: ONYXKEYS, + safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], + registerStorageEventListener: () => {}, + }); + + Onyx.multiSet({ + [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT, + [ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails, + [ONYXKEYS.BETAS]: [CONST.BETAS.DEFAULT_ROOMS], + [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.GSD, + [ONYXKEYS.IS_LOADING_REPORT_DATA]: false, + ...mockedResponseMap, + }); + }); -test('[SidebarLinks] should scroll and click some of the items', () => { - const scenario = async () => { - const eventData = { - nativeEvent: { - contentOffset: { - y: variables.optionRowHeight * 5, - }, - contentSize: { - // Dimensions of the scrollable content - height: variables.optionRowHeight * 10, - width: 100, - }, - layoutMeasurement: { - // Dimensions of the device - height: variables.optionRowHeight * 5, - width: 100, + // Initialize the network key for OfflineWithFeedback + beforeEach(() => { + wrapOnyxWithWaitForBatchedUpdates(Onyx); + return Onyx.merge(ONYXKEYS.NETWORK, {isOffline: false}); + }); + + afterAll(() => { + Onyx.clear(); + }); + + test('[SidebarLinks] should render Sidebar with 500 reports stored', async () => { + const scenario = async () => { + // Query for the sidebar + await screen.findByTestId('lhn-options-list'); + /** + * Query for display names of participants [1, 2]. + * This will ensure that the sidebar renders a list of items. + */ + await screen.findAllByText('One, Two'); + }; + + await waitForBatchedUpdates(); + await measurePerformance(, {scenario, runs}); + }); + + test('[SidebarLinks] should scroll and click some of the items', async () => { + const scenario = async () => { + const eventData = { + nativeEvent: { + contentOffset: { + y: variables.optionRowHeight * 5, + }, + contentSize: { + // Dimensions of the scrollable content + height: variables.optionRowHeight * 10, + width: 100, + }, + layoutMeasurement: { + // Dimensions of the device + height: variables.optionRowHeight * 5, + width: 100, + }, }, - }, + }; + + const lhnOptionsList = await screen.findByTestId('lhn-options-list'); + + fireEvent.scroll(lhnOptionsList, eventData); + // find elements that are currently visible in the viewport + const button1 = await screen.findByTestId('7'); + const button2 = await screen.findByTestId('8'); + fireEvent.press(button1); + fireEvent.press(button2); }; - const lhnOptionsList = await screen.findByTestId('lhn-options-list'); - - fireEvent.scroll(lhnOptionsList, eventData); - // find elements that are currently visible in the viewport - const button1 = await screen.findByTestId('7'); - const button2 = await screen.findByTestId('8'); - fireEvent.press(button1); - fireEvent.press(button2); - }; - - return waitForBatchedUpdates() - .then(() => - Onyx.multiSet({ - [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT, - [ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails, - [ONYXKEYS.BETAS]: [CONST.BETAS.DEFAULT_ROOMS], - [ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.GSD, - [ONYXKEYS.IS_LOADING_REPORT_DATA]: false, - ...mockedResponseMap, - }), - ) - .then(() => measurePerformance(, {scenario, runs})); + await waitForBatchedUpdates(); + + await measurePerformance(, {scenario, runs}); + }); }); diff --git a/tests/perf-test/SidebarUtils.perf-test.ts b/tests/perf-test/SidebarUtils.perf-test.ts index 6722cbf493a5..6ca81796d3ac 100644 --- a/tests/perf-test/SidebarUtils.perf-test.ts +++ b/tests/perf-test/SidebarUtils.perf-test.ts @@ -15,18 +15,6 @@ import createRandomReportAction from '../utils/collections/reportActions'; import createRandomReport from '../utils/collections/reports'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; -beforeAll(() => - Onyx.init({ - keys: ONYXKEYS, - safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], - }), -); - -// Clear out Onyx after each test so that each test starts with a clean slate -afterEach(() => { - Onyx.clear(); -}); - const getMockedReports = (length = 500) => createCollection( (item) => `${ONYXKEYS.COLLECTION.REPORT}${item.reportID}`, @@ -47,52 +35,61 @@ const personalDetails = createCollection( const mockedResponseMap = getMockedReports(5000) as Record<`${typeof ONYXKEYS.COLLECTION.REPORT}`, Report>; const runs = CONST.PERFORMANCE_TESTS.RUNS; -test('[SidebarUtils] getOptionData on 5k reports', async () => { - const report = createRandomReport(1); - const preferredLocale = 'en'; - const policy = createRandomPolicy(1); - const parentReportAction = createRandomReportAction(1); +describe('SidebarUtils', () => { + beforeAll(() => { + Onyx.init({ + keys: ONYXKEYS, + safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS], + }); - Onyx.multiSet({ - ...mockedResponseMap, + Onyx.multiSet({ + ...mockedResponseMap, + }); }); - await waitForBatchedUpdates(); - await measureFunction(() => SidebarUtils.getOptionData(report, reportActions, personalDetails, preferredLocale, policy, parentReportAction), {runs}); -}); + afterAll(() => { + Onyx.clear(); + }); -test('[SidebarUtils] getOrderedReportIDs on 5k reports', async () => { - const currentReportId = '1'; - const allReports = getMockedReports(); - const betas = [CONST.BETAS.DEFAULT_ROOMS]; + test('[SidebarUtils] getOptionData on 5k reports', async () => { + const report = createRandomReport(1); + const preferredLocale = 'en'; + const policy = createRandomPolicy(1); + const parentReportAction = createRandomReportAction(1); - const policies = createCollection( - (item) => `${ONYXKEYS.COLLECTION.POLICY}${item.id}`, - (index) => createRandomPolicy(index), - ); + await waitForBatchedUpdates(); + await measureFunction(() => SidebarUtils.getOptionData(report, reportActions, personalDetails, preferredLocale, policy, parentReportAction), {runs}); + }); + + test('[SidebarUtils] getOrderedReportIDs on 5k reports', async () => { + const currentReportId = '1'; + const allReports = getMockedReports(); + const betas = [CONST.BETAS.DEFAULT_ROOMS]; - const allReportActions = Object.fromEntries( - Object.keys(reportActions).map((key) => [ - key, - [ - { - errors: reportActions[key].errors ?? [], - message: [ - { - moderationDecision: { - decision: reportActions[key].message?.[0]?.moderationDecision?.decision, + const policies = createCollection( + (item) => `${ONYXKEYS.COLLECTION.POLICY}${item.id}`, + (index) => createRandomPolicy(index), + ); + + const allReportActions = Object.fromEntries( + Object.keys(reportActions).map((key) => [ + key, + [ + { + errors: reportActions[key].errors ?? [], + message: [ + { + moderationDecision: { + decision: reportActions[key].message?.[0]?.moderationDecision?.decision, + }, }, - }, - ], - }, - ], - ]), - ) as unknown as OnyxCollection; + ], + }, + ], + ]), + ) as unknown as OnyxCollection; - Onyx.multiSet({ - ...mockedResponseMap, + await waitForBatchedUpdates(); + await measureFunction(() => SidebarUtils.getOrderedReportIDs(currentReportId, allReports, betas, policies, CONST.PRIORITY_MODE.DEFAULT, allReportActions), {runs}); }); - - await waitForBatchedUpdates(); - await measureFunction(() => SidebarUtils.getOrderedReportIDs(currentReportId, allReports, betas, policies, CONST.PRIORITY_MODE.DEFAULT, allReportActions), {runs}); }); From 11942e755df07c08267359e036cf40b63d57c3b7 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Wed, 10 Jan 2024 16:13:05 +0700 Subject: [PATCH 30/57] migrate Error page to Typescript --- .../ErrorBodyText/{index.js => index.tsx} | 17 +++++++---------- .../{index.website.js => index.website.tsx} | 0 ...nericErrorPage.js => GenericErrorPage.tsx} | 17 +++++++---------- .../{NotFoundPage.js => NotFoundPage.tsx} | 19 +++++++------------ 4 files changed, 21 insertions(+), 32 deletions(-) rename src/pages/ErrorPage/ErrorBodyText/{index.js => index.tsx} (54%) rename src/pages/ErrorPage/ErrorBodyText/{index.website.js => index.website.tsx} (100%) rename src/pages/ErrorPage/{GenericErrorPage.js => GenericErrorPage.tsx} (91%) rename src/pages/ErrorPage/{NotFoundPage.js => NotFoundPage.tsx} (55%) diff --git a/src/pages/ErrorPage/ErrorBodyText/index.js b/src/pages/ErrorPage/ErrorBodyText/index.tsx similarity index 54% rename from src/pages/ErrorPage/ErrorBodyText/index.js rename to src/pages/ErrorPage/ErrorBodyText/index.tsx index 47b765f8f5e8..44c4f0ee2968 100644 --- a/src/pages/ErrorPage/ErrorBodyText/index.js +++ b/src/pages/ErrorPage/ErrorBodyText/index.tsx @@ -1,29 +1,26 @@ import React from 'react'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; -const propTypes = { - ...withLocalizePropTypes, -}; - -function ErrorBodyText(props) { +function ErrorBodyText() { const styles = useThemeStyles(); + const {translate} = useLocalize(); return ( - {`${props.translate('genericErrorPage.body.helpTextMobile')} `} + {`${translate('genericErrorPage.body.helpTextMobile')} `} - {props.translate('genericErrorPage.body.helpTextWeb')} + {translate('genericErrorPage.body.helpTextWeb')} ); } ErrorBodyText.displayName = 'ErrorBodyText'; -ErrorBodyText.propTypes = propTypes; -export default withLocalize(ErrorBodyText); + +export default ErrorBodyText; diff --git a/src/pages/ErrorPage/ErrorBodyText/index.website.js b/src/pages/ErrorPage/ErrorBodyText/index.website.tsx similarity index 100% rename from src/pages/ErrorPage/ErrorBodyText/index.website.js rename to src/pages/ErrorPage/ErrorBodyText/index.website.tsx diff --git a/src/pages/ErrorPage/GenericErrorPage.js b/src/pages/ErrorPage/GenericErrorPage.tsx similarity index 91% rename from src/pages/ErrorPage/GenericErrorPage.js rename to src/pages/ErrorPage/GenericErrorPage.tsx index 56fb5b970084..a05ef7954ba9 100644 --- a/src/pages/ErrorPage/GenericErrorPage.js +++ b/src/pages/ErrorPage/GenericErrorPage.tsx @@ -9,7 +9,7 @@ import ImageSVG from '@components/ImageSVG'; import SafeAreaConsumer from '@components/SafeAreaConsumer'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; -import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; +import useLocalize from '@hooks/useLocalize'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -18,20 +18,18 @@ import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; import ErrorBodyText from './ErrorBodyText'; -const propTypes = { - ...withLocalizePropTypes, -}; - -function GenericErrorPage({translate}) { +function GenericErrorPage() { const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); + const {translate} = useLocalize(); + const {resetBoundary} = useErrorBoundary(); return ( {({paddingBottom}) => ( - + @@ -78,7 +76,7 @@ function GenericErrorPage({translate}) { - + void; }; // eslint-disable-next-line rulesdir/no-negated-variables -function NotFoundPage(props) { +function NotFoundPage({onBackButtonPress = () => Navigation.goBack(ROUTES.HOME)}: NotFoundPageProps) { return ( Navigation.dismissModal()} /> ); } NotFoundPage.displayName = 'NotFoundPage'; -NotFoundPage.propTypes = propTypes; -NotFoundPage.defaultProps = defaultProps; export default NotFoundPage; From e35690c510c657e5fdd85a57b155171eb42c7134 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Wed, 10 Jan 2024 16:34:59 +0700 Subject: [PATCH 31/57] change style to styles --- src/pages/ErrorPage/GenericErrorPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/ErrorPage/GenericErrorPage.tsx b/src/pages/ErrorPage/GenericErrorPage.tsx index a05ef7954ba9..0d7fcca26954 100644 --- a/src/pages/ErrorPage/GenericErrorPage.tsx +++ b/src/pages/ErrorPage/GenericErrorPage.tsx @@ -76,7 +76,7 @@ function GenericErrorPage() { - + Date: Wed, 10 Jan 2024 17:06:21 +0700 Subject: [PATCH 32/57] remove unnecessary style --- src/pages/ErrorPage/GenericErrorPage.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/ErrorPage/GenericErrorPage.tsx b/src/pages/ErrorPage/GenericErrorPage.tsx index 0d7fcca26954..f4f1d91418c7 100644 --- a/src/pages/ErrorPage/GenericErrorPage.tsx +++ b/src/pages/ErrorPage/GenericErrorPage.tsx @@ -76,7 +76,7 @@ function GenericErrorPage() { - + Date: Wed, 10 Jan 2024 17:56:04 +0700 Subject: [PATCH 33/57] make some props as optional --- src/components/BlockingViews/FullPageNotFoundView.tsx | 4 ++-- src/pages/ErrorPage/ErrorBodyText/index.tsx | 1 + src/pages/ErrorPage/NotFoundPage.tsx | 5 +---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/src/components/BlockingViews/FullPageNotFoundView.tsx b/src/components/BlockingViews/FullPageNotFoundView.tsx index 5993e60861f5..807029addf5e 100644 --- a/src/components/BlockingViews/FullPageNotFoundView.tsx +++ b/src/components/BlockingViews/FullPageNotFoundView.tsx @@ -33,10 +33,10 @@ type FullPageNotFoundViewProps = { linkKey?: TranslationPaths; /** Method to trigger when pressing the back button of the header */ - onBackButtonPress: () => void; + onBackButtonPress?: () => void; /** Function to call when pressing the navigation link */ - onLinkPress: () => void; + onLinkPress?: () => void; }; // eslint-disable-next-line rulesdir/no-negated-variables diff --git a/src/pages/ErrorPage/ErrorBodyText/index.tsx b/src/pages/ErrorPage/ErrorBodyText/index.tsx index 44c4f0ee2968..d9ece1ccc35b 100644 --- a/src/pages/ErrorPage/ErrorBodyText/index.tsx +++ b/src/pages/ErrorPage/ErrorBodyText/index.tsx @@ -8,6 +8,7 @@ import CONST from '@src/CONST'; function ErrorBodyText() { const styles = useThemeStyles(); const {translate} = useLocalize(); + return ( {`${translate('genericErrorPage.body.helpTextMobile')} `} diff --git a/src/pages/ErrorPage/NotFoundPage.tsx b/src/pages/ErrorPage/NotFoundPage.tsx index 968b4865a7d8..a324b048119a 100644 --- a/src/pages/ErrorPage/NotFoundPage.tsx +++ b/src/pages/ErrorPage/NotFoundPage.tsx @@ -1,21 +1,18 @@ import React from 'react'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import ScreenWrapper from '@components/ScreenWrapper'; -import Navigation from '@libs/Navigation/Navigation'; -import ROUTES from '@src/ROUTES'; type NotFoundPageProps = { onBackButtonPress?: () => void; }; // eslint-disable-next-line rulesdir/no-negated-variables -function NotFoundPage({onBackButtonPress = () => Navigation.goBack(ROUTES.HOME)}: NotFoundPageProps) { +function NotFoundPage({onBackButtonPress}: NotFoundPageProps) { return ( Navigation.dismissModal()} /> ); From 6950bbb66297ddb9964cbe259469fb2ff02f7d2d Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Wed, 10 Jan 2024 17:57:46 +0700 Subject: [PATCH 34/57] fix lint --- src/pages/ErrorPage/ErrorBodyText/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/ErrorPage/ErrorBodyText/index.tsx b/src/pages/ErrorPage/ErrorBodyText/index.tsx index d9ece1ccc35b..e675e0447361 100644 --- a/src/pages/ErrorPage/ErrorBodyText/index.tsx +++ b/src/pages/ErrorPage/ErrorBodyText/index.tsx @@ -8,7 +8,7 @@ import CONST from '@src/CONST'; function ErrorBodyText() { const styles = useThemeStyles(); const {translate} = useLocalize(); - + return ( {`${translate('genericErrorPage.body.helpTextMobile')} `} From 9375d642e90f3a1811ff913cad87249f24425937 Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Thu, 11 Jan 2024 00:33:51 +0500 Subject: [PATCH 35/57] add comment for getReportFieldTitle function --- src/libs/ReportUtils.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index c8ce08276769..46e303fc1e90 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4316,6 +4316,10 @@ function navigateToPrivateNotes(report: Report, session: Session) { Navigation.navigate(ROUTES.PRIVATE_NOTES_LIST.getRoute(report.reportID)); } +/** + * Given a report field and a report, get the title of the field. + * This is specially useful when we have a report field of type formula. + */ function getReportFieldTitle(report: OnyxEntry, reportField: PolicyReportField) { const value = report?.reportFields?.[reportField.fieldID] ?? reportField.defaultValue; From bb8555a8f0bbbc905639022dced1dbe429012240 Mon Sep 17 00:00:00 2001 From: tienifr Date: Thu, 11 Jan 2024 16:50:07 +0700 Subject: [PATCH 36/57] fix: 33940 --- src/libs/actions/IOU.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index ac604019354b..e85f5d3423bd 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -945,6 +945,7 @@ function getUpdateMoneyRequestParams(transactionID, transactionThreadReportID, t const transaction = allTransactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`]; const iouReport = allReports[`${ONYXKEYS.COLLECTION.REPORT}${transactionThread.parentReportID}`]; const isFromExpenseReport = ReportUtils.isExpenseReport(iouReport); + const isScanning = TransactionUtils.hasReceipt(transaction) && TransactionUtils.isReceiptBeingScanned(transaction); const updatedTransaction = TransactionUtils.getUpdatedTransaction(transaction, transactionChanges, isFromExpenseReport); const transactionDetails = ReportUtils.getTransactionDetails(updatedTransaction); @@ -1030,6 +1031,30 @@ function getUpdateMoneyRequestParams(transactionID, transactionThreadReportID, t }, }); + if (isScanning && (_.has(transactionChanges, 'amount') || _.has(transactionChanges, 'currency'))) { + optimisticData.push( + ...[ + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.reportID}`, + value: { + [transactionThread.parentReportActionID]: { + whisperedToAccountIDs: [], + }, + }, + }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: `${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${iouReport.parentReportID}`, + value: { + [iouReport.parentReportActionID]: { + whisperedToAccountIDs: [], + }, + }, + }, + ], + ); + } // Update recently used categories if the category is changed if (_.has(transactionChanges, 'category')) { const optimisticPolicyRecentlyUsedCategories = Policy.buildOptimisticPolicyRecentlyUsedCategories(iouReport.policyID, transactionChanges.category); From 200140eb352489e8b78f1b65596143a1591684a3 Mon Sep 17 00:00:00 2001 From: Pavlo Tsimura Date: Thu, 11 Jan 2024 14:57:32 +0100 Subject: [PATCH 37/57] Show Join & Leave buttons on empty threads --- src/libs/ReportUtils.ts | 19 +++++++++++-- src/libs/actions/Report.ts | 2 +- src/pages/home/HeaderView.js | 4 +-- .../report/ContextMenu/ContextMenuActions.js | 28 ++++--------------- 4 files changed, 24 insertions(+), 29 deletions(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index e619cb3c80dd..545dbf664771 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -1095,13 +1095,25 @@ function getReportNotificationPreference(report: OnyxEntry): string | nu } /** - * Returns whether or not the author of the action is this user - * + * Checks if the current user is the action's author */ -function isActionCreator(reportAction: OnyxEntry): boolean { +function isActionCreator(reportAction: OnyxEntry | Partial): boolean { return reportAction?.actorAccountID === currentUserAccountID; } +/** + * Returns the notification preference of the action's child report if it exists. + * Otherwise, calculates it based on the action's authorship. + */ +function getChildReportNotificationPreference(reportAction: OnyxEntry | Partial): NotificationPreference { + const childReportNotificationPreference = reportAction?.childReportNotificationPreference ?? ''; + if (childReportNotificationPreference) { + return childReportNotificationPreference; + } + + return isActionCreator(reportAction) ? CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS : CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN; +} + /** * Can only delete if the author is this user and the action is an ADDCOMMENT action or an IOU action in an unsettled report, or if the user is a * policy admin @@ -4533,6 +4545,7 @@ export { shouldAutoFocusOnKeyPress, shouldDisplayThreadReplies, shouldDisableThread, + getChildReportNotificationPreference, }; export type {ExpenseOriginalMessage, OptionData, OptimisticChatReport, OptimisticCreatedReportAction}; diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index 55e91834a803..90ef14c96128 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -739,7 +739,7 @@ function navigateToAndOpenChildReport(childReportID = '0', parentReportAction: P '', undefined, undefined, - CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN, + ReportUtils.getChildReportNotificationPreference(parentReportAction), parentReportAction.reportActionID, parentReportID, ); diff --git a/src/pages/home/HeaderView.js b/src/pages/home/HeaderView.js index edf6b65b2f4a..2e6fbf61240d 100644 --- a/src/pages/home/HeaderView.js +++ b/src/pages/home/HeaderView.js @@ -109,9 +109,7 @@ function HeaderView(props) { const isAutomatedExpensifyAccount = ReportUtils.hasSingleParticipant(props.report) && ReportUtils.hasAutomatedExpensifyAccountIDs(participants); const parentReportAction = ReportActionsUtils.getParentReportAction(props.report); const isCanceledTaskReport = ReportUtils.isCanceledTaskReport(props.report, parentReportAction); - const lastVisibleMessage = ReportActionsUtils.getLastVisibleMessage(props.report.reportID); const isWhisperAction = ReportActionsUtils.isWhisperAction(parentReportAction); - const isEmptyChat = !props.report.lastMessageText && !props.report.lastMessageTranslationKey && !lastVisibleMessage.lastMessageText && !lastVisibleMessage.lastMessageTranslationKey; const isUserCreatedPolicyRoom = ReportUtils.isUserCreatedPolicyRoom(props.report); const isPolicyMember = useMemo(() => !_.isEmpty(props.policy), [props.policy]); const canLeaveRoom = ReportUtils.canLeaveRoom(props.report, isPolicyMember); @@ -153,7 +151,7 @@ function HeaderView(props) { ), ); - const canJoinOrLeave = (isChatThread && !isEmptyChat) || isUserCreatedPolicyRoom || canLeaveRoom; + const canJoinOrLeave = isChatThread || isUserCreatedPolicyRoom || canLeaveRoom; const canJoin = canJoinOrLeave && !isWhisperAction && props.report.notificationPreference === CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN; const canLeave = canJoinOrLeave && ((isChatThread && props.report.notificationPreference.length) || isUserCreatedPolicyRoom || canLeaveRoom); if (canJoin) { diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.js b/src/pages/home/report/ContextMenu/ContextMenuActions.js index f22eda58ce7f..eb48dafbe584 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.js +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.js @@ -156,14 +156,10 @@ export default [ successTextTranslateKey: '', successIcon: null, shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID) => { - let childReportNotificationPreference = lodashGet(reportAction, 'childReportNotificationPreference', ''); - if (!childReportNotificationPreference) { - const isActionCreator = ReportUtils.isActionCreator(reportAction); - childReportNotificationPreference = isActionCreator ? CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS : CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN; - } + const childReportNotificationPreference = ReportUtils.getChildReportNotificationPreference(reportAction); const isDeletedAction = ReportActionsUtils.isDeletedAction(reportAction); const shouldDisplayThreadReplies = ReportUtils.shouldDisplayThreadReplies(reportAction, reportID); - const subscribed = childReportNotificationPreference !== 'hidden'; + const subscribed = childReportNotificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN; const isCommentAction = reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT && !ReportUtils.isThreadFirstChat(reportAction, reportID); const isReportPreviewAction = reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.REPORTPREVIEW; const isIOUAction = reportAction.actionName === CONST.REPORT.ACTIONS.TYPE.IOU && !ReportActionsUtils.isSplitBillAction(reportAction); @@ -171,11 +167,7 @@ export default [ return !subscribed && !isWhisperAction && (isCommentAction || isReportPreviewAction || isIOUAction) && (!isDeletedAction || shouldDisplayThreadReplies); }, onPress: (closePopover, {reportAction, reportID}) => { - let childReportNotificationPreference = lodashGet(reportAction, 'childReportNotificationPreference', ''); - if (!childReportNotificationPreference) { - const isActionCreator = ReportUtils.isActionCreator(reportAction); - childReportNotificationPreference = isActionCreator ? CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS : CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN; - } + const childReportNotificationPreference = ReportUtils.getChildReportNotificationPreference(reportAction); if (closePopover) { hideContextMenu(false, () => { ReportActionComposeFocusManager.focus(); @@ -196,14 +188,10 @@ export default [ successTextTranslateKey: '', successIcon: null, shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID) => { - let childReportNotificationPreference = lodashGet(reportAction, 'childReportNotificationPreference', ''); - if (!childReportNotificationPreference) { - const isActionCreator = ReportUtils.isActionCreator(reportAction); - childReportNotificationPreference = isActionCreator ? CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS : CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN; - } + const childReportNotificationPreference = ReportUtils.getChildReportNotificationPreference(reportAction); const isDeletedAction = ReportActionsUtils.isDeletedAction(reportAction); const shouldDisplayThreadReplies = ReportUtils.shouldDisplayThreadReplies(reportAction, reportID); - const subscribed = childReportNotificationPreference !== 'hidden'; + const subscribed = childReportNotificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN; if (type !== CONST.CONTEXT_MENU_TYPES.REPORT_ACTION) { return false; } @@ -213,11 +201,7 @@ export default [ return subscribed && (isCommentAction || isReportPreviewAction || isIOUAction) && (!isDeletedAction || shouldDisplayThreadReplies); }, onPress: (closePopover, {reportAction, reportID}) => { - let childReportNotificationPreference = lodashGet(reportAction, 'childReportNotificationPreference', ''); - if (!childReportNotificationPreference) { - const isActionCreator = ReportUtils.isActionCreator(reportAction); - childReportNotificationPreference = isActionCreator ? CONST.REPORT.NOTIFICATION_PREFERENCE.ALWAYS : CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN; - } + const childReportNotificationPreference = ReportUtils.getChildReportNotificationPreference(reportAction); if (closePopover) { hideContextMenu(false, () => { ReportActionComposeFocusManager.focus(); From 4173cd0c2e8c765730c0b0be100ebf68ceb5d65e Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Thu, 11 Jan 2024 14:05:44 -0700 Subject: [PATCH 38/57] Load parent report action from withOnyx in ComposerWithSuggestions --- .../ComposerWithSuggestions/ComposerWithSuggestions.js | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js index 6c1d71625dc9..9d3c456b5e87 100644 --- a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js +++ b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js @@ -127,8 +127,8 @@ function ComposerWithSuggestions({ const maxComposerLines = isSmallScreenWidth ? CONST.COMPOSER.MAX_LINES_SMALL_SCREEN : CONST.COMPOSER.MAX_LINES; const isEmptyChat = useMemo(() => _.size(reportActions) === 1, [reportActions]); - const parentAction = ReportActionsUtils.getParentReportAction(report); - const shouldAutoFocus = !modal.isVisible && (shouldFocusInputOnScreenFocus || (isEmptyChat && !ReportActionsUtils.isTransactionThread(parentAction))) && shouldShowComposeInput; + const parentReportAction = lodashGet(parentReportActions, [report.parentReportActionID]); + const shouldAutoFocus = !modal.isVisible && (shouldFocusInputOnScreenFocus || (isEmptyChat && !ReportActionsUtils.isTransactionThread(parentReportAction))) && shouldShowComposeInput; const valueRef = useRef(value); valueRef.current = value; @@ -344,9 +344,6 @@ function ComposerWithSuggestions({ const valueLength = valueRef.current.length; if (e.key === CONST.KEYBOARD_SHORTCUTS.ARROW_UP.shortcutKey && textInputRef.current.selectionStart === 0 && valueLength === 0 && !ReportUtils.chatIncludesChronos(report)) { e.preventDefault(); - - const parentReportActionID = lodashGet(report, 'parentReportActionID', ''); - const parentReportAction = lodashGet(parentReportActions, [parentReportActionID], {}); const lastReportAction = _.find( [...reportActions, parentReportAction], (action) => ReportUtils.canEditReportAction(action) && !ReportActionsUtils.isMoneyRequestAction(action), From 6e6f0a2984b73e0f43bd13ecc9b6fb882581cb09 Mon Sep 17 00:00:00 2001 From: tienifr Date: Fri, 12 Jan 2024 11:22:46 +0700 Subject: [PATCH 39/57] fix: drag drop file safari --- src/hooks/useDragAndDrop.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index 8c9054dc0bf1..6e1121d76ba7 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -1,6 +1,6 @@ import {useIsFocused} from '@react-navigation/native'; import type React from 'react'; -import {useCallback, useContext, useEffect, useState} from 'react'; +import {useCallback, useContext, useEffect, useRef, useState} from 'react'; import type {View} from 'react-native'; import {PopoverContext} from '@components/PopoverProvider'; @@ -31,6 +31,8 @@ export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllow const [isDraggingOver, setIsDraggingOver] = useState(false); const {close: closePopover} = useContext(PopoverContext); + const enterTarget = useRef(null); + useEffect(() => { if (isFocused && !isDisabled) { return; @@ -76,6 +78,7 @@ export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllow break; case DRAG_ENTER_EVENT: handleDragEvent(event); + enterTarget.current=event.target if (isDraggingOver) { return; } @@ -86,7 +89,7 @@ export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllow return; } // This is necessary because dragging over children will cause dragleave to execute on the parent. - if ((event.currentTarget as HTMLElement | null)?.contains(event.relatedTarget as HTMLElement | null)) { + if (enterTarget.current !== event.target){ return; } From da54b6ca518c7ffbf499e5d4818b1c746e1dfbb5 Mon Sep 17 00:00:00 2001 From: Tim Golen Date: Fri, 12 Jan 2024 07:41:28 -0700 Subject: [PATCH 40/57] Fix hook dependencies --- .../ComposerWithSuggestions/ComposerWithSuggestions.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js index 9d3c456b5e87..413807b1f992 100644 --- a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js +++ b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js @@ -353,7 +353,7 @@ function ComposerWithSuggestions({ } } }, - [isKeyboardShown, isSmallScreenWidth, parentReportActions, report, reportActions, reportID, handleSendMessage, suggestionsRef, valueRef], + [isKeyboardShown, isSmallScreenWidth, parentReportAction, report, reportActions, reportID, handleSendMessage, suggestionsRef, valueRef], ); const onChangeText = useCallback( From 2327a35c044d0cb8733abf7a2cd9b50653c5833a Mon Sep 17 00:00:00 2001 From: Sibtain Ali Date: Sun, 14 Jan 2024 19:56:09 +0500 Subject: [PATCH 41/57] feat: add report type to getReportFieldTitle fn --- src/libs/ReportUtils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 46e303fc1e90..0e4caed68a5e 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4320,7 +4320,7 @@ function navigateToPrivateNotes(report: Report, session: Session) { * Given a report field and a report, get the title of the field. * This is specially useful when we have a report field of type formula. */ -function getReportFieldTitle(report: OnyxEntry, reportField: PolicyReportField) { +function getReportFieldTitle(report: OnyxEntry, reportField: PolicyReportField): string { const value = report?.reportFields?.[reportField.fieldID] ?? reportField.defaultValue; if (reportField.type !== 'formula') { From 7b40424e63103acab9dd8dd99c1dc9e3fd577142 Mon Sep 17 00:00:00 2001 From: tienifr Date: Mon, 15 Jan 2024 14:38:00 +0700 Subject: [PATCH 42/57] lint fix --- src/hooks/useDragAndDrop.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hooks/useDragAndDrop.ts b/src/hooks/useDragAndDrop.ts index 6e1121d76ba7..7644d7bba5f0 100644 --- a/src/hooks/useDragAndDrop.ts +++ b/src/hooks/useDragAndDrop.ts @@ -78,7 +78,7 @@ export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllow break; case DRAG_ENTER_EVENT: handleDragEvent(event); - enterTarget.current=event.target + enterTarget.current = event.target; if (isDraggingOver) { return; } @@ -89,7 +89,7 @@ export default function useDragAndDrop({dropZone, onDrop = () => {}, shouldAllow return; } // This is necessary because dragging over children will cause dragleave to execute on the parent. - if (enterTarget.current !== event.target){ + if (enterTarget.current !== event.target) { return; } From 526129ff9c645f04584812f856e6249388e721e6 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Mon, 15 Jan 2024 12:38:26 +0000 Subject: [PATCH 43/57] Update version to 1.4.25-1 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 18ef2984f67a..4088f69cf008 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -98,8 +98,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001042500 - versionName "1.4.25-0" + versionCode 1001042501 + versionName "1.4.25-1" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index b4056989a1c4..813c136f3c2c 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.25.0 + 1.4.25.1 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 4f75315fb1ec..dfa278adacc5 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.25.0 + 1.4.25.1 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index a0328855047b..73420efed711 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -5,7 +5,7 @@ CFBundleShortVersionString 1.4.25 CFBundleVersion - 1.4.25.0 + 1.4.25.1 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 0acbc00bf99d..b530468d7725 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.25-0", + "version": "1.4.25-1", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.25-0", + "version": "1.4.25-1", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 8682d4ad7385..a5823e18e357 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.25-0", + "version": "1.4.25-1", "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.", From 8bad243151aa4a9a9147a5219be87ca56d7ba929 Mon Sep 17 00:00:00 2001 From: Bernhard Owen Josephus Date: Mon, 15 Jan 2024 20:46:01 +0800 Subject: [PATCH 44/57] includes parent action actor account ID --- src/components/LHNOptionsList/LHNOptionsList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/LHNOptionsList/LHNOptionsList.js b/src/components/LHNOptionsList/LHNOptionsList.js index 71b14b6fadcd..6bb4973d0c64 100644 --- a/src/components/LHNOptionsList/LHNOptionsList.js +++ b/src/components/LHNOptionsList/LHNOptionsList.js @@ -118,7 +118,7 @@ function LHNOptionsList({ const transactionID = lodashGet(itemParentReportAction, ['originalMessage', 'IOUTransactionID'], ''); const itemTransaction = transactionID ? transactions[`${ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`] : {}; const itemComment = draftComments[`${ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT}${reportID}`] || ''; - const participants = [...ReportUtils.getParticipantsIDs(itemFullReport), itemFullReport.ownerAccountID]; + const participants = [...ReportUtils.getParticipantsIDs(itemFullReport), itemFullReport.ownerAccountID, itemParentReportAction.actorAccountID]; const participantsPersonalDetails = OptionsListUtils.getPersonalDetailsForAccountIDs(participants, personalDetails); From 497ed9273d99afd1cdb061acb78014e15ffdefe8 Mon Sep 17 00:00:00 2001 From: Rodrigo Lino da Costa Date: Mon, 15 Jan 2024 10:25:29 -0300 Subject: [PATCH 45/57] Better comment regarding eslint-disable for transactions --- src/components/ReportActionItem/ReportPreview.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/ReportActionItem/ReportPreview.js b/src/components/ReportActionItem/ReportPreview.js index 9c2e9916730c..843581ef3e22 100644 --- a/src/components/ReportActionItem/ReportPreview.js +++ b/src/components/ReportActionItem/ReportPreview.js @@ -142,7 +142,8 @@ function ReportPreview(props) { hasOnlyDistanceRequests: ReportUtils.hasOnlyDistanceRequestTransactions(props.iouReportID), hasNonReimbursableTransactions: ReportUtils.hasNonReimbursableTransactions(props.iouReportID), }), - // eslint-disable-next-line react-hooks/exhaustive-deps -- we just want this to run when transactions get updated + // When transactions get updated these status may have changed, so that is a case where we also want to run this. + // eslint-disable-next-line react-hooks/exhaustive-deps [props.transactions, props.iouReportID, props.action], ); From 681967ec3e1d127c58269f2d6474534a685d4e8a Mon Sep 17 00:00:00 2001 From: Vit Horacek Date: Mon, 15 Jan 2024 13:55:33 +0000 Subject: [PATCH 46/57] Fix some new occurrences --- src/libs/actions/IOU.js | 7 +++---- src/pages/home/ReportScreen.js | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index 0f0395416187..d6aabb30eb5d 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -3353,9 +3353,8 @@ function cancelPayment(expenseReport, chatReport) { ...expenseReport, lastMessageText: lodashGet(optimisticReportAction, 'message.0.text', ''), lastMessageHtml: lodashGet(optimisticReportAction, 'message.0.html', ''), - state: isFree ? CONST.REPORT.STATE.SUBMITTED : CONST.REPORT.STATE.OPEN, - stateNum: isFree ? CONST.REPORT.STATE_NUM.PROCESSING : CONST.REPORT.STATE.OPEN, - statusNum: isFree ? CONST.REPORT.STATUS.SUBMITTED : CONST.REPORT.STATE.OPEN, + stateNum: isFree ? CONST.REPORT.STATE_NUM.SUBMITTED : CONST.REPORT.STATE_NUM.OPEN, + statusNum: isFree ? CONST.REPORT.STATUS_NUM.SUBMITTED : CONST.REPORT.STATUS_NUM.OPEN, }, }, ...(chatReport.reportID @@ -3400,7 +3399,7 @@ function cancelPayment(expenseReport, chatReport) { onyxMethod: Onyx.METHOD.MERGE, key: `${ONYXKEYS.COLLECTION.REPORT}${expenseReport.reportID}`, value: { - statusNum: CONST.REPORT.STATUS.REIMBURSED, + statusNum: CONST.REPORT.STATUS_NUM.REIMBURSED, }, }, ...(chatReport.reportID diff --git a/src/pages/home/ReportScreen.js b/src/pages/home/ReportScreen.js index 5d9dac033a6b..b35d9240f3f7 100644 --- a/src/pages/home/ReportScreen.js +++ b/src/pages/home/ReportScreen.js @@ -187,7 +187,6 @@ function ReportScreen({ // There are no reportActions at all to display and we are still in the process of loading the next set of actions. const isLoadingInitialReportActions = _.isEmpty(reportActions) && reportMetadata.isLoadingInitialReportActions; - const isOptimisticDelete = lodashGet(report, 'statusNum') === CONST.REPORT.STATUS_NUM.CLOSED; const shouldHideReport = !ReportUtils.canAccessReport(report, policies, betas); const isLoading = !reportID || !isSidebarLoaded || _.isEmpty(personalDetails); From af11e7eac707114ac9095d6b945748df40290a37 Mon Sep 17 00:00:00 2001 From: ImgBotApp Date: Mon, 15 Jan 2024 15:12:01 +0000 Subject: [PATCH 47/57] [ImgBot] Optimize images *Total -- 921.81kb -> 875.33kb (5.04%) /android/app/src/main/res/drawable/ic_launcher_monochrome.png -- 2.14kb -> 1.61kb (24.9%) /assets/images/simple-illustrations/simple-illustration__commentbubbles.svg -- 1.66kb -> 1.50kb (9.77%) /assets/images/thumbs-up.svg -- 0.80kb -> 0.75kb (6.72%) /assets/images/simple-illustrations/simple-illustration__handcard.svg -- 2.95kb -> 2.76kb (6.3%) /assets/images/simple-illustrations/simple-illustration__mailbox.svg -- 3.93kb -> 3.71kb (5.61%) /assets/images/simple-illustrations/simple-illustration__trashcan.svg -- 3.60kb -> 3.41kb (5.48%) /assets/images/home-background--mobile-new.svg -- 826.24kb -> 782.62kb (5.28%) /assets/images/simple-illustrations/simple-illustration__hourglass.svg -- 4.43kb -> 4.24kb (4.49%) /assets/images/product-illustrations/telescope.svg -- 5.53kb -> 5.30kb (4.08%) /assets/images/simple-illustrations/simple-illustration__hotdogstand.svg -- 16.58kb -> 16.04kb (3.26%) /assets/images/simple-illustrations/simple-illustration__smallrocket.svg -- 8.86kb -> 8.62kb (2.74%) /assets/images/simple-illustrations/simple-illustration__bigrocket.svg -- 20.64kb -> 20.40kb (1.15%) /docs/assets/images/send-money.svg -- 3.94kb -> 3.91kb (0.62%) /assets/images/signIn/google-logo.svg -- 1.17kb -> 1.17kb (0.42%) /docs/assets/images/subscription-annual.svg -- 9.39kb -> 9.37kb (0.24%) /assets/images/new-expensify.svg -- 1.46kb -> 1.46kb (0.07%) /assets/images/expensify-logo--dev.svg -- 2.52kb -> 2.52kb (0.04%) /assets/images/expensify-logo--staging.svg -- 2.83kb -> 2.83kb (0.03%) /assets/images/expensify-logo--adhoc.svg -- 3.12kb -> 3.12kb (0.03%) Signed-off-by: ImgBotApp --- .../res/drawable/ic_launcher_monochrome.png | Bin 2193 -> 1647 bytes assets/images/expensify-logo--adhoc.svg | 2 +- assets/images/expensify-logo--dev.svg | 2 +- assets/images/expensify-logo--staging.svg | 2 +- assets/images/home-background--mobile-new.svg | 8836 +---------------- assets/images/new-expensify.svg | 2 +- .../product-illustrations/telescope.svg | 80 +- assets/images/signIn/google-logo.svg | 2 +- .../simple-illustration__bigrocket.svg | 101 +- .../simple-illustration__commentbubbles.svg | 23 +- .../simple-illustration__handcard.svg | 42 +- .../simple-illustration__hotdogstand.svg | 99 +- .../simple-illustration__hourglass.svg | 57 +- .../simple-illustration__mailbox.svg | 72 +- .../simple-illustration__smallrocket.svg | 46 +- .../simple-illustration__trashcan.svg | 53 +- assets/images/thumbs-up.svg | 9 +- docs/assets/images/send-money.svg | 26 +- docs/assets/images/subscription-annual.svg | 24 +- 19 files changed, 18 insertions(+), 9460 deletions(-) diff --git a/android/app/src/main/res/drawable/ic_launcher_monochrome.png b/android/app/src/main/res/drawable/ic_launcher_monochrome.png index b1a286b6f8dd2be8cc1a884e9768b3322554812c..0af99b087923431eb40190d69a81686dfc364f51 100644 GIT binary patch delta 1540 zcmV+f2K)Ju5$_C;8BzoQ001K? zfP?@5`Tzg`fam}Kbua(`>RI+y?e7jT@qQ9J+u00Lr5M??VshmXv^ks%mU2XskI zMF;2s4-W_sjq=y{000GINklcN^r@t5c&= zxo&jT-lCi;^?&q)v|f#JrF7o5WV*j8>btm#5x32#y2~$8_1L`bjJ7q$RToXwV{4Vs zxv_C8$@&^=j!up@viz#DkamJFIGv0zr!7b@s!e76-zuc79|*l#)hgtaDgD!K%9N{6 zt?qxV+W>;&YGbQYtz1dqr)H{yLu`eHP|~2$(5VO%_5Jh1a!!;5hQi@RM-D1ys`^*k ztDwtV_L7g6<0_AQfA>rpGuaF7FH(VZDiYJua+Exyc^U?bl`AQpkQh%_6JgGJJ*R#C z^Q|RPrm3Ect?dHS<2b94GH34UHV;dgoZNo~Bl?oMxXKSmKB=pqbBx(abv?8y=3X|H=h+uzs zeEHxT(tU&_qZ=2T-SHLv)Atc3l~%`Cw(y7VC2agcGmtB`3q#9(!g7nbV!Al6>?dse zyKmPPRxX~p_Y~$%Q=3^a;dpoA-cy)Ha>e1wx^59t<9&sdwi1sz!rs5`=~mP7&Gzo) zlGxgL(nrX$x`^Xt4xOF5u{27pU~hk6g`FM3d6b{Jx3I)ciK>ax!FvlE3+&A`h4oRU z>-~k*R%Wp{3Gx2I#zK2y;~p$IrLe?Cfhvy_NcI;tRLefE6e|ll=w8HX{q8O#A8Nvp2L2YT}&qQfz zi{kHA-DaZr`+a%k$7zLi7M54sg%&Ue3y;rUXNy2;V~ao%>9Ou(Zo;`F*WKpUUsG7k zM$)sV9dl-}y@jQAPV7jc90h;2w=ievxb$m2Zq)0tlo5jBz7O=JwjSuqB0SW+?<2E~ zwQ~gg;+3R*g?S4LE3blLb{b&@k9|m1IoxC`VJ2Uwv-EV&{e+E;uOGTR+2}(IXAoxe zaIo<%FAgv4!|oB6Zgg=!Ikd2J;VF-oOYXxD7T-r$WBCZ#sY8#m!wP>}a;Wr$=P`d+ zVg15H$@CaYBEM>2-o2y27n;_m2{OhCzSGyOKg~kmF#FKi2z&Jo8neAv`pVZxeMZeVd;+eG!6hQm6O!#+8;oS+4Pj zST5{WN8TgMX^HNm@3l1g;@_p6IRq>{x|!M%6+z3O4iVuLfh)$nD&>JGc%ocY@QO7l z$J?`uf9q_UPL&Gf%5-~JPtN32s8ajpr)3D3b1zm$-MkC3HntbYx+4WjbSWWnpw> z05UK#G%YYOEipAzF*Q0cG&(RhD=;uRFfcYuuWkSU03~!qSaf7zbY(hiZ)9m^c>ppn qGBhnPF)cAQR53L=Ff=+aH!CnOIxsLt5f{<`0000A>L|k|V_zL*M}+#16;5wJ2@>ud%RXn&|$R^2t$rDUBVNx;mk z^TK-LY6_NXk{xRj24fs-xO_-=nx??@I*wO;IsJYfK<=N&d-EuzQ+lnx4^Wrhw;vDb zqksuaQERn_^g+i#=Npw{pOsIa-Ky+9zZXzgQn>+QEAa1BHlRHF->6)$5o9PPAJQMX zu0Yz~?=){vJ%1nlBt! zxjT(-3cgdl8ue#LxZd4jtpQnNq@t-r|o_#3xLbe;Nn>pK3T_m zHftRuVUvdR7!q7QNl(vrycIU3(Xe|iW-a)<)FQ~jCL|4O8q%TR)9B^z(Y|xK`8Qxl z({LwvwYvO$Zf=>&)>bqp9j~Mw`$PJ-u9vi4=f`fBU;&mL`RqI03n6(IO>QMF6WHGi1oKkm?TJfqiOjWZv$S9w1>^U-Br zu};g@UdDSRk5+>jPmkgs3M_IBW=)Ue$Vcrpou3?e&d<>g>7Rfx@zf(|An}|ui-l?f;2uQy=@+1X)v_RAV z^M7{z?uDs+bmq$nC~AQH$B}2R>F+^sTyJ*o$oDS=wB;J?cVRBSIr3x$wB-Q%MVQOp zktZqOGdm&%nD_q6(`-Q*duP6+U?K)sa^&e%?pYML%)aa1kuTi5#I4p~y)ZXViyS=@fYgx&WhXAX9XHsd>`dM(5c!lj+B!5Sq zUcp3cBKD3vNtoMfM;_0`u_{{)FweDEIZ;`dOLpW5`4FP0<6xfW@NpkDAJ0QY39yQIYcTG^rkCVvB6^--U!AA{ z_KP!LBTOwj^HGCU#Csp+d4@f%^M7AQ9y?dP0*d?sK5KGZYMNvnn~7_jqLU73r)l-_ zzx`y4Bwr2Yxo5`8Wcglnx6`!7zJM>nJDTsD`{C`z$I5hC{w3V4G^+4N2(Zqv51j&w zzFfug2FuVd;a*T9-<(h0GFmYUo~5tktu(rZsksL0ocoXzSo9jqIxqH)e1BQgVkI^5 z1&(z@^+MIMd{@%Xnno*)s$FWX!8+&mvk-z6B+m(dr}DhpjuK#Ro!jn&FdF$zy7efQ zo<7w|qY8hG0hZ*iy&54D?}>k}vRY|W;jb~k?ws50gmAL_1uv_dRvK0KYYVVuz;+uU zBr8yJUtzu5tUbU!JGVJiXMfTveWz{7@)s(5qSId2yV1Ir#q_$K9iMkb%=e;eKC};_ z8Bqe8YquD){ z?Te==_*`lQ6n0+o^ndlrWQDWQyuo(v`D}Il{(lt{cQFwwq+bgryO*)9Z)>WR?Ebzv zeWrbOsh~Qio#4h?#No~bH>te-lEQ+AukL`?`5*RDV`{~#g|GsRhK(cD5Lj8j$~3Aw&|X>*Sg1hOaWXK01xzUE z*sa}Zok3;$M&|`Wu+9SOja#x)Vfc!W;_ILogKm9xpPT!vrlhFkwli&pwk?;l=2 diff --git a/assets/images/expensify-logo--adhoc.svg b/assets/images/expensify-logo--adhoc.svg index 273002deca9b..52b381dc4b78 100644 --- a/assets/images/expensify-logo--adhoc.svg +++ b/assets/images/expensify-logo--adhoc.svg @@ -1 +1 @@ - + \ No newline at end of file diff --git a/assets/images/expensify-logo--dev.svg b/assets/images/expensify-logo--dev.svg index e8e3fb5033d9..2c9ae142e283 100644 --- a/assets/images/expensify-logo--dev.svg +++ b/assets/images/expensify-logo--dev.svg @@ -1 +1 @@ - + \ No newline at end of file diff --git a/assets/images/expensify-logo--staging.svg b/assets/images/expensify-logo--staging.svg index 78dcc1581f99..a1e7482c133b 100644 --- a/assets/images/expensify-logo--staging.svg +++ b/assets/images/expensify-logo--staging.svg @@ -1 +1 @@ - + \ No newline at end of file diff --git a/assets/images/home-background--mobile-new.svg b/assets/images/home-background--mobile-new.svg index 0da937cae059..d81f2a18cc78 100644 --- a/assets/images/home-background--mobile-new.svg +++ b/assets/images/home-background--mobile-new.svg @@ -1,8835 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/assets/images/new-expensify.svg b/assets/images/new-expensify.svg index 89102ecbc5e4..7bfef1fd38b4 100644 --- a/assets/images/new-expensify.svg +++ b/assets/images/new-expensify.svg @@ -1 +1 @@ - + \ No newline at end of file diff --git a/assets/images/product-illustrations/telescope.svg b/assets/images/product-illustrations/telescope.svg index 95617c801789..1830dff0fe3c 100644 --- a/assets/images/product-illustrations/telescope.svg +++ b/assets/images/product-illustrations/telescope.svg @@ -1,79 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/assets/images/signIn/google-logo.svg b/assets/images/signIn/google-logo.svg index 4fbdc804a0a2..169ea34b23ee 100644 --- a/assets/images/signIn/google-logo.svg +++ b/assets/images/signIn/google-logo.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/assets/images/simple-illustrations/simple-illustration__bigrocket.svg b/assets/images/simple-illustrations/simple-illustration__bigrocket.svg index 1afd5f66b6ea..64d6dc2200f0 100644 --- a/assets/images/simple-illustrations/simple-illustration__bigrocket.svg +++ b/assets/images/simple-illustrations/simple-illustration__bigrocket.svg @@ -1,100 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/assets/images/simple-illustrations/simple-illustration__commentbubbles.svg b/assets/images/simple-illustrations/simple-illustration__commentbubbles.svg index 829d3ee2e3fe..ab9d3ae4db70 100644 --- a/assets/images/simple-illustrations/simple-illustration__commentbubbles.svg +++ b/assets/images/simple-illustrations/simple-illustration__commentbubbles.svg @@ -1,22 +1 @@ - - - - - - - - - - - - + \ No newline at end of file diff --git a/assets/images/simple-illustrations/simple-illustration__handcard.svg b/assets/images/simple-illustrations/simple-illustration__handcard.svg index 7419b33d425c..a49e0ee5b77f 100644 --- a/assets/images/simple-illustrations/simple-illustration__handcard.svg +++ b/assets/images/simple-illustrations/simple-illustration__handcard.svg @@ -1,41 +1 @@ - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/assets/images/simple-illustrations/simple-illustration__hotdogstand.svg b/assets/images/simple-illustrations/simple-illustration__hotdogstand.svg index 471b978bb97e..5b5e12a99a9b 100644 --- a/assets/images/simple-illustrations/simple-illustration__hotdogstand.svg +++ b/assets/images/simple-illustrations/simple-illustration__hotdogstand.svg @@ -1,98 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/assets/images/simple-illustrations/simple-illustration__hourglass.svg b/assets/images/simple-illustrations/simple-illustration__hourglass.svg index 539e1e45b795..683e74a657e8 100644 --- a/assets/images/simple-illustrations/simple-illustration__hourglass.svg +++ b/assets/images/simple-illustrations/simple-illustration__hourglass.svg @@ -1,56 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/assets/images/simple-illustrations/simple-illustration__mailbox.svg b/assets/images/simple-illustrations/simple-illustration__mailbox.svg index 81b1f508fb52..7af7c71e24f3 100644 --- a/assets/images/simple-illustrations/simple-illustration__mailbox.svg +++ b/assets/images/simple-illustrations/simple-illustration__mailbox.svg @@ -1,71 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/assets/images/simple-illustrations/simple-illustration__smallrocket.svg b/assets/images/simple-illustrations/simple-illustration__smallrocket.svg index 0f8f166c849f..388bb968a762 100644 --- a/assets/images/simple-illustrations/simple-illustration__smallrocket.svg +++ b/assets/images/simple-illustrations/simple-illustration__smallrocket.svg @@ -1,45 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/assets/images/simple-illustrations/simple-illustration__trashcan.svg b/assets/images/simple-illustrations/simple-illustration__trashcan.svg index 4e66efa0a67e..66cc9ee27550 100644 --- a/assets/images/simple-illustrations/simple-illustration__trashcan.svg +++ b/assets/images/simple-illustrations/simple-illustration__trashcan.svg @@ -1,52 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/assets/images/thumbs-up.svg b/assets/images/thumbs-up.svg index ef81c88fc854..3e2a4a5125b6 100644 --- a/assets/images/thumbs-up.svg +++ b/assets/images/thumbs-up.svg @@ -1,8 +1 @@ - - - - - + \ No newline at end of file diff --git a/docs/assets/images/send-money.svg b/docs/assets/images/send-money.svg index e858f0d5c327..7abce818f09e 100644 --- a/docs/assets/images/send-money.svg +++ b/docs/assets/images/send-money.svg @@ -1,25 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/docs/assets/images/subscription-annual.svg b/docs/assets/images/subscription-annual.svg index a4b99a43b16e..f74ce086b2c7 100644 --- a/docs/assets/images/subscription-annual.svg +++ b/docs/assets/images/subscription-annual.svg @@ -1,23 +1 @@ - - - - - - - - - - - - - - - - - - - - - - - + \ No newline at end of file From bf703f7aa926c8f578d3c541d3b8114fe56b4c42 Mon Sep 17 00:00:00 2001 From: situchan Date: Mon, 15 Jan 2024 22:30:20 +0600 Subject: [PATCH 48/57] re-downgrade react-native-pdf version --- ios/Podfile.lock | 4 ++-- package-lock.json | 14 +++++++------- package.json | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 379194a70fd9..f433c4f1e1e2 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -1180,7 +1180,7 @@ PODS: - React-Core - react-native-pager-view (6.2.2): - React-Core - - react-native-pdf (6.7.4): + - react-native-pdf (6.7.3): - React-Core - react-native-performance (5.1.0): - React-Core @@ -1911,7 +1911,7 @@ SPEC CHECKSUMS: react-native-key-command: 5af6ee30ff4932f78da6a2109017549042932aa5 react-native-netinfo: 8a7fd3f7130ef4ad2fb4276d5c9f8d3f28d2df3d react-native-pager-view: 02a5c4962530f7efc10dd51ee9cdabeff5e6c631 - react-native-pdf: 79aa75e39a80c1d45ffe58aa500f3cf08f267a2e + react-native-pdf: b4ca3d37a9a86d9165287741c8b2ef4d8940c00e react-native-performance: cef2b618d47b277fb5c3280b81a3aad1e72f2886 react-native-plaid-link-sdk: df1618a85a615d62ff34e34b76abb7a56497fbc1 react-native-quick-sqlite: bcc7a7a250a40222f18913a97cd356bf82d0a6c4 diff --git a/package-lock.json b/package-lock.json index b530468d7725..f7e5d3453a5f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -96,7 +96,7 @@ "react-native-modal": "^13.0.0", "react-native-onyx": "1.0.126", "react-native-pager-view": "6.2.2", - "react-native-pdf": "^6.7.4", + "react-native-pdf": "6.7.3", "react-native-performance": "^5.1.0", "react-native-permissions": "^3.9.3", "react-native-picker-select": "git+https://github.com/Expensify/react-native-picker-select.git#7a407cd4174d9838a944c1c2e1cb4a9737ac69c5", @@ -47079,9 +47079,9 @@ } }, "node_modules/react-native-pdf": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/react-native-pdf/-/react-native-pdf-6.7.4.tgz", - "integrity": "sha512-sBeNcsrTRnLjmiU9Wx7Uk0K2kPSQtKIIG+FECdrEG16TOdtmQ3iqqEwt0dmy0pJegpg07uES5BXqiKsKkRUIFw==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/react-native-pdf/-/react-native-pdf-6.7.3.tgz", + "integrity": "sha512-bK1fVkj18kBA5YlRFNJ3/vJ1bEX3FDHyAPY6ArtIdVs+vv0HzcK5WH9LSd2bxUsEMIyY9CSjP4j8BcxNXTiQkQ==", "dependencies": { "crypto-js": "4.2.0", "deprecated-react-native-prop-types": "^2.3.0" @@ -89718,9 +89718,9 @@ "requires": {} }, "react-native-pdf": { - "version": "6.7.4", - "resolved": "https://registry.npmjs.org/react-native-pdf/-/react-native-pdf-6.7.4.tgz", - "integrity": "sha512-sBeNcsrTRnLjmiU9Wx7Uk0K2kPSQtKIIG+FECdrEG16TOdtmQ3iqqEwt0dmy0pJegpg07uES5BXqiKsKkRUIFw==", + "version": "6.7.3", + "resolved": "https://registry.npmjs.org/react-native-pdf/-/react-native-pdf-6.7.3.tgz", + "integrity": "sha512-bK1fVkj18kBA5YlRFNJ3/vJ1bEX3FDHyAPY6ArtIdVs+vv0HzcK5WH9LSd2bxUsEMIyY9CSjP4j8BcxNXTiQkQ==", "requires": { "crypto-js": "4.2.0", "deprecated-react-native-prop-types": "^2.3.0" diff --git a/package.json b/package.json index a5823e18e357..b13875990d41 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,7 @@ "react-native-modal": "^13.0.0", "react-native-onyx": "1.0.126", "react-native-pager-view": "6.2.2", - "react-native-pdf": "^6.7.4", + "react-native-pdf": "6.7.3", "react-native-performance": "^5.1.0", "react-native-permissions": "^3.9.3", "react-native-picker-select": "git+https://github.com/Expensify/react-native-picker-select.git#7a407cd4174d9838a944c1c2e1cb4a9737ac69c5", From d17214de01e757aa586dd4c55de24a886c86d4bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Mon, 15 Jan 2024 17:33:19 +0100 Subject: [PATCH 49/57] replaced referall cta with new component --- .../ReferralProgramCTA.tsx} | 20 +++++---- src/pages/SearchPage/SearchPageFooter.tsx | 44 +------------------ ...yForRefactorRequestParticipantsSelector.js | 4 +- .../MoneyRequestParticipantsSelector.js | 4 +- 4 files changed, 18 insertions(+), 54 deletions(-) rename src/{pages/iou/MoneyRequestReferralProgramCTA.tsx => components/ReferralProgramCTA.tsx} (71%) diff --git a/src/pages/iou/MoneyRequestReferralProgramCTA.tsx b/src/components/ReferralProgramCTA.tsx similarity index 71% rename from src/pages/iou/MoneyRequestReferralProgramCTA.tsx rename to src/components/ReferralProgramCTA.tsx index 31394e1bd0e1..e77d30da8487 100644 --- a/src/pages/iou/MoneyRequestReferralProgramCTA.tsx +++ b/src/components/ReferralProgramCTA.tsx @@ -1,20 +1,23 @@ import React from 'react'; -import Icon from '@components/Icon'; -import {Info} from '@components/Icon/Expensicons'; -import {PressableWithoutFeedback} from '@components/Pressable'; -import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; import Navigation from '@src/libs/Navigation/Navigation'; import ROUTES from '@src/ROUTES'; +import Icon from './Icon'; +import {Info} from './Icon/Expensicons'; +import {PressableWithoutFeedback} from './Pressable'; +import Text from './Text'; -type MoneyRequestReferralProgramCTAProps = { - referralContentType: typeof CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SEND_MONEY | typeof CONST.REFERRAL_PROGRAM.CONTENT_TYPES.MONEY_REQUEST; +type ReferralProgramCTAProps = { + referralContentType: + | typeof CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SEND_MONEY + | typeof CONST.REFERRAL_PROGRAM.CONTENT_TYPES.MONEY_REQUEST + | typeof CONST.REFERRAL_PROGRAM.CONTENT_TYPES.REFER_FRIEND; }; -function MoneyRequestReferralProgramCTA({referralContentType}: MoneyRequestReferralProgramCTAProps) { +function ReferralProgramCTA({referralContentType}: ReferralProgramCTAProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); const theme = useTheme(); @@ -41,9 +44,10 @@ function MoneyRequestReferralProgramCTA({referralContentType}: MoneyRequestRefer src={Info} height={20} width={20} + fill={theme.icon} /> ); } -export default MoneyRequestReferralProgramCTA; +export default ReferralProgramCTA; diff --git a/src/pages/SearchPage/SearchPageFooter.tsx b/src/pages/SearchPage/SearchPageFooter.tsx index 69429962869b..e0ef67ad9ec3 100644 --- a/src/pages/SearchPage/SearchPageFooter.tsx +++ b/src/pages/SearchPage/SearchPageFooter.tsx @@ -1,55 +1,15 @@ import React from 'react'; import {View} from 'react-native'; -import Icon from '@components/Icon'; -import {Info} from '@components/Icon/Expensicons'; -import {PressableWithoutFeedback} from '@components/Pressable'; -import Text from '@components/Text'; -import useLocalize from '@hooks/useLocalize'; -import useTheme from '@hooks/useTheme'; +import ReferralProgramCTA from '@components/ReferralProgramCTA'; import useThemeStyles from '@hooks/useThemeStyles'; -import Navigation from '@libs/Navigation/Navigation'; import CONST from '@src/CONST'; -import ROUTES from '@src/ROUTES'; function SearchPageFooter() { const themeStyles = useThemeStyles(); - const theme = useTheme(); - const {translate} = useLocalize(); return ( - { - Navigation.navigate(ROUTES.REFERRAL_DETAILS_MODAL.getRoute(CONST.REFERRAL_PROGRAM.CONTENT_TYPES.REFER_FRIEND)); - }} - style={[ - themeStyles.p5, - themeStyles.w100, - themeStyles.br2, - themeStyles.highlightBG, - themeStyles.flexRow, - themeStyles.justifyContentBetween, - themeStyles.alignItemsCenter, - {gap: 10}, - ]} - accessibilityLabel="referral" - role={CONST.ACCESSIBILITY_ROLE.BUTTON} - > - - {translate(`referralProgram.${CONST.REFERRAL_PROGRAM.CONTENT_TYPES.REFER_FRIEND}.buttonText1`)} - - {translate(`referralProgram.${CONST.REFERRAL_PROGRAM.CONTENT_TYPES.REFER_FRIEND}.buttonText2`)} - - - - + ); } diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index 68e9f68a2bc5..f8c412993bab 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -8,6 +8,7 @@ import Button from '@components/Button'; import FormHelpMessage from '@components/FormHelpMessage'; import {usePersonalDetails} from '@components/OnyxProvider'; import {PressableWithFeedback} from '@components/Pressable'; +import ReferralProgramCTA from '@components/ReferralProgramCTA'; import SelectCircle from '@components/SelectCircle'; import SelectionList from '@components/SelectionList'; import useLocalize from '@hooks/useLocalize'; @@ -16,7 +17,6 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as Report from '@libs/actions/Report'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import MoneyRequestReferralProgramCTA from '@pages/iou/MoneyRequestReferralProgramCTA'; import reportPropTypes from '@pages/reportPropTypes'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -266,7 +266,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ () => ( - + {shouldShowSplitBillErrorMessage && ( diff --git a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js index 9edede770233..9567b17ecdf5 100755 --- a/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js +++ b/src/pages/iou/steps/MoneyRequstParticipantsPage/MoneyRequestParticipantsSelector.js @@ -8,6 +8,7 @@ import Button from '@components/Button'; import FormHelpMessage from '@components/FormHelpMessage'; import {usePersonalDetails} from '@components/OnyxProvider'; import {PressableWithFeedback} from '@components/Pressable'; +import ReferralProgramCTA from '@components/ReferralProgramCTA'; import SelectCircle from '@components/SelectCircle'; import SelectionList from '@components/SelectionList'; import useLocalize from '@hooks/useLocalize'; @@ -16,7 +17,6 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as Report from '@libs/actions/Report'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as OptionsListUtils from '@libs/OptionsListUtils'; -import MoneyRequestReferralProgramCTA from '@pages/iou/MoneyRequestReferralProgramCTA'; import reportPropTypes from '@pages/reportPropTypes'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -285,7 +285,7 @@ function MoneyRequestParticipantsSelector({ () => ( - + {shouldShowSplitBillErrorMessage && ( From a4ecc58d3e14f96cd64fe622d528bf598e0fe6a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Mon, 15 Jan 2024 17:50:06 +0100 Subject: [PATCH 50/57] adding ReferralCTA to OptionsSelector --- .../OptionsSelector/BaseOptionsSelector.js | 35 ++----------------- src/components/ReferralProgramCTA.tsx | 3 +- 2 files changed, 4 insertions(+), 34 deletions(-) diff --git a/src/components/OptionsSelector/BaseOptionsSelector.js b/src/components/OptionsSelector/BaseOptionsSelector.js index 197829bb1ea9..ba4a0010e8ae 100755 --- a/src/components/OptionsSelector/BaseOptionsSelector.js +++ b/src/components/OptionsSelector/BaseOptionsSelector.js @@ -11,6 +11,7 @@ import Icon from '@components/Icon'; import {Info} from '@components/Icon/Expensicons'; import OptionsList from '@components/OptionsList'; import {PressableWithoutFeedback} from '@components/Pressable'; +import ReferralProgramCTA from '@components/ReferralProgramCTA'; import ShowMoreButton from '@components/ShowMoreButton'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; @@ -667,39 +668,7 @@ class BaseOptionsSelector extends Component { {this.props.shouldShowReferralCTA && ( - { - Navigation.navigate(ROUTES.REFERRAL_DETAILS_MODAL.getRoute(this.props.referralContentType)); - }} - style={[ - this.props.themeStyles.p5, - this.props.themeStyles.w100, - this.props.themeStyles.br2, - this.props.themeStyles.highlightBG, - this.props.themeStyles.flexRow, - this.props.themeStyles.justifyContentBetween, - this.props.themeStyles.alignItemsCenter, - {gap: 10}, - ]} - accessibilityLabel="referral" - role={CONST.ACCESSIBILITY_ROLE.BUTTON} - > - - {this.props.translate(`referralProgram.${this.props.referralContentType}.buttonText1`)} - - {this.props.translate(`referralProgram.${this.props.referralContentType}.buttonText2`)} - - - - + )} diff --git a/src/components/ReferralProgramCTA.tsx b/src/components/ReferralProgramCTA.tsx index e77d30da8487..473d5cdbed08 100644 --- a/src/components/ReferralProgramCTA.tsx +++ b/src/components/ReferralProgramCTA.tsx @@ -12,8 +12,9 @@ import Text from './Text'; type ReferralProgramCTAProps = { referralContentType: - | typeof CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SEND_MONEY | typeof CONST.REFERRAL_PROGRAM.CONTENT_TYPES.MONEY_REQUEST + | typeof CONST.REFERRAL_PROGRAM.CONTENT_TYPES.START_CHAT + | typeof CONST.REFERRAL_PROGRAM.CONTENT_TYPES.SEND_MONEY | typeof CONST.REFERRAL_PROGRAM.CONTENT_TYPES.REFER_FRIEND; }; From a4e3ae2546882b0971ed80e6ce0fd4c6b85cf956 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Mon, 15 Jan 2024 17:01:59 +0000 Subject: [PATCH 51/57] Update version to 1.4.25-2 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 4088f69cf008..ea0d00c1ef6f 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -98,8 +98,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001042501 - versionName "1.4.25-1" + versionCode 1001042502 + versionName "1.4.25-2" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 813c136f3c2c..369d7445401c 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.25.1 + 1.4.25.2 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index dfa278adacc5..4efe964b55c5 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.25.1 + 1.4.25.2 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 73420efed711..1ab5b13f6c65 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -5,7 +5,7 @@ CFBundleShortVersionString 1.4.25 CFBundleVersion - 1.4.25.1 + 1.4.25.2 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index f7e5d3453a5f..a2260ffd4cd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.25-1", + "version": "1.4.25-2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.25-1", + "version": "1.4.25-2", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index b13875990d41..55c56716a3ca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.25-1", + "version": "1.4.25-2", "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.", From 0ea199fcb5e4696b52f5187a622f0500d31a057f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20M=C3=B3rawski?= Date: Mon, 15 Jan 2024 18:10:04 +0100 Subject: [PATCH 52/57] removed unnecessary imports --- src/components/OptionsSelector/BaseOptionsSelector.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/components/OptionsSelector/BaseOptionsSelector.js b/src/components/OptionsSelector/BaseOptionsSelector.js index ba4a0010e8ae..412aeedcf965 100755 --- a/src/components/OptionsSelector/BaseOptionsSelector.js +++ b/src/components/OptionsSelector/BaseOptionsSelector.js @@ -7,13 +7,9 @@ import ArrowKeyFocusManager from '@components/ArrowKeyFocusManager'; import Button from '@components/Button'; import FixedFooter from '@components/FixedFooter'; import FormHelpMessage from '@components/FormHelpMessage'; -import Icon from '@components/Icon'; -import {Info} from '@components/Icon/Expensicons'; import OptionsList from '@components/OptionsList'; -import {PressableWithoutFeedback} from '@components/Pressable'; import ReferralProgramCTA from '@components/ReferralProgramCTA'; import ShowMoreButton from '@components/ShowMoreButton'; -import Text from '@components/Text'; import TextInput from '@components/TextInput'; import withLocalize, {withLocalizePropTypes} from '@components/withLocalize'; import withNavigationFocus from '@components/withNavigationFocus'; @@ -22,10 +18,8 @@ import withThemeStyles, {withThemeStylesPropTypes} from '@components/withThemeSt import compose from '@libs/compose'; import getPlatform from '@libs/getPlatform'; import KeyboardShortcut from '@libs/KeyboardShortcut'; -import Navigation from '@libs/Navigation/Navigation'; import setSelection from '@libs/setSelection'; import CONST from '@src/CONST'; -import ROUTES from '@src/ROUTES'; import {defaultProps as optionsSelectorDefaultProps, propTypes as optionsSelectorPropTypes} from './optionsSelectorPropTypes'; const propTypes = { From 2b1153166930952b07745569063888812f5cfddf Mon Sep 17 00:00:00 2001 From: mkhutornyi Date: Mon, 15 Jan 2024 19:56:13 +0100 Subject: [PATCH 53/57] fix unable to add assignee when creating a task --- src/pages/tasks/TaskAssigneeSelectorModal.js | 42 ++++++++++---------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/pages/tasks/TaskAssigneeSelectorModal.js b/src/pages/tasks/TaskAssigneeSelectorModal.js index a4fc61910be2..1a526a9cdd9b 100644 --- a/src/pages/tasks/TaskAssigneeSelectorModal.js +++ b/src/pages/tasks/TaskAssigneeSelectorModal.js @@ -184,29 +184,29 @@ function TaskAssigneeSelectorModal(props) { return sectionsList; }, [filteredCurrentUserOption, filteredPersonalDetails, filteredRecentReports, filteredUserToInvite, props]); - const selectReport = (option) => { - if (!option) { - return; - } - - // Check to see if we're creating a new task - // If there's no route params, we're creating a new task - if (!props.route.params && option.accountID) { - Task.setAssigneeValue(option.login, option.accountID, props.task.shareDestination, OptionsListUtils.isCurrentUser(option)); - return Navigation.goBack(ROUTES.NEW_TASK); - } - - // Check to see if we're editing a task and if so, update the assignee - if (report) { - if (option.accountID !== report.managerID) { - const assigneeChatReport = Task.setAssigneeValue(option.login, option.accountID, props.route.params.reportID, OptionsListUtils.isCurrentUser(option)); + const selectReport = useCallback( + (option) => { + if (!option) { + return; + } - // Pass through the selected assignee - Task.editTaskAssignee(report, props.session.accountID, option.login, option.accountID, assigneeChatReport); + // Check to see if we're editing a task and if so, update the assignee + if (report) { + if (option.accountID !== report.managerID) { + const assigneeChatReport = Task.setAssigneeValue(option.login, option.accountID, report.reportID, OptionsListUtils.isCurrentUser(option)); + + // Pass through the selected assignee + Task.editTaskAssignee(report, props.session.accountID, option.login, option.accountID, assigneeChatReport); + } + Navigation.dismissModal(report.reportID); + // If there's no report, we're creating a new task + } else if (option.accountID) { + Task.setAssigneeValue(option.login, option.accountID, props.task.shareDestination, OptionsListUtils.isCurrentUser(option)); + Navigation.goBack(ROUTES.NEW_TASK); } - return Navigation.dismissModal(report.reportID); - } - }; + }, + [props.session.accountID, props.task.shareDestination, report], + ); const isOpen = ReportUtils.isOpenTaskReport(report); const canModifyTask = Task.canModifyTask(report, props.currentUserPersonalDetails.accountID, lodashGet(props.rootParentReportPolicy, 'role', '')); From fc86d35899a122b42a0e6bd2ff10062d367de21e Mon Sep 17 00:00:00 2001 From: s-alves10 Date: Mon, 15 Jan 2024 13:18:35 -0600 Subject: [PATCH 54/57] fix: remove fill props from Icon in ImageCropView --- src/components/AvatarCropModal/ImageCropView.js | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/components/AvatarCropModal/ImageCropView.js b/src/components/AvatarCropModal/ImageCropView.js index 92cbe3a4da04..f69fe7eb5ecb 100644 --- a/src/components/AvatarCropModal/ImageCropView.js +++ b/src/components/AvatarCropModal/ImageCropView.js @@ -6,7 +6,6 @@ import Animated, {interpolate, useAnimatedStyle} from 'react-native-reanimated'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; import useStyleUtils from '@hooks/useStyleUtils'; -import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import ControlSelection from '@libs/ControlSelection'; import gestureHandlerPropTypes from './gestureHandlerPropTypes'; @@ -51,7 +50,6 @@ const defaultProps = { }; function ImageCropView(props) { - const theme = useTheme(); const styles = useThemeStyles(); const StyleUtils = useStyleUtils(); const containerStyle = StyleUtils.getWidthAndHeightStyle(props.containerSize, props.containerSize); @@ -90,7 +88,8 @@ function ImageCropView(props) { From 2c41828572d1fcd6d7cf599fdd01889cee755db6 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Mon, 15 Jan 2024 19:32:17 +0000 Subject: [PATCH 55/57] Update version to 1.4.25-3 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index ea0d00c1ef6f..3069329ecf0d 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -98,8 +98,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001042502 - versionName "1.4.25-2" + versionCode 1001042503 + versionName "1.4.25-3" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 369d7445401c..6386396bd62c 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.25.2 + 1.4.25.3 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 4efe964b55c5..a3371f8685b0 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.25.2 + 1.4.25.3 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 1ab5b13f6c65..73f5e5df9345 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -5,7 +5,7 @@ CFBundleShortVersionString 1.4.25 CFBundleVersion - 1.4.25.2 + 1.4.25.3 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index a2260ffd4cd5..7d0cb0449e17 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.25-2", + "version": "1.4.25-3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.25-2", + "version": "1.4.25-3", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 55c56716a3ca..fce867738f25 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.25-2", + "version": "1.4.25-3", "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.", From 11672881653e5fcdd341a32211bf079ad2165f35 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Mon, 15 Jan 2024 19:56:20 +0000 Subject: [PATCH 56/57] Update version to 1.4.25-4 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 3069329ecf0d..ed2944632aad 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -98,8 +98,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001042503 - versionName "1.4.25-3" + versionCode 1001042504 + versionName "1.4.25-4" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 6386396bd62c..305e7a8ede5e 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.25.3 + 1.4.25.4 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index a3371f8685b0..438a9331b4f6 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.25.3 + 1.4.25.4 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 73f5e5df9345..1782fd6daf98 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -5,7 +5,7 @@ CFBundleShortVersionString 1.4.25 CFBundleVersion - 1.4.25.3 + 1.4.25.4 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index 7d0cb0449e17..ae77c1751229 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.25-3", + "version": "1.4.25-4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.25-3", + "version": "1.4.25-4", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index fce867738f25..e5def6f1918a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.25-3", + "version": "1.4.25-4", "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.", From bfb7f22cc6cfb286334aa53701b8659266598044 Mon Sep 17 00:00:00 2001 From: OSBotify Date: Tue, 16 Jan 2024 09:50:02 +0000 Subject: [PATCH 57/57] Update version to 1.4.25-5 --- android/app/build.gradle | 4 ++-- ios/NewExpensify/Info.plist | 2 +- ios/NewExpensifyTests/Info.plist | 2 +- ios/NotificationServiceExtension/Info.plist | 2 +- package-lock.json | 4 ++-- package.json | 2 +- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index ed2944632aad..38ba58bb6a86 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -98,8 +98,8 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion multiDexEnabled rootProject.ext.multiDexEnabled - versionCode 1001042504 - versionName "1.4.25-4" + versionCode 1001042505 + versionName "1.4.25-5" } flavorDimensions "default" diff --git a/ios/NewExpensify/Info.plist b/ios/NewExpensify/Info.plist index 305e7a8ede5e..f361946c2584 100644 --- a/ios/NewExpensify/Info.plist +++ b/ios/NewExpensify/Info.plist @@ -40,7 +40,7 @@ CFBundleVersion - 1.4.25.4 + 1.4.25.5 ITSAppUsesNonExemptEncryption LSApplicationQueriesSchemes diff --git a/ios/NewExpensifyTests/Info.plist b/ios/NewExpensifyTests/Info.plist index 438a9331b4f6..bf9e98fec664 100644 --- a/ios/NewExpensifyTests/Info.plist +++ b/ios/NewExpensifyTests/Info.plist @@ -19,6 +19,6 @@ CFBundleSignature ???? CFBundleVersion - 1.4.25.4 + 1.4.25.5 diff --git a/ios/NotificationServiceExtension/Info.plist b/ios/NotificationServiceExtension/Info.plist index 1782fd6daf98..5ee62047829d 100644 --- a/ios/NotificationServiceExtension/Info.plist +++ b/ios/NotificationServiceExtension/Info.plist @@ -5,7 +5,7 @@ CFBundleShortVersionString 1.4.25 CFBundleVersion - 1.4.25.4 + 1.4.25.5 NSExtension NSExtensionPointIdentifier diff --git a/package-lock.json b/package-lock.json index ae77c1751229..e9d4c4f90b2d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "new.expensify", - "version": "1.4.25-4", + "version": "1.4.25-5", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "new.expensify", - "version": "1.4.25-4", + "version": "1.4.25-5", "hasInstallScript": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index e5def6f1918a..237d64e25b4a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "new.expensify", - "version": "1.4.25-4", + "version": "1.4.25-5", "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.",