From 3c91994a84f00a7b00df6ff81e801d4d8f7f5d02 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Sat, 21 Sep 2024 13:47:17 +0700 Subject: [PATCH 01/10] Calculate routes for pending transaction backup --- src/CONST.ts | 6 + src/hooks/useFetchRoute.ts | 7 +- src/libs/API/types.ts | 1 + src/libs/actions/Transaction.ts | 268 +++++++++++++++++- .../step/IOURequestStepConfirmation.tsx | 2 +- .../request/step/IOURequestStepDistance.tsx | 7 +- src/types/utils/TransactionStateType.ts | 6 + 7 files changed, 285 insertions(+), 12 deletions(-) create mode 100644 src/types/utils/TransactionStateType.ts diff --git a/src/CONST.ts b/src/CONST.ts index 5a0c6f395eb4..87ca20a5d020 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -5775,6 +5775,12 @@ const CONST = { REPORT_ACTIONS: 'actions', REPORT_ACTION_PREVIEW: 'preview', }, + + TRANSACTION_STATE: { + CURRENT: 'current', + DRAFT: 'draft', + BACKUP: 'backup', + } } as const; type Country = keyof typeof CONST.ALL_COUNTRIES; diff --git a/src/hooks/useFetchRoute.ts b/src/hooks/useFetchRoute.ts index 4222f9f0183c..650734b68dc3 100644 --- a/src/hooks/useFetchRoute.ts +++ b/src/hooks/useFetchRoute.ts @@ -1,7 +1,6 @@ import isEqual from 'lodash/isEqual'; import {useEffect} from 'react'; import type {OnyxEntry} from 'react-native-onyx'; -import * as IOUUtils from '@libs/IOUUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import * as TransactionAction from '@userActions/Transaction'; import type {IOUAction} from '@src/CONST'; @@ -9,8 +8,10 @@ import type {Transaction} from '@src/types/onyx'; import type {WaypointCollection} from '@src/types/onyx/Transaction'; import useNetwork from './useNetwork'; import usePrevious from './usePrevious'; +import TransactionState from '@src/types/utils/TransactionStateType'; +import CONST from '@src/CONST'; -export default function useFetchRoute(transaction: OnyxEntry, waypoints: WaypointCollection | undefined, action: IOUAction) { +export default function useFetchRoute(transaction: OnyxEntry, waypoints: WaypointCollection | undefined, action: IOUAction, transactionState: TransactionState = CONST.TRANSACTION_STATE.CURRENT) { const {isOffline} = useNetwork(); const hasRouteError = !!transaction?.errorFields?.route; const hasRoute = TransactionUtils.hasRoute(transaction); @@ -27,7 +28,7 @@ export default function useFetchRoute(transaction: OnyxEntry, waypo return; } - TransactionAction.getRoute(transaction.transactionID, validatedWaypoints, IOUUtils.shouldUseTransactionDraft(action)); + TransactionAction.getRoute(transaction.transactionID, validatedWaypoints, transactionState); }, [shouldFetchRoute, transaction?.transactionID, validatedWaypoints, isOffline, action]); return {shouldFetchRoute, validatedWaypoints}; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index 37bdf6b81d6e..1976cce2d13a 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -842,6 +842,7 @@ const READ_COMMANDS = { SEND_PERFORMANCE_TIMING: 'SendPerformanceTiming', GET_ROUTE: 'GetRoute', GET_ROUTE_FOR_DRAFT: 'GetRouteForDraft', + GET_ROUTE_FOR_BACKUP: 'GetRouteForBackup', GET_STATEMENT_PDF: 'GetStatementPDF', OPEN_ONFIDO_FLOW: 'OpenOnfidoFlow', OPEN_INITIAL_SETTINGS_PAGE: 'OpenInitialSettingsPage', diff --git a/src/libs/actions/Transaction.ts b/src/libs/actions/Transaction.ts index e19251b62ce8..506c9a6ece4c 100644 --- a/src/libs/actions/Transaction.ts +++ b/src/libs/actions/Transaction.ts @@ -16,6 +16,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {PersonalDetails, RecentWaypoint, ReportAction, ReportActions, ReviewDuplicates, Transaction, TransactionViolation, TransactionViolations} from '@src/types/onyx'; import type {OnyxData} from '@src/types/onyx/Request'; import type {WaypointCollection} from '@src/types/onyx/Transaction'; +import type TransactionState from '@src/types/utils/TransactionStateType'; let recentWaypoints: RecentWaypoint[] = []; Onyx.connect({ @@ -199,13 +200,27 @@ function removeWaypoint(transaction: OnyxEntry, currentIndex: strin return Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction?.transactionID}`, newTransaction); } -function getOnyxDataForRouteRequest(transactionID: string, isDraft = false): OnyxData { +function getOnyxDataForRouteRequest(transactionID: string, transactionState: TransactionState = CONST.TRANSACTION_STATE.CURRENT): OnyxData { + let keyPrefix; + switch (transactionState) { + case CONST.TRANSACTION_STATE.DRAFT: + keyPrefix = ONYXKEYS.COLLECTION.TRANSACTION_DRAFT; + break; + case CONST.TRANSACTION_STATE.BACKUP: + keyPrefix = ONYXKEYS.COLLECTION.TRANSACTION_BACKUP; + break; + case CONST.TRANSACTION_STATE.CURRENT: + default: + keyPrefix = ONYXKEYS.COLLECTION.TRANSACTION; + break; + } + return { optimisticData: [ { // Clears any potentially stale error messages from fetching the route onyxMethod: Onyx.METHOD.MERGE, - key: `${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, + key: `${keyPrefix}${transactionID}`, value: { comment: { isLoading: true, @@ -220,7 +235,7 @@ function getOnyxDataForRouteRequest(transactionID: string, isDraft = false): Ony successData: [ { onyxMethod: Onyx.METHOD.MERGE, - key: `${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, + key: `${keyPrefix}${transactionID}`, value: { comment: { isLoading: false, @@ -231,7 +246,7 @@ function getOnyxDataForRouteRequest(transactionID: string, isDraft = false): Ony failureData: [ { onyxMethod: Onyx.METHOD.MERGE, - key: `${isDraft ? ONYXKEYS.COLLECTION.TRANSACTION_DRAFT : ONYXKEYS.COLLECTION.TRANSACTION}${transactionID}`, + key: `${keyPrefix}${transactionID}`, value: { comment: { isLoading: false, @@ -242,19 +257,258 @@ function getOnyxDataForRouteRequest(transactionID: string, isDraft = false): Ony }; } +function mockGetBackupRoute(transactionID: string) { + Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_BACKUP}${transactionID}`, { + "routes": { + "route0": { + "distance": 154384.844, + "geometry": { + "coordinates": [ + [ + 107.61964, + -6.917596 + ], + [ + 107.621458, + -6.918055 + ], + [ + 107.621155, + -6.919264 + ], + [ + 107.621862, + -6.92007 + ], + [ + 107.617256, + -6.922397 + ], + [ + 107.586943, + -6.918774 + ], + [ + 107.585588, + -6.926812 + ], + [ + 107.552806, + -6.938898 + ], + [ + 107.541552, + -6.912423 + ], + [ + 107.507715, + -6.867412 + ], + [ + 107.504802, + -6.856305 + ], + [ + 107.50362, + -6.841229 + ], + [ + 107.471934, + -6.809238 + ], + [ + 107.447898, + -6.798421 + ], + [ + 107.439988, + -6.779357 + ], + [ + 107.440242, + -6.74621 + ], + [ + 107.431506, + -6.708104 + ], + [ + 107.442126, + -6.666515 + ], + [ + 107.427061, + -6.653178 + ], + [ + 107.428849, + -6.642103 + ], + [ + 107.421426, + -6.611517 + ], + [ + 107.434251, + -6.579176 + ], + [ + 107.424954, + -6.559044 + ], + [ + 107.446783, + -6.484271 + ], + [ + 107.444693, + -6.467799 + ], + [ + 107.426815, + -6.442001 + ], + [ + 107.424102, + -6.423177 + ], + [ + 107.402604, + -6.392909 + ], + [ + 107.334314, + -6.355931 + ], + [ + 107.277154, + -6.349437 + ], + [ + 107.256766, + -6.349048 + ], + [ + 107.235902, + -6.355155 + ], + [ + 107.206996, + -6.349584 + ], + [ + 107.099379, + -6.29197 + ], + [ + 106.981406, + -6.249348 + ], + [ + 106.957583, + -6.256527 + ], + [ + 106.916207, + -6.258484 + ], + [ + 106.889886, + -6.244657 + ], + [ + 106.880764, + -6.247631 + ], + [ + 106.833371, + -6.240614 + ], + [ + 106.815565, + -6.224157 + ], + [ + 106.811859, + -6.219031 + ], + [ + 106.817977, + -6.214838 + ], + [ + 106.822696, + -6.195377 + ], + [ + 106.822922, + -6.194464 + ] + ], + "type": "LineString" + } + } + }, + "comment": { + "waypoints": { + "waypoint0": { + "keyForList": "Bandung_1726892371069", + "lat": -6.9174639, + "lng": 107.6191228, + "address": "Bandung, Bandung City, West Java, Indonesia", + "name": "Bandung" + }, + "waypoint1": { + "keyForList": "Jakarta_1726892375416", + "lat": -6.1944491, + "lng": 106.8229198, + "address": "Jakarta, Indonesia", + "name": "Jakarta" + } + }, + "customUnit": { + "quantity": 154384.844 + } + } + } + ) +} + + /** * Gets the route for a set of waypoints * Used so we can generate a map view of the provided waypoints */ -function getRoute(transactionID: string, waypoints: WaypointCollection, isDraft: boolean) { + + +function getRoute(transactionID: string, waypoints: WaypointCollection, routeType: TransactionState = CONST.TRANSACTION_STATE.CURRENT) { + if (routeType === CONST.TRANSACTION_STATE.BACKUP) + { + mockGetBackupRoute(transactionID); + } + const parameters: GetRouteParams = { transactionID, waypoints: JSON.stringify(waypoints), }; - API.read(isDraft ? READ_COMMANDS.GET_ROUTE_FOR_DRAFT : READ_COMMANDS.GET_ROUTE, parameters, getOnyxDataForRouteRequest(transactionID, isDraft)); -} + let command; + switch (routeType) { + case 'draft': + command = READ_COMMANDS.GET_ROUTE_FOR_DRAFT; + break; + case 'current': + command = READ_COMMANDS.GET_ROUTE; + break; + case 'backup': + command = READ_COMMANDS.GET_ROUTE_FOR_BACKUP; + break; + default: + throw new Error('Invalid route type'); + } + API.read(command, parameters, getOnyxDataForRouteRequest(transactionID, routeType === 'draft')); +} /** * Updates all waypoints stored in the transaction specified by the provided transactionID. * diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx index 6c1457abef62..5c7d697c01be 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx @@ -161,7 +161,7 @@ function IOURequestStepConfirmation({ const isPolicyExpenseChat = useMemo(() => participants?.some((participant) => participant.isPolicyExpenseChat), [participants]); const formHasBeenSubmitted = useRef(false); - useFetchRoute(transaction, transaction?.comment?.waypoints, action); + useFetchRoute(transaction, transaction?.comment?.waypoints, action, IOUUtils.shouldUseTransactionDraft(action) ? CONST.TRANSACTION_STATE.DRAFT : CONST.TRANSACTION_STATE.CURRENT); useEffect(() => { const policyExpenseChat = participants?.find((participant) => participant.isPolicyExpenseChat); diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index 14597df8e313..12d2cf375ca1 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -90,7 +90,12 @@ function IOURequestStepDistance({ }, [optimisticWaypoints, transaction], ); - const {shouldFetchRoute, validatedWaypoints} = useFetchRoute(transaction, waypoints, action); + + const backupWaypoints = !!transactionBackup?.pendingFields?.waypoints ? transactionBackup?.comment?.waypoints : undefined; + + const { shouldFetchRoute, validatedWaypoints } = useFetchRoute(transaction, waypoints, action, IOUUtils.shouldUseTransactionDraft(action) ? CONST.TRANSACTION_STATE.DRAFT : CONST.TRANSACTION_STATE.CURRENT); + useFetchRoute(transactionBackup, backupWaypoints, action, CONST.TRANSACTION_STATE.BACKUP); + const waypointsList = Object.keys(waypoints); const previousWaypoints = usePrevious(waypoints); const numberOfWaypoints = Object.keys(waypoints).length; diff --git a/src/types/utils/TransactionStateType.ts b/src/types/utils/TransactionStateType.ts new file mode 100644 index 000000000000..81c1438d873c --- /dev/null +++ b/src/types/utils/TransactionStateType.ts @@ -0,0 +1,6 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type TransactionStateType = ValueOf; + +export default TransactionStateType; \ No newline at end of file From 5f511d271bcf33beddf4c439d5f9454e2df4d41a Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Sat, 21 Sep 2024 15:44:00 +0700 Subject: [PATCH 02/10] fix incorrect param input --- src/libs/actions/Transaction.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libs/actions/Transaction.ts b/src/libs/actions/Transaction.ts index 506c9a6ece4c..1222e6455770 100644 --- a/src/libs/actions/Transaction.ts +++ b/src/libs/actions/Transaction.ts @@ -507,7 +507,7 @@ function getRoute(transactionID: string, waypoints: WaypointCollection, routeTyp throw new Error('Invalid route type'); } - API.read(command, parameters, getOnyxDataForRouteRequest(transactionID, routeType === 'draft')); + API.read(command, parameters, getOnyxDataForRouteRequest(transactionID, routeType)); } /** * Updates all waypoints stored in the transaction specified by the provided transactionID. From a53236d45b59a374fb0dfd43f879a6e4456dcba9 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Sat, 21 Sep 2024 16:05:33 +0700 Subject: [PATCH 03/10] return if use mock data --- src/libs/actions/Transaction.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libs/actions/Transaction.ts b/src/libs/actions/Transaction.ts index 1222e6455770..26eae38d2588 100644 --- a/src/libs/actions/Transaction.ts +++ b/src/libs/actions/Transaction.ts @@ -482,9 +482,11 @@ function mockGetBackupRoute(transactionID: string) { function getRoute(transactionID: string, waypoints: WaypointCollection, routeType: TransactionState = CONST.TRANSACTION_STATE.CURRENT) { + /** For testing, remove when new API endpoint ready, waypoints: Bandung, Jakarta */ if (routeType === CONST.TRANSACTION_STATE.BACKUP) { mockGetBackupRoute(transactionID); + return; } const parameters: GetRouteParams = { From ce2e18852de695f4990bf69f2a64a1a2dffcae36 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Fri, 25 Oct 2024 20:39:43 +0700 Subject: [PATCH 04/10] Refactor transaction state const --- src/hooks/useFetchRoute.ts | 2 +- src/libs/actions/Transaction.ts | 235 +----------------- .../step/IOURequestStepConfirmation.tsx | 2 +- .../request/step/IOURequestStepDistance.tsx | 4 +- src/types/utils/TransactionStateType.ts | 2 +- 5 files changed, 10 insertions(+), 235 deletions(-) diff --git a/src/hooks/useFetchRoute.ts b/src/hooks/useFetchRoute.ts index 650734b68dc3..b96d344cd78c 100644 --- a/src/hooks/useFetchRoute.ts +++ b/src/hooks/useFetchRoute.ts @@ -11,7 +11,7 @@ import usePrevious from './usePrevious'; import TransactionState from '@src/types/utils/TransactionStateType'; import CONST from '@src/CONST'; -export default function useFetchRoute(transaction: OnyxEntry, waypoints: WaypointCollection | undefined, action: IOUAction, transactionState: TransactionState = CONST.TRANSACTION_STATE.CURRENT) { +export default function useFetchRoute(transaction: OnyxEntry, waypoints: WaypointCollection | undefined, action: IOUAction, transactionState: TransactionState = CONST.TRANSACTION.STATE.CURRENT) { const {isOffline} = useNetwork(); const hasRouteError = !!transaction?.errorFields?.route; const hasRoute = TransactionUtils.hasRoute(transaction); diff --git a/src/libs/actions/Transaction.ts b/src/libs/actions/Transaction.ts index f7439322e00d..654e0943c74e 100644 --- a/src/libs/actions/Transaction.ts +++ b/src/libs/actions/Transaction.ts @@ -204,16 +204,16 @@ function removeWaypoint(transaction: OnyxEntry, currentIndex: strin return Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction?.transactionID}`, newTransaction); } -function getOnyxDataForRouteRequest(transactionID: string, transactionState: TransactionState = CONST.TRANSACTION_STATE.CURRENT): OnyxData { +function getOnyxDataForRouteRequest(transactionID: string, transactionState: TransactionState = CONST.TRANSACTION.STATE.CURRENT): OnyxData { let keyPrefix; switch (transactionState) { - case CONST.TRANSACTION_STATE.DRAFT: + case CONST.TRANSACTION.STATE.DRAFT: keyPrefix = ONYXKEYS.COLLECTION.TRANSACTION_DRAFT; break; - case CONST.TRANSACTION_STATE.BACKUP: + case CONST.TRANSACTION.STATE.BACKUP: keyPrefix = ONYXKEYS.COLLECTION.TRANSACTION_BACKUP; break; - case CONST.TRANSACTION_STATE.CURRENT: + case CONST.TRANSACTION.STATE.CURRENT: default: keyPrefix = ONYXKEYS.COLLECTION.TRANSACTION; break; @@ -261,224 +261,6 @@ function getOnyxDataForRouteRequest(transactionID: string, transactionState: Tra }; } -function mockGetBackupRoute(transactionID: string) { - Onyx.merge(`${ONYXKEYS.COLLECTION.TRANSACTION_BACKUP}${transactionID}`, { - "routes": { - "route0": { - "distance": 154384.844, - "geometry": { - "coordinates": [ - [ - 107.61964, - -6.917596 - ], - [ - 107.621458, - -6.918055 - ], - [ - 107.621155, - -6.919264 - ], - [ - 107.621862, - -6.92007 - ], - [ - 107.617256, - -6.922397 - ], - [ - 107.586943, - -6.918774 - ], - [ - 107.585588, - -6.926812 - ], - [ - 107.552806, - -6.938898 - ], - [ - 107.541552, - -6.912423 - ], - [ - 107.507715, - -6.867412 - ], - [ - 107.504802, - -6.856305 - ], - [ - 107.50362, - -6.841229 - ], - [ - 107.471934, - -6.809238 - ], - [ - 107.447898, - -6.798421 - ], - [ - 107.439988, - -6.779357 - ], - [ - 107.440242, - -6.74621 - ], - [ - 107.431506, - -6.708104 - ], - [ - 107.442126, - -6.666515 - ], - [ - 107.427061, - -6.653178 - ], - [ - 107.428849, - -6.642103 - ], - [ - 107.421426, - -6.611517 - ], - [ - 107.434251, - -6.579176 - ], - [ - 107.424954, - -6.559044 - ], - [ - 107.446783, - -6.484271 - ], - [ - 107.444693, - -6.467799 - ], - [ - 107.426815, - -6.442001 - ], - [ - 107.424102, - -6.423177 - ], - [ - 107.402604, - -6.392909 - ], - [ - 107.334314, - -6.355931 - ], - [ - 107.277154, - -6.349437 - ], - [ - 107.256766, - -6.349048 - ], - [ - 107.235902, - -6.355155 - ], - [ - 107.206996, - -6.349584 - ], - [ - 107.099379, - -6.29197 - ], - [ - 106.981406, - -6.249348 - ], - [ - 106.957583, - -6.256527 - ], - [ - 106.916207, - -6.258484 - ], - [ - 106.889886, - -6.244657 - ], - [ - 106.880764, - -6.247631 - ], - [ - 106.833371, - -6.240614 - ], - [ - 106.815565, - -6.224157 - ], - [ - 106.811859, - -6.219031 - ], - [ - 106.817977, - -6.214838 - ], - [ - 106.822696, - -6.195377 - ], - [ - 106.822922, - -6.194464 - ] - ], - "type": "LineString" - } - } - }, - "comment": { - "waypoints": { - "waypoint0": { - "keyForList": "Bandung_1726892371069", - "lat": -6.9174639, - "lng": 107.6191228, - "address": "Bandung, Bandung City, West Java, Indonesia", - "name": "Bandung" - }, - "waypoint1": { - "keyForList": "Jakarta_1726892375416", - "lat": -6.1944491, - "lng": 106.8229198, - "address": "Jakarta, Indonesia", - "name": "Jakarta" - } - }, - "customUnit": { - "quantity": 154384.844 - } - } - } - ) -} - - /** * Sanitizes the waypoints by removing the pendingAction property. * @@ -499,14 +281,7 @@ function sanitizeRecentWaypoints(waypoints: WaypointCollection): WaypointCollect */ -function getRoute(transactionID: string, waypoints: WaypointCollection, routeType: TransactionState = CONST.TRANSACTION_STATE.CURRENT) { - /** For testing, remove when new API endpoint ready, waypoints: Bandung, Jakarta */ - if (routeType === CONST.TRANSACTION_STATE.BACKUP) - { - mockGetBackupRoute(transactionID); - return; - } - +function getRoute(transactionID: string, waypoints: WaypointCollection, routeType: TransactionState = CONST.TRANSACTION.STATE.CURRENT) { const parameters: GetRouteParams = { transactionID, waypoints: JSON.stringify(sanitizeRecentWaypoints(waypoints)), diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx index ee934a380d31..f436504315be 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.tsx +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.tsx @@ -145,7 +145,7 @@ function IOURequestStepConfirmation({ const isPolicyExpenseChat = useMemo(() => participants?.some((participant) => participant.isPolicyExpenseChat), [participants]); const formHasBeenSubmitted = useRef(false); - useFetchRoute(transaction, transaction?.comment?.waypoints, action, IOUUtils.shouldUseTransactionDraft(action) ? CONST.TRANSACTION_STATE.DRAFT : CONST.TRANSACTION_STATE.CURRENT); + useFetchRoute(transaction, transaction?.comment?.waypoints, action, IOUUtils.shouldUseTransactionDraft(action) ? CONST.TRANSACTION.STATE.DRAFT : CONST.TRANSACTION.STATE.CURRENT); useEffect(() => { const policyExpenseChat = participants?.find((participant) => participant.isPolicyExpenseChat); diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index ec45545b42fc..1b1b30d697f4 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -81,8 +81,8 @@ function IOURequestStepDistance({ const backupWaypoints = !!transactionBackup?.pendingFields?.waypoints ? transactionBackup?.comment?.waypoints : undefined; - const { shouldFetchRoute, validatedWaypoints } = useFetchRoute(transaction, waypoints, action, IOUUtils.shouldUseTransactionDraft(action) ? CONST.TRANSACTION_STATE.DRAFT : CONST.TRANSACTION_STATE.CURRENT); - useFetchRoute(transactionBackup, backupWaypoints, action, CONST.TRANSACTION_STATE.BACKUP); + const { shouldFetchRoute, validatedWaypoints } = useFetchRoute(transaction, waypoints, action, IOUUtils.shouldUseTransactionDraft(action) ? CONST.TRANSACTION.STATE.DRAFT : CONST.TRANSACTION.STATE.CURRENT); + useFetchRoute(transactionBackup, backupWaypoints, action, CONST.TRANSACTION.STATE.BACKUP); const waypointsList = Object.keys(waypoints); const previousWaypoints = usePrevious(waypoints); diff --git a/src/types/utils/TransactionStateType.ts b/src/types/utils/TransactionStateType.ts index 81c1438d873c..fa5dd8a2862f 100644 --- a/src/types/utils/TransactionStateType.ts +++ b/src/types/utils/TransactionStateType.ts @@ -1,6 +1,6 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; -type TransactionStateType = ValueOf; +type TransactionStateType = ValueOf; export default TransactionStateType; \ No newline at end of file From e01442fd9b8f4621d3c979928af0658f5e88893a Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Fri, 25 Oct 2024 20:57:23 +0700 Subject: [PATCH 05/10] add ReadCommandParameters for transaction backup --- src/libs/API/types.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts index a513668df115..c47926c22886 100644 --- a/src/libs/API/types.ts +++ b/src/libs/API/types.ts @@ -959,6 +959,7 @@ type ReadCommandParameters = { [READ_COMMANDS.SEND_PERFORMANCE_TIMING]: Parameters.SendPerformanceTimingParams; [READ_COMMANDS.GET_ROUTE]: Parameters.GetRouteParams; [READ_COMMANDS.GET_ROUTE_FOR_DRAFT]: Parameters.GetRouteParams; + [READ_COMMANDS.GET_ROUTE_FOR_BACKUP]: Parameters.GetRouteParams; [READ_COMMANDS.GET_STATEMENT_PDF]: Parameters.GetStatementPDFParams; [READ_COMMANDS.OPEN_ONFIDO_FLOW]: null; [READ_COMMANDS.OPEN_INITIAL_SETTINGS_PAGE]: null; From be7c27aba578a4e41e2e7a5a39e37f0ee621879c Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Sat, 26 Oct 2024 07:11:11 +0700 Subject: [PATCH 06/10] prettier & lint --- src/hooks/useFetchRoute.ts | 13 +++++++++---- src/libs/actions/Transaction.ts | 1 - .../iou/request/step/IOURequestStepDistance.tsx | 9 +++++++-- src/types/utils/TransactionStateType.ts | 2 +- 4 files changed, 17 insertions(+), 8 deletions(-) diff --git a/src/hooks/useFetchRoute.ts b/src/hooks/useFetchRoute.ts index b96d344cd78c..3232b7e02e37 100644 --- a/src/hooks/useFetchRoute.ts +++ b/src/hooks/useFetchRoute.ts @@ -4,14 +4,19 @@ import type {OnyxEntry} from 'react-native-onyx'; import * as TransactionUtils from '@libs/TransactionUtils'; import * as TransactionAction from '@userActions/Transaction'; import type {IOUAction} from '@src/CONST'; +import CONST from '@src/CONST'; import type {Transaction} from '@src/types/onyx'; import type {WaypointCollection} from '@src/types/onyx/Transaction'; +import type TransactionState from '@src/types/utils/TransactionStateType'; import useNetwork from './useNetwork'; import usePrevious from './usePrevious'; -import TransactionState from '@src/types/utils/TransactionStateType'; -import CONST from '@src/CONST'; -export default function useFetchRoute(transaction: OnyxEntry, waypoints: WaypointCollection | undefined, action: IOUAction, transactionState: TransactionState = CONST.TRANSACTION.STATE.CURRENT) { +export default function useFetchRoute( + transaction: OnyxEntry, + waypoints: WaypointCollection | undefined, + action: IOUAction, + transactionState: TransactionState = CONST.TRANSACTION.STATE.CURRENT, +) { const {isOffline} = useNetwork(); const hasRouteError = !!transaction?.errorFields?.route; const hasRoute = TransactionUtils.hasRoute(transaction); @@ -29,7 +34,7 @@ export default function useFetchRoute(transaction: OnyxEntry, waypo } TransactionAction.getRoute(transaction.transactionID, validatedWaypoints, transactionState); - }, [shouldFetchRoute, transaction?.transactionID, validatedWaypoints, isOffline, action]); + }, [shouldFetchRoute, transaction?.transactionID, validatedWaypoints, isOffline, action, transactionState]); return {shouldFetchRoute, validatedWaypoints}; } diff --git a/src/libs/actions/Transaction.ts b/src/libs/actions/Transaction.ts index 654e0943c74e..6f210a8ed095 100644 --- a/src/libs/actions/Transaction.ts +++ b/src/libs/actions/Transaction.ts @@ -280,7 +280,6 @@ function sanitizeRecentWaypoints(waypoints: WaypointCollection): WaypointCollect * Used so we can generate a map view of the provided waypoints */ - function getRoute(transactionID: string, waypoints: WaypointCollection, routeType: TransactionState = CONST.TRANSACTION.STATE.CURRENT) { const parameters: GetRouteParams = { transactionID, diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index 1b1b30d697f4..b81f45f91aae 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -79,9 +79,14 @@ function IOURequestStepDistance({ [optimisticWaypoints, transaction], ); - const backupWaypoints = !!transactionBackup?.pendingFields?.waypoints ? transactionBackup?.comment?.waypoints : undefined; + const backupWaypoints = transactionBackup?.pendingFields?.waypoints ? transactionBackup?.comment?.waypoints : undefined; - const { shouldFetchRoute, validatedWaypoints } = useFetchRoute(transaction, waypoints, action, IOUUtils.shouldUseTransactionDraft(action) ? CONST.TRANSACTION.STATE.DRAFT : CONST.TRANSACTION.STATE.CURRENT); + const {shouldFetchRoute, validatedWaypoints} = useFetchRoute( + transaction, + waypoints, + action, + IOUUtils.shouldUseTransactionDraft(action) ? CONST.TRANSACTION.STATE.DRAFT : CONST.TRANSACTION.STATE.CURRENT, + ); useFetchRoute(transactionBackup, backupWaypoints, action, CONST.TRANSACTION.STATE.BACKUP); const waypointsList = Object.keys(waypoints); diff --git a/src/types/utils/TransactionStateType.ts b/src/types/utils/TransactionStateType.ts index fa5dd8a2862f..5564de95c001 100644 --- a/src/types/utils/TransactionStateType.ts +++ b/src/types/utils/TransactionStateType.ts @@ -3,4 +3,4 @@ import type CONST from '@src/CONST'; type TransactionStateType = ValueOf; -export default TransactionStateType; \ No newline at end of file +export default TransactionStateType; From 5f29bd5eec6a7fa0fe09a1d1547ea8f5c0b8be2e Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Sat, 26 Oct 2024 07:13:50 +0700 Subject: [PATCH 07/10] add comment --- src/pages/iou/request/step/IOURequestStepDistance.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index b81f45f91aae..69798617145d 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -87,6 +87,8 @@ function IOURequestStepDistance({ action, IOUUtils.shouldUseTransactionDraft(action) ? CONST.TRANSACTION.STATE.DRAFT : CONST.TRANSACTION.STATE.CURRENT, ); + + // When online, fetch the backup route to ensure the map is populated even if the user does not save the transaction useFetchRoute(transactionBackup, backupWaypoints, action, CONST.TRANSACTION.STATE.BACKUP); const waypointsList = Object.keys(waypoints); From 2c1fe4235c90823306a65e4f5e0129bf0a6e0009 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Sat, 26 Oct 2024 14:04:37 +0700 Subject: [PATCH 08/10] Update missing transaction report fields by re-opening transaction report when backup restored --- .../iou/request/step/IOURequestStepDistance.tsx | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/src/pages/iou/request/step/IOURequestStepDistance.tsx b/src/pages/iou/request/step/IOURequestStepDistance.tsx index 69798617145d..03cffc1ec1dd 100644 --- a/src/pages/iou/request/step/IOURequestStepDistance.tsx +++ b/src/pages/iou/request/step/IOURequestStepDistance.tsx @@ -20,6 +20,7 @@ import useNetwork from '@hooks/useNetwork'; import usePolicy from '@hooks/usePolicy'; import usePrevious from '@hooks/usePrevious'; import useThemeStyles from '@hooks/useThemeStyles'; +import * as Report from '@libs/actions/Report'; import DistanceRequestUtils from '@libs/DistanceRequestUtils'; import type {MileageRate} from '@libs/DistanceRequestUtils'; import * as ErrorUtils from '@libs/ErrorUtils'; @@ -80,17 +81,16 @@ function IOURequestStepDistance({ ); const backupWaypoints = transactionBackup?.pendingFields?.waypoints ? transactionBackup?.comment?.waypoints : undefined; - + // When online, fetch the backup route to ensure the map is populated even if the user does not save the transaction. + // Fetch the backup route first to ensure the backup transaction map is updated before the main transaction map. + // This prevents a scenario where the main map loads, the user dismisses the map editor, and the backup map has not yet loaded due to delay. + useFetchRoute(transactionBackup, backupWaypoints, action, CONST.TRANSACTION.STATE.BACKUP); const {shouldFetchRoute, validatedWaypoints} = useFetchRoute( transaction, waypoints, action, IOUUtils.shouldUseTransactionDraft(action) ? CONST.TRANSACTION.STATE.DRAFT : CONST.TRANSACTION.STATE.CURRENT, ); - - // When online, fetch the backup route to ensure the map is populated even if the user does not save the transaction - useFetchRoute(transactionBackup, backupWaypoints, action, CONST.TRANSACTION.STATE.BACKUP); - const waypointsList = Object.keys(waypoints); const previousWaypoints = usePrevious(waypoints); const numberOfWaypoints = Object.keys(waypoints).length; @@ -225,6 +225,12 @@ function IOURequestStepDistance({ return; } TransactionEdit.restoreOriginalTransactionFromBackup(transaction?.transactionID ?? '-1', IOUUtils.shouldUseTransactionDraft(action)); + + // If the user opens IOURequestStepDistance in offline mode and then goes online, re-open the report to fill in missing fields from the transaction backup + if (!transaction?.reportID) { + return; + } + Report.openReport(transaction?.reportID); }; // eslint-disable-next-line react-compiler/react-compiler, react-hooks/exhaustive-deps }, []); From 48356fa112909a138ec9897d5f389d789e715ba3 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Wed, 30 Oct 2024 09:43:52 +0700 Subject: [PATCH 09/10] change routeType to const --- src/libs/actions/Transaction.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libs/actions/Transaction.ts b/src/libs/actions/Transaction.ts index 6f210a8ed095..85963e17cc72 100644 --- a/src/libs/actions/Transaction.ts +++ b/src/libs/actions/Transaction.ts @@ -288,13 +288,13 @@ function getRoute(transactionID: string, waypoints: WaypointCollection, routeTyp let command; switch (routeType) { - case 'draft': + case CONST.TRANSACTION.STATE.DRAFT: command = READ_COMMANDS.GET_ROUTE_FOR_DRAFT; break; - case 'current': + case CONST.TRANSACTION.STATE.CURRENT: command = READ_COMMANDS.GET_ROUTE; break; - case 'backup': + case CONST.TRANSACTION.STATE.BACKUP: command = READ_COMMANDS.GET_ROUTE_FOR_BACKUP; break; default: From 198ccb37cc57dde053e88bd539df1cc367679c79 Mon Sep 17 00:00:00 2001 From: Wildan Muhlis Date: Wed, 30 Oct 2024 13:09:28 +0700 Subject: [PATCH 10/10] Resolve map not clickable when restoring transaction backup --- src/libs/actions/Transaction.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libs/actions/Transaction.ts b/src/libs/actions/Transaction.ts index 85963e17cc72..fe15515bcb4a 100644 --- a/src/libs/actions/Transaction.ts +++ b/src/libs/actions/Transaction.ts @@ -244,6 +244,14 @@ function getOnyxDataForRouteRequest(transactionID: string, transactionState: Tra comment: { isLoading: false, }, + // When the user opens the distance request editor and changes the connection from offline to online, + // the transaction's pendingFields and pendingAction will be removed, but not transactionBackup. + // We clear the pendingFields and pendingAction for the backup here to ensure consistency with the transaction. + // Without this, the map will not be clickable if the user dismisses the distance request editor without saving. + ...(transactionState === CONST.TRANSACTION.STATE.BACKUP && { + pendingFields: {waypoints: null}, + pendingAction: null, + }), }, }, ],