Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
0d2b282
work on unreported expense RHP in progress
sumo-slonik Feb 28, 2025
66256ba
Merge branch 'feature/kuba-nowakowski/create-new-reusable-transaction…
sumo-slonik Mar 6, 2025
9a0f99d
Merge branch 'main' into feature/kuba-nowakowski/Create-Add-unreporte…
sumo-slonik Mar 6, 2025
0242f90
work in progress
sumo-slonik Mar 7, 2025
7ec6b39
Merge branch 'feature/kuba-nowakowski/create-new-reusable-transaction…
sumo-slonik Mar 7, 2025
44c5801
Merge branch 'feature/kuba-nowakowski/create-new-reusable-transaction…
sumo-slonik Mar 7, 2025
a6b97aa
work in progress
sumo-slonik Mar 10, 2025
7c5f72b
Merge branch 'feature/kuba-nowakowski/create-new-reusable-transaction…
sumo-slonik Mar 11, 2025
5ee2492
Merge branch 'feature/kuba-nowakowski/create-new-reusable-transaction…
sumo-slonik Mar 11, 2025
b5ab772
working scrollable list with new items
sumo-slonik Mar 12, 2025
42c1e6f
Merge branch 'feature/kuba-nowakowski/create-new-reusable-transaction…
sumo-slonik Mar 13, 2025
17c36e3
working on page
sumo-slonik Mar 14, 2025
04a4d4a
Merge branch 'main' into feature/kuba-nowakowski/Create-Add-unreporte…
sumo-slonik Mar 14, 2025
4961732
Fix hover style of TransactionItemRow
JakubKorytko Mar 14, 2025
70cbdd3
Add some style to AddUnreportedExpense
JakubKorytko Mar 14, 2025
a885456
Merge pull request #212 from software-mansion-labs/korytko/style-add-…
sumo-slonik Mar 17, 2025
fc34245
Merge remote-tracking branch 'origin/feature/kuba-nowakowski/Create-A…
sumo-slonik Mar 17, 2025
6b317dd
run new report flow, and add button unreported page
sumo-slonik Mar 17, 2025
6aa96fd
working UI without logic
sumo-slonik Mar 17, 2025
ccf400b
working on navigation, working passing report id to page
sumo-slonik Mar 18, 2025
894bbf0
Merge branch 'main' into feature/kuba-nowakowski/Create-Add-unreporte…
sumo-slonik Mar 24, 2025
794cc62
work in progress on API connection
sumo-slonik Mar 24, 2025
35839e7
workinng on types
sumo-slonik Mar 26, 2025
c044ed5
fix types and styles
sumo-slonik Mar 26, 2025
f84b2dd
Merge branch 'feature/57468-ChangeTransactionsReport' into feature/ku…
sumo-slonik Mar 31, 2025
2dbcbf9
working connection with API
sumo-slonik Apr 1, 2025
3c3e6bc
Merge branch 'main' into feature/kuba-nowakowski/Create-Add-unreporte…
sumo-slonik Apr 1, 2025
dacc2e2
working on optimistick data
sumo-slonik Apr 2, 2025
dfa2381
Merge branch 'feature/57468-ChangeTransactionsReport' into feature/ku…
sumo-slonik Apr 2, 2025
5326a6f
Add report preview actions to new preview component
jnowakow Apr 7, 2025
6ca8a5f
Fix several blockers after PR-58084
jnowakow Apr 9, 2025
357308a
Merge branch 'main' of github.com:Expensify/App into jnowakow/blocker…
jnowakow Apr 9, 2025
d2be1d5
fix test
jnowakow Apr 9, 2025
6a890dc
Further fixes
jnowakow Apr 9, 2025
c36fc9d
Revert "revert 58084"
jnowakow Apr 10, 2025
ba3eb29
fix 'Download as PDF' option is shown for DM thread
SzymczakJ Apr 10, 2025
228fc50
fix No warning is shown when unapproving an expense that has been exp…
SzymczakJ Apr 10, 2025
59cca89
fix "Pay with Expensify" button extends out of screen
SzymczakJ Apr 10, 2025
21ee95f
Merge branch 'main' of github.com:Expensify/App into jnowakow/simplif…
jnowakow Apr 11, 2025
515d557
Merge branch 'jnowakow/blockers-after-58084' into jnowakow/simplified…
jnowakow Apr 11, 2025
d9fa312
fix unnecessary delete option
sumo-slonik Apr 11, 2025
27d9378
fix 59904
jnowakow Apr 11, 2025
c2a0b2a
fix 59909
jnowakow Apr 11, 2025
6dff03e
Fix 59916
jnowakow Apr 11, 2025
e971067
Merge branch 'main' into jnowakow/simplified-actions-on-header-v2
jnowakow Apr 11, 2025
97321d9
Fix 59928
jnowakow Apr 11, 2025
a6ada46
Merge branch 'main' of github.com:Expensify/App into jnowakow/simplif…
jnowakow Apr 14, 2025
e5d8000
Merge branch 'jnowakow/actions-on-new-preview-component' into jnowako…
jnowakow Apr 14, 2025
5df34d7
Fix linter, prettier and tests
jnowakow Apr 14, 2025
450817a
Fix prettier 2
jnowakow Apr 14, 2025
6118cd4
Merge pull request #221 from software-mansion-labs/bugfix/kuba_nowako…
sumo-slonik Apr 14, 2025
049eb51
Fix checks
jnowakow Apr 14, 2025
19ccb60
Merge branch 'jnowakow/simplified-actions-on-header-v2' into feature/…
sumo-slonik Apr 14, 2025
647428d
work in progress, before merge main
sumo-slonik Apr 15, 2025
aca155d
Merge branch 'main' into feature/kuba-nowakowski/Create-Add-unreporte…
sumo-slonik Apr 15, 2025
5c6c880
fix merge
sumo-slonik Apr 15, 2025
0255c96
working rhp
sumo-slonik Apr 15, 2025
ee087ce
fix hover of transaction item row
sumo-slonik Apr 15, 2025
7345555
working on getting unreported transactions
sumo-slonik Apr 16, 2025
5ac5d08
Merge branch 'main' into feature/kuba-nowakowski/Create-Add-unreporte…
sumo-slonik Apr 16, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1181,10 +1181,28 @@ const CONST = {
APPROVE: 'approve',
PAY: 'pay',
EXPORT_TO_ACCOUNTING: 'exportToAccounting',
REMOVE_HOLD: 'removeHold',
MARK_AS_CASH: 'markAsCash',
MOVE_UNREPORTED_EXPENSE: 'moveUnreportedExpense',
},
TRANSACTION_PRIMARY_ACTIONS: {
REMOVE_HOLD: 'removeHold',
REVIEW_DUPLICATES: 'reviewDuplicates',
MARK_AS_CASH: 'markAsCash',
},
REPORT_PREVIEW_ACTIONS: {
VIEW: 'view',
REVIEW: 'review',
SUBMIT: 'submit',
APPROVE: 'approve',
PAY: 'pay',
EXPORT_TO_ACCOUNTING: 'exportToAccounting',
},
TRANSACTION_SECONDARY_ACTIONS: {
HOLD: 'hold',
VIEW_DETAILS: 'viewDetails',
DELETE: 'delete',
},
ACTIONS: {
LIMIT: 50,
// OldDot Actions render getMessage from Web-Expensify/lib/Report/Action PHP files via getMessageOfOldDotReportAction in ReportActionsUtils.ts
Expand Down
4 changes: 4 additions & 0 deletions src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2334,6 +2334,10 @@ const ROUTES = {
route: 'settings/workspaces/:policyID/accounting/sage-intacct/advanced/payment-account',
getRoute: (policyID: string) => `settings/workspaces/${policyID}/accounting/sage-intacct/advanced/payment-account` as const,
},
ADD_UNREPORTED_EXPENSE: {
route: 'search/r/:reportID/AddUnreportedExpense',
getRoute: (reportID: string | undefined) => `search/r/${reportID}/AddUnreportedExpense` as const,
},
DEBUG_REPORT: {
route: 'debug/report/:reportID',
getRoute: (reportID: string | undefined) => `debug/report/${reportID}` as const,
Expand Down
2 changes: 2 additions & 0 deletions src/SCREENS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ const SCREENS = {
REPORT_EXPORT: 'Report_Export',
MISSING_PERSONAL_DETAILS: 'MissingPersonalDetails',
DEBUG: 'Debug',
ADD_UNREPORTED_EXPENSE: 'AddUnreportedExpense',
},
PUBLIC_CONSOLE_DEBUG: 'Console_Debug',
ONBOARDING_MODAL: {
Expand Down Expand Up @@ -692,6 +693,7 @@ const SCREENS = {
FEATURE_TRAINING_ROOT: 'FeatureTraining_Root',
RESTRICTED_ACTION_ROOT: 'RestrictedAction_Root',
MISSING_PERSONAL_DETAILS_ROOT: 'MissingPersonalDetails_Root',
ADD_UNREPORTED_EXPENSES_ROOT: 'AddUnreportedExpenses_Root',
DEBUG: {
REPORT: 'Debug_Report',
REPORT_ACTION: 'Debug_Report_Action',
Expand Down
19 changes: 8 additions & 11 deletions src/components/AvatarWithDisplayName.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ import ROUTES from '@src/ROUTES';
import type {Policy, Report} from '@src/types/onyx';
import type {Icon} from '@src/types/onyx/OnyxCommon';
import {getButtonRole} from './Button/utils';
import CaretWrapper from './CaretWrapper';
import DisplayNames from './DisplayNames';
import {FallbackAvatar} from './Icon/Expensicons';
import MultipleAvatars from './MultipleAvatars';
Expand Down Expand Up @@ -155,16 +154,14 @@ function AvatarWithDisplayName({policy, report, isAnonymous = false, size = CONS
</View>
</PressableWithoutFeedback>
<View style={[styles.flex1, styles.flexColumn]}>
<CaretWrapper>
<DisplayNames
fullTitle={title}
displayNamesWithTooltips={displayNamesWithTooltips}
tooltipEnabled
numberOfLines={1}
textStyles={[isAnonymous ? styles.headerAnonymousFooter : styles.headerText, styles.pre]}
shouldUseFullTitle={isMoneyRequestOrReport || isAnonymous}
/>
</CaretWrapper>
<DisplayNames
fullTitle={title}
displayNamesWithTooltips={displayNamesWithTooltips}
tooltipEnabled
numberOfLines={1}
textStyles={[isAnonymous ? styles.headerAnonymousFooter : styles.headerText, styles.pre]}
shouldUseFullTitle={isMoneyRequestOrReport || isAnonymous}
/>
{Object.keys(parentNavigationSubtitleData).length > 0 && (
<ParentNavigationSubtitle
parentNavigationSubtitleData={parentNavigationSubtitleData}
Expand Down
630 changes: 399 additions & 231 deletions src/components/MoneyReportHeader.tsx

Large diffs are not rendered by default.

196 changes: 149 additions & 47 deletions src/components/MoneyRequestHeader.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
import {useRoute} from '@react-navigation/native';
import type {ReactNode} from 'react';
import React, {useCallback, useEffect} from 'react';
import React, {useCallback, useEffect, useMemo, useState} from 'react';
import {View} from 'react-native';
import type {OnyxEntry} from 'react-native-onyx';
import {useOnyx} from 'react-native-onyx';
import type {ValueOf} from 'type-fest';
import useLocalize from '@hooks/useLocalize';
import useResponsiveLayout from '@hooks/useResponsiveLayout';
import useTheme from '@hooks/useTheme';
import useThemeStyles from '@hooks/useThemeStyles';
import useTransactionViolations from '@hooks/useTransactionViolations';
import {deleteMoneyRequest, getNavigationUrlOnMoneyRequestDelete} from '@libs/actions/IOU';
import Navigation from '@libs/Navigation/Navigation';
import {getOriginalMessage, isMoneyRequestAction} from '@libs/ReportActionsUtils';
import {getTransactionThreadPrimaryAction} from '@libs/ReportPrimaryActionUtils';
import {getSecondaryTransactionThreadActions} from '@libs/ReportSecondaryActionUtils';
import {changeMoneyRequestHoldStatus, navigateBackOnDeleteTransaction, navigateToDetailsPage} from '@libs/ReportUtils';
import {
checkIfShouldShowMarkAsCashButton,
hasPendingRTERViolation as hasPendingRTERViolationTransactionUtils,
hasReceipt,
isDuplicate as isDuplicateTransactionUtils,
Expand All @@ -33,6 +37,10 @@ import type IconAsset from '@src/types/utils/IconAsset';
import isLoadingOnyxValue from '@src/types/utils/isLoadingOnyxValue';
import BrokenConnectionDescription from './BrokenConnectionDescription';
import Button from './Button';
import ButtonWithDropdownMenu from './ButtonWithDropdownMenu';
import type {DropdownOption} from './ButtonWithDropdownMenu/types';
import ConfirmModal from './ConfirmModal';
import DecisionModal from './DecisionModal';
import HeaderWithBackButton from './HeaderWithBackButton';
import Icon from './Icon';
import * as Expensicons from './Icon/Expensicons';
Expand Down Expand Up @@ -68,6 +76,8 @@ function MoneyRequestHeader({report, parentReportAction, policy, onBackButtonPre
);
const transactionViolations = useTransactionViolations(transaction?.transactionID);

const [isDeleteModalVisible, setIsDeleteModalVisible] = useState(false);
const [downloadErrorModalVisible, setDownloadErrorModalVisible] = useState(false);
const [dismissedHoldUseExplanation, dismissedHoldUseExplanationResult] = useOnyx(ONYXKEYS.NVP_DISMISSED_HOLD_USE_EXPLANATION, {initialValue: true});
const [isLoadingReportData] = useOnyx(ONYXKEYS.IS_LOADING_REPORT_DATA);
const isLoadingHoldUseExplained = isLoadingOnyxValue(dismissedHoldUseExplanationResult);
Expand All @@ -85,7 +95,6 @@ function MoneyRequestHeader({report, parentReportAction, policy, onBackButtonPre
const hasPendingRTERViolation = hasPendingRTERViolationTransactionUtils(transactionViolations);

const shouldShowBrokenConnectionViolation = shouldShowBrokenConnectionViolationTransactionUtils(parentReport, policy, transactionViolations);
const shouldShowMarkAsCashButton = checkIfShouldShowMarkAsCashButton(hasPendingRTERViolation, shouldShowBrokenConnectionViolation, parentReport, policy);

const markAsCash = useCallback(() => {
markAsCashAction(transaction?.transactionID, reportID);
Expand Down Expand Up @@ -144,12 +153,89 @@ function MoneyRequestHeader({report, parentReportAction, policy, onBackButtonPre
Navigation.navigate(ROUTES.PROCESS_MONEY_REQUEST_HOLD.getRoute(Navigation.getReportRHPActiveRoute()));
}, [dismissedHoldUseExplanation, isLoadingHoldUseExplained, isOnHold]);

const primaryAction = useMemo(() => {
if (!report || !parentReport || !transaction) {
return '';
}
return getTransactionThreadPrimaryAction(report, parentReport, transaction, transactionViolations, policy);
}, [parentReport, policy, report, transaction, transactionViolations]);

const primaryActionImplementation = {
[CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS.REMOVE_HOLD]: (
<Button
success
text={translate('iou.unhold')}
onPress={() => {
changeMoneyRequestHoldStatus(parentReportAction);
}}
/>
),
[CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS.REVIEW_DUPLICATES]: (
<Button
success
text={translate('iou.reviewDuplicates')}
onPress={() => {
if (!reportID) {
return;
}
Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.getRoute(reportID, Navigation.getReportRHPActiveRoute()));
}}
/>
),
[CONST.REPORT.TRANSACTION_PRIMARY_ACTIONS.MARK_AS_CASH]: (
<Button
success
text={translate('iou.markAsCash')}
onPress={markAsCash}
/>
),
};

const secondaryActions = useMemo(() => {
if (!parentReport || !transaction) {
return [];
}
return getSecondaryTransactionThreadActions(parentReport, transaction);
}, [parentReport, transaction]);

const secondaryActionsImplementation: Record<ValueOf<typeof CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS>, DropdownOption<ValueOf<typeof CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS>>> = {
[CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.HOLD]: {
text: translate('iou.hold'),
icon: Expensicons.Stopwatch,
value: CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.HOLD,
onSelected: () => {
if (!parentReportAction) {
throw new Error('Parent action does not exist');
}

changeMoneyRequestHoldStatus(parentReportAction);
},
},
[CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.VIEW_DETAILS]: {
value: CONST.REPORT.SECONDARY_ACTIONS.VIEW_DETAILS,
text: translate('iou.viewDetails'),
icon: Expensicons.Info,
onSelected: () => {
navigateToDetailsPage(report, Navigation.getReportRHPActiveRoute());
},
},
[CONST.REPORT.TRANSACTION_SECONDARY_ACTIONS.DELETE]: {
text: translate('common.delete'),
icon: Expensicons.Trashcan,
value: CONST.REPORT.SECONDARY_ACTIONS.DELETE,
onSelected: () => {
setIsDeleteModalVisible(true);
},
},
};

const applicableSecondaryActions = secondaryActions.map((action) => secondaryActionsImplementation[action]);

return (
<View style={[styles.pl0, styles.borderBottom]}>
<HeaderWithBackButton
shouldShowBorderBottom={false}
shouldShowReportAvatarWithDisplay
shouldEnableDetailPageNavigation
shouldShowPinButton={false}
report={
reportID
Expand All @@ -164,53 +250,39 @@ function MoneyRequestHeader({report, parentReportAction, policy, onBackButtonPre
shouldShowBackButton={shouldUseNarrowLayout}
shouldDisplaySearchRouter={shouldDisplaySearchRouter}
onBackButtonPress={onBackButtonPress}
shouldEnableDetailPageNavigation
>
{shouldShowMarkAsCashButton && !shouldUseNarrowLayout && (
<Button
success
text={translate('iou.markAsCash')}
style={[styles.p0]}
onPress={markAsCash}
/>
)}
{isDuplicate && !shouldUseNarrowLayout && (
<Button
success
text={translate('iou.reviewDuplicates')}
style={[styles.p0, styles.ml2]}
onPress={() => {
if (!reportID) {
return;
}
Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.getRoute(reportID, Navigation.getReportRHPActiveRoute()));
}}
/>
{!shouldUseNarrowLayout && (
<View style={[styles.flexRow, styles.gap2]}>
{!!primaryAction && primaryActionImplementation[primaryAction]}
{!!applicableSecondaryActions.length && (
<ButtonWithDropdownMenu
success={false}
onPress={() => {}}
shouldAlwaysShowDropdownMenu
customText={translate('common.more')}
options={applicableSecondaryActions}
isSplitButton={false}
/>
)}
</View>
)}
{shouldDisplayTransactionNavigation && <MoneyRequestReportTransactionsNavigation currentReportID={reportID} />}
</HeaderWithBackButton>
{shouldShowMarkAsCashButton && shouldUseNarrowLayout && (
<View style={[styles.ph5, styles.pb3]}>
<Button
success
text={translate('iou.markAsCash')}
style={[styles.w100, styles.pr0]}
onPress={markAsCash}
/>
</View>
)}
{isDuplicate && shouldUseNarrowLayout && (
<View style={[styles.ph5, styles.pb3]}>
<Button
success
text={translate('iou.reviewDuplicates')}
style={[styles.w100, styles.pr0]}
onPress={() => {
if (!reportID) {
return;
}
Navigation.navigate(ROUTES.TRANSACTION_DUPLICATE_REVIEW_PAGE.getRoute(reportID, Navigation.getReportRHPActiveRoute()));
}}
/>
{shouldUseNarrowLayout && (
<View style={[styles.flexRow, styles.gap2, styles.pb3, styles.ph5, styles.w100, styles.alignItemsCenter, styles.justifyContentCenter]}>
{!!primaryAction && <View style={[styles.flexGrow4]}>{primaryActionImplementation[primaryAction]}</View>}
{!!applicableSecondaryActions.length && (
<ButtonWithDropdownMenu
success={false}
onPress={() => {}}
shouldAlwaysShowDropdownMenu
customText={translate('common.more')}
options={applicableSecondaryActions}
isSplitButton={false}
wrapperStyle={[!primaryAction && styles.flexGrow4]}
/>
)}
</View>
)}
{!!statusBarProps && (
Expand All @@ -222,6 +294,36 @@ function MoneyRequestHeader({report, parentReportAction, policy, onBackButtonPre
</View>
)}
<LoadingBar shouldShow={(isLoadingReportData && shouldUseNarrowLayout) ?? false} />
<DecisionModal
title={translate('common.downloadFailedTitle')}
prompt={translate('common.downloadFailedDescription')}
isSmallScreenWidth={isSmallScreenWidth}
onSecondOptionSubmit={() => setDownloadErrorModalVisible(false)}
secondOptionText={translate('common.buttonConfirm')}
isVisible={downloadErrorModalVisible}
onClose={() => setDownloadErrorModalVisible(false)}
/>
<ConfirmModal
title={translate('iou.deleteExpense', {count: 1})}
isVisible={isDeleteModalVisible}
onConfirm={() => {
setIsDeleteModalVisible(false);
if (!parentReportAction || !transaction) {
throw new Error('Data missing');
}

deleteMoneyRequest(transaction?.transactionID, parentReportAction);

const goBackRoute = getNavigationUrlOnMoneyRequestDelete(transaction.transactionID, parentReportAction, true);
navigateBackOnDeleteTransaction(goBackRoute);
}}
onCancel={() => setIsDeleteModalVisible(false)}
prompt={translate('iou.deleteConfirmation', {count: 1})}
confirmText={translate('common.delete')}
cancelText={translate('common.cancel')}
danger
shouldEnableNewFocusManagement
/>
</View>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, {useCallback} from 'react';
import {InteractionManager, View} from 'react-native';
import type {OnyxCollection, OnyxEntry} from 'react-native-onyx';
import {useOnyx} from 'react-native-onyx';
import Button from '@components/Button';
import HeaderGap from '@components/HeaderGap';
import MoneyReportHeader from '@components/MoneyReportHeader';
import OfflineWithFeedback from '@components/OfflineWithFeedback';
Expand All @@ -21,6 +22,7 @@ import {buildCannedSearchQuery} from '@libs/SearchQueryUtils';
import Navigation from '@navigation/Navigation';
import ReportActionsView from '@pages/home/report/ReportActionsView';
import ReportFooter from '@pages/home/report/ReportFooter';
import {openUnreportedExpense} from '@userActions/Report';
import NAVIGATORS from '@src/NAVIGATORS';
import ONYXKEYS from '@src/ONYXKEYS';
import type {Route} from '@src/ROUTES';
Expand Down
Loading