Skip to content

Commit 30ca9e1

Browse files
committed
Merge branch 'main' of github.com:Expensify/App into feature/new-modal-for-popover
2 parents c369446 + 04e58bd commit 30ca9e1

37 files changed

+622
-474
lines changed

Mobile-Expensify

android/app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ android {
114114
minSdkVersion rootProject.ext.minSdkVersion
115115
targetSdkVersion rootProject.ext.targetSdkVersion
116116
multiDexEnabled rootProject.ext.multiDexEnabled
117-
versionCode 1009014303
118-
versionName "9.1.43-3"
117+
versionCode 1009014305
118+
versionName "9.1.43-5"
119119
// Supported language variants must be declared here to avoid from being removed during the compilation.
120120
// This also helps us to not include unnecessary language variants in the APK.
121121
resConfigs "en", "es"

ios/NewExpensify/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
</dict>
4545
</array>
4646
<key>CFBundleVersion</key>
47-
<string>9.1.43.3</string>
47+
<string>9.1.43.5</string>
4848
<key>FullStory</key>
4949
<dict>
5050
<key>OrgId</key>

ios/NotificationServiceExtension/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<key>CFBundleShortVersionString</key>
1414
<string>9.1.43</string>
1515
<key>CFBundleVersion</key>
16-
<string>9.1.43.3</string>
16+
<string>9.1.43.5</string>
1717
<key>NSExtension</key>
1818
<dict>
1919
<key>NSExtensionPointIdentifier</key>

ios/ShareViewController/Info.plist

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
<key>CFBundleShortVersionString</key>
1414
<string>9.1.43</string>
1515
<key>CFBundleVersion</key>
16-
<string>9.1.43.3</string>
16+
<string>9.1.43.5</string>
1717
<key>NSExtension</key>
1818
<dict>
1919
<key>NSExtensionAttributes</key>

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "new.expensify",
3-
"version": "9.1.43-3",
3+
"version": "9.1.43-5",
44
"author": "Expensify, Inc.",
55
"homepage": "https://new.expensify.com",
66
"description": "New Expensify is the next generation of Expensify: a reimagination of payments based atop a foundation of chat.",

src/components/AttachmentModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ function AttachmentModal({
538538
iouType,
539539
draftTransactionID ?? transaction?.transactionID,
540540
report?.reportID,
541-
Navigation.getActiveRouteWithoutParams(),
541+
Navigation.getActiveRoute(),
542542
),
543543
);
544544
}

src/components/ConfirmModal.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ function ConfirmModal({
165165
shouldEnableNewFocusManagement={shouldEnableNewFocusManagement}
166166
restoreFocusType={restoreFocusType}
167167
shouldHandleNavigationBack={shouldHandleNavigationBack}
168+
shouldUseNewModal
168169
>
169170
<ConfirmContent
170171
title={title}

src/components/MoneyRequestReportView/MoneyRequestReportTransactionsNavigation.tsx

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import {findFocusedRoute, useFocusEffect} from '@react-navigation/native';
2-
import React, {useCallback, useMemo} from 'react';
1+
import {findFocusedRoute} from '@react-navigation/native';
2+
import React, {useEffect, useMemo} from 'react';
33
import Icon from '@components/Icon';
44
import * as Expensicons from '@components/Icon/Expensicons';
55
import PressableWithFeedback from '@components/Pressable/PressableWithFeedback';
@@ -37,19 +37,18 @@ function MoneyRequestReportTransactionsNavigation({currentReportID}: MoneyReques
3737
const backTo = Navigation.getActiveRoute();
3838

3939
/**
40-
* We clear the sibling transactionThreadIDs when unfocusing this component
41-
* only when the focus actually goes to a different SCREEN (and not a different version of the same SCREEN)
40+
* We clear the sibling transactionThreadIDs when unmounting this component
41+
* only when the mount actually goes to a different SCREEN (and not a different version of the same SCREEN)
4242
*/
43-
useFocusEffect(
44-
useCallback(() => {
45-
return () => {
46-
const focusedRoute = findFocusedRoute(navigationRef.getRootState());
47-
if (focusedRoute?.name !== SCREENS.SEARCH.REPORT_RHP) {
48-
clearActiveTransactionThreadIDs();
49-
}
50-
};
51-
}, []),
52-
);
43+
useEffect(() => {
44+
return () => {
45+
const focusedRoute = findFocusedRoute(navigationRef.getRootState());
46+
if (focusedRoute?.name === SCREENS.SEARCH.REPORT_RHP) {
47+
return;
48+
}
49+
clearActiveTransactionThreadIDs();
50+
};
51+
}, []);
5352

5453
if (reportIDsList.length < 2) {
5554
return;

src/components/ReportActionItem/MoneyRequestReportPreview/MoneyRequestReportPreviewContent.tsx

Lines changed: 159 additions & 160 deletions
Large diffs are not rendered by default.

src/components/ReportActionItem/MoneyRequestReportPreview/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type MoneyRequestReportPreviewStyleType = {
1414
contentContainerStyle: ViewStyle;
1515
transactionPreviewStyle: TransactionPreviewStyle;
1616
componentStyle: StyleProp<ViewStyle>;
17+
expenseCountVisible: boolean;
1718
};
1819

1920
type MoneyRequestReportPreviewProps = {

src/components/ReportActionItem/TransactionPreview/index.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ function TransactionPreview(props: TransactionPreviewProps) {
3737
iouReportID,
3838
transactionID: transactionIDFromProps,
3939
onPreviewPressed,
40+
reportPreviewAction,
4041
contextAction,
4142
} = props;
4243

@@ -130,7 +131,7 @@ function TransactionPreview(props: TransactionPreviewProps) {
130131
sessionAccountID={sessionAccountID}
131132
walletTermsErrors={walletTerms?.errors}
132133
routeName={route.name}
133-
reportPreviewAction={props.reportPreviewAction}
134+
reportPreviewAction={reportPreviewAction}
134135
/>
135136
);
136137
}

src/components/Search/SearchPageHeader/SearchStatusBar.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ function SearchStatusBar({queryJSON, onStatusChange, headerButtonsOptions}: Sear
271271
: queryJSON.status === CONST.SEARCH.STATUS.EXPENSE.OUTSTANDING;
272272
const {renderProductTrainingTooltip, shouldShowProductTrainingTooltip, hideProductTrainingTooltip} = useProductTrainingContext(
273273
CONST.PRODUCT_TRAINING_TOOLTIP_NAMES.OUTSANDING_FILTER,
274-
isScreenFocused && !isOutstandingStatusActive,
274+
isScreenFocused && !isOutstandingStatusActive && queryJSON.type === CONST.SEARCH.DATA_TYPES.EXPENSE,
275275
);
276276
// Controls the visibility of the educational tooltip based on user scrolling.
277277
// Hides the tooltip when the user is scrolling and displays it once scrolling stops.

src/libs/DebugUtils.ts

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import ONYXKEYS from '@src/ONYXKEYS';
1111
import type {Beta, Policy, Report, ReportAction, ReportActions, ReportNameValuePairs, Transaction, TransactionViolation} from '@src/types/onyx';
1212
import type {Comment} from '@src/types/onyx/Transaction';
1313
import {getLinkedTransactionID} from './ReportActionsUtils';
14-
import {getReasonAndReportActionThatRequiresAttention, getReportNameValuePairs, isArchivedReport, reasonForReportToBeInOptionList, shouldDisplayViolationsRBRInLHN} from './ReportUtils';
14+
import {getReasonAndReportActionThatRequiresAttention, reasonForReportToBeInOptionList, shouldDisplayViolationsRBRInLHN} from './ReportUtils';
1515
import SidebarUtils from './SidebarUtils';
1616
import {getTransactionID as TransactionUtilsGetTransactionID} from './TransactionUtils';
1717

@@ -1368,13 +1368,8 @@ type RBRReasonAndReportAction = {
13681368
/**
13691369
* Gets the report action that is causing the RBR to show up in LHN
13701370
*/
1371-
function getReasonAndReportActionForRBRInLHNRow(report: Report, reportActions: OnyxEntry<ReportActions>, hasViolations: boolean): RBRReasonAndReportAction | null {
1372-
// This will get removed as part of https://github.com/Expensify/App/issues/59961
1373-
// eslint-disable-next-line deprecation/deprecation
1374-
const reportNameValuePairs = getReportNameValuePairs(report?.reportID);
1375-
1376-
const {reason, reportAction} =
1377-
SidebarUtils.getReasonAndReportActionThatHasRedBrickRoad(report, reportActions, hasViolations, transactionViolations, isArchivedReport(reportNameValuePairs)) ?? {};
1371+
function getReasonAndReportActionForRBRInLHNRow(report: Report, reportActions: OnyxEntry<ReportActions>, hasViolations: boolean, isArchivedReport = false): RBRReasonAndReportAction | null {
1372+
const {reason, reportAction} = SidebarUtils.getReasonAndReportActionThatHasRedBrickRoad(report, reportActions, hasViolations, transactionViolations, isArchivedReport) ?? {};
13781373

13791374
if (reason) {
13801375
return {reason: `debug.reasonRBR.${reason}`, reportAction};

src/libs/TransactionPreviewUtils.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ import {convertToDisplayString} from './CurrencyUtils';
1010
import DateUtils from './DateUtils';
1111
import type {PlatformStackRouteProp} from './Navigation/PlatformStackNavigation/types';
1212
import type {TransactionDuplicateNavigatorParamList} from './Navigation/types';
13-
import {getOriginalMessage, getReportAction, isMessageDeleted, isMoneyRequestAction} from './ReportActionsUtils';
14-
import {isPaidGroupPolicy, isPaidGroupPolicyExpenseReport, isReportApproved, isSettled} from './ReportUtils';
13+
import {getOriginalMessage, getReportAction, getReportActions, isMessageDeleted, isMoneyRequestAction} from './ReportActionsUtils';
14+
import {hasActionsWithErrors, hasReportViolations, isPaidGroupPolicy, isPaidGroupPolicyExpenseReport, isReportApproved, isReportOwner, isSettled} from './ReportUtils';
1515
import type {TransactionDetails} from './ReportUtils';
1616
import StringUtils from './StringUtils';
1717
import {
@@ -135,6 +135,24 @@ function getViolationTranslatePath(violations: OnyxTypes.TransactionViolations,
135135
return isTooLong || hasViolationsAndHold || hasViolationsAndFieldErrors ? {translationPath: 'violations.reviewRequired'} : {text: violationMessage};
136136
}
137137

138+
/**
139+
* Extracts unique error messages from report actions. If no report or actions are found,
140+
* it returns an empty array. It identifies the latest error in each action and filters out duplicates to
141+
* ensure only unique error messages are returned.
142+
*/
143+
function getUniqueActionErrors(report: OnyxEntry<OnyxTypes.Report>) {
144+
const reportActions = Object.values(report ? getReportActions(report) ?? {} : {});
145+
146+
const reportErrors = reportActions.map((reportAction) => {
147+
const errors = reportAction.errors ?? {};
148+
const key = Object.keys(errors).sort().reverse().at(0) ?? '';
149+
const error = errors[key];
150+
return typeof error === 'string' ? error : '';
151+
});
152+
153+
return [...new Set(reportErrors)].filter((err) => err.length);
154+
}
155+
138156
function getTransactionPreviewTextAndTranslationPaths({
139157
iouReport,
140158
transaction,
@@ -167,6 +185,7 @@ function getTransactionPreviewTextAndTranslationPaths({
167185
const isScanning = hasReceipt(transaction) && isReceiptBeingScanned(transaction);
168186
const hasFieldErrors = hasMissingSmartscanFields(transaction);
169187
const hasViolationsOfTypeNotice = hasNoticeTypeViolation(transaction?.transactionID, violations, true) && isPaidGroupPolicy(iouReport);
188+
const hasActionWithErrors = hasActionsWithErrors(iouReport?.reportID);
170189

171190
const {amount: requestAmount, currency: requestCurrency} = transactionDetails;
172191

@@ -197,6 +216,11 @@ function getTransactionPreviewTextAndTranslationPaths({
197216
}
198217
}
199218

219+
if (RBRMessage === undefined && hasActionWithErrors) {
220+
const actionsWithErrors = getUniqueActionErrors(iouReport);
221+
RBRMessage = actionsWithErrors.length > 1 ? {translationPath: 'violations.reviewRequired'} : {text: actionsWithErrors.at(0)};
222+
}
223+
200224
RBRMessage ??= {text: ''};
201225

202226
let previewHeaderText: TranslationPathOrText[] = [showCashOrCard];
@@ -307,7 +331,8 @@ function createTransactionPreviewConditionals({
307331
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
308332
const hasAnyViolations = hasViolationsOfTypeNotice || hasWarningTypeViolation(transaction?.transactionID, violations, true) || hasViolation(transaction, violations, true);
309333
const hasErrorOrOnHold = hasFieldErrors || (!isFullySettled && !isFullyApproved && isTransactionOnHold);
310-
const shouldShowRBR = hasAnyViolations || hasErrorOrOnHold;
334+
const hasReportViolationsOrActionErrors = (isReportOwner(iouReport) && hasReportViolations(iouReport?.reportID)) || hasActionsWithErrors(iouReport?.reportID);
335+
const shouldShowRBR = hasAnyViolations || hasErrorOrOnHold || hasReportViolationsOrActionErrors;
311336

312337
// When there are no settled transactions in duplicates, show the "Keep this one" button
313338
const shouldShowKeepButton = areThereDuplicates;
@@ -345,5 +370,6 @@ export {
345370
createTransactionPreviewConditionals,
346371
getOriginalTransactionIfBillIsSplit,
347372
getViolationTranslatePath,
373+
getUniqueActionErrors,
348374
};
349375
export type {TranslationPathOrText};

src/libs/__mocks__/TransactionPreviewUtils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,6 @@ export {
3636
getReviewNavigationRoute,
3737
getOriginalTransactionIfBillIsSplit,
3838
getViolationTranslatePath,
39+
getUniqueActionErrors,
3940
} from '../TransactionPreviewUtils';
4041
export {getIOUData};

src/pages/Debug/Report/DebugReportPage.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,19 @@ import * as Expensicons from '@components/Icon/Expensicons';
77
import ScreenWrapper from '@components/ScreenWrapper';
88
import Text from '@components/Text';
99
import useLocalize from '@hooks/useLocalize';
10+
import useReportIsArchived from '@hooks/useReportIsArchived';
1011
import useStyleUtils from '@hooks/useStyleUtils';
1112
import useTheme from '@hooks/useTheme';
1213
import useThemeStyles from '@hooks/useThemeStyles';
1314
import {navigateToConciergeChatAndDeleteReport} from '@libs/actions/Report';
1415
import DebugUtils from '@libs/DebugUtils';
15-
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
16+
import {canUseTouchScreen} from '@libs/DeviceCapabilities';
1617
import type {DebugTabNavigatorRoutes} from '@libs/Navigation/DebugTabNavigator';
1718
import DebugTabNavigator from '@libs/Navigation/DebugTabNavigator';
1819
import Navigation from '@libs/Navigation/Navigation';
1920
import type {PlatformStackScreenProps} from '@libs/Navigation/PlatformStackNavigation/types';
2021
import type {DebugParamList} from '@libs/Navigation/types';
21-
import * as ReportUtils from '@libs/ReportUtils';
22+
import {hasReportViolations, isReportOwner, shouldDisplayViolationsRBRInLHN} from '@libs/ReportUtils';
2223
import DebugDetails from '@pages/Debug/DebugDetails';
2324
import DebugJSON from '@pages/Debug/DebugJSON';
2425
import NotFoundPage from '@pages/ErrorPage/NotFoundPage';
@@ -50,21 +51,22 @@ function DebugReportPage({
5051
const styles = useThemeStyles();
5152
const StyleUtils = useStyleUtils();
5253
const theme = useTheme();
53-
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`);
54-
const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`);
55-
const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS);
54+
const [report] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT}${reportID}`, {canBeMissing: true});
55+
const [reportActions] = useOnyx(`${ONYXKEYS.COLLECTION.REPORT_ACTIONS}${reportID}`, {canBeMissing: true});
56+
const [transactionViolations] = useOnyx(ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS, {canBeMissing: true});
5657
const transactionID = DebugUtils.getTransactionID(report, reportActions);
58+
const isReportArchived = useReportIsArchived(reportID);
5759

5860
const metadata = useMemo<Metadata[]>(() => {
5961
if (!report) {
6062
return [];
6163
}
6264

63-
const shouldDisplayViolations = ReportUtils.shouldDisplayViolationsRBRInLHN(report, transactionViolations);
64-
const shouldDisplayReportViolations = ReportUtils.isReportOwner(report) && ReportUtils.hasReportViolations(reportID);
65+
const shouldDisplayViolations = shouldDisplayViolationsRBRInLHN(report, transactionViolations);
66+
const shouldDisplayReportViolations = isReportOwner(report) && hasReportViolations(reportID);
6567
const hasViolations = !!shouldDisplayViolations || shouldDisplayReportViolations;
6668
const {reason: reasonGBR, reportAction: reportActionGBR} = DebugUtils.getReasonAndReportActionForGBRInLHNRow(report) ?? {};
67-
const {reason: reasonRBR, reportAction: reportActionRBR} = DebugUtils.getReasonAndReportActionForRBRInLHNRow(report, reportActions, hasViolations) ?? {};
69+
const {reason: reasonRBR, reportAction: reportActionRBR} = DebugUtils.getReasonAndReportActionForRBRInLHNRow(report, reportActions, hasViolations, isReportArchived) ?? {};
6870
const hasRBR = !!reasonRBR;
6971
const hasGBR = !hasRBR && !!reasonGBR;
7072
const reasonLHN = DebugUtils.getReasonForShowingRowInLHN(report, hasRBR);
@@ -112,7 +114,7 @@ function DebugReportPage({
112114
: undefined,
113115
},
114116
];
115-
}, [report, reportActions, reportID, transactionViolations, translate]);
117+
}, [report, reportActions, reportID, transactionViolations, translate, isReportArchived]);
116118

117119
const DebugDetailsTab = useCallback(
118120
() => (
@@ -213,7 +215,7 @@ function DebugReportPage({
213215
<ScreenWrapper
214216
includeSafeAreaPaddingBottom={false}
215217
shouldEnableKeyboardAvoidingView={false}
216-
shouldEnableMinHeight={DeviceCapabilities.canUseTouchScreen()}
218+
shouldEnableMinHeight={canUseTouchScreen()}
217219
testID={DebugReportPage.displayName}
218220
>
219221
{({safeAreaPaddingBottomStyle}) => (

src/pages/ReportDetailsPage.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,8 @@ function ReportDetailsPage({policies, report, route, reportMetadata}: ReportDeta
439439
(!isUserCreatedPolicyRoom && participants.length) ||
440440
(isUserCreatedPolicyRoom && (isPolicyEmployee || (isChatThread && !isPublicRoomUtil(report))))) &&
441441
!isConciergeChatReport(report) &&
442-
!isSystemChat
442+
!isSystemChat &&
443+
activeChatMembers.length > 0
443444
) {
444445
items.push({
445446
key: CONST.REPORT_DETAILS_MENU_ITEM.MEMBERS,
@@ -1174,6 +1175,7 @@ function ReportDetailsPage({policies, report, route, reportMetadata}: ReportDeta
11741175
isVisible={isPDFModalVisible}
11751176
type={isSmallScreenWidth ? CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED : CONST.MODAL.MODAL_TYPE.CONFIRM}
11761177
innerContainerStyle={styles.pv0}
1178+
shouldUseNewModal
11771179
>
11781180
<View style={[styles.m5]}>
11791181
<View>

src/pages/ReportParticipantsPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,9 +240,9 @@ function ReportParticipantsPage({report, route}: ReportParticipantsPageProps) {
240240
const accountIDsToRemove = selectedMembers.filter((id) => id !== currentUserAccountID);
241241
removeFromGroupChat(report.reportID, accountIDsToRemove);
242242
setSearchValue('');
243-
setSelectedMembers([]);
244243
setRemoveMembersConfirmModalVisible(false);
245244
InteractionManager.runAfterInteractions(() => {
245+
setSelectedMembers([]);
246246
clearUserSearchPhrase();
247247
});
248248
};

src/pages/RoomMembersPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,9 @@ function RoomMembersPage({report, policies}: RoomMembersPageProps) {
132132
removeFromRoom(report.reportID, selectedMembers);
133133
}
134134
setSearchValue('');
135-
setSelectedMembers([]);
136135
setRemoveMembersConfirmModalVisible(false);
137136
InteractionManager.runAfterInteractions(() => {
137+
setSelectedMembers([]);
138138
clearUserSearchPhrase();
139139
});
140140
};

0 commit comments

Comments
 (0)