From 087cbcddeb4ace851c591b571bb62da0b5492ee0 Mon Sep 17 00:00:00 2001 From: FitseTLT Date: Wed, 20 Mar 2024 15:09:31 +0300 Subject: [PATCH 001/512] implemented confirmed route for report preview --- .../ReportActionItemImages.tsx | 27 +++++++++++++------ .../ReportActionItem/ReportPreview.tsx | 2 +- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/components/ReportActionItem/ReportActionItemImages.tsx b/src/components/ReportActionItem/ReportActionItemImages.tsx index ffc12957dcb4..dc9ed0d371fb 100644 --- a/src/components/ReportActionItem/ReportActionItemImages.tsx +++ b/src/components/ReportActionItem/ReportActionItemImages.tsx @@ -2,11 +2,13 @@ import React from 'react'; import {View} from 'react-native'; import {Polygon, Svg} from 'react-native-svg'; +import ConfirmedRoute from '@components/ConfirmedRoute'; import Text from '@components/Text'; import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import type {ThumbnailAndImageURI} from '@libs/ReceiptUtils'; +import * as TransactionUtils from '@libs/TransactionUtils'; import variables from '@styles/variables'; import ReportActionItemImage from './ReportActionItemImage'; @@ -70,19 +72,28 @@ function ReportActionItemImages({images, size, total, isHovered = false}: Report // Show a border to separate multiple images. Shown to the right for each except the last. const shouldShowBorder = shownImages.length > 1 && index < shownImages.length - 1; const borderStyle = shouldShowBorder ? styles.reportActionItemImageBorder : {}; + const isDistanceRequest = TransactionUtils.isDistanceRequest(transaction); + const hasPendingWaypoints = transaction?.pendingFields?.waypoints; + const showMapAsImage = isDistanceRequest && hasPendingWaypoints; return ( - + {showMapAsImage ? ( + + + + ) : ( + + )} {isLastImage && remaining > 0 && ( diff --git a/src/components/ReportActionItem/ReportPreview.tsx b/src/components/ReportActionItem/ReportPreview.tsx index f1aa1751dd84..57fa568eb487 100644 --- a/src/components/ReportActionItem/ReportPreview.tsx +++ b/src/components/ReportActionItem/ReportPreview.tsx @@ -135,7 +135,7 @@ function ReportPreview({ const isScanning = hasReceipts && areAllRequestsBeingSmartScanned; const hasErrors = hasMissingSmartscanFields || (canUseViolations && ReportUtils.hasViolations(iouReportID, transactionViolations)); const lastThreeTransactionsWithReceipts = transactionsWithReceipts.slice(-3); - const lastThreeReceipts = lastThreeTransactionsWithReceipts.map((transaction) => ReceiptUtils.getThumbnailAndImageURIs(transaction)); + const lastThreeReceipts = lastThreeTransactionsWithReceipts.map((transaction) => ({...ReceiptUtils.getThumbnailAndImageURIs(transaction), transaction})); let formattedMerchant = numberOfRequests === 1 && hasReceipts ? TransactionUtils.getMerchant(transactionsWithReceipts[0]) : null; if (TransactionUtils.isPartialMerchant(formattedMerchant ?? '')) { From eb4b183fcfbcce82e4277c84dc1aeb1a62a2e480 Mon Sep 17 00:00:00 2001 From: dukenv0307 Date: Thu, 21 Mar 2024 11:29:12 +0700 Subject: [PATCH 002/512] feature: Add validation flow to bank account set up --- src/languages/en.ts | 1 + src/languages/es.ts | 1 + src/libs/actions/User.ts | 7 +++++++ src/pages/ReimbursementAccount/BankAccountStep.js | 15 +++++++++++++++ 4 files changed, 24 insertions(+) diff --git a/src/languages/en.ts b/src/languages/en.ts index 29618b083bd5..60c051a289b1 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1413,6 +1413,7 @@ export default { validateAccountError: { phrase1: 'Hold up! We need you to validate your account first. To do so, ', phrase2: 'sign back in with a magic code', + phrase3: 'o verifique la cuenta aquí', }, hasPhoneLoginError: 'To add a verified bank account please ensure your primary login is a valid email and try again. You can add your phone number as a secondary login.', hasBeenThrottledError: 'There was an error adding your bank account. Please wait a few minutes and try again.', diff --git a/src/languages/es.ts b/src/languages/es.ts index 874921ee911a..811bfd2031d4 100644 --- a/src/languages/es.ts +++ b/src/languages/es.ts @@ -1432,6 +1432,7 @@ export default { validateAccountError: { phrase1: '¡Un momento! Primero necesitas validar tu cuenta. Para hacerlo, ', phrase2: 'vuelve a iniciar sesión con un código mágico', + phrase3: '', }, hasPhoneLoginError: 'Para añadir una cuenta bancaria verificada, asegúrate de que tu nombre de usuario principal sea un correo electrónico válido y vuelve a intentarlo. Puedes añadir tu número de teléfono como nombre de usuario secundario.', diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index 2d23edfba93f..e2bc4791d465 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -390,6 +390,13 @@ function validateSecondaryLogin(contactMethod: string, validateCode: string) { isLoading: true, }, }, + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.USER, + value: { + validated: true, + }, + }, ]; const successData: OnyxUpdate[] = [ { diff --git a/src/pages/ReimbursementAccount/BankAccountStep.js b/src/pages/ReimbursementAccount/BankAccountStep.js index e8aacadc6e1a..0ebcb1fe891e 100644 --- a/src/pages/ReimbursementAccount/BankAccountStep.js +++ b/src/pages/ReimbursementAccount/BankAccountStep.js @@ -20,6 +20,7 @@ import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; import getPlaidDesktopMessage from '@libs/getPlaidDesktopMessage'; +import Navigation from '@libs/Navigation/Navigation'; import variables from '@styles/variables'; import * as BankAccounts from '@userActions/BankAccounts'; import * as Link from '@userActions/Link'; @@ -83,6 +84,7 @@ function BankAccountStep(props) { props.policyID, ROUTES.WORKSPACE_INITIAL.getRoute(props.policyID), )}`; + const loginNames = _.keys(props.loginList); const removeExistingBankAccountDetails = () => { const bankAccountData = { @@ -180,6 +182,16 @@ function BankAccountStep(props) { > {props.translate('bankAccount.validateAccountError.phrase2')} + { + const login = props.loginList[loginNames[0]]; + + Navigation.navigate(ROUTES.SETTINGS_CONTACT_METHOD_DETAILS.getRoute(login.partnerUserID || loginNames[0])); + }} + > + {props.translate('bankAccount.validateAccountError.phrase3')} + . @@ -221,5 +233,8 @@ export default compose( isPlaidDisabled: { key: ONYXKEYS.IS_PLAID_DISABLED, }, + loginList: { + key: ONYXKEYS.LOGIN_LIST, + }, }), )(BankAccountStep); From cd70586476cf318c6fc0b6da01d0ec7a12a28356 Mon Sep 17 00:00:00 2001 From: FitseTLT Date: Thu, 28 Mar 2024 22:50:35 +0300 Subject: [PATCH 003/512] minor fixes --- src/components/ReportActionItem/ReportActionItemImages.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/ReportActionItem/ReportActionItemImages.tsx b/src/components/ReportActionItem/ReportActionItemImages.tsx index 53560307b314..921bb2271c69 100644 --- a/src/components/ReportActionItem/ReportActionItemImages.tsx +++ b/src/components/ReportActionItem/ReportActionItemImages.tsx @@ -71,8 +71,8 @@ function ReportActionItemImages({images, size, total, isHovered = false}: Report // Show a border to separate multiple images. Shown to the right for each except the last. const shouldShowBorder = shownImages.length > 1 && index < shownImages.length - 1; const borderStyle = shouldShowBorder ? styles.reportActionItemImageBorder : {}; - const isDistanceRequest = TransactionUtils.isDistanceRequest(transaction); - const hasPendingWaypoints = transaction?.pendingFields?.waypoints; + const isDistanceRequest = transaction && TransactionUtils.isDistanceRequest(transaction); + const hasPendingWaypoints = transaction && TransactionUtils.isFetchingWaypointsFromServer(transaction); const showMapAsImage = isDistanceRequest && hasPendingWaypoints; return ( {showMapAsImage ? ( - + ) : ( From 4828b6270f4cc3a13661b272111fc525730c6c37 Mon Sep 17 00:00:00 2001 From: FitseTLT Date: Mon, 8 Apr 2024 21:01:55 +0300 Subject: [PATCH 004/512] Changed empty state route pending icon --- assets/images/emptystate__routepending.svg | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/assets/images/emptystate__routepending.svg b/assets/images/emptystate__routepending.svg index 90f3296d37d6..aba08554d02f 100644 --- a/assets/images/emptystate__routepending.svg +++ b/assets/images/emptystate__routepending.svg @@ -1 +1,18 @@ - \ No newline at end of file + + + + + + + + + From 77e3ca4cf5c1bdfbf8b60ac3fde93228a374ddf7 Mon Sep 17 00:00:00 2001 From: FitseTLT Date: Mon, 8 Apr 2024 21:14:46 +0300 Subject: [PATCH 005/512] add icon fill color --- src/components/DistanceMapView/index.android.tsx | 3 +++ src/components/MapView/PendingMapView.tsx | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/src/components/DistanceMapView/index.android.tsx b/src/components/DistanceMapView/index.android.tsx index 168a480c6100..629b05d7bccf 100644 --- a/src/components/DistanceMapView/index.android.tsx +++ b/src/components/DistanceMapView/index.android.tsx @@ -5,6 +5,7 @@ import * as Expensicons from '@components/Icon/Expensicons'; import MapView from '@components/MapView'; import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; +import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import type DistanceMapViewProps from './types'; @@ -13,6 +14,7 @@ function DistanceMapView({overlayStyle, ...rest}: DistanceMapViewProps) { const [isMapReady, setIsMapReady] = useState(false); const {isOffline} = useNetwork(); const {translate} = useLocalize(); + const theme = useTheme(); return ( <> @@ -33,6 +35,7 @@ function DistanceMapView({overlayStyle, ...rest}: DistanceMapViewProps) { title={translate('distance.mapPending.title')} subtitle={isOffline ? translate('distance.mapPending.subtitle') : translate('distance.mapPending.onlineSubtitle')} shouldShowLink={false} + iconColor={theme.border} /> )} diff --git a/src/components/MapView/PendingMapView.tsx b/src/components/MapView/PendingMapView.tsx index 32bf42a14b10..e729d03ad477 100644 --- a/src/components/MapView/PendingMapView.tsx +++ b/src/components/MapView/PendingMapView.tsx @@ -4,6 +4,7 @@ import {View} from 'react-native'; import BlockingView from '@components/BlockingViews/BlockingView'; import Icon from '@components/Icon'; import * as Expensicons from '@components/Icon/Expensicons'; +import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import variables from '@styles/variables'; import type {PendingMapViewProps} from './MapViewTypes'; @@ -11,11 +12,13 @@ import type {PendingMapViewProps} from './MapViewTypes'; function PendingMapView({title = '', subtitle = '', style}: PendingMapViewProps) { const hasTextContent = !_.isEmpty(title) || !_.isEmpty(subtitle); const styles = useThemeStyles(); + const theme = useTheme(); return ( {hasTextContent ? ( )} From 420850de85d9ee701402a027b0692f42814432c7 Mon Sep 17 00:00:00 2001 From: FitseTLT Date: Mon, 8 Apr 2024 21:43:23 +0300 Subject: [PATCH 006/512] down sized icon for multiple previews --- src/components/ConfirmedRoute.tsx | 7 +++++-- src/components/MapView/MapViewTypes.ts | 3 +++ src/components/MapView/PendingMapView.tsx | 7 ++++--- src/components/ReportActionItem/ReportActionItemImages.tsx | 5 ++++- 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/components/ConfirmedRoute.tsx b/src/components/ConfirmedRoute.tsx index 17c5097b8154..596fc74dbbf6 100644 --- a/src/components/ConfirmedRoute.tsx +++ b/src/components/ConfirmedRoute.tsx @@ -26,9 +26,12 @@ type ConfirmedRoutePropsOnyxProps = { type ConfirmedRouteProps = ConfirmedRoutePropsOnyxProps & { /** Transaction that stores the distance request data */ transaction: OnyxEntry; + + /** Whether the size of the route pending icon is small. */ + isSmallIcon?: boolean; }; -function ConfirmedRoute({mapboxAccessToken, transaction}: ConfirmedRouteProps) { +function ConfirmedRoute({mapboxAccessToken, transaction, isSmallIcon}: ConfirmedRouteProps) { const {isOffline} = useNetwork(); const {route0: route} = transaction?.routes ?? {}; const waypoints = transaction?.comment?.waypoints ?? {}; @@ -102,7 +105,7 @@ function ConfirmedRoute({mapboxAccessToken, transaction}: ConfirmedRouteProps) { styleURL={CONST.MAPBOX.STYLE_URL} /> ) : ( - + ); } diff --git a/src/components/MapView/MapViewTypes.ts b/src/components/MapView/MapViewTypes.ts index 3fa52c54339b..d5c903fdeccb 100644 --- a/src/components/MapView/MapViewTypes.ts +++ b/src/components/MapView/MapViewTypes.ts @@ -36,6 +36,9 @@ type PendingMapViewProps = { /** Style applied to PendingMapView */ style?: StyleProp; + + /** Whether the size of the route pending icon is small. */ + isSmallIcon?: boolean; }; // Initial state of the map diff --git a/src/components/MapView/PendingMapView.tsx b/src/components/MapView/PendingMapView.tsx index e729d03ad477..2c79a0446f5e 100644 --- a/src/components/MapView/PendingMapView.tsx +++ b/src/components/MapView/PendingMapView.tsx @@ -9,10 +9,11 @@ import useThemeStyles from '@hooks/useThemeStyles'; import variables from '@styles/variables'; import type {PendingMapViewProps} from './MapViewTypes'; -function PendingMapView({title = '', subtitle = '', style}: PendingMapViewProps) { +function PendingMapView({title = '', subtitle = '', style, isSmallIcon = false}: PendingMapViewProps) { const hasTextContent = !_.isEmpty(title) || !_.isEmpty(subtitle); const styles = useThemeStyles(); const theme = useTheme(); + const iconSize = isSmallIcon ? variables.iconSizeSuperLarge : variables.iconSizeUltraLarge; return ( {hasTextContent ? ( @@ -27,8 +28,8 @@ function PendingMapView({title = '', subtitle = '', style}: PendingMapViewProps) diff --git a/src/components/ReportActionItem/ReportActionItemImages.tsx b/src/components/ReportActionItem/ReportActionItemImages.tsx index 921bb2271c69..04f5e5e7fdbb 100644 --- a/src/components/ReportActionItem/ReportActionItemImages.tsx +++ b/src/components/ReportActionItem/ReportActionItemImages.tsx @@ -81,7 +81,10 @@ function ReportActionItemImages({images, size, total, isHovered = false}: Report > {showMapAsImage ? ( - + ) : ( Date: Tue, 9 Apr 2024 11:12:59 +0300 Subject: [PATCH 007/512] change ultra large icon size --- src/styles/variables.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/variables.ts b/src/styles/variables.ts index 309c90fc631e..e70d2bf5c575 100644 --- a/src/styles/variables.ts +++ b/src/styles/variables.ts @@ -81,7 +81,7 @@ export default { iconSizeXLarge: 28, iconSizeExtraLarge: 40, iconSizeSuperLarge: 60, - iconSizeUltraLarge: 120, + iconSizeUltraLarge: 80, iconBottomBar: 24, sidebarAvatarSize: 28, iconHeader: 48, From 3a7f04cdbaa1232244d5c1efe4f1c587c81f7d64 Mon Sep 17 00:00:00 2001 From: FitseTLT Date: Tue, 9 Apr 2024 13:02:58 +0300 Subject: [PATCH 008/512] changed background color --- src/styles/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/styles/index.ts b/src/styles/index.ts index f165974119ff..d775fa04920a 100644 --- a/src/styles/index.ts +++ b/src/styles/index.ts @@ -4341,7 +4341,7 @@ const styles = (theme: ThemeColors) => }, mapPendingView: { - backgroundColor: theme.highlightBG, + backgroundColor: theme.hoverComponentBG, ...flex.flex1, borderRadius: variables.componentBorderRadiusLarge, }, From 23d62ea94184a054843ec5c3b20f273ceea6327c Mon Sep 17 00:00:00 2001 From: FitseTLT Date: Thu, 11 Apr 2024 22:42:57 +0300 Subject: [PATCH 009/512] fix border radius --- src/components/ConfirmedRoute.tsx | 7 ++++++- src/styles/utils/index.ts | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/components/ConfirmedRoute.tsx b/src/components/ConfirmedRoute.tsx index 596fc74dbbf6..fb0b4ddbb534 100644 --- a/src/components/ConfirmedRoute.tsx +++ b/src/components/ConfirmedRoute.tsx @@ -3,6 +3,7 @@ import type {ReactNode} from 'react'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import useNetwork from '@hooks/useNetwork'; +import useStyleUtils from '@hooks/useStyleUtils'; import useTheme from '@hooks/useTheme'; import useThemeStyles from '@hooks/useThemeStyles'; import * as TransactionUtils from '@libs/TransactionUtils'; @@ -38,6 +39,7 @@ function ConfirmedRoute({mapboxAccessToken, transaction, isSmallIcon}: Confirmed const coordinates = route?.geometry?.coordinates ?? []; const theme = useTheme(); const styles = useThemeStyles(); + const StyleUtils = useStyleUtils(); const getMarkerComponent = useCallback( (icon: IconAsset): ReactNode => ( @@ -105,7 +107,10 @@ function ConfirmedRoute({mapboxAccessToken, transaction, isSmallIcon}: Confirmed styleURL={CONST.MAPBOX.STYLE_URL} /> ) : ( - + ); } diff --git a/src/styles/utils/index.ts b/src/styles/utils/index.ts index e9efc84e8807..dd66a72faafa 100644 --- a/src/styles/utils/index.ts +++ b/src/styles/utils/index.ts @@ -419,6 +419,13 @@ function getBackgroundAndBorderStyle(backgroundColor: ColorValue | undefined): V }; } +/** + * Returns a style with the specified borderRadius + */ +function getBorderRadiusStyle(borderRadius: number): ViewStyle { + return {borderRadius}; +} + /** * Returns a style with the specified backgroundColor */ @@ -1108,6 +1115,7 @@ const staticStyleUtils = { getAvatarSize, getAvatarWidthStyle, getBackgroundAndBorderStyle, + getBorderRadiusStyle, getBackgroundColorStyle, getBackgroundColorWithOpacityStyle, getPaddingLeft, From b7cdaf83cbf947f9566005bca083f08e1a0047b9 Mon Sep 17 00:00:00 2001 From: gijoe0295 Date: Fri, 12 Apr 2024 04:04:11 +0700 Subject: [PATCH 010/512] feat: surfacing potential duplicates --- src/components/HoldBanner.tsx | 11 +++++-- src/components/MoneyRequestHeader.tsx | 29 +++++++++++++++-- src/languages/en.ts | 2 ++ src/languages/es.ts | 2 ++ src/libs/Permissions.ts | 2 +- src/libs/TransactionUtils.ts | 47 +++++++++++++++++++++++++-- src/types/onyx/Transaction.ts | 2 ++ 7 files changed, 87 insertions(+), 8 deletions(-) diff --git a/src/components/HoldBanner.tsx b/src/components/HoldBanner.tsx index af77d9076629..5376087ba849 100644 --- a/src/components/HoldBanner.tsx +++ b/src/components/HoldBanner.tsx @@ -5,14 +5,19 @@ import useThemeStyles from '@hooks/useThemeStyles'; import Text from './Text'; import TextPill from './TextPill'; -function HoldBanner() { +type HoldBannerProps = { + isRequestDuplicate?: boolean; + shouldShowBorderBottom?: boolean; +}; + +function HoldBanner({isRequestDuplicate = false, shouldShowBorderBottom = false}: HoldBannerProps) { const styles = useThemeStyles(); const {translate} = useLocalize(); return ( - + {translate('iou.hold')} - {translate('iou.requestOnHold')} + {isRequestDuplicate ? translate('iou.requestDuplicate') : translate('iou.requestOnHold')} ); } diff --git a/src/components/MoneyRequestHeader.tsx b/src/components/MoneyRequestHeader.tsx index f451f5f15581..6588b8167e62 100644 --- a/src/components/MoneyRequestHeader.tsx +++ b/src/components/MoneyRequestHeader.tsx @@ -16,6 +16,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Policy, Report, ReportAction, ReportActions, Session, Transaction} from '@src/types/onyx'; import type {OriginalMessageIOU} from '@src/types/onyx/OriginalMessage'; +import Button from './Button'; import ConfirmModal from './ConfirmModal'; import HeaderWithBackButton from './HeaderWithBackButton'; import HoldBanner from './HoldBanner'; @@ -61,6 +62,7 @@ function MoneyRequestHeader({session, parentReport, report, parentReportAction, const isSettled = ReportUtils.isSettled(moneyRequestReport?.reportID); const isApproved = ReportUtils.isReportApproved(moneyRequestReport); const isOnHold = TransactionUtils.isOnHold(transaction); + const isDuplicate = TransactionUtils.isDuplicate(transaction?.transactionID ?? ''); const {isSmallScreenWidth, windowWidth} = useWindowDimensions(); // Only the requestor can take delete the request, admins can only edit it. @@ -178,7 +180,15 @@ function MoneyRequestHeader({session, parentReport, report, parentReportAction, policy={policy} shouldShowBackButton={isSmallScreenWidth} onBackButtonPress={() => Navigation.goBack(undefined, false, true)} - /> + > + {isDuplicate && !isSmallScreenWidth && ( +