Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TS migration] Migrate 'IOUWaypoint' page to TypeScript #33244

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
dde6aca
chore: move IOUWaypoint Pages to TS
kubabutkiewicz Dec 18, 2023
36c73ed
ref: seperate types
kubabutkiewicz Dec 18, 2023
a32e718
chore: added todos
kubabutkiewicz Dec 20, 2023
1d1f0fa
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Dec 20, 2023
049e7ad
fix: address comments
kubabutkiewicz Dec 20, 2023
2a75175
fix: adjust recentwaypoint type
kubabutkiewicz Dec 21, 2023
437636a
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Jan 2, 2024
9b36c85
fix: type problems
kubabutkiewicz Jan 2, 2024
3a448bb
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Jan 3, 2024
7f463df
fix: resolve comments
kubabutkiewicz Jan 3, 2024
26ee70c
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Jan 8, 2024
72b7efb
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Jan 15, 2024
02dbc36
fix: move changes to new file
kubabutkiewicz Jan 15, 2024
e6164a2
fix: type errors
kubabutkiewicz Jan 15, 2024
f8c1cc4
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Jan 15, 2024
b399f8a
fix: types
kubabutkiewicz Jan 15, 2024
4755a0f
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Jan 18, 2024
374a4a3
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Jan 22, 2024
5adf756
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Jan 31, 2024
bfb8b43
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 2, 2024
5190bd1
fix: typecheck
kubabutkiewicz Feb 2, 2024
4bcf243
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 2, 2024
c232f39
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 5, 2024
bf8e335
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 6, 2024
2deb942
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 6, 2024
e945840
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 7, 2024
490c77a
fix: typecheck
kubabutkiewicz Feb 7, 2024
ce58b9d
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 8, 2024
040a383
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 13, 2024
61a2595
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 14, 2024
7a7baf9
fix: typecheck
kubabutkiewicz Feb 14, 2024
75073fe
fix: typecheck
kubabutkiewicz Feb 14, 2024
59a03f9
fix: typecheck
kubabutkiewicz Feb 14, 2024
3aea0ef
fix: when searching for waypoint
kubabutkiewicz Feb 14, 2024
b94ab89
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 15, 2024
f600f67
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 15, 2024
0f84798
fix: ci
kubabutkiewicz Feb 15, 2024
e60d866
fix: removed podfile.lock and gemfile
kubabutkiewicz Feb 20, 2024
567d0a7
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 20, 2024
73d0864
fix: revert changes to Gemfile.lock
kubabutkiewicz Feb 20, 2024
28eacfe
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 22, 2024
e34ae0b
fix: resolve comments
kubabutkiewicz Feb 22, 2024
1ff718c
Merge branch 'main' of github.com:kubabutkiewicz/expensify-app into t…
kubabutkiewicz Feb 23, 2024
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
2 changes: 1 addition & 1 deletion src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -546,4 +546,4 @@ type Route = RouteIsPlainString extends true ? never : AllRoutes;

type HybridAppRoute = (typeof HYBRID_APP_ROUTES)[keyof typeof HYBRID_APP_ROUTES];

export type {Route, HybridAppRoute};
export type {Route, HybridAppRoute, AllRoutes};
10 changes: 5 additions & 5 deletions src/components/AddressSearch/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ function AddressSearch(

const renderHeaderComponent = () => (
<>
{predefinedPlaces.length > 0 && (
{(predefinedPlaces?.length ?? 0) > 0 && (
<>
{/* This will show current location button in list if there are some recent destinations */}
{shouldShowCurrentLocationButton && (
Expand Down Expand Up @@ -339,7 +339,7 @@ function AddressSearch(
fetchDetails
suppressDefaultStyles
enablePoweredByContainer={false}
predefinedPlaces={predefinedPlaces}
predefinedPlaces={predefinedPlaces ?? undefined}
listEmptyComponent={listEmptyComponent}
listLoaderComponent={listLoader}
renderHeaderComponent={renderHeaderComponent}
Expand All @@ -348,7 +348,7 @@ function AddressSearch(
const subtitle = data.isPredefinedPlace ? data.description : data.structured_formatting.secondary_text;
return (
<View>
{title && <Text style={[styles.googleSearchText]}>{title}</Text>}
{!!title && <Text style={[styles.googleSearchText]}>{title}</Text>}
<Text style={[styles.textLabelSupporting]}>{subtitle}</Text>
</View>
);
Expand Down Expand Up @@ -398,10 +398,10 @@ function AddressSearch(
if (inputID) {
onInputChange?.(text);
} else {
onInputChange({street: text});
onInputChange?.({street: text});
}
// If the text is empty and we have no predefined places, we set displayListViewBorder to false to prevent UI flickering
if (!text && !predefinedPlaces.length) {
if (!text && !predefinedPlaces?.length) {
setDisplayListViewBorder(false);
}
},
Expand Down
6 changes: 4 additions & 2 deletions src/components/AddressSearch/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ type RenamedInputKeysProps = {
lat: string;
lng: string;
zipCode: string;
address?: string;
country?: string;
};

type OnPressProps = {
Expand Down Expand Up @@ -59,7 +61,7 @@ type AddressSearchProps = {
defaultValue?: string;

/** A callback function when the value of this field has changed */
onInputChange: (value: string | number | RenamedInputKeysProps | StreetValue, key?: string) => void;
onInputChange?: (value: string | number | RenamedInputKeysProps | StreetValue, key?: string) => void;

/** A callback function when an address has been auto-selected */
onPress?: (props: OnPressProps) => void;
Expand All @@ -74,7 +76,7 @@ type AddressSearchProps = {
canUseCurrentLocation?: boolean;

/** A list of predefined places that can be shown when the user isn't searching for something */
predefinedPlaces?: Place[];
predefinedPlaces?: Place[] | null;

/** A map of inputID key names */
renamedInputKeys: RenamedInputKeysProps;
Expand Down
11 changes: 7 additions & 4 deletions src/hooks/useLocationBias.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import {useMemo} from 'react';
import type {OnyxEntry} from 'react-native-onyx';
import type {UserLocation} from '@src/types/onyx';
import type {WaypointCollection} from '@src/types/onyx/Transaction';

/**
* Construct the rectangular boundary based on user location and waypoints
*/
export default function useLocationBias(allWaypoints: Record<string, {lng?: number; lat?: number}>, userLocation?: {latitude: number; longitude: number}) {
export default function useLocationBias(allWaypoints: WaypointCollection, userLocation?: OnyxEntry<UserLocation>) {
return useMemo(() => {
const hasFilledWaypointCount = Object.values(allWaypoints).some((waypoint) => Object.keys(waypoint).length > 0);
// If there are no filled wayPoints and if user's current location cannot be retrieved,
// it is futile to arrive at a biased location. Let's return
if (!hasFilledWaypointCount && userLocation === undefined) {
return null;
return undefined;
}

// Gather the longitudes and latitudes from filled waypoints.
Expand All @@ -29,8 +32,8 @@ export default function useLocationBias(allWaypoints: Record<string, {lng?: numb
// When no filled waypoints are available but the current location of the user is available,
// let us consider the current user's location to construct a rectangular bound
if (!hasFilledWaypointCount && userLocation !== undefined) {
longitudes.push(userLocation.longitude);
latitudes.push(userLocation.latitude);
longitudes.push(userLocation?.longitude ?? 0);
latitudes.push(userLocation?.latitude ?? 0);
}

// Extend the rectangular bound by 0.5 degree (roughly around 25-30 miles in US)
Expand Down
7 changes: 7 additions & 0 deletions src/libs/Navigation/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,13 @@ type MoneyRequestNavigatorParamList = {
reportID: string;
backTo: string;
};
[SCREENS.MONEY_REQUEST.STEP_WAYPOINT]: {
iouType: ValueOf<typeof CONST.IOU.TYPE>;
reportID: string;
backTo: Routes | undefined;
action: ValueOf<typeof CONST.IOU.ACTION>;
pageIndex: string;
};
[SCREENS.MONEY_REQUEST.STEP_MERCHANT]: {
action: ValueOf<typeof CONST.IOU.ACTION>;
iouType: ValueOf<typeof CONST.IOU.TYPE>;
Expand Down
6 changes: 5 additions & 1 deletion src/libs/ValidationUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ function validateCardNumber(value: string): boolean {
/**
* Validating that this is a valid address (PO boxes are not allowed)
*/
function isValidAddress(value: string): boolean {
function isValidAddress(value: FormValue): boolean {
if (typeof value !== 'string') {
return false;
}

if (!CONST.REGEX.ANY_VALUE.test(value) || value.match(CONST.REGEX.EMOJIS)) {
return false;
}
Expand Down
12 changes: 7 additions & 5 deletions src/libs/actions/Transaction.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {isEqual} from 'lodash';
import lodashClone from 'lodash/clone';
import lodashHas from 'lodash/has';
import type {OnyxEntry} from 'react-native-onyx';
import Onyx from 'react-native-onyx';
import * as API from '@libs/API';
import type {GetRouteForDraftParams, GetRouteParams} from '@libs/API/parameters';
Expand Down Expand Up @@ -106,7 +107,7 @@ function saveWaypoint(transactionID: string, index: string, waypoint: RecentWayp
}
}

function removeWaypoint(transaction: Transaction, currentIndex: string, isDraft: boolean) {
function removeWaypoint(transaction: OnyxEntry<Transaction>, currentIndex: string, isDraft?: boolean) {
// Index comes from the route params and is a string
const index = Number(currentIndex);
const existingWaypoints = transaction?.comment?.waypoints ?? {};
Expand Down Expand Up @@ -134,9 +135,10 @@ function removeWaypoint(transaction: Transaction, currentIndex: string, isDraft:
// to remove nested keys while also preserving other object keys
// Doing a deep clone of the transaction to avoid mutating the original object and running into a cache issue when using Onyx.set
let newTransaction: Transaction = {
...transaction,
// eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style
...(transaction as Transaction),
kubabutkiewicz marked this conversation as resolved.
Show resolved Hide resolved
comment: {
...transaction.comment,
...transaction?.comment,
waypoints: reIndexedWaypoints,
},
// We want to reset the amount only for draft transactions (when creating the request).
Expand Down Expand Up @@ -164,10 +166,10 @@ function removeWaypoint(transaction: Transaction, currentIndex: string, isDraft:
};
}
if (isDraft) {
Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transaction.transactionID}`, newTransaction);
Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION_DRAFT}${transaction?.transactionID}`, newTransaction);
return;
}
Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction.transactionID}`, newTransaction);
Onyx.set(`${ONYXKEYS.COLLECTION.TRANSACTION}${transaction?.transactionID}`, newTransaction);
MonilBhavsar marked this conversation as resolved.
Show resolved Hide resolved
}

function getOnyxDataForRouteRequest(transactionID: string, isDraft = false): OnyxData {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,39 +1,21 @@
import PropTypes from 'prop-types';
import type {StackScreenProps} from '@react-navigation/stack';
import React from 'react';
import {withOnyx} from 'react-native-onyx';
import type {MoneyRequestNavigatorParamList} from '@libs/Navigation/types';
import ONYXKEYS from '@src/ONYXKEYS';
import type SCREENS from '@src/SCREENS';
import IOURequestStepWaypoint from './request/step/IOURequestStepWaypoint';

const propTypes = {
/** The transactionID of this request */
transactionID: PropTypes.string,

/** Route params */
route: PropTypes.shape({
params: PropTypes.shape({
/** IOU type */
iouType: PropTypes.string,

/** Index of the waypoint being edited */
waypointIndex: PropTypes.string,
}),
}),
};

const defaultProps = {
transactionID: '',
route: {
params: {
iouType: '',
waypointIndex: '',
},
},
type MoneyRequestWaypointPageOnyxProps = {
transactionID: string | undefined;
};
type MoneyRequestWaypointPageProps = StackScreenProps<MoneyRequestNavigatorParamList, typeof SCREENS.MONEY_REQUEST.STEP_WAYPOINT> & MoneyRequestWaypointPageOnyxProps;

// This component is responsible for grabbing the transactionID from the IOU key
// You can't use Onyx props in the withOnyx mapping, so we need to set up and access the transactionID here, and then pass it down so that WaypointEditor can subscribe to the transaction.
function MoneyRequestWaypointPage({transactionID, route}) {
function MoneyRequestWaypointPage({transactionID = '', route}: MoneyRequestWaypointPageProps) {
return (
// @ts-expect-error TODO: Remove this once withFullTransactionOrNotFound(https://github.com/Expensify/App/issues/36123) is migrated to TypeScript.
<IOURequestStepWaypoint
// Put the transactionID into the route params so that WaypointEdit behaves the same when creating a new waypoint
// or editing an existing waypoint.
Expand All @@ -48,8 +30,7 @@ function MoneyRequestWaypointPage({transactionID, route}) {
}

MoneyRequestWaypointPage.displayName = 'MoneyRequestWaypointPage';
MoneyRequestWaypointPage.propTypes = propTypes;
MoneyRequestWaypointPage.defaultProps = defaultProps;
export default withOnyx({
transactionID: {key: ONYXKEYS.IOU, selector: (iou) => iou && iou.transactionID},

export default withOnyx<MoneyRequestWaypointPageProps, MoneyRequestWaypointPageOnyxProps>({
transactionID: {key: ONYXKEYS.IOU, selector: (iou) => iou?.transactionID},
})(MoneyRequestWaypointPage);
Loading
Loading