-
Notifications
You must be signed in to change notification settings - Fork 3k
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 IOURequestStepTag/Participants/Merchant #39186
[TS migration] Migrate IOURequestStepTag/Participants/Merchant #39186
Conversation
…rticipants to Typescript
@ruben-rebelo can you check lint and typecheck steps? |
@ruben-rebelo Why is this PR on hold for #38990? Can we move with this one without having to wait? |
Also we have conflicts! |
@ruben-rebelo #38990 was merged! 🎉 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will continue review later
|
||
if (isMerchantRequired && _.isEmpty(value.moneyRequestMerchant)) { | ||
if (isMerchantRequired && (value.moneyRequestMerchant ?? '').length <= 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (isMerchantRequired && (value.moneyRequestMerchant ?? '').length <= 0) { | |
if (isMerchantRequired && (value.moneyRequestMerchant ?? '').length === 0) { |
it will never be less than 0
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since value.moneyRequestMerchant
is string
if (isMerchantRequired && (value.moneyRequestMerchant ?? '').length <= 0) { | |
if (isMerchantRequired && !value.moneyRequestMerchant) { |
/** | ||
* @param {Object} value | ||
* @param {String} value.moneyRequestMerchant | ||
* @param value | ||
* @param value.moneyRequestMerchant | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's remove everything
if (isEditing) { | ||
// When creating new money requests newMerchant can be blank so we fall back on PARTIAL_TRANSACTION_MERCHANT | ||
IOU.updateMoneyRequestMerchant(transactionID, reportID, newMerchant || CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT, policy, policyTags, policyCategories); | ||
IOU.updateMoneyRequestMerchant(transactionID, reportID, newMerchant ?? CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT, policy, policyTags, policyCategories); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IOU.updateMoneyRequestMerchant(transactionID, reportID, newMerchant ?? CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT, policy, policyTags, policyCategories); | |
IOU.updateMoneyRequestMerchant(transactionID, reportID, newMerchant || CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT, policy, policyTags, policyCategories); |
We will introduce a regression if we use ??
here
// eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents | ||
WithFullTransactionOrNotFoundProps<typeof SCREENS.MONEY_REQUEST.STEP_PARTICIPANTS>; | ||
|
||
type IouRef = ValueOf<typeof CONST.IOU.TYPE> | null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type IouRef = ValueOf<typeof CONST.IOU.TYPE> | null; | |
type IOURef = ValueOf<typeof CONST.IOU.TYPE> | null; |
src/libs/TransactionUtils.ts
Outdated
const headerTitles = { | ||
[CONST.IOU.REQUEST_TYPE.DISTANCE]: 'tabSelector.distance', | ||
[CONST.IOU.REQUEST_TYPE.MANUAL]: 'tabSelector.manual', | ||
[CONST.IOU.REQUEST_TYPE.SCAN]: 'tabSelector.scan', | ||
}; | ||
return headerTitles[getRequestType(transaction)]; | ||
return headerTitles[getRequestType(transaction)] as TranslationPaths; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can type headerTitles instead of using assertion, see example from PR
(value: ValidationData) => { | ||
const errors: ValidationData = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this function relates to form validation, maybe we can use FormOnyxValues
and FormInputErrors
types as in other places (there are a lot of examples through the app)
|
||
if (isMerchantRequired && _.isEmpty(value.moneyRequestMerchant)) { | ||
if (isMerchantRequired && (value.moneyRequestMerchant ?? '').length <= 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since value.moneyRequestMerchant
is string
if (isMerchantRequired && (value.moneyRequestMerchant ?? '').length <= 0) { | |
if (isMerchantRequired && !value.moneyRequestMerchant) { |
}, [receiptType, receiptPath, receiptFilename, iouRequestType, iouType, transactionID, reportID]); | ||
|
||
const updateRouteParams = useCallback(() => { | ||
IOU.updateMoneyRequestTypeParams(navigation.getState().routes, newIouType.current); | ||
const navigationState = navigation.getState(); | ||
if (!navigationState || !newIouType.current) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make sure this update doesn't cause regression
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
@@ -80,7 +91,7 @@ function IOURequestStepParticipants({ | |||
}, [participants, updateRouteParams]); | |||
|
|||
const addParticipant = useCallback( | |||
(val, selectedIouType) => { | |||
(val: Participant[], selectedIouType: ValueOf<typeof CONST.IOU.TYPE>) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we can create a type for ValueOf<typeof CONST.IOU.TYPE>
?
@@ -110,15 +121,15 @@ function IOURequestStepParticipants({ | |||
} | |||
|
|||
// When a participant is selected, the reportID needs to be saved because that's the reportID that will be used in the confirmation step. | |||
selectedReportID.current = lodashGet(val, '[0].reportID', reportID); | |||
selectedReportID.current = val[0].reportID ?? reportID; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
selectedReportID.current = val[0].reportID ?? reportID; | |
selectedReportID.current = val[0]?.reportID ?? reportID; |
// /** Holds data related to Money Request view state, rather than the underlying Money Request data. */ | ||
// transaction: OnyxEntry<OnyxTypes.Transaction>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we still need it?
Co-authored-by: Viktoryia Kliushun <[email protected]>
@ruben-rebelo we have lint errors now |
…Merchant # Conflicts: # src/pages/iou/request/step/IOURequestStepTag.js
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm!
type IOUValueType = ValueOf<typeof CONST.IOU.TYPE>; | ||
|
||
type IOURequestStepParticipantsProps = IOURequestStepParticipantsOnyxProps & | ||
StackScreenProps<MoneyRequestNavigatorParamList, typeof SCREENS.MONEY_REQUEST.STEP_PARTICIPANTS> & |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think StackScreenProps
is needed when WithWritableReportOrNotFoundProps
is used
report: {}, | ||
}; | ||
type IOURequestStepMerchantProps = IOURequestStepMerchantOnyxProps & | ||
StackScreenProps<MoneyRequestNavigatorParamList, typeof SCREENS.MONEY_REQUEST.STEP_MERCHANT> & |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
}; | ||
|
||
type IOURequestStepTagProps = IOURequestStepTagOnyxProps & | ||
StackScreenProps<MoneyRequestNavigatorParamList, typeof SCREENS.MONEY_REQUEST.STEP_TAG> & |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
@blazejkustra You are right, Updated! |
@mananjadhav Please copy/paste the Reviewer Checklist from here into a new comment on this PR and complete it. If you have the K2 extension, you can simply click: [this button] |
src/libs/TransactionUtils.ts
Outdated
@@ -45,16 +47,16 @@ function isDistanceRequest(transaction: OnyxEntry<Transaction>): boolean { | |||
return type === CONST.TRANSACTION.TYPE.CUSTOM_UNIT && customUnitName === CONST.CUSTOM_UNITS.NAME_DISTANCE; | |||
} | |||
|
|||
function isScanRequest(transaction: Transaction): boolean { | |||
function isScanRequest(transaction: OnyxEntry<Transaction>): boolean { | |||
// This is used during the request creation flow before the transaction has been saved to the server | |||
if (lodashHas(transaction, 'iouRequestType')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could we have lodashHas(transaction, 'iouRequestType')
replaced it with transaction?.iouRequestType
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can, but this was not done as this is not part of this issue.
Should we change it? wdyt?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we need to change, a better replacement would be using in
if (transaction && 'iouRequestType' in transaction) {
return transaction.iouRequestType === CONST.IOU.REQUEST_TYPE.DISTANCE;
}
@@ -314,7 +314,7 @@ function clearMoneyRequest(transactionID: string) { | |||
/** | |||
* Update money request-related pages IOU type params | |||
*/ | |||
function updateMoneyRequestTypeParams(routes: StackNavigationState<ParamListBase>['routes'] | NavigationPartialRoute[], newIouType: string, tab: string) { | |||
function updateMoneyRequestTypeParams(routes: StackNavigationState<ParamListBase>['routes'] | NavigationPartialRoute[], newIouType: string, tab?: string) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we sure making tab?
won't have any impact?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this specific case we had to make it optional as it was never passed a tab prop.
I've tested the other calls of the functions and everything was working as expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did partial review, left to review the tsx. Will need time to compare with js. Will get to it in next few hours.
@mananjadhav I've updated the PR based on the withFullTransactionOrNotFound HOC that got merged. |
if (isEditing) { | ||
// When creating new money requests newMerchant can be blank so we fall back on PARTIAL_TRANSACTION_MERCHANT | ||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
any specific reason we want to disable this lint?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a left-over, removed it, thanks for pointing it out!
Reviewer Checklist
Screenshots/VideosAndroid: Nativeandroid-ts-migration.movAndroid: mWeb Chromemweb-chrome-ts-migration.moviOS: Nativeios-ts-migration.moviOS: mWeb Safarimweb-safari-ts-migration.movMacOS: Chrome / Safariweb-ts-migration.movMacOS: Desktopdesktop-ts-migration.mov |
…Merchant # Conflicts: # src/libs/Navigation/types.ts # src/libs/TransactionUtils.ts # src/pages/iou/request/step/withFullTransactionOrNotFound.tsx
@ruben-rebelo I see some Typescript errors after the latest main merge. Can you take a look? |
@ruben-rebelo Please do the following changes to fix the TS errors. diff --git a/src/components/ScreenWrapper.tsx b/src/components/ScreenWrapper.tsx
index b78e274371..e7d311e658 100644
--- a/src/components/ScreenWrapper.tsx
+++ b/src/components/ScreenWrapper.tsx
@@ -25,7 +25,7 @@ import SafeAreaConsumer from './SafeAreaConsumer';
import TestToolsModal from './TestToolsModal';
import withNavigationFallback from './withNavigationFallback';
-type ChildrenProps = {
+type ScreenWrapperChildrenProps = {
insets: EdgeInsets;
safeAreaPaddingBottomStyle?: {
paddingBottom?: DimensionValue;
@@ -35,7 +35,7 @@ type ChildrenProps = {
type ScreenWrapperProps = {
/** Returns a function as a child to pass insets to or a node to render without insets */
- children: ReactNode | React.FC<ChildrenProps>;
+ children: ReactNode | React.FC<ScreenWrapperChildrenProps>;
/** A unique ID to find the screen wrapper in tests */
testID: string;
@@ -281,3 +281,5 @@ function ScreenWrapper(
ScreenWrapper.displayName = 'ScreenWrapper';
export default withNavigationFallback(forwardRef(ScreenWrapper));
+
+export type {ScreenWrapperChildrenProps};
diff --git a/src/pages/iou/request/step/StepScreenWrapper.tsx b/src/pages/iou/request/step/StepScreenWrapper.tsx
index e64f2792d2..93285d359d 100644
--- a/src/pages/iou/request/step/StepScreenWrapper.tsx
+++ b/src/pages/iou/request/step/StepScreenWrapper.tsx
@@ -1,8 +1,9 @@
+import type {ReactNode} from 'react';
import React from 'react';
-import type {PropsWithChildren} from 'react';
import {View} from 'react-native';
import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView';
import HeaderWithBackButton from '@components/HeaderWithBackButton';
+import type {ScreenWrapperChildrenProps} from '@components/ScreenWrapper';
import ScreenWrapper from '@components/ScreenWrapper';
import useThemeStyles from '@hooks/useThemeStyles';
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
@@ -29,6 +30,9 @@ type StepScreenWrapperProps = {
/** Whether or not to include safe area padding */
includeSafeAreaPaddingBottom?: boolean;
+
+ /** Returns a function as a child to pass insets to or a node to render without insets */
+ children: ReactNode | React.FC<ScreenWrapperChildrenProps>;
};
function StepScreenWrapper({
@@ -40,11 +44,11 @@ function StepScreenWrapper({
shouldShowWrapper,
shouldShowNotFoundPage,
includeSafeAreaPaddingBottom,
-}: PropsWithChildren<StepScreenWrapperProps>) {
+}: StepScreenWrapperProps) {
const styles = useThemeStyles();
if (!shouldShowWrapper) {
- return <FullPageNotFoundView shouldShow={shouldShowNotFoundPage}>{children}</FullPageNotFoundView>;
+ return <FullPageNotFoundView shouldShow={shouldShowNotFoundPage}>{children as ReactNode}</FullPageNotFoundView>;
}
return (
|
✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release. |
🚀 Deployed to staging by https://github.com/puneetlath in version: 1.4.63-0 🚀
|
🚀 Deployed to production by https://github.com/mountiny in version: 1.4.63-21 🚀
|
@@ -123,7 +97,7 @@ function IOURequestStepMerchant({ | |||
navigateBack(); | |||
return; | |||
} | |||
IOU.setMoneyRequestMerchant(transactionID, newMerchant, !isEditing); | |||
IOU.setMoneyRequestMerchant(transactionID, newMerchant ?? '', !isEditing); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This empty string fallback caused issue #41939 where if we set the merchant to something else first, for example "test", then the transaction draft merchant becomes "test".
merchant: 'test'
Then if we clear it, becomes empty string.
merchant: ''
If we submit an expense with an empty string of merchant, the BE response will return Expense
as the merchant.
Note: The fallback should've been newMerchant || CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT
like it is below for updateMoneyRequestMerchant
function.
Details
[TS migration] Migrate IOURequestStepTag/Participants/Merchant
Fixed Issues
$ #38916
PROPOSAL:
Tests
Workspace must have tags enabled
Request money to a workspace (Participant list works)
Add tag, Merchant to the request (Tag and merchant is added)
Verify that no errors appear in the JS console
Offline tests
N/A
QA Steps
Same as in Tests section
PR Author Checklist
### Fixed Issues
section aboveTests
sectionOffline steps
sectionQA steps
sectiontoggleReport
and notonIconClick
)myBool && <MyComponent />
.src/languages/*
files and using the translation methodSTYLE.md
) were followedAvatar
, I verified the components usingAvatar
are working as expected)StyleUtils.getBackgroundAndBorderStyle(theme.componentBG)
)Avatar
is modified, I verified thatAvatar
is working as expected in all cases)Design
label and/or tagged@Expensify/design
so the design team can review the changes.ScrollView
component to make it scrollable when more elements are added to the page.main
branch was merged into this PR after a review, I tested again and verified the outcome was still expected according to theTest
steps.Screenshots/Videos
Android: Native
android-native.mp4
Android: mWeb Chrome
android-web.mov
iOS: Native
ios-native.mov
iOS: mWeb Safari
ios-web.mov
MacOS: Chrome / Safari
macos-web.mov
MacOS: Desktop
macos-desktop.mov