diff --git a/contributingGuides/FORMS.md b/contributingGuides/FORMS.md index d87f9f889090..b2f912277dc5 100644 --- a/contributingGuides/FORMS.md +++ b/contributingGuides/FORMS.md @@ -10,7 +10,7 @@ Any form input needs to be wrapped in [InputWrapper](https://github.com/Expensif @@ -248,7 +248,7 @@ function onSubmit(values) { @@ -263,7 +263,7 @@ const BankAccountForm = () => ( @@ -271,7 +271,7 @@ const BankAccountForm = () => ( diff --git a/src/CONST.ts b/src/CONST.ts index a939f0942839..e33fc3eb23fb 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -195,45 +195,6 @@ const CONST = { DOMAIN: '@expensify.sms', }, BANK_ACCOUNT: { - BANK_INFO_STEP: { - INPUT_KEY: { - ROUTING_NUMBER: 'routingNumber', - ACCOUNT_NUMBER: 'accountNumber', - PLAID_MASK: 'plaidMask', - IS_SAVINGS: 'isSavings', - BANK_NAME: 'bankName', - PLAID_ACCOUNT_ID: 'plaidAccountID', - PLAID_ACCESS_TOKEN: 'plaidAccessToken', - }, - }, - PERSONAL_INFO_STEP: { - INPUT_KEY: { - FIRST_NAME: 'firstName', - LAST_NAME: 'lastName', - DOB: 'dob', - SSN_LAST_4: 'ssnLast4', - STREET: 'requestorAddressStreet', - CITY: 'requestorAddressCity', - STATE: 'requestorAddressState', - ZIP_CODE: 'requestorAddressZipCode', - }, - }, - BUSINESS_INFO_STEP: { - INPUT_KEY: { - COMPANY_NAME: 'companyName', - COMPANY_TAX_ID: 'companyTaxID', - COMPANY_WEBSITE: 'website', - COMPANY_PHONE: 'companyPhone', - STREET: 'addressStreet', - CITY: 'addressCity', - STATE: 'addressState', - ZIP_CODE: 'addressZipCode', - INCORPORATION_TYPE: 'incorporationType', - INCORPORATION_DATE: 'incorporationDate', - INCORPORATION_STATE: 'incorporationState', - HAS_NO_CONNECTION_TO_CANNABIS: 'hasNoConnectionToCannabis', - }, - }, BENEFICIAL_OWNER_INFO_STEP: { SUBSTEP: { IS_USER_UBO: 1, @@ -242,11 +203,6 @@ const CONST = { ARE_THERE_MORE_UBOS: 4, UBOS_LIST: 5, }, - INPUT_KEY: { - OWNS_MORE_THAN_25_PERCENT: 'ownsMoreThan25Percent', - HAS_OTHER_BENEFICIAL_OWNERS: 'hasOtherBeneficialOwners', - BENEFICIAL_OWNERS: 'beneficialOwners', - }, BENEFICIAL_OWNER_DATA: { BENEFICIAL_OWNER_KEYS: 'beneficialOwnerKeys', PREFIX: 'beneficialOwner', @@ -270,13 +226,6 @@ const CONST = { EXIT: 'EXIT', }, }, - COMPLETE_VERIFICATION: { - INPUT_KEY: { - IS_AUTHORIZED_TO_USE_BANK_ACCOUNT: 'isAuthorizedToUseBankAccount', - CERTIFY_TRUE_INFORMATION: 'certifyTrueInformation', - ACCEPT_TERMS_AND_CONDITIONS: 'acceptTermsAndConditions', - }, - }, ERROR: { MISSING_ROUTING_NUMBER: '402 Missing routingNumber', MAX_ROUTING_NUMBER: '402 Maximum Size Exceeded routingNumber', diff --git a/src/ONYXKEYS.ts b/src/ONYXKEYS.ts index 751ee105ceb7..0735bc53e56c 100755 --- a/src/ONYXKEYS.ts +++ b/src/ONYXKEYS.ts @@ -1,7 +1,9 @@ import type {OnyxEntry} from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import type CONST from './CONST'; +import type * as FormTypes from './types/form'; import type * as OnyxTypes from './types/onyx'; +import type AssertTypesEqual from './types/utils/AssertTypesEqual'; import type DeepValueOf from './types/utils/DeepValueOf'; /** @@ -237,9 +239,6 @@ const ONYXKEYS = { // The last update ID that was applied to the client ONYX_UPDATES_LAST_UPDATE_ID_APPLIED_TO_CLIENT: 'OnyxUpdatesLastUpdateIDAppliedToClient', - // Receipt upload modal - RECEIPT_MODAL: 'receiptModal', - // The access token to be used with the Mapbox library MAPBOX_ACCESS_TOKEN: 'mapboxAccessToken', @@ -379,12 +378,85 @@ const ONYXKEYS = { }, } as const; -type OnyxKeysMap = typeof ONYXKEYS; -type OnyxCollectionKey = ValueOf; -type OnyxKey = DeepValueOf>; -type OnyxFormKey = ValueOf; +type AllOnyxKeys = DeepValueOf; + +type OnyxFormValuesMapping = { + [ONYXKEYS.FORMS.ADD_DEBIT_CARD_FORM]: FormTypes.AddDebitCardForm; + [ONYXKEYS.FORMS.WORKSPACE_SETTINGS_FORM]: FormTypes.WorkspaceSettingsForm; + [ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM]: FormTypes.WorkspaceRateAndUnitForm; + [ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM]: FormTypes.CloseAccountForm; + [ONYXKEYS.FORMS.PROFILE_SETTINGS_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.DISPLAY_NAME_FORM]: FormTypes.DisplayNameForm; + [ONYXKEYS.FORMS.ROOM_NAME_FORM]: FormTypes.RoomNameForm; + [ONYXKEYS.FORMS.REPORT_DESCRIPTION_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.LEGAL_NAME_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.WORKSPACE_INVITE_MESSAGE_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.DATE_OF_BIRTH_FORM]: FormTypes.DateOfBirthForm; + [ONYXKEYS.FORMS.HOME_ADDRESS_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.NEW_ROOM_FORM]: FormTypes.NewRoomForm; + [ONYXKEYS.FORMS.ROOM_SETTINGS_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.NEW_TASK_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.EDIT_TASK_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.MONEY_REQUEST_DESCRIPTION_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.MONEY_REQUEST_MERCHANT_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.MONEY_REQUEST_AMOUNT_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.MONEY_REQUEST_DATE_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.NEW_CONTACT_METHOD_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.WAYPOINT_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.SETTINGS_STATUS_SET_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.SETTINGS_STATUS_CLEAR_DATE_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.SETTINGS_STATUS_SET_CLEAR_AFTER_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.PRIVATE_NOTES_FORM]: FormTypes.PrivateNotesForm; + [ONYXKEYS.FORMS.I_KNOW_A_TEACHER_FORM]: FormTypes.IKnowTeacherForm; + [ONYXKEYS.FORMS.INTRO_SCHOOL_PRINCIPAL_FORM]: FormTypes.IntroSchoolPrincipalForm; + [ONYXKEYS.FORMS.REPORT_VIRTUAL_CARD_FRAUD]: FormTypes.Form; + [ONYXKEYS.FORMS.REPORT_PHYSICAL_CARD_FORM]: FormTypes.Form; + [ONYXKEYS.FORMS.GET_PHYSICAL_CARD_FORM]: FormTypes.GetPhysicalCardForm; + [ONYXKEYS.FORMS.REPORT_FIELD_EDIT_FORM]: FormTypes.ReportFieldEditForm; + [ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM]: FormTypes.ReimbursementAccountForm; + [ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT]: FormTypes.PersonalBankAccountForm; +}; -type OnyxValues = { +type OnyxFormDraftValuesMapping = { + [K in keyof OnyxFormValuesMapping as `${K}Draft`]: OnyxFormValuesMapping[K]; +}; + +type OnyxCollectionValuesMapping = { + [ONYXKEYS.COLLECTION.DOWNLOAD]: OnyxTypes.Download; + [ONYXKEYS.COLLECTION.POLICY]: OnyxTypes.Policy; + [ONYXKEYS.COLLECTION.POLICY_DRAFTS]: OnyxTypes.Policy; + [ONYXKEYS.COLLECTION.POLICY_CATEGORIES]: OnyxTypes.PolicyCategories; + [ONYXKEYS.COLLECTION.POLICY_TAGS]: OnyxTypes.PolicyTags; + [ONYXKEYS.COLLECTION.POLICY_MEMBERS]: OnyxTypes.PolicyMembers; + [ONYXKEYS.COLLECTION.POLICY_MEMBERS_DRAFTS]: OnyxTypes.PolicyMember; + [ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES]: OnyxTypes.RecentlyUsedCategories; + [ONYXKEYS.COLLECTION.POLICY_REPORT_FIELDS]: OnyxTypes.PolicyReportFields; + [ONYXKEYS.COLLECTION.DEPRECATED_POLICY_MEMBER_LIST]: OnyxTypes.PolicyMembers; + [ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MEMBERS_DRAFT]: OnyxTypes.InvitedEmailsToAccountIDs; + [ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MESSAGE_DRAFT]: string; + [ONYXKEYS.COLLECTION.REPORT]: OnyxTypes.Report; + [ONYXKEYS.COLLECTION.REPORT_METADATA]: OnyxTypes.ReportMetadata; + [ONYXKEYS.COLLECTION.REPORT_ACTIONS]: OnyxTypes.ReportActions; + [ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS]: OnyxTypes.ReportActionsDrafts; + [ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS]: OnyxTypes.ReportActionReactions; + [ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT]: string; + [ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT_NUMBER_OF_LINES]: number; + [ONYXKEYS.COLLECTION.REPORT_IS_COMPOSER_FULL_SIZE]: boolean; + [ONYXKEYS.COLLECTION.REPORT_USER_IS_TYPING]: OnyxTypes.ReportUserIsTyping; + [ONYXKEYS.COLLECTION.REPORT_USER_IS_LEAVING_ROOM]: boolean; + [ONYXKEYS.COLLECTION.SECURITY_GROUP]: OnyxTypes.SecurityGroup; + [ONYXKEYS.COLLECTION.TRANSACTION]: OnyxTypes.Transaction; + [ONYXKEYS.COLLECTION.TRANSACTION_DRAFT]: OnyxTypes.Transaction; + [ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS]: OnyxTypes.TransactionViolations; + [ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT]: OnyxTypes.Transaction; + [ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS]: OnyxTypes.RecentlyUsedTags; + [ONYXKEYS.COLLECTION.SELECTED_TAB]: string; + [ONYXKEYS.COLLECTION.PRIVATE_NOTES_DRAFT]: string; + [ONYXKEYS.COLLECTION.NEXT_STEP]: OnyxTypes.ReportNextStep; + [ONYXKEYS.COLLECTION.POLICY_TAX_RATE]: string[]; +}; + +type OnyxValuesMapping = { [ONYXKEYS.ACCOUNT]: OnyxTypes.Account; [ONYXKEYS.ACCOUNT_MANAGER_REPORT_ID]: string; [ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER]: boolean; @@ -465,113 +537,23 @@ type OnyxValues = { [ONYXKEYS.LAST_VISITED_PATH]: string | undefined; [ONYXKEYS.RECENTLY_USED_REPORT_FIELDS]: OnyxTypes.RecentlyUsedReportFields; [ONYXKEYS.UPDATE_REQUIRED]: boolean; + [ONYXKEYS.PLAID_CURRENT_EVENT]: string; +}; - // Collections - [ONYXKEYS.COLLECTION.DOWNLOAD]: OnyxTypes.Download; - [ONYXKEYS.COLLECTION.POLICY]: OnyxTypes.Policy; - [ONYXKEYS.COLLECTION.POLICY_DRAFTS]: OnyxTypes.Policy; - [ONYXKEYS.COLLECTION.POLICY_CATEGORIES]: OnyxTypes.PolicyCategories; - [ONYXKEYS.COLLECTION.POLICY_TAGS]: OnyxTypes.PolicyTags; - [ONYXKEYS.COLLECTION.POLICY_MEMBERS]: OnyxTypes.PolicyMembers; - [ONYXKEYS.COLLECTION.POLICY_MEMBERS_DRAFTS]: OnyxTypes.PolicyMember; - [ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_CATEGORIES]: OnyxTypes.RecentlyUsedCategories; - [ONYXKEYS.COLLECTION.POLICY_REPORT_FIELDS]: OnyxTypes.PolicyReportFields; - [ONYXKEYS.COLLECTION.DEPRECATED_POLICY_MEMBER_LIST]: OnyxTypes.PolicyMembers; - [ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MEMBERS_DRAFT]: OnyxTypes.InvitedEmailsToAccountIDs | undefined; - [ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MESSAGE_DRAFT]: string | undefined; - [ONYXKEYS.COLLECTION.REPORT]: OnyxTypes.Report; - [ONYXKEYS.COLLECTION.REPORT_METADATA]: OnyxTypes.ReportMetadata; - [ONYXKEYS.COLLECTION.REPORT_ACTIONS]: OnyxTypes.ReportActions; - [ONYXKEYS.COLLECTION.REPORT_ACTIONS_DRAFTS]: OnyxTypes.ReportActionsDrafts; - [ONYXKEYS.COLLECTION.REPORT_ACTIONS_REACTIONS]: OnyxTypes.ReportActionReactions; - [ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT]: string; - [ONYXKEYS.COLLECTION.REPORT_DRAFT_COMMENT_NUMBER_OF_LINES]: number; - [ONYXKEYS.COLLECTION.REPORT_IS_COMPOSER_FULL_SIZE]: boolean; - [ONYXKEYS.COLLECTION.REPORT_USER_IS_TYPING]: OnyxTypes.ReportUserIsTyping; - [ONYXKEYS.COLLECTION.REPORT_USER_IS_LEAVING_ROOM]: boolean; - [ONYXKEYS.COLLECTION.SECURITY_GROUP]: OnyxTypes.SecurityGroup; - [ONYXKEYS.COLLECTION.TRANSACTION]: OnyxTypes.Transaction; - [ONYXKEYS.COLLECTION.TRANSACTION_DRAFT]: OnyxTypes.Transaction; - [ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS]: OnyxTypes.TransactionViolations; - [ONYXKEYS.COLLECTION.SPLIT_TRANSACTION_DRAFT]: OnyxTypes.Transaction; - [ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS]: OnyxTypes.RecentlyUsedTags; - [ONYXKEYS.COLLECTION.SELECTED_TAB]: string; - [ONYXKEYS.COLLECTION.PRIVATE_NOTES_DRAFT]: string; - [ONYXKEYS.COLLECTION.NEXT_STEP]: OnyxTypes.ReportNextStep; +type OnyxValues = OnyxValuesMapping & OnyxCollectionValuesMapping & OnyxFormValuesMapping & OnyxFormDraftValuesMapping; - // Forms - [ONYXKEYS.FORMS.ADD_DEBIT_CARD_FORM]: OnyxTypes.AddDebitCardForm; - [ONYXKEYS.FORMS.ADD_DEBIT_CARD_FORM_DRAFT]: OnyxTypes.AddDebitCardForm; - [ONYXKEYS.FORMS.WORKSPACE_SETTINGS_FORM]: OnyxTypes.WorkspaceSettingsForm; - [ONYXKEYS.FORMS.WORKSPACE_SETTINGS_FORM_DRAFT]: OnyxTypes.WorkspaceSettingsForm; - [ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM]: OnyxTypes.CloseAccountForm; - [ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM_DRAFT]: OnyxTypes.CloseAccountForm; - [ONYXKEYS.FORMS.PROFILE_SETTINGS_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.PROFILE_SETTINGS_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.DISPLAY_NAME_FORM]: OnyxTypes.DisplayNameForm; - [ONYXKEYS.FORMS.DISPLAY_NAME_FORM_DRAFT]: OnyxTypes.DisplayNameForm; - [ONYXKEYS.FORMS.ROOM_NAME_FORM]: OnyxTypes.RoomNameForm; - [ONYXKEYS.FORMS.ROOM_NAME_FORM_DRAFT]: OnyxTypes.RoomNameForm; - [ONYXKEYS.FORMS.REPORT_DESCRIPTION_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.REPORT_DESCRIPTION_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.LEGAL_NAME_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.LEGAL_NAME_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.WORKSPACE_INVITE_MESSAGE_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.WORKSPACE_INVITE_MESSAGE_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.DATE_OF_BIRTH_FORM]: OnyxTypes.DateOfBirthForm; - [ONYXKEYS.FORMS.DATE_OF_BIRTH_FORM_DRAFT]: OnyxTypes.DateOfBirthForm; - [ONYXKEYS.FORMS.HOME_ADDRESS_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.HOME_ADDRESS_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.NEW_ROOM_FORM]: OnyxTypes.NewRoomForm; - [ONYXKEYS.FORMS.NEW_ROOM_FORM_DRAFT]: OnyxTypes.NewRoomForm; - [ONYXKEYS.FORMS.ROOM_SETTINGS_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.ROOM_SETTINGS_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.NEW_TASK_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.NEW_TASK_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.EDIT_TASK_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.EDIT_TASK_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.MONEY_REQUEST_DESCRIPTION_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.MONEY_REQUEST_DESCRIPTION_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.MONEY_REQUEST_MERCHANT_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.MONEY_REQUEST_MERCHANT_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.MONEY_REQUEST_AMOUNT_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.MONEY_REQUEST_AMOUNT_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.MONEY_REQUEST_DATE_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.MONEY_REQUEST_DATE_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.NEW_CONTACT_METHOD_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.NEW_CONTACT_METHOD_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.WAYPOINT_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.WAYPOINT_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.SETTINGS_STATUS_SET_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.SETTINGS_STATUS_SET_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.SETTINGS_STATUS_CLEAR_DATE_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.SETTINGS_STATUS_CLEAR_DATE_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.SETTINGS_STATUS_SET_CLEAR_AFTER_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.SETTINGS_STATUS_SET_CLEAR_AFTER_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.PRIVATE_NOTES_FORM]: OnyxTypes.PrivateNotesForm; - [ONYXKEYS.FORMS.PRIVATE_NOTES_FORM_DRAFT]: OnyxTypes.PrivateNotesForm; - [ONYXKEYS.FORMS.I_KNOW_A_TEACHER_FORM]: OnyxTypes.IKnowATeacherForm; - [ONYXKEYS.FORMS.I_KNOW_A_TEACHER_FORM_DRAFT]: OnyxTypes.IKnowATeacherForm; - [ONYXKEYS.FORMS.INTRO_SCHOOL_PRINCIPAL_FORM]: OnyxTypes.IntroSchoolPrincipalForm; - [ONYXKEYS.FORMS.INTRO_SCHOOL_PRINCIPAL_FORM_DRAFT]: OnyxTypes.IntroSchoolPrincipalForm; - [ONYXKEYS.FORMS.REPORT_VIRTUAL_CARD_FRAUD]: OnyxTypes.Form; - [ONYXKEYS.FORMS.REPORT_VIRTUAL_CARD_FRAUD_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.REPORT_PHYSICAL_CARD_FORM]: OnyxTypes.Form; - [ONYXKEYS.FORMS.REPORT_PHYSICAL_CARD_FORM_DRAFT]: OnyxTypes.Form; - [ONYXKEYS.FORMS.GET_PHYSICAL_CARD_FORM]: OnyxTypes.GetPhysicalCardForm; - [ONYXKEYS.FORMS.GET_PHYSICAL_CARD_FORM_DRAFT]: OnyxTypes.GetPhysicalCardForm; - [ONYXKEYS.FORMS.REPORT_FIELD_EDIT_FORM]: OnyxTypes.ReportFieldEditForm; - [ONYXKEYS.FORMS.REPORT_FIELD_EDIT_FORM_DRAFT]: OnyxTypes.Form; - // @ts-expect-error Different values are defined under the same key: ReimbursementAccount and ReimbursementAccountForm - [ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM]: OnyxTypes.ReimbursementAccountForm; - [ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT]: OnyxTypes.ReimbursementAccountForm; - [ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT]: OnyxTypes.PersonalBankAccount; - [ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT_DRAFT]: OnyxTypes.PersonalBankAccount; -}; +type OnyxCollectionKey = keyof OnyxCollectionValuesMapping; +type OnyxFormKey = keyof OnyxFormValuesMapping; +type OnyxFormDraftKey = keyof OnyxFormDraftValuesMapping; +type OnyxValueKey = keyof OnyxValuesMapping; + +type OnyxKey = OnyxValueKey | OnyxCollectionKey | OnyxFormKey | OnyxFormDraftKey; +type OnyxValue = OnyxEntry; -type OnyxKeyValue = OnyxEntry; +type MissingOnyxKeysError = `Error: Types don't match, OnyxKey type is missing: ${Exclude}`; +/** If this type errors, it means that the `OnyxKey` type is missing some keys. */ +// eslint-disable-next-line @typescript-eslint/no-unused-vars +type AssertOnyxKeys = AssertTypesEqual; export default ONYXKEYS; -export type {OnyxKey, OnyxCollectionKey, OnyxValues, OnyxKeyValue, OnyxFormKey, OnyxKeysMap}; +export type {OnyxValues, OnyxKey, OnyxCollectionKey, OnyxValue, OnyxValueKey, OnyxFormKey, OnyxFormValuesMapping, OnyxFormDraftKey}; diff --git a/src/components/AddressForm.js b/src/components/AddressForm.js index aee1b652b22c..1bd55004074a 100644 --- a/src/components/AddressForm.js +++ b/src/components/AddressForm.js @@ -9,6 +9,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import Navigation from '@libs/Navigation/Navigation'; import * as ValidationUtils from '@libs/ValidationUtils'; import CONST from '@src/CONST'; +import INPUT_IDS from '@src/types/form/HomeAddressForm'; import AddressSearch from './AddressSearch'; import CountrySelector from './CountrySelector'; import FormProvider from './Form/FormProvider'; @@ -127,7 +128,7 @@ function AddressForm({city, country, formID, onAddressChanged, onSubmit, shouldS { onAddressChanged(data, key); @@ -136,12 +137,12 @@ function AddressForm({city, country, formID, onAddressChanged, onSubmit, shouldS }} defaultValue={street1 || ''} renamedInputKeys={{ - street: 'addressLine1', - street2: 'addressLine2', - city: 'city', - state: 'state', - zipCode: 'zipPostCode', - country: 'country', + street: INPUT_IDS.ADDRESS_LINE_1, + street2: INPUT_IDS.ADDRESS_LINE_2, + city: INPUT_IDS.CITY, + state: INPUT_IDS.STATE, + zipCode: INPUT_IDS.ZIP_POST_CODE, + country: INPUT_IDS.COUNTRY, }} maxInputLength={CONST.FORM_CHARACTER_LIMIT} shouldSaveDraft={shouldSaveDraft} @@ -150,7 +151,7 @@ function AddressForm({city, country, formID, onAddressChanged, onSubmit, shouldS @@ -173,7 +174,7 @@ function AddressForm({city, country, formID, onAddressChanged, onSubmit, shouldS ; + +type RegisterInput = (inputID: keyof Form, shouldSubmitForm: boolean, inputProps: InputProps) => InputProps; type FormContext = { registerInput: RegisterInput; }; @@ -10,3 +14,5 @@ export default createContext({ throw new Error('Registered input should be wrapped with FormWrapper'); }, }); + +export type {RegisterInput}; diff --git a/src/components/Form/FormProvider.tsx b/src/components/Form/FormProvider.tsx index 8cf6df2fa8f5..ad09b68a5f39 100644 --- a/src/components/Form/FormProvider.tsx +++ b/src/components/Form/FormProvider.tsx @@ -9,21 +9,23 @@ import * as ValidationUtils from '@libs/ValidationUtils'; import Visibility from '@libs/Visibility'; import * as FormActions from '@userActions/FormActions'; import CONST from '@src/CONST'; +import type {TranslationPaths} from '@src/languages/types'; import type {OnyxFormKey} from '@src/ONYXKEYS'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Form, Network} from '@src/types/onyx'; -import type {FormValueType} from '@src/types/onyx/Form'; -import type {Errors} from '@src/types/onyx/OnyxCommon'; +import type {Form} from '@src/types/form'; +import type {Network} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import type {RegisterInput} from './FormContext'; import FormContext from './FormContext'; import FormWrapper from './FormWrapper'; -import type {BaseInputProps, FormProps, InputRefs, OnyxFormKeyWithoutDraft, OnyxFormValues, OnyxFormValuesFields, RegisterInput, ValueTypeKey} from './types'; +import type {FormInputErrors, FormOnyxValues, FormProps, InputComponentBaseProps, InputRefs, ValueTypeKey} from './types'; // In order to prevent Checkbox focus loss when the user are focusing a TextInput and proceeds to toggle a CheckBox in web and mobile web. // 200ms delay was chosen as a result of empirical testing. // More details: https://github.com/Expensify/App/pull/16444#issuecomment-1482983426 const VALIDATE_DELAY = 200; +type GenericFormInputErrors = Partial>; type InitialDefaultValue = false | Date | ''; function getInitialValueByType(valueType?: ValueTypeKey): InitialDefaultValue { @@ -53,10 +55,10 @@ type FormProviderOnyxProps = { type FormProviderProps = FormProviderOnyxProps & FormProps & { /** Children to render. */ - children: ((props: {inputValues: OnyxFormValues}) => ReactNode) | ReactNode; + children: ((props: {inputValues: FormOnyxValues}) => ReactNode) | ReactNode; /** Callback to validate the form */ - validate?: (values: OnyxFormValuesFields) => Errors; + validate?: (values: FormOnyxValues) => FormInputErrors; /** Should validate function be called when input loose focus */ shouldValidateOnBlur?: boolean; @@ -72,7 +74,7 @@ type FormProviderProps = FormProvider }; type FormRef = { - resetForm: (optionalValue: OnyxFormValues) => void; + resetForm: (optionalValue: FormOnyxValues) => void; }; function FormProvider( @@ -95,11 +97,11 @@ function FormProvider( const inputRefs = useRef({}); const touchedInputs = useRef>({}); const [inputValues, setInputValues] = useState
(() => ({...draftValues})); - const [errors, setErrors] = useState({}); + const [errors, setErrors] = useState({}); const hasServerError = useMemo(() => !!formState && !isEmptyObject(formState?.errors), [formState]); const onValidate = useCallback( - (values: OnyxFormValuesFields, shouldClearServerError = true) => { + (values: FormOnyxValues, shouldClearServerError = true) => { const trimmedStringValues = ValidationUtils.prepareValues(values); if (shouldClearServerError) { @@ -107,7 +109,7 @@ function FormProvider( } FormActions.clearErrorFields(formID); - const validateErrors = validate?.(trimmedStringValues) ?? {}; + const validateErrors: GenericFormInputErrors = validate?.(trimmedStringValues) ?? {}; // Validate the input for html tags. It should supersede any other error Object.entries(trimmedStringValues).forEach(([inputID, inputValue]) => { @@ -212,13 +214,13 @@ function FormProvider( }, [enabledWhenOffline, formState?.isLoading, inputValues, network?.isOffline, onSubmit, onValidate]); const resetForm = useCallback( - (optionalValue: OnyxFormValuesFields) => { + (optionalValue: FormOnyxValues) => { Object.keys(inputValues).forEach((inputID) => { setInputValues((prevState) => { const copyPrevState = {...prevState}; touchedInputs.current[inputID] = false; - copyPrevState[inputID] = optionalValue[inputID as keyof OnyxFormValuesFields] || ''; + copyPrevState[inputID] = optionalValue[inputID as keyof FormOnyxValues] || ''; return copyPrevState; }); @@ -232,8 +234,8 @@ function FormProvider( })); const registerInput = useCallback( - (inputID: keyof Form, shouldSubmitForm: boolean, inputProps: TInputProps): TInputProps => { - const newRef: MutableRefObject = inputRefs.current[inputID] ?? inputProps.ref ?? createRef(); + (inputID, shouldSubmitForm, inputProps) => { + const newRef: MutableRefObject = inputRefs.current[inputID] ?? inputProps.ref ?? createRef(); if (inputRefs.current[inputID] !== newRef) { inputRefs.current[inputID] = newRef; } @@ -251,10 +253,10 @@ function FormProvider( const errorFields = formState?.errorFields?.[inputID] ?? {}; const fieldErrorMessage = - Object.keys(errorFields) + (Object.keys(errorFields) .sort() .map((key) => errorFields[key]) - .at(-1) ?? ''; + .at(-1) as string) ?? ''; const inputRef = inputProps.ref; @@ -270,7 +272,7 @@ function FormProvider( }), ref: typeof inputRef === 'function' - ? (node: BaseInputProps) => { + ? (node: InputComponentBaseProps) => { inputRef(node); newRef.current = node; } @@ -334,7 +336,7 @@ function FormProvider( } inputProps.onBlur?.(event); }, - onInputChange: (value: FormValueType, key?: string) => { + onInputChange: (value, key) => { const inputKey = key ?? inputID; setInputValues((prevState) => { const newState = { @@ -349,7 +351,7 @@ function FormProvider( }); if (inputProps.shouldSaveDraft && !formID.includes('Draft')) { - FormActions.setDraftValues(formID as OnyxFormKeyWithoutDraft, {[inputKey]: value}); + FormActions.setDraftValues(formID as OnyxFormKey, {[inputKey]: value}); } inputProps.onValueChange?.(value, inputKey); }, diff --git a/src/components/Form/FormWrapper.tsx b/src/components/Form/FormWrapper.tsx index e8778cf25d58..3a64a3df9af9 100644 --- a/src/components/Form/FormWrapper.tsx +++ b/src/components/Form/FormWrapper.tsx @@ -11,11 +11,10 @@ import type {SafeAreaChildrenProps} from '@components/SafeAreaConsumer/types'; import ScrollViewWithContext from '@components/ScrollViewWithContext'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ErrorUtils from '@libs/ErrorUtils'; -import type {Form} from '@src/types/onyx'; -import type {Errors} from '@src/types/onyx/OnyxCommon'; +import type {Form} from '@src/types/form'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import type {FormProps, InputRefs} from './types'; +import type {FormInputErrors, FormProps, InputRefs} from './types'; type FormWrapperOnyxProps = { /** Contains the form state that must be accessed outside the component */ @@ -32,7 +31,7 @@ type FormWrapperProps = ChildrenProps & submitFlexEnabled?: boolean; /** Server side errors keyed by microtime */ - errors: Errors; + errors: FormInputErrors; /** Assuming refs are React refs */ inputRefs: RefObject; diff --git a/src/components/Form/InputWrapper.tsx b/src/components/Form/InputWrapper.tsx index fc9d1773c5d8..4d55de008516 100644 --- a/src/components/Form/InputWrapper.tsx +++ b/src/components/Form/InputWrapper.tsx @@ -1,27 +1,29 @@ -import type {ForwardedRef} from 'react'; +import type {ComponentPropsWithoutRef, ComponentType, ForwardedRef} from 'react'; import React, {forwardRef, useContext} from 'react'; import type {AnimatedTextInputRef} from '@components/RNTextInput'; import RoomNameInput from '@components/RoomNameInput'; import TextInput from '@components/TextInput'; import {canUseTouchScreen} from '@libs/DeviceCapabilities'; import FormContext from './FormContext'; -import type {InputWrapperProps, ValidInputs} from './types'; +import type {InputComponentBaseProps, InputComponentValueProps, ValidInputs, ValueTypeKey} from './types'; -const textInputBasedComponents: ValidInputs[] = [TextInput, RoomNameInput]; +const textInputBasedComponents: ComponentType[] = [TextInput, RoomNameInput]; -function computeComponentSpecificRegistrationParams({ +type ComputedComponentSpecificRegistrationParams = { + shouldSubmitForm: boolean; + shouldSetTouchedOnBlurOnly: boolean; + blurOnSubmit: boolean | undefined; +}; + +function computeComponentSpecificRegistrationParams({ InputComponent, shouldSubmitForm, multiline, autoGrowHeight, blurOnSubmit, -}: InputWrapperProps): { - readonly shouldSubmitForm: boolean; - readonly blurOnSubmit: boolean | undefined; - readonly shouldSetTouchedOnBlurOnly: boolean; -} { +}: InputComponentBaseProps): ComputedComponentSpecificRegistrationParams { if (textInputBasedComponents.includes(InputComponent)) { - const isEffectivelyMultiline = Boolean(multiline) || Boolean(autoGrowHeight); + const isEffectivelyMultiline = !!multiline || !!autoGrowHeight; // If the user can use the hardware keyboard, they have access to an alternative way of inserting a new line // (like a Shift+Enter keyboard shortcut). For simplicity, we assume that when there's no touch screen, it's a @@ -31,7 +33,7 @@ function computeComponentSpecificRegistrationParams( // We want to avoid a situation when the user can't insert a new line. For single-line inputs, it's not a problem and we // force-enable form submission. For multi-line inputs, ensure that it was requested to enable form submission for this specific // input and that alternative ways exist to add a new line. - const shouldReallySubmitForm = isEffectivelyMultiline ? Boolean(shouldSubmitForm) && canUseHardwareKeyboard : true; + const shouldReallySubmitForm = isEffectivelyMultiline ? !!shouldSubmitForm && canUseHardwareKeyboard : true; return { // There are inputs that don't have onBlur methods, to simulate the behavior of onBlur in e.g. checkbox, we had to @@ -52,15 +54,28 @@ function computeComponentSpecificRegistrationParams( }; } -function InputWrapper(props: InputWrapperProps, ref: ForwardedRef) { - const {InputComponent, inputID, valueType = 'string', shouldSubmitForm: propShouldSubmitForm, ...rest} = props; +type InputWrapperProps = ComponentPropsWithoutRef & + InputComponentValueProps & { + InputComponent: TInput; + inputID: string; + isFocused?: boolean; + + /** + * Should the containing form be submitted when this input is submitted itself? + * Currently, meaningful only for text inputs. + */ + shouldSubmitForm?: boolean; + }; + +function InputWrapper(props: InputWrapperProps, ref: ForwardedRef) { + const {InputComponent, inputID, valueType = 'string', shouldSubmitForm: propShouldSubmitForm, ...rest} = props as InputComponentBaseProps; const {registerInput} = useContext(FormContext); - const {shouldSetTouchedOnBlurOnly, blurOnSubmit, shouldSubmitForm} = computeComponentSpecificRegistrationParams(props); + const {shouldSetTouchedOnBlurOnly, blurOnSubmit, shouldSubmitForm} = computeComponentSpecificRegistrationParams(props as InputComponentBaseProps); // TODO: Sometimes we return too many props with register input, so we need to consider if it's better to make the returned type more general and disregard the issue, or we would like to omit the unused props somehow. - // eslint-disable-next-line react/jsx-props-no-spreading, @typescript-eslint/no-explicit-any - return ; + // eslint-disable-next-line react/jsx-props-no-spreading + return ; } InputWrapper.displayName = 'InputWrapper'; diff --git a/src/components/Form/types.ts b/src/components/Form/types.ts index 2705b2c8fd4e..93d9df12456c 100644 --- a/src/components/Form/types.ts +++ b/src/components/Form/types.ts @@ -1,24 +1,26 @@ -import type {ComponentProps, FocusEvent, Key, MutableRefObject, ReactNode, Ref} from 'react'; +import type {ComponentType, FocusEvent, Key, MutableRefObject, ReactNode, Ref} from 'react'; import type {GestureResponderEvent, NativeSyntheticEvent, StyleProp, TextInputFocusEventData, TextInputSubmitEditingEventData, ViewStyle} from 'react-native'; +import type {ValueOf} from 'type-fest'; import type AddressSearch from '@components/AddressSearch'; import type AmountForm from '@components/AmountForm'; import type AmountTextInput from '@components/AmountTextInput'; import type CheckboxWithLabel from '@components/CheckboxWithLabel'; +import type CountrySelector from '@components/CountrySelector'; import type Picker from '@components/Picker'; import type SingleChoiceQuestion from '@components/SingleChoiceQuestion'; import type StatePicker from '@components/StatePicker'; import type TextInput from '@components/TextInput'; import type BusinessTypePicker from '@pages/ReimbursementAccount/BusinessInfo/substeps/TypeBusiness/BusinessTypePicker'; +import type {TranslationPaths} from '@src/languages/types'; import type {OnyxFormKey, OnyxValues} from '@src/ONYXKEYS'; -import type Form from '@src/types/onyx/Form'; -import type {BaseForm, FormValueType} from '@src/types/onyx/Form'; +import type {BaseForm} from '@src/types/form/Form'; /** * This type specifies all the inputs that can be used with `InputWrapper` component. Make sure to update it * when adding new inputs or removing old ones. * * TODO: Add remaining inputs here once these components are migrated to Typescript: - * CountrySelector | StatePicker | DatePicker | EmojiPickerButtonDropdown | RoomNameInput | ValuePicker + * DatePicker | EmojiPickerButtonDropdown | RoomNameInput | ValuePicker */ type ValidInputs = | typeof TextInput @@ -27,54 +29,53 @@ type ValidInputs = | typeof CheckboxWithLabel | typeof Picker | typeof AddressSearch + | typeof CountrySelector | typeof AmountForm | typeof BusinessTypePicker | typeof StatePicker; type ValueTypeKey = 'string' | 'boolean' | 'date'; +type ValueTypeMap = { + string: string; + boolean: boolean; + date: Date; +}; +type FormValue = ValueOf; -type MeasureLayoutOnSuccessCallback = (left: number, top: number, width: number, height: number) => void; +type InputComponentValueProps = { + valueType?: TValue; + value?: ValueTypeMap[TValue]; + defaultValue?: ValueTypeMap[TValue]; + onValueChange?: (value: ValueTypeMap[TValue], key: string) => void; + shouldSaveDraft?: boolean; + shouldUseDefaultValue?: boolean; +}; -type BaseInputProps = { +type MeasureLayoutOnSuccessCallback = (left: number, top: number, width: number, height: number) => void; +type InputComponentBaseProps = InputComponentValueProps & { + InputComponent: ComponentType; + inputID: string; + errorText?: string; shouldSetTouchedOnBlurOnly?: boolean; - onValueChange?: (value: unknown, key: string) => void; + isFocused?: boolean; + measureLayout?: (ref: unknown, callback: MeasureLayoutOnSuccessCallback) => void; + focus?: () => void; onTouched?: (event: GestureResponderEvent) => void; - valueType?: ValueTypeKey; - value?: FormValueType; - defaultValue?: FormValueType; onBlur?: (event: FocusEvent | NativeSyntheticEvent) => void; onPressOut?: (event: GestureResponderEvent) => void; onPress?: (event: GestureResponderEvent) => void; - shouldSaveDraft?: boolean; - shouldUseDefaultValue?: boolean; - key?: Key | null | undefined; + onInputChange?: (value: FormValue, key: string) => void; + onSubmitEditing?: (event: NativeSyntheticEvent) => void; + key?: Key; ref?: Ref; - isFocused?: boolean; - measureLayout?: (ref: unknown, callback: MeasureLayoutOnSuccessCallback) => void; - focus?: () => void; multiline?: boolean; autoGrowHeight?: boolean; blurOnSubmit?: boolean; - onSubmitEditing?: (event: NativeSyntheticEvent) => void; + shouldSubmitForm?: boolean; }; -type InputWrapperProps = Omit & - ComponentProps & { - InputComponent: TInput; - inputID: string; - - /** - * Should the containing form be submitted when this input is submitted itself? - * Currently, meaningful only for text inputs. - */ - shouldSubmitForm?: boolean; - }; - -type ExcludeDraft = T extends `${string}Draft` ? never : T; -type OnyxFormKeyWithoutDraft = ExcludeDraft; - -type OnyxFormValues = OnyxValues[TOnyxKey]; -type OnyxFormValuesFields = Omit, keyof BaseForm>; +type FormOnyxValues = Omit; +type FormOnyxKeys = keyof FormOnyxValues; type FormProps = { /** A unique Onyx key identifying the form */ @@ -90,7 +91,7 @@ type FormProps = { isSubmitButtonVisible?: boolean; /** Callback to submit the form */ - onSubmit: (values: OnyxFormValuesFields) => void; + onSubmit: (values: FormOnyxValues) => void; /** Should the button be enabled when offline */ enabledWhenOffline?: boolean; @@ -114,8 +115,8 @@ type FormProps = { disablePressOnEnter?: boolean; }; -type RegisterInput = (inputID: keyof Form, shouldSubmitForm: boolean, inputProps: TInputProps) => TInputProps; +type InputRefs = Record>; -type InputRefs = Record>; +type FormInputErrors = Partial, TranslationPaths>>; -export type {InputWrapperProps, FormProps, RegisterInput, ValidInputs, BaseInputProps, ValueTypeKey, OnyxFormValues, OnyxFormValuesFields, InputRefs, OnyxFormKeyWithoutDraft}; +export type {FormProps, ValidInputs, InputComponentValueProps, FormValue, ValueTypeKey, FormOnyxValues, FormOnyxKeys, FormInputErrors, InputRefs, InputComponentBaseProps, ValueTypeMap}; diff --git a/src/components/KYCWall/BaseKYCWall.tsx b/src/components/KYCWall/BaseKYCWall.tsx index ab2d217deb0e..b43e5265a970 100644 --- a/src/components/KYCWall/BaseKYCWall.tsx +++ b/src/components/KYCWall/BaseKYCWall.tsx @@ -281,6 +281,7 @@ export default withOnyx({ bankAccountList: { key: ONYXKEYS.BANK_ACCOUNT_LIST, }, + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/components/createOnyxContext.tsx b/src/components/createOnyxContext.tsx index 4fb8b9a7281c..50cda00b17b4 100644 --- a/src/components/createOnyxContext.tsx +++ b/src/components/createOnyxContext.tsx @@ -3,42 +3,40 @@ import type {ComponentType, ForwardedRef, ForwardRefExoticComponent, PropsWithou import React, {createContext, forwardRef, useContext} from 'react'; import {withOnyx} from 'react-native-onyx'; import getComponentDisplayName from '@libs/getComponentDisplayName'; -import type {OnyxCollectionKey, OnyxKey, OnyxKeyValue, OnyxValues} from '@src/ONYXKEYS'; +import type {OnyxKey, OnyxValue, OnyxValues} from '@src/ONYXKEYS'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; -type OnyxKeys = (OnyxKey | OnyxCollectionKey) & keyof OnyxValues; - // Provider types -type ProviderOnyxProps = Record>; +type ProviderOnyxProps = Record>; -type ProviderPropsWithOnyx = ChildrenProps & ProviderOnyxProps; +type ProviderPropsWithOnyx = ChildrenProps & ProviderOnyxProps; // withOnyxKey types -type WithOnyxKeyProps = { +type WithOnyxKeyProps = { propName?: TOnyxKey | TNewOnyxKey; // It's not possible to infer the type of props of the wrapped component, so we have to use `any` here // eslint-disable-next-line @typescript-eslint/no-explicit-any - transformValue?: (value: OnyxKeyValue, props: any) => TTransformedValue; + transformValue?: (value: OnyxValue, props: any) => TTransformedValue; }; type WrapComponentWithConsumer = , TRef>( WrappedComponent: ComponentType>, ) => ForwardRefExoticComponent> & RefAttributes>; -type WithOnyxKey = >( +type WithOnyxKey = >( props?: WithOnyxKeyProps, ) => WrapComponentWithConsumer; // createOnyxContext return type -type CreateOnyxContext = [ +type CreateOnyxContext = [ WithOnyxKey, ComponentType, TOnyxKey>>, - React.Context>, + React.Context>, () => OnyxValues[TOnyxKey], ]; -export default (onyxKeyName: TOnyxKey): CreateOnyxContext => { - const Context = createContext>(null); +export default (onyxKeyName: TOnyxKey): CreateOnyxContext => { + const Context = createContext>(null); function Provider(props: ProviderPropsWithOnyx): ReactNode { return {props.children}; } @@ -52,7 +50,7 @@ export default (onyxKeyName: TOnyxKey): CreateOnyxCon // eslint-disable-next-line @typescript-eslint/no-explicit-any } as Record)(Provider); - function withOnyxKey>({ + function withOnyxKey>({ propName, transformValue, }: WithOnyxKeyProps = {}) { diff --git a/src/hooks/useReimbursementAccountStepFormSubmit.ts b/src/hooks/useReimbursementAccountStepFormSubmit.ts index 1f4de6ed2677..f3a17447c7d7 100644 --- a/src/hooks/useReimbursementAccountStepFormSubmit.ts +++ b/src/hooks/useReimbursementAccountStepFormSubmit.ts @@ -1,13 +1,13 @@ import {useCallback} from 'react'; +import type {FormOnyxKeys, FormOnyxValues} from '@components/Form/types'; import * as FormActions from '@userActions/FormActions'; -import type {OnyxFormKeyWithoutDraft} from '@userActions/FormActions'; +import type {OnyxFormKey} from '@src/ONYXKEYS'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; import type {SubStepProps} from './useSubStep/types'; type UseReimbursementAccountStepFormSubmitParams = Pick & { - formId?: OnyxFormKeyWithoutDraft; - fieldIds: Array; + formId?: OnyxFormKey; + fieldIds: Array>; }; /** @@ -25,7 +25,7 @@ export default function useReimbursementAccountStepFormSubmit({ fieldIds, }: UseReimbursementAccountStepFormSubmitParams) { return useCallback( - (values: ReimbursementAccountDraftValues) => { + (values: FormOnyxValues) => { if (isEditing) { const stepValues = fieldIds.reduce( (acc, key) => ({ diff --git a/src/libs/API/parameters/AcceptACHContractForBankAccount.ts b/src/libs/API/parameters/AcceptACHContractForBankAccount.ts index cd9473038fb0..6cf2735beabc 100644 --- a/src/libs/API/parameters/AcceptACHContractForBankAccount.ts +++ b/src/libs/API/parameters/AcceptACHContractForBankAccount.ts @@ -1,4 +1,4 @@ -import type {ACHContractStepProps} from '@src/types/onyx/ReimbursementAccountDraft'; +import type {ACHContractStepProps} from '@src/types/form/ReimbursementAccountForm'; type AcceptACHContractForBankAccount = ACHContractStepProps & {bankAccountID: number; canUseNewVbbaFlow?: boolean}; diff --git a/src/libs/API/parameters/UpdateBeneficialOwnersForBankAccountParams.ts b/src/libs/API/parameters/UpdateBeneficialOwnersForBankAccountParams.ts index aad6b1d34685..4d4e1af87e3b 100644 --- a/src/libs/API/parameters/UpdateBeneficialOwnersForBankAccountParams.ts +++ b/src/libs/API/parameters/UpdateBeneficialOwnersForBankAccountParams.ts @@ -1,4 +1,4 @@ -import type {ACHContractStepProps} from '@src/types/onyx/ReimbursementAccountDraft'; +import type {ACHContractStepProps} from '@src/types/form/ReimbursementAccountForm'; type UpdateBeneficialOwnersForBankAccountParams = ACHContractStepProps & {bankAccountID: number; canUseNewVbbaFlow?: boolean}; diff --git a/src/libs/API/parameters/UpdateCompanyInformationForBankAccountParams.ts b/src/libs/API/parameters/UpdateCompanyInformationForBankAccountParams.ts index a2dc4ab2e1d3..324c7070bbe2 100644 --- a/src/libs/API/parameters/UpdateCompanyInformationForBankAccountParams.ts +++ b/src/libs/API/parameters/UpdateCompanyInformationForBankAccountParams.ts @@ -1,4 +1,4 @@ -import type {BankAccountStepProps, CompanyStepProps, ReimbursementAccountProps} from '@src/types/onyx/ReimbursementAccountDraft'; +import type {BankAccountStepProps, CompanyStepProps, ReimbursementAccountProps} from '@src/types/form/ReimbursementAccountForm'; type BankAccountCompanyInformation = BankAccountStepProps & CompanyStepProps & ReimbursementAccountProps; diff --git a/src/libs/API/parameters/UpdatePersonalInformationForBankAccountParams.ts b/src/libs/API/parameters/UpdatePersonalInformationForBankAccountParams.ts index b4ec55877e71..b9c2ce65405b 100644 --- a/src/libs/API/parameters/UpdatePersonalInformationForBankAccountParams.ts +++ b/src/libs/API/parameters/UpdatePersonalInformationForBankAccountParams.ts @@ -1,4 +1,4 @@ -import type {RequestorStepProps} from '@src/types/onyx/ReimbursementAccountDraft'; +import type {RequestorStepProps} from '@src/types/form/ReimbursementAccountForm'; type UpdatePersonalInformationForBankAccountParams = RequestorStepProps & {bankAccountID: number; canUseNewVbbaFlow: boolean}; diff --git a/src/libs/FormUtils.ts b/src/libs/FormUtils.ts index 37241df49af7..4d0571ada6f2 100644 --- a/src/libs/FormUtils.ts +++ b/src/libs/FormUtils.ts @@ -1,6 +1,6 @@ -import type {OnyxFormKeyWithoutDraft} from '@components/Form/types'; +import type {OnyxFormDraftKey, OnyxFormKey} from '@src/ONYXKEYS'; -function getDraftKey(formID: OnyxFormKeyWithoutDraft): `${OnyxFormKeyWithoutDraft}Draft` { +function getDraftKey(formID: OnyxFormKey): OnyxFormDraftKey { return `${formID}Draft`; } diff --git a/src/libs/GetPhysicalCardUtils.ts b/src/libs/GetPhysicalCardUtils.ts index 82d991efb3aa..cf49ba03f287 100644 --- a/src/libs/GetPhysicalCardUtils.ts +++ b/src/libs/GetPhysicalCardUtils.ts @@ -1,7 +1,8 @@ import type {OnyxEntry} from 'react-native-onyx'; import ROUTES from '@src/ROUTES'; import type {Route} from '@src/ROUTES'; -import type {GetPhysicalCardForm, LoginList, PrivatePersonalDetails} from '@src/types/onyx'; +import type {GetPhysicalCardForm} from '@src/types/form'; +import type {LoginList, PrivatePersonalDetails} from '@src/types/onyx'; import Navigation from './Navigation/Navigation'; import * as PersonalDetailsUtils from './PersonalDetailsUtils'; import * as UserUtils from './UserUtils'; diff --git a/src/libs/OnyxSelectors/reportWithoutHasDraftSelector.ts b/src/libs/OnyxSelectors/reportWithoutHasDraftSelector.ts index 1062aa4b45c6..9c7e6402d69b 100644 --- a/src/libs/OnyxSelectors/reportWithoutHasDraftSelector.ts +++ b/src/libs/OnyxSelectors/reportWithoutHasDraftSelector.ts @@ -1,6 +1,6 @@ -import type {OnyxKeyValue} from '@src/ONYXKEYS'; +import type {OnyxValue} from '@src/ONYXKEYS'; -export default function reportWithoutHasDraftSelector(report: OnyxKeyValue<'report_'>) { +export default function reportWithoutHasDraftSelector(report: OnyxValue<'report_'>) { if (!report) { return report; } diff --git a/src/libs/ValidationUtils.ts b/src/libs/ValidationUtils.ts index e52075ccba06..02ae638a41d3 100644 --- a/src/libs/ValidationUtils.ts +++ b/src/libs/ValidationUtils.ts @@ -5,8 +5,9 @@ import isDate from 'lodash/isDate'; import isEmpty from 'lodash/isEmpty'; import isObject from 'lodash/isObject'; import type {OnyxCollection} from 'react-native-onyx'; -import type {OnyxFormValuesFields} from '@components/Form/types'; +import type {FormInputErrors, FormOnyxKeys, FormOnyxValues} from '@components/Form/types'; import CONST from '@src/CONST'; +import type {OnyxFormKey} from '@src/ONYXKEYS'; import type {Report} from '@src/types/onyx'; import * as CardUtils from './CardUtils'; import DateUtils from './DateUtils'; @@ -76,7 +77,7 @@ function isValidPastDate(date: string | Date): boolean { * Used to validate a value that is "required". * @param value - field value */ -function isRequiredFulfilled(value?: string | boolean | Date | unknown[] | Record | null): boolean { +function isRequiredFulfilled(value?: string | boolean | Date): boolean { if (!value) { return false; } @@ -92,21 +93,17 @@ function isRequiredFulfilled(value?: string | boolean | Date | unknown[] | Recor } return Boolean(value); } -/** - * Used for getting errors for required fields. - */ -type GetFieldRequiredErrorsReturn = {[P in K[number]]: string}; /** * Used to add requiredField error to the fields passed. * @param values - all form values * @param requiredFields - required fields for particular form */ -function getFieldRequiredErrors(values: T, requiredFields: K): GetFieldRequiredErrorsReturn { - const errors: GetFieldRequiredErrorsReturn = {} as GetFieldRequiredErrorsReturn; +function getFieldRequiredErrors(values: FormOnyxValues, requiredFields: Array>): FormInputErrors { + const errors: FormInputErrors = {}; - requiredFields.forEach((fieldKey: K[number]) => { - if (isRequiredFulfilled(values[fieldKey as keyof OnyxFormValuesFields])) { + requiredFields.forEach((fieldKey) => { + if (isRequiredFulfilled(values[fieldKey] as keyof FormOnyxValues)) { return; } diff --git a/src/libs/actions/BankAccounts.ts b/src/libs/actions/BankAccounts.ts index 1342a869bf7b..c5f68317bf18 100644 --- a/src/libs/actions/BankAccounts.ts +++ b/src/libs/actions/BankAccounts.ts @@ -18,9 +18,9 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type {Route} from '@src/ROUTES'; +import type {ACHContractStepProps, BeneficialOwnersStepProps, CompanyStepProps, RequestorStepProps} from '@src/types/form/ReimbursementAccountForm'; import type PlaidBankAccount from '@src/types/onyx/PlaidBankAccount'; import type {BankAccountStep, BankAccountSubStep} from '@src/types/onyx/ReimbursementAccount'; -import type {ACHContractStepProps, BeneficialOwnersStepProps, CompanyStepProps, OnfidoData, RequestorStepProps} from '@src/types/onyx/ReimbursementAccountDraft'; import type {OnyxData} from '@src/types/onyx/Request'; import * as ReimbursementAccount from './ReimbursementAccount'; @@ -427,7 +427,7 @@ function connectBankAccountManually(bankAccountID: number, accountNumber?: strin /** * Verify the user's identity via Onfido */ -function verifyIdentityForBankAccount(bankAccountID: number, onfidoData: OnfidoData) { +function verifyIdentityForBankAccount(bankAccountID: number, onfidoData: Record) { const parameters: VerifyIdentityForBankAccountParams = { bankAccountID, onfidoData: JSON.stringify(onfidoData), diff --git a/src/libs/actions/FormActions.ts b/src/libs/actions/FormActions.ts index 0d2d3e867dbf..3a0bdb94d5f5 100644 --- a/src/libs/actions/FormActions.ts +++ b/src/libs/actions/FormActions.ts @@ -1,8 +1,7 @@ import Onyx from 'react-native-onyx'; -import type {KeyValueMapping, NullishDeep} from 'react-native-onyx'; -import type {OnyxFormKeyWithoutDraft} from '@components/Form/types'; +import type {NullishDeep} from 'react-native-onyx'; import FormUtils from '@libs/FormUtils'; -import type {OnyxFormKey} from '@src/ONYXKEYS'; +import type {OnyxFormDraftKey, OnyxFormKey, OnyxValue} from '@src/ONYXKEYS'; import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; function setIsLoading(formID: OnyxFormKey, isLoading: boolean) { @@ -25,13 +24,12 @@ function clearErrorFields(formID: OnyxFormKey) { Onyx.merge(formID, {errorFields: null}); } -function setDraftValues(formID: OnyxFormKeyWithoutDraft, draftValues: NullishDeep) { +function setDraftValues(formID: OnyxFormKey, draftValues: NullishDeep>) { Onyx.merge(FormUtils.getDraftKey(formID), draftValues); } -function clearDraftValues(formID: OnyxFormKeyWithoutDraft) { +function clearDraftValues(formID: OnyxFormKey) { Onyx.set(FormUtils.getDraftKey(formID), null); } -export type {OnyxFormKeyWithoutDraft}; export {setDraftValues, setErrorFields, setErrors, clearErrors, clearErrorFields, setIsLoading, clearDraftValues}; diff --git a/src/libs/actions/PersonalDetails.ts b/src/libs/actions/PersonalDetails.ts index 53491b386b8c..5ae37bb85f10 100644 --- a/src/libs/actions/PersonalDetails.ts +++ b/src/libs/actions/PersonalDetails.ts @@ -21,7 +21,8 @@ import * as UserUtils from '@libs/UserUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {DateOfBirthForm, PersonalDetails, PersonalDetailsList, PrivatePersonalDetails} from '@src/types/onyx'; +import type {DateOfBirthForm} from '@src/types/form'; +import type {PersonalDetails, PersonalDetailsList, PrivatePersonalDetails} from '@src/types/onyx'; import type {SelectedTimezone, Timezone} from '@src/types/onyx/PersonalDetails'; import * as Session from './Session'; diff --git a/src/libs/onyxSubscribe.ts b/src/libs/onyxSubscribe.ts index 3a2daca900e4..afb8818ced40 100644 --- a/src/libs/onyxSubscribe.ts +++ b/src/libs/onyxSubscribe.ts @@ -8,7 +8,7 @@ import type {OnyxCollectionKey, OnyxKey} from '@src/ONYXKEYS'; * @param mapping Same as for Onyx.connect() * @return Unsubscribe callback */ -function onyxSubscribe(mapping: ConnectOptions) { +function onyxSubscribe(mapping: ConnectOptions) { const connectionId = Onyx.connect(mapping); return () => Onyx.disconnect(connectionId); } diff --git a/src/pages/EditReportFieldDatePage.tsx b/src/pages/EditReportFieldDatePage.tsx index 82659eca62c2..45d2f31073ec 100644 --- a/src/pages/EditReportFieldDatePage.tsx +++ b/src/pages/EditReportFieldDatePage.tsx @@ -3,7 +3,7 @@ import {View} from 'react-native'; import DatePicker from '@components/DatePicker'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; -import type {OnyxFormValuesFields} from '@components/Form/types'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import type {AnimatedTextInputRef} from '@components/RNTextInput'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -11,7 +11,6 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Errors} from '@src/types/onyx/OnyxCommon'; type EditReportFieldDatePageProps = { /** Value of the policy report field */ @@ -27,7 +26,7 @@ type EditReportFieldDatePageProps = { isRequired: boolean; /** Callback to fire when the Save button is pressed */ - onSubmit: (form: OnyxFormValuesFields) => void; + onSubmit: (form: FormOnyxValues) => void; }; function EditReportFieldDatePage({fieldName, isRequired, onSubmit, fieldValue, fieldID}: EditReportFieldDatePageProps) { @@ -36,8 +35,8 @@ function EditReportFieldDatePage({fieldName, isRequired, onSubmit, fieldValue, f const inputRef = useRef(null); const validate = useCallback( - (value: OnyxFormValuesFields) => { - const errors: Errors = {}; + (value: FormOnyxValues) => { + const errors: FormInputErrors = {}; if (isRequired && value[fieldID].trim() === '') { errors[fieldID] = 'common.error.fieldRequired'; } diff --git a/src/pages/EditReportFieldPage.tsx b/src/pages/EditReportFieldPage.tsx index 5bb53ef9122e..4124a9ebef98 100644 --- a/src/pages/EditReportFieldPage.tsx +++ b/src/pages/EditReportFieldPage.tsx @@ -3,7 +3,7 @@ import React from 'react'; import {withOnyx} from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx'; import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; -import type {OnyxFormValuesFields} from '@components/Form/types'; +import type {FormOnyxValues} from '@components/Form/types'; import ScreenWrapper from '@components/ScreenWrapper'; import Navigation from '@libs/Navigation/Navigation'; import * as ReportUtils from '@libs/ReportUtils'; @@ -64,7 +64,7 @@ function EditReportFieldPage({route, policy, report, policyReportFields}: EditRe const isReportFieldTitle = ReportUtils.isReportFieldOfTypeTitle(reportField); - const handleReportFieldChange = (form: OnyxFormValuesFields) => { + const handleReportFieldChange = (form: FormOnyxValues) => { const value = form[reportField.fieldID] || ''; if (isReportFieldTitle) { ReportActions.updateReportName(report.reportID, value, report.reportName ?? ''); diff --git a/src/pages/EditReportFieldTextPage.tsx b/src/pages/EditReportFieldTextPage.tsx index ea9d2d3bed6d..9cda559280a9 100644 --- a/src/pages/EditReportFieldTextPage.tsx +++ b/src/pages/EditReportFieldTextPage.tsx @@ -2,7 +2,7 @@ import React, {useCallback, useRef} from 'react'; import {View} from 'react-native'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; -import type {OnyxFormValuesFields} from '@components/Form/types'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import type {AnimatedTextInputRef} from '@components/RNTextInput'; import ScreenWrapper from '@components/ScreenWrapper'; @@ -11,7 +11,6 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {Errors} from '@src/types/onyx/OnyxCommon'; type EditReportFieldTextPageProps = { /** Value of the policy report field */ @@ -27,7 +26,7 @@ type EditReportFieldTextPageProps = { isRequired: boolean; /** Callback to fire when the Save button is pressed */ - onSubmit: (form: OnyxFormValuesFields) => void; + onSubmit: (form: FormOnyxValues) => void; }; function EditReportFieldTextPage({fieldName, onSubmit, fieldValue, isRequired, fieldID}: EditReportFieldTextPageProps) { @@ -36,8 +35,8 @@ function EditReportFieldTextPage({fieldName, onSubmit, fieldValue, isRequired, f const inputRef = useRef(null); const validate = useCallback( - (values: OnyxFormValuesFields) => { - const errors: Errors = {}; + (values: FormOnyxValues) => { + const errors: FormInputErrors = {}; if (isRequired && values[fieldID].trim() === '') { errors[fieldID] = 'common.error.fieldRequired'; } diff --git a/src/pages/EditRequestMerchantPage.js b/src/pages/EditRequestMerchantPage.js index e5966bad2d2b..420bcbc35630 100644 --- a/src/pages/EditRequestMerchantPage.js +++ b/src/pages/EditRequestMerchantPage.js @@ -11,6 +11,7 @@ import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/MoneyRequestMerchantForm'; const propTypes = { /** Transaction default merchant value */ @@ -59,8 +60,8 @@ function EditRequestMerchantPage({defaultMerchant, onSubmit, isPolicyExpenseChat void; }; -const BANK_INFO_STEP_KEYS = CONST.BANK_ACCOUNT.BANK_INFO_STEP.INPUT_KEY; +const BANK_INFO_STEP_KEYS = INPUT_IDS.BANK_INFO_STEP; const manualSubsteps: Array> = [Manual, Confirmation]; const plaidSubsteps: Array> = [Plaid, Confirmation]; const receivedRedirectURI = getPlaidOAuthReceivedRedirectURI(); @@ -46,7 +48,7 @@ function BankInfo({reimbursementAccount, reimbursementAccountDraft, plaidLinkTok const styles = useThemeStyles(); const [redirectedFromPlaidToManual, setRedirectedFromPlaidToManual] = React.useState(false); - const values = useMemo(() => getSubstepValues(BANK_INFO_STEP_KEYS, reimbursementAccountDraft ?? {}, reimbursementAccount ?? {}), [reimbursementAccount, reimbursementAccountDraft]); + const values = useMemo(() => getSubstepValues(BANK_INFO_STEP_KEYS, reimbursementAccountDraft, reimbursementAccount ?? {}), [reimbursementAccount, reimbursementAccountDraft]); let setupType = reimbursementAccount?.achData?.subStep ?? ''; @@ -150,6 +152,7 @@ function BankInfo({reimbursementAccount, reimbursementAccountDraft, plaidLinkTok BankInfo.displayName = 'BankInfo'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BankInfo/substeps/Confirmation.tsx b/src/pages/ReimbursementAccount/BankInfo/substeps/Confirmation.tsx index c1fc3f82b277..f2070e38b942 100644 --- a/src/pages/ReimbursementAccount/BankInfo/substeps/Confirmation.tsx +++ b/src/pages/ReimbursementAccount/BankInfo/substeps/Confirmation.tsx @@ -14,7 +14,9 @@ import * as ErrorUtils from '@libs/ErrorUtils'; import getSubstepValues from '@pages/ReimbursementAccount/utils/getSubstepValues'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccount, ReimbursementAccountForm} from '@src/types/onyx'; +import type {ReimbursementAccountForm} from '@src/types/form'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; +import type {ReimbursementAccount} from '@src/types/onyx'; type ConfirmationOnyxProps = { /** Reimbursement account from ONYX */ @@ -26,7 +28,7 @@ type ConfirmationOnyxProps = { type ConfirmationProps = ConfirmationOnyxProps & SubStepProps; -const BANK_INFO_STEP_KEYS = CONST.BANK_ACCOUNT.BANK_INFO_STEP.INPUT_KEY; +const BANK_INFO_STEP_KEYS = INPUT_IDS.BANK_INFO_STEP; const BANK_INFO_STEP_INDEXES = CONST.REIMBURSEMENT_ACCOUNT_SUBSTEP_INDEX.BANK_ACCOUNT; function Confirmation({reimbursementAccount, reimbursementAccountDraft, onNext, onMove}: ConfirmationProps) { @@ -36,7 +38,7 @@ function Confirmation({reimbursementAccount, reimbursementAccountDraft, onNext, const isLoading = reimbursementAccount?.isLoading ?? false; const setupType = reimbursementAccount?.achData?.subStep ?? ''; const bankAccountID = Number(reimbursementAccount?.achData?.bankAccountID ?? '0'); - const values = useMemo(() => getSubstepValues(BANK_INFO_STEP_KEYS, reimbursementAccountDraft ?? {}, reimbursementAccount ?? {}), [reimbursementAccount, reimbursementAccountDraft]); + const values = useMemo(() => getSubstepValues(BANK_INFO_STEP_KEYS, reimbursementAccountDraft, reimbursementAccount ?? {}), [reimbursementAccount, reimbursementAccountDraft]); const error = ErrorUtils.getLatestErrorMessage(reimbursementAccount ?? {}); const handleModifyAccountNumbers = () => { @@ -101,6 +103,7 @@ function Confirmation({reimbursementAccount, reimbursementAccountDraft, onNext, Confirmation.displayName = 'Confirmation'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BankInfo/substeps/Manual.tsx b/src/pages/ReimbursementAccount/BankInfo/substeps/Manual.tsx index a9a2c49969aa..1b3998190293 100644 --- a/src/pages/ReimbursementAccount/BankInfo/substeps/Manual.tsx +++ b/src/pages/ReimbursementAccount/BankInfo/substeps/Manual.tsx @@ -3,6 +3,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; @@ -12,8 +13,8 @@ import * as ValidationUtils from '@libs/ValidationUtils'; import ExampleCheckImage from '@pages/ReimbursementAccount/ExampleCheck'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; import type {ReimbursementAccount} from '@src/types/onyx'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; type ManualOnyxProps = { /** Reimbursement account from ONYX */ @@ -22,46 +23,37 @@ type ManualOnyxProps = { type ManualProps = ManualOnyxProps & SubStepProps; -type FormValues = {routingNumber: string; accountNumber: string}; - -const BANK_INFO_STEP_KEYS = CONST.BANK_ACCOUNT.BANK_INFO_STEP.INPUT_KEY; +const BANK_INFO_STEP_KEYS = INPUT_IDS.BANK_INFO_STEP; const STEP_FIELDS = [BANK_INFO_STEP_KEYS.ROUTING_NUMBER, BANK_INFO_STEP_KEYS.ACCOUNT_NUMBER]; function Manual({reimbursementAccount, onNext}: ManualProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const defaultValues: FormValues = { + const defaultValues = { [BANK_INFO_STEP_KEYS.ROUTING_NUMBER]: reimbursementAccount?.achData?.[BANK_INFO_STEP_KEYS.ROUTING_NUMBER] ?? '', [BANK_INFO_STEP_KEYS.ACCOUNT_NUMBER]: reimbursementAccount?.achData?.[BANK_INFO_STEP_KEYS.ACCOUNT_NUMBER] ?? '', }; - /** - * @param {Object} values - form input values passed by the Form component - * @returns {Object} - */ - const validate = useCallback( - (values: ReimbursementAccountDraftValues) => { - const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); - const routingNumber = values.routingNumber?.trim(); + const validate = useCallback((values: FormOnyxValues): FormInputErrors => { + const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); + const routingNumber = values.routingNumber?.trim(); - if ( - values.accountNumber && - !CONST.BANK_ACCOUNT.REGEX.US_ACCOUNT_NUMBER.test(values.accountNumber.trim()) && - !CONST.BANK_ACCOUNT.REGEX.MASKED_US_ACCOUNT_NUMBER.test(values.accountNumber.trim()) - ) { - errors.accountNumber = 'bankAccount.error.accountNumber'; - } else if (values.accountNumber && values.accountNumber === routingNumber) { - errors.accountNumber = translate('bankAccount.error.routingAndAccountNumberCannotBeSame'); - } - if (routingNumber && (!CONST.BANK_ACCOUNT.REGEX.SWIFT_BIC.test(routingNumber) || !ValidationUtils.isValidRoutingNumber(routingNumber))) { - errors.routingNumber = 'bankAccount.error.routingNumber'; - } + if ( + values.accountNumber && + !CONST.BANK_ACCOUNT.REGEX.US_ACCOUNT_NUMBER.test(values.accountNumber.trim()) && + !CONST.BANK_ACCOUNT.REGEX.MASKED_US_ACCOUNT_NUMBER.test(values.accountNumber.trim()) + ) { + errors.accountNumber = 'bankAccount.error.accountNumber'; + } else if (values.accountNumber && values.accountNumber === routingNumber) { + errors.accountNumber = 'bankAccount.error.routingAndAccountNumberCannotBeSame'; + } + if (routingNumber && (!CONST.BANK_ACCOUNT.REGEX.SWIFT_BIC.test(routingNumber) || !ValidationUtils.isValidRoutingNumber(routingNumber))) { + errors.routingNumber = 'bankAccount.error.routingNumber'; + } - return errors; - }, - [translate], - ); + return errors; + }, []); const shouldDisableInputs = !!(reimbursementAccount?.achData?.bankAccountID ?? ''); @@ -108,6 +100,7 @@ function Manual({reimbursementAccount, onNext}: ManualProps) { Manual.displayName = 'Manual'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BankInfo/substeps/Plaid.tsx b/src/pages/ReimbursementAccount/BankInfo/substeps/Plaid.tsx index 111327788b2b..7728ef836d64 100644 --- a/src/pages/ReimbursementAccount/BankInfo/substeps/Plaid.tsx +++ b/src/pages/ReimbursementAccount/BankInfo/substeps/Plaid.tsx @@ -5,6 +5,7 @@ import {withOnyx} from 'react-native-onyx'; import AddPlaidBankAccount from '@components/AddPlaidBankAccount'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import useLocalize from '@hooks/useLocalize'; import type {SubStepProps} from '@hooks/useSubStep/types'; import useThemeStyles from '@hooks/useThemeStyles'; @@ -12,9 +13,9 @@ import * as BankAccounts from '@userActions/BankAccounts'; import * as ReimbursementAccountActions from '@userActions/ReimbursementAccount'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {PlaidData, ReimbursementAccount, ReimbursementAccountForm} from '@src/types/onyx'; -import type {Errors} from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; +import type {ReimbursementAccountForm} from '@src/types/form'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; +import type {PlaidData, ReimbursementAccount} from '@src/types/onyx'; type PlaidOnyxProps = { /** Reimbursement account from ONYX */ @@ -29,10 +30,10 @@ type PlaidOnyxProps = { type PlaidProps = PlaidOnyxProps & SubStepProps; -const BANK_INFO_STEP_KEYS = CONST.BANK_ACCOUNT.BANK_INFO_STEP.INPUT_KEY; +const BANK_INFO_STEP_KEYS = INPUT_IDS.BANK_INFO_STEP; -const validate = (values: ReimbursementAccountDraftValues): Errors => { - const errorFields: Errors = {}; +const validate = (values: FormOnyxValues): FormInputErrors => { + const errorFields: FormInputErrors = {}; if (!values.selectedPlaidAccountID) { errorFields.selectedPlaidAccountID = 'bankAccount.error.youNeedToSelectAnOption'; @@ -98,7 +99,7 @@ function Plaid({reimbursementAccount, reimbursementAccountDraft, onNext, plaidDa bankAccountID={bankAccountID} selectedPlaidAccountID={selectedPlaidAccountID} isDisplayedInNewVBBA - inputID="selectedPlaidAccountID" + inputID={BANK_INFO_STEP_KEYS.SELECTED_PLAID_ACCOUNT_ID} inputMode={CONST.INPUT_MODE.TEXT} style={[styles.mt5]} defaultValue={selectedPlaidAccountID} @@ -110,6 +111,7 @@ function Plaid({reimbursementAccount, reimbursementAccountDraft, onNext, plaidDa Plaid.displayName = 'Plaid'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/AddressUBO.tsx b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/AddressUBO.tsx index d0ab0e45398b..999710310224 100644 --- a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/AddressUBO.tsx +++ b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/AddressUBO.tsx @@ -2,6 +2,7 @@ import React from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit'; @@ -11,8 +12,7 @@ import * as ValidationUtils from '@libs/ValidationUtils'; import AddressForm from '@pages/ReimbursementAccount/AddressForm'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccountForm} from '@src/types/onyx'; -import type {BeneficialOwnerDraftData, ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; +import type {ReimbursementAccountForm} from '@src/types/form'; const BENEFICIAL_OWNER_INFO_KEY = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA; const BENEFICIAL_OWNER_PREFIX = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA.PREFIX; @@ -22,18 +22,17 @@ type AddressUBOOnyxProps = { reimbursementAccountDraft: OnyxEntry; }; type AddressUBOProps = SubStepProps & AddressUBOOnyxProps & {beneficialOwnerBeingModifiedID: string}; -type FormValues = BeneficialOwnerDraftData; function AddressUBO({reimbursementAccountDraft, onNext, isEditing, beneficialOwnerBeingModifiedID}: AddressUBOProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const inputKeys: Record = { + const inputKeys = { street: `${BENEFICIAL_OWNER_PREFIX}_${beneficialOwnerBeingModifiedID}_${BENEFICIAL_OWNER_INFO_KEY.STREET}`, city: `${BENEFICIAL_OWNER_PREFIX}_${beneficialOwnerBeingModifiedID}_${BENEFICIAL_OWNER_INFO_KEY.CITY}`, state: `${BENEFICIAL_OWNER_PREFIX}_${beneficialOwnerBeingModifiedID}_${BENEFICIAL_OWNER_INFO_KEY.STATE}`, zipCode: `${BENEFICIAL_OWNER_PREFIX}_${beneficialOwnerBeingModifiedID}_${BENEFICIAL_OWNER_INFO_KEY.ZIP_CODE}`, - }; + } as const; const stepFields = [inputKeys.street, inputKeys.city, inputKeys.state, inputKeys.zipCode]; @@ -44,7 +43,7 @@ function AddressUBO({reimbursementAccountDraft, onNext, isEditing, beneficialOwn zipCode: reimbursementAccountDraft?.[inputKeys.zipCode] ?? '', }; - const validate = (values: ReimbursementAccountDraftValues) => { + const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, stepFields); if (values[inputKeys.street] && !ValidationUtils.isValidAddress(values[inputKeys.street])) { diff --git a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/ConfirmationUBO.tsx b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/ConfirmationUBO.tsx index 6ea33bf07789..c5475c86230d 100644 --- a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/ConfirmationUBO.tsx +++ b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/ConfirmationUBO.tsx @@ -15,7 +15,8 @@ import * as ErrorUtils from '@libs/ErrorUtils'; import getValuesForBeneficialOwner from '@pages/ReimbursementAccount/utils/getValuesForBeneficialOwner'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccount, ReimbursementAccountForm} from '@src/types/onyx'; +import type {ReimbursementAccountForm} from '@src/types/form'; +import type {ReimbursementAccount} from '@src/types/onyx'; type ConfirmationUBOOnyxProps = { /** Reimbursement account from ONYX */ @@ -121,6 +122,7 @@ function ConfirmationUBO({reimbursementAccount, reimbursementAccountDraft, onNex ConfirmationUBO.displayName = 'ConfirmationUBO'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/DateOfBirthUBO.tsx b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/DateOfBirthUBO.tsx index e18693ee2322..be1a0f170665 100644 --- a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/DateOfBirthUBO.tsx +++ b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/DateOfBirthUBO.tsx @@ -5,6 +5,7 @@ import {withOnyx} from 'react-native-onyx'; import DatePicker from '@components/DatePicker'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit'; @@ -13,8 +14,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as ValidationUtils from '@libs/ValidationUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccountForm} from '@src/types/onyx'; -import type {BeneficialOwnerDraftData, ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; +import type {ReimbursementAccountForm} from '@src/types/form'; const DOB = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA.DOB; const BENEFICIAL_OWNER_PREFIX = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA.PREFIX; @@ -24,22 +24,19 @@ type DateOfBirthUBOOnyxProps = { reimbursementAccountDraft: OnyxEntry; }; type DateOfBirthUBOProps = SubStepProps & DateOfBirthUBOOnyxProps & {beneficialOwnerBeingModifiedID: string}; -type FormValues = BeneficialOwnerDraftData; function DateOfBirthUBO({reimbursementAccountDraft, onNext, isEditing, beneficialOwnerBeingModifiedID}: DateOfBirthUBOProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const dobInputID: keyof FormValues = `${BENEFICIAL_OWNER_PREFIX}_${beneficialOwnerBeingModifiedID}_${DOB}`; - const stepFields = [dobInputID]; - + const dobInputID = `${BENEFICIAL_OWNER_PREFIX}_${beneficialOwnerBeingModifiedID}_${DOB}` as const; const dobDefaultValue = reimbursementAccountDraft?.[dobInputID] ?? ''; const minDate = subYears(new Date(), CONST.DATE_BIRTH.MAX_AGE); const maxDate = subYears(new Date(), CONST.DATE_BIRTH.MIN_AGE_FOR_PAYMENT); - const validate = (values: ReimbursementAccountDraftValues) => { - const errors = ValidationUtils.getFieldRequiredErrors(values, stepFields); + const validate = (values: FormOnyxValues): FormInputErrors => { + const errors = ValidationUtils.getFieldRequiredErrors(values, [dobInputID]); if (values[dobInputID]) { if (!ValidationUtils.isValidPastDate(values[dobInputID]) || !ValidationUtils.meetsMaximumAgeRequirement(values[dobInputID])) { @@ -53,7 +50,7 @@ function DateOfBirthUBO({reimbursementAccountDraft, onNext, isEditing, beneficia }; const handleSubmit = useReimbursementAccountStepFormSubmit({ - fieldIds: stepFields, + fieldIds: [dobInputID], isEditing, onNext, }); diff --git a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/LegalNameUBO.tsx b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/LegalNameUBO.tsx index d608378adfbf..ccd7104e2276 100644 --- a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/LegalNameUBO.tsx +++ b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/LegalNameUBO.tsx @@ -3,6 +3,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; @@ -12,8 +13,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as ValidationUtils from '@libs/ValidationUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccountForm} from '@src/types/onyx'; -import type {BeneficialOwnerDraftData} from '@src/types/onyx/ReimbursementAccountDraft'; +import type {ReimbursementAccountForm} from '@src/types/form'; const {FIRST_NAME, LAST_NAME} = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA; const BENEFICIAL_OWNER_PREFIX = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA.PREFIX; @@ -23,19 +23,19 @@ type LegalNameUBOOnyxProps = { reimbursementAccountDraft: OnyxEntry; }; type LegalNameUBOProps = SubStepProps & LegalNameUBOOnyxProps & {beneficialOwnerBeingModifiedID: string}; -type FormValues = BeneficialOwnerDraftData; function LegalNameUBO({reimbursementAccountDraft, onNext, isEditing, beneficialOwnerBeingModifiedID}: LegalNameUBOProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const firstNameInputID: keyof FormValues = `${BENEFICIAL_OWNER_PREFIX}_${beneficialOwnerBeingModifiedID}_${FIRST_NAME}`; - const lastNameInputID: keyof FormValues = `${BENEFICIAL_OWNER_PREFIX}_${beneficialOwnerBeingModifiedID}_${LAST_NAME}`; + const firstNameInputID = `${BENEFICIAL_OWNER_PREFIX}_${beneficialOwnerBeingModifiedID}_${FIRST_NAME}` as const; + const lastNameInputID = `${BENEFICIAL_OWNER_PREFIX}_${beneficialOwnerBeingModifiedID}_${LAST_NAME}` as const; const stepFields = [firstNameInputID, lastNameInputID]; const defaultFirstName = reimbursementAccountDraft?.[firstNameInputID] ?? ''; const defaultLastName = reimbursementAccountDraft?.[lastNameInputID] ?? ''; - const validate = (values: FormValues) => ValidationUtils.getFieldRequiredErrors(values, stepFields); + const validate = (values: FormOnyxValues): FormInputErrors => + ValidationUtils.getFieldRequiredErrors(values, stepFields); const handleSubmit = useReimbursementAccountStepFormSubmit({ fieldIds: stepFields, diff --git a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/SocialSecurityNumberUBO.tsx b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/SocialSecurityNumberUBO.tsx index 51a9c9c566bd..3b5710134114 100644 --- a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/SocialSecurityNumberUBO.tsx +++ b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/SocialSecurityNumberUBO.tsx @@ -4,6 +4,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; @@ -13,8 +14,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as ValidationUtils from '@libs/ValidationUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccountForm} from '@src/types/onyx'; -import type {BeneficialOwnerDraftData, ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; +import type {ReimbursementAccountForm} from '@src/types/form'; const SSN_LAST_4 = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA.SSN_LAST_4; const BENEFICIAL_OWNER_PREFIX = CONST.BANK_ACCOUNT.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNER_DATA.PREFIX; @@ -24,17 +24,16 @@ type SocialSecurityNumberUBOOnyxProps = { reimbursementAccountDraft: OnyxEntry; }; type SocialSecurityNumberUBOProps = SubStepProps & SocialSecurityNumberUBOOnyxProps & {beneficialOwnerBeingModifiedID: string}; -type FormValues = BeneficialOwnerDraftData; function SocialSecurityNumberUBO({reimbursementAccountDraft, onNext, isEditing, beneficialOwnerBeingModifiedID}: SocialSecurityNumberUBOProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const ssnLast4InputID: keyof FormValues = `${BENEFICIAL_OWNER_PREFIX}_${beneficialOwnerBeingModifiedID}_${SSN_LAST_4}`; + const ssnLast4InputID = `${BENEFICIAL_OWNER_PREFIX}_${beneficialOwnerBeingModifiedID}_${SSN_LAST_4}` as const; const defaultSsnLast4 = reimbursementAccountDraft?.[ssnLast4InputID] ?? ''; const stepFields = [ssnLast4InputID]; - const validate = (values: ReimbursementAccountDraftValues) => { + const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, stepFields); if (values[ssnLast4InputID] && !ValidationUtils.isValidSSNLastFour(values[ssnLast4InputID])) { errors[ssnLast4InputID] = 'bankAccount.error.ssnLast4'; diff --git a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/CompanyOwnersListUBO.tsx b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/CompanyOwnersListUBO.tsx index cafe7fd98e8c..650972966ebd 100644 --- a/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/CompanyOwnersListUBO.tsx +++ b/src/pages/ReimbursementAccount/BeneficialOwnerInfo/substeps/CompanyOwnersListUBO.tsx @@ -16,7 +16,9 @@ import getSubstepValues from '@pages/ReimbursementAccount/utils/getSubstepValues import getValuesForBeneficialOwner from '@pages/ReimbursementAccount/utils/getValuesForBeneficialOwner'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccount, ReimbursementAccountForm} from '@src/types/onyx'; +import type {ReimbursementAccountForm} from '@src/types/form'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; +import type {ReimbursementAccount} from '@src/types/onyx'; const reimbursementAccountDefault = { achData: { @@ -54,7 +56,7 @@ type CompanyOwnersListUBOProps = CompanyOwnersListUBOIOnyxProps & { isAnyoneElseUBO: boolean; }; -const REQUESTOR_PERSONAL_INFO_KEYS = CONST.BANK_ACCOUNT.PERSONAL_INFO_STEP.INPUT_KEY; +const REQUESTOR_PERSONAL_INFO_KEYS = INPUT_IDS.PERSONAL_INFO_STEP; function CompanyOwnersListUBO({ reimbursementAccount = reimbursementAccountDefault, @@ -69,7 +71,7 @@ function CompanyOwnersListUBO({ const styles = useThemeStyles(); const isLoading = reimbursementAccount?.isLoading ?? false; - const requestorData = getSubstepValues(REQUESTOR_PERSONAL_INFO_KEYS, {}, reimbursementAccount); + const requestorData = getSubstepValues(REQUESTOR_PERSONAL_INFO_KEYS, null, reimbursementAccount); const error = ErrorUtils.getLatestErrorMessage(reimbursementAccount); const extraBeneficialOwners = @@ -148,6 +150,7 @@ function CompanyOwnersListUBO({ CompanyOwnersListUBO.displayName = 'CompanyOwnersListUBO'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BeneficialOwnersStep.tsx b/src/pages/ReimbursementAccount/BeneficialOwnersStep.tsx index f21776fd9a4a..406033b10b03 100644 --- a/src/pages/ReimbursementAccount/BeneficialOwnersStep.tsx +++ b/src/pages/ReimbursementAccount/BeneficialOwnersStep.tsx @@ -14,7 +14,8 @@ import * as BankAccounts from '@userActions/BankAccounts'; import * as FormActions from '@userActions/FormActions'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccount, ReimbursementAccountForm} from '@src/types/onyx'; +import type {ReimbursementAccountForm} from '@src/types/form'; +import type {ReimbursementAccount} from '@src/types/onyx'; import BeneficialOwnerCheckUBO from './BeneficialOwnerInfo/substeps/BeneficialOwnerCheckUBO'; import AddressUBO from './BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/AddressUBO'; import ConfirmationUBO from './BeneficialOwnerInfo/substeps/BeneficialOwnerDetailsFormSubsteps/ConfirmationUBO'; @@ -280,6 +281,7 @@ function BeneficialOwnersStep({reimbursementAccount, reimbursementAccountDraft, BeneficialOwnersStep.displayName = 'BeneficialOwnersStep'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BusinessInfo/BusinessInfo.tsx b/src/pages/ReimbursementAccount/BusinessInfo/BusinessInfo.tsx index b7c0192ccc76..21f90c414b5d 100644 --- a/src/pages/ReimbursementAccount/BusinessInfo/BusinessInfo.tsx +++ b/src/pages/ReimbursementAccount/BusinessInfo/BusinessInfo.tsx @@ -16,7 +16,9 @@ import getSubstepValues from '@pages/ReimbursementAccount/utils/getSubstepValues import * as BankAccounts from '@userActions/BankAccounts'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccount, ReimbursementAccountForm} from '@src/types/onyx'; +import type {ReimbursementAccountForm} from '@src/types/form'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; +import type {ReimbursementAccount} from '@src/types/onyx'; import AddressBusiness from './substeps/AddressBusiness'; import ConfirmationBusiness from './substeps/ConfirmationBusiness'; import IncorporationDateBusiness from './substeps/IncorporationDateBusiness'; @@ -40,7 +42,7 @@ type BusinessInfoProps = BusinessInfoOnyxProps & { onBackButtonPress: () => void; }; -const BUSINESS_INFO_STEP_KEYS = CONST.BANK_ACCOUNT.BUSINESS_INFO_STEP.INPUT_KEY; +const BUSINESS_INFO_STEP_KEYS = INPUT_IDS.BUSINESS_INFO_STEP; const bodyContent: Array> = [ NameBusiness, @@ -124,6 +126,7 @@ function BusinessInfo({reimbursementAccount, reimbursementAccountDraft, onBackBu BusinessInfo.displayName = 'BusinessInfo'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BusinessInfo/substeps/AddressBusiness.tsx b/src/pages/ReimbursementAccount/BusinessInfo/substeps/AddressBusiness.tsx index 7f3131d59920..354620f5e46a 100644 --- a/src/pages/ReimbursementAccount/BusinessInfo/substeps/AddressBusiness.tsx +++ b/src/pages/ReimbursementAccount/BusinessInfo/substeps/AddressBusiness.tsx @@ -2,6 +2,7 @@ import React from 'react'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit'; @@ -9,11 +10,9 @@ import type {SubStepProps} from '@hooks/useSubStep/types'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ValidationUtils from '@libs/ValidationUtils'; import AddressForm from '@pages/ReimbursementAccount/AddressForm'; -import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; import type {ReimbursementAccount} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; type AddressBusinessOnyxProps = { /** Reimbursement account from ONYX */ @@ -22,7 +21,7 @@ type AddressBusinessOnyxProps = { type AddressBusinessProps = AddressBusinessOnyxProps & SubStepProps; -const COMPANY_BUSINESS_INFO_KEY = CONST.BANK_ACCOUNT.BUSINESS_INFO_STEP.INPUT_KEY; +const COMPANY_BUSINESS_INFO_KEY = INPUT_IDS.BUSINESS_INFO_STEP; const INPUT_KEYS = { street: COMPANY_BUSINESS_INFO_KEY.STREET, @@ -33,7 +32,7 @@ const INPUT_KEYS = { const STEP_FIELDS = [COMPANY_BUSINESS_INFO_KEY.STREET, COMPANY_BUSINESS_INFO_KEY.CITY, COMPANY_BUSINESS_INFO_KEY.STATE, COMPANY_BUSINESS_INFO_KEY.ZIP_CODE]; -const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => { +const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); if (values.addressStreet && !ValidationUtils.isValidAddress(values.addressStreet)) { @@ -93,6 +92,7 @@ function AddressBusiness({reimbursementAccount, onNext, isEditing}: AddressBusin AddressBusiness.displayName = 'AddressBusiness'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BusinessInfo/substeps/ConfirmationBusiness.tsx b/src/pages/ReimbursementAccount/BusinessInfo/substeps/ConfirmationBusiness.tsx index 71c0a613314d..0be5db5e788a 100644 --- a/src/pages/ReimbursementAccount/BusinessInfo/substeps/ConfirmationBusiness.tsx +++ b/src/pages/ReimbursementAccount/BusinessInfo/substeps/ConfirmationBusiness.tsx @@ -6,6 +6,7 @@ import {withOnyx} from 'react-native-onyx'; import CheckboxWithLabel from '@components/CheckboxWithLabel'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import MenuItemWithTopDescription from '@components/MenuItemWithTopDescription'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; @@ -17,9 +18,9 @@ import getSubstepValues from '@pages/ReimbursementAccount/utils/getSubstepValues import CONST from '@src/CONST'; import type {TranslationPaths} from '@src/languages/types'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccount, ReimbursementAccountForm} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; +import type {ReimbursementAccountForm} from '@src/types/form'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; +import type {ReimbursementAccount} from '@src/types/onyx'; type ConfirmationBusinessOnyxProps = { /** Reimbursement account from ONYX */ @@ -33,10 +34,10 @@ type ConfirmationBusinessProps = ConfirmationBusinessOnyxProps & SubStepProps; type States = keyof typeof COMMON_CONST.STATES; -const BUSINESS_INFO_STEP_KEYS = CONST.BANK_ACCOUNT.BUSINESS_INFO_STEP.INPUT_KEY; +const BUSINESS_INFO_STEP_KEYS = INPUT_IDS.BUSINESS_INFO_STEP; const BUSINESS_INFO_STEP_INDEXES = CONST.REIMBURSEMENT_ACCOUNT_SUBSTEP_INDEX.BUSINESS_INFO; -const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => { +const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, [BUSINESS_INFO_STEP_KEYS.HAS_NO_CONNECTION_TO_CANNABIS]); if (!values.hasNoConnectionToCannabis) { @@ -153,6 +154,7 @@ function ConfirmationBusiness({reimbursementAccount, reimbursementAccountDraft, ConfirmationBusiness.displayName = 'ConfirmationBusiness'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BusinessInfo/substeps/IncorporationDateBusiness.tsx b/src/pages/ReimbursementAccount/BusinessInfo/substeps/IncorporationDateBusiness.tsx index 9bd4e296fdbb..476d26f9589a 100644 --- a/src/pages/ReimbursementAccount/BusinessInfo/substeps/IncorporationDateBusiness.tsx +++ b/src/pages/ReimbursementAccount/BusinessInfo/substeps/IncorporationDateBusiness.tsx @@ -4,17 +4,17 @@ import {withOnyx} from 'react-native-onyx'; import DatePicker from '@components/DatePicker'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit'; import type {SubStepProps} from '@hooks/useSubStep/types'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ValidationUtils from '@libs/ValidationUtils'; -import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccount, ReimbursementAccountForm} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; +import type {ReimbursementAccountForm} from '@src/types/form'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; +import type {ReimbursementAccount} from '@src/types/onyx'; type IncorporationDateBusinessOnyxProps = { /** Reimbursement account from ONYX */ @@ -26,10 +26,10 @@ type IncorporationDateBusinessOnyxProps = { type IncorporationDateBusinessProps = IncorporationDateBusinessOnyxProps & SubStepProps; -const COMPANY_INCORPORATION_DATE_KEY = CONST.BANK_ACCOUNT.BUSINESS_INFO_STEP.INPUT_KEY.INCORPORATION_DATE; +const COMPANY_INCORPORATION_DATE_KEY = INPUT_IDS.BUSINESS_INFO_STEP.INCORPORATION_DATE; const STEP_FIELDS = [COMPANY_INCORPORATION_DATE_KEY]; -const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => { +const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); if (values.incorporationDate && !ValidationUtils.isValidDate(values.incorporationDate)) { @@ -81,6 +81,7 @@ function IncorporationDateBusiness({reimbursementAccount, reimbursementAccountDr IncorporationDateBusiness.displayName = 'IncorporationDateBusiness'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BusinessInfo/substeps/IncorporationStateBusiness.tsx b/src/pages/ReimbursementAccount/BusinessInfo/substeps/IncorporationStateBusiness.tsx index ae3b135ab335..b437e6ec05b5 100644 --- a/src/pages/ReimbursementAccount/BusinessInfo/substeps/IncorporationStateBusiness.tsx +++ b/src/pages/ReimbursementAccount/BusinessInfo/substeps/IncorporationStateBusiness.tsx @@ -3,6 +3,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import StatePicker from '@components/StatePicker'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; @@ -10,11 +11,9 @@ import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccoun import type {SubStepProps} from '@hooks/useSubStep/types'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ValidationUtils from '@libs/ValidationUtils'; -import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; import type {ReimbursementAccount} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; type IncorporationStateBusinessOnyxProps = { /** Reimbursement account from ONYX */ @@ -23,10 +22,11 @@ type IncorporationStateBusinessOnyxProps = { type IncorporationStateBusinessProps = IncorporationStateBusinessOnyxProps & SubStepProps; -const COMPANY_INCORPORATION_STATE_KEY = CONST.BANK_ACCOUNT.BUSINESS_INFO_STEP.INPUT_KEY.INCORPORATION_STATE; +const COMPANY_INCORPORATION_STATE_KEY = INPUT_IDS.BUSINESS_INFO_STEP.INCORPORATION_STATE; const STEP_FIELDS = [COMPANY_INCORPORATION_STATE_KEY]; -const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); +const validate = (values: FormOnyxValues): FormInputErrors => + ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); function IncorporationStateBusiness({reimbursementAccount, onNext, isEditing}: IncorporationStateBusinessProps) { const {translate} = useLocalize(); @@ -64,6 +64,7 @@ function IncorporationStateBusiness({reimbursementAccount, onNext, isEditing}: I IncorporationStateBusiness.displayName = 'IncorporationStateBusiness'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BusinessInfo/substeps/NameBusiness.tsx b/src/pages/ReimbursementAccount/BusinessInfo/substeps/NameBusiness.tsx index 4008c54f8c83..8fc637fd24f2 100644 --- a/src/pages/ReimbursementAccount/BusinessInfo/substeps/NameBusiness.tsx +++ b/src/pages/ReimbursementAccount/BusinessInfo/substeps/NameBusiness.tsx @@ -3,6 +3,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; @@ -12,9 +13,8 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as ValidationUtils from '@libs/ValidationUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; import type {ReimbursementAccount} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; type NameBusinessOnyxProps = { /** Reimbursement account from ONYX */ @@ -23,10 +23,10 @@ type NameBusinessOnyxProps = { type NameBusinessProps = NameBusinessOnyxProps & SubStepProps; -const COMPANY_NAME_KEY = CONST.BANK_ACCOUNT.BUSINESS_INFO_STEP.INPUT_KEY.COMPANY_NAME; +const COMPANY_NAME_KEY = INPUT_IDS.BUSINESS_INFO_STEP.COMPANY_NAME; const STEP_FIELDS = [COMPANY_NAME_KEY]; -const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => { +const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); if (values.companyName && !ValidationUtils.isValidCompanyName(values.companyName)) { @@ -80,6 +80,7 @@ function NameBusiness({reimbursementAccount, onNext, isEditing}: NameBusinessPro NameBusiness.displayName = 'NameBusiness'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BusinessInfo/substeps/PhoneNumberBusiness.tsx b/src/pages/ReimbursementAccount/BusinessInfo/substeps/PhoneNumberBusiness.tsx index 03abcd341048..e0d369e099d1 100644 --- a/src/pages/ReimbursementAccount/BusinessInfo/substeps/PhoneNumberBusiness.tsx +++ b/src/pages/ReimbursementAccount/BusinessInfo/substeps/PhoneNumberBusiness.tsx @@ -3,6 +3,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; @@ -12,9 +13,8 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as ValidationUtils from '@libs/ValidationUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; import type {ReimbursementAccount} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; type PhoneNumberBusinessOnyxProps = { /** Reimbursement account from ONYX */ @@ -23,10 +23,10 @@ type PhoneNumberBusinessOnyxProps = { type PhoneNumberBusinessProps = PhoneNumberBusinessOnyxProps & SubStepProps; -const COMPANY_PHONE_NUMBER_KEY = CONST.BANK_ACCOUNT.BUSINESS_INFO_STEP.INPUT_KEY.COMPANY_PHONE; +const COMPANY_PHONE_NUMBER_KEY = INPUT_IDS.BUSINESS_INFO_STEP.COMPANY_PHONE; const STEP_FIELDS = [COMPANY_PHONE_NUMBER_KEY]; -const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => { +const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); if (values.companyPhone && !ValidationUtils.isValidUSPhone(values.companyPhone, true)) { @@ -76,6 +76,7 @@ function PhoneNumberBusiness({reimbursementAccount, onNext, isEditing}: PhoneNum PhoneNumberBusiness.displayName = 'PhoneNumberBusiness'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BusinessInfo/substeps/TaxIdBusiness.tsx b/src/pages/ReimbursementAccount/BusinessInfo/substeps/TaxIdBusiness.tsx index 7bcd130bfdf8..46680276e76e 100644 --- a/src/pages/ReimbursementAccount/BusinessInfo/substeps/TaxIdBusiness.tsx +++ b/src/pages/ReimbursementAccount/BusinessInfo/substeps/TaxIdBusiness.tsx @@ -3,6 +3,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; @@ -12,9 +13,8 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as ValidationUtils from '@libs/ValidationUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; import type {ReimbursementAccount} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; type TaxIdBusinessOnyxProps = { /** Reimbursement account from ONYX */ @@ -23,10 +23,10 @@ type TaxIdBusinessOnyxProps = { type TaxIdBusinessProps = TaxIdBusinessOnyxProps & SubStepProps; -const COMPANY_TAX_ID_KEY = CONST.BANK_ACCOUNT.BUSINESS_INFO_STEP.INPUT_KEY.COMPANY_TAX_ID; +const COMPANY_TAX_ID_KEY = INPUT_IDS.BUSINESS_INFO_STEP.COMPANY_TAX_ID; const STEP_FIELDS = [COMPANY_TAX_ID_KEY]; -const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => { +const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); if (values.companyTaxID && !ValidationUtils.isValidTaxID(values.companyTaxID)) { @@ -80,6 +80,7 @@ function TaxIdBusiness({reimbursementAccount, onNext, isEditing}: TaxIdBusinessP TaxIdBusiness.displayName = 'TaxIdBusiness'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BusinessInfo/substeps/TypeBusiness/TypeBusiness.tsx b/src/pages/ReimbursementAccount/BusinessInfo/substeps/TypeBusiness/TypeBusiness.tsx index 7648fab80a3f..f573923bd5c5 100644 --- a/src/pages/ReimbursementAccount/BusinessInfo/substeps/TypeBusiness/TypeBusiness.tsx +++ b/src/pages/ReimbursementAccount/BusinessInfo/substeps/TypeBusiness/TypeBusiness.tsx @@ -3,17 +3,16 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit'; import type {SubStepProps} from '@hooks/useSubStep/types'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ValidationUtils from '@libs/ValidationUtils'; -import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; import type {ReimbursementAccount} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; import BusinessTypePicker from './BusinessTypePicker'; type TypeBusinessOnyxProps = { @@ -23,13 +22,14 @@ type TypeBusinessOnyxProps = { type TypeBusinessProps = TypeBusinessOnyxProps & SubStepProps; -const COMPANY_INCORPORATION_TYPE_KEY = CONST.BANK_ACCOUNT.BUSINESS_INFO_STEP.INPUT_KEY.INCORPORATION_TYPE; +const COMPANY_INCORPORATION_TYPE_KEY = INPUT_IDS.BUSINESS_INFO_STEP.INCORPORATION_TYPE; const STEP_FIELDS = [COMPANY_INCORPORATION_TYPE_KEY]; function TypeBusiness({reimbursementAccount, onNext, isEditing}: TypeBusinessProps) { const {translate} = useLocalize(); const styles = useThemeStyles(); - const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); + const validate = (values: FormOnyxValues): FormInputErrors => + ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); const defaultIncorporationType = reimbursementAccount?.achData?.incorporationType ?? ''; @@ -64,6 +64,7 @@ function TypeBusiness({reimbursementAccount, onNext, isEditing}: TypeBusinessPro TypeBusiness.displayName = 'TypeBusiness'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/BusinessInfo/substeps/WebsiteBusiness.tsx b/src/pages/ReimbursementAccount/BusinessInfo/substeps/WebsiteBusiness.tsx index 9f3591d6b070..fedb9b29af71 100644 --- a/src/pages/ReimbursementAccount/BusinessInfo/substeps/WebsiteBusiness.tsx +++ b/src/pages/ReimbursementAccount/BusinessInfo/substeps/WebsiteBusiness.tsx @@ -4,6 +4,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; @@ -14,9 +15,8 @@ import * as ValidationUtils from '@libs/ValidationUtils'; import * as BankAccounts from '@userActions/BankAccounts'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; import type {ReimbursementAccount, Session, User} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; type WebsiteBusinessOnyxProps = { /** Reimbursement account from ONYX */ @@ -31,10 +31,10 @@ type WebsiteBusinessOnyxProps = { type WebsiteBusinessProps = WebsiteBusinessOnyxProps & SubStepProps; -const COMPANY_WEBSITE_KEY = CONST.BANK_ACCOUNT.BUSINESS_INFO_STEP.INPUT_KEY.COMPANY_WEBSITE; +const COMPANY_WEBSITE_KEY = INPUT_IDS.BUSINESS_INFO_STEP.COMPANY_WEBSITE; const STEP_FIELDS = [COMPANY_WEBSITE_KEY]; -const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => { +const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); if (values.website && !ValidationUtils.isValidWebsite(values.website)) { @@ -93,6 +93,7 @@ function WebsiteBusiness({reimbursementAccount, user, session, onNext, isEditing WebsiteBusiness.displayName = 'WebsiteBusiness'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/CompleteVerification/CompleteVerification.tsx b/src/pages/ReimbursementAccount/CompleteVerification/CompleteVerification.tsx index b566ed32120d..20d4663dcf8d 100644 --- a/src/pages/ReimbursementAccount/CompleteVerification/CompleteVerification.tsx +++ b/src/pages/ReimbursementAccount/CompleteVerification/CompleteVerification.tsx @@ -14,7 +14,9 @@ import getSubstepValues from '@pages/ReimbursementAccount/utils/getSubstepValues import * as BankAccounts from '@userActions/BankAccounts'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccount, ReimbursementAccountForm} from '@src/types/onyx'; +import type {ReimbursementAccountForm} from '@src/types/form'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; +import type {ReimbursementAccount} from '@src/types/onyx'; import ConfirmAgreements from './substeps/ConfirmAgreements'; type CompleteVerificationOnyxProps = { @@ -30,7 +32,7 @@ type CompleteVerificationProps = CompleteVerificationOnyxProps & { onBackButtonPress: () => void; }; -const COMPLETE_VERIFICATION_KEYS = CONST.BANK_ACCOUNT.COMPLETE_VERIFICATION.INPUT_KEY; +const COMPLETE_VERIFICATION_KEYS = INPUT_IDS.COMPLETE_VERIFICATION; const bodyContent: Array> = [ConfirmAgreements]; function CompleteVerification({reimbursementAccount, reimbursementAccountDraft, onBackButtonPress}: CompleteVerificationProps) { @@ -91,6 +93,7 @@ function CompleteVerification({reimbursementAccount, reimbursementAccountDraft, CompleteVerification.displayName = 'CompleteVerification'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/CompleteVerification/substeps/ConfirmAgreements.tsx b/src/pages/ReimbursementAccount/CompleteVerification/substeps/ConfirmAgreements.tsx index 00b94102a632..aa554ca87eb2 100644 --- a/src/pages/ReimbursementAccount/CompleteVerification/substeps/ConfirmAgreements.tsx +++ b/src/pages/ReimbursementAccount/CompleteVerification/substeps/ConfirmAgreements.tsx @@ -4,17 +4,16 @@ import type {OnyxEntry} from 'react-native-onyx'; import CheckboxWithLabel from '@components/CheckboxWithLabel'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import TextLink from '@components/TextLink'; import useLocalize from '@hooks/useLocalize'; import type {SubStepProps} from '@hooks/useSubStep/types'; import useThemeStyles from '@hooks/useThemeStyles'; import * as ValidationUtils from '@libs/ValidationUtils'; -import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; import type {ReimbursementAccount} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; type ConfirmAgreementsOnyxProps = { /** Reimbursement account from ONYX */ @@ -23,14 +22,14 @@ type ConfirmAgreementsOnyxProps = { type ConfirmAgreementsProps = SubStepProps & ConfirmAgreementsOnyxProps; -const COMPLETE_VERIFICATION_KEYS = CONST.BANK_ACCOUNT.COMPLETE_VERIFICATION.INPUT_KEY; +const COMPLETE_VERIFICATION_KEYS = INPUT_IDS.COMPLETE_VERIFICATION; const STEP_FIELDS = [ - CONST.BANK_ACCOUNT.COMPLETE_VERIFICATION.INPUT_KEY.IS_AUTHORIZED_TO_USE_BANK_ACCOUNT, - CONST.BANK_ACCOUNT.COMPLETE_VERIFICATION.INPUT_KEY.ACCEPT_TERMS_AND_CONDITIONS, - CONST.BANK_ACCOUNT.COMPLETE_VERIFICATION.INPUT_KEY.CERTIFY_TRUE_INFORMATION, + INPUT_IDS.COMPLETE_VERIFICATION.IS_AUTHORIZED_TO_USE_BANK_ACCOUNT, + INPUT_IDS.COMPLETE_VERIFICATION.ACCEPT_TERMS_AND_CONDITIONS, + INPUT_IDS.COMPLETE_VERIFICATION.CERTIFY_TRUE_INFORMATION, ]; -const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => { +const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); if (!ValidationUtils.isRequiredFulfilled(values.acceptTermsAndConditions)) { @@ -104,6 +103,7 @@ function ConfirmAgreements({onNext, reimbursementAccount}: ConfirmAgreementsProp ConfirmAgreements.displayName = 'ConfirmAgreements'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/ConnectBankAccount/ConnectBankAccount.tsx b/src/pages/ReimbursementAccount/ConnectBankAccount/ConnectBankAccount.tsx index 84ea11021148..1682cb66f7c8 100644 --- a/src/pages/ReimbursementAccount/ConnectBankAccount/ConnectBankAccount.tsx +++ b/src/pages/ReimbursementAccount/ConnectBankAccount/ConnectBankAccount.tsx @@ -102,6 +102,7 @@ export default withOnyx({ policy: { key: ({reimbursementAccount}) => `${ONYXKEYS.COLLECTION.POLICY}${reimbursementAccount?.achData?.policyID}`, }, + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/ConnectBankAccount/components/BankAccountValidationForm.tsx b/src/pages/ReimbursementAccount/ConnectBankAccount/components/BankAccountValidationForm.tsx index 506e6410440e..d921343c9557 100644 --- a/src/pages/ReimbursementAccount/ConnectBankAccount/components/BankAccountValidationForm.tsx +++ b/src/pages/ReimbursementAccount/ConnectBankAccount/components/BankAccountValidationForm.tsx @@ -3,6 +3,7 @@ import React, {useCallback} from 'react'; import {View} from 'react-native'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; @@ -13,8 +14,8 @@ import * as ValidationUtils from '@libs/ValidationUtils'; import * as BankAccounts from '@userActions/BankAccounts'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; import type {Policy, ReimbursementAccount} from '@src/types/onyx'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; import Enable2FACard from './Enable2FACard'; type BankAccountValidationFormProps = { @@ -28,11 +29,19 @@ type BankAccountValidationFormProps = { policy: Policy | null; }; -const getAmountValues = (values: ReimbursementAccountDraftValues): Record => ({ - amount1: values?.amount1 ?? '', - amount2: values?.amount2 ?? '', - amount3: values?.amount3 ?? '', -}); +type AmountValues = { + amount1: string; + amount2: string; + amount3: string; +}; + +function getAmountValues(values: FormOnyxValues): AmountValues { + return { + amount1: values?.amount1 ?? '', + amount2: values?.amount2 ?? '', + amount3: values?.amount3 ?? '', + }; +} const filterInput = (amount: string, amountRegex?: RegExp) => { let value = amount ? amount.toString().trim() : ''; @@ -50,27 +59,27 @@ function BankAccountValidationForm({requiresTwoFactorAuth, reimbursementAccount, const policyID = reimbursementAccount?.achData?.policyID ?? ''; - const validate = (values: ReimbursementAccountDraftValues) => { - const errors: Record = {}; + const validate = (values: FormOnyxValues): FormInputErrors => { + const errors: FormInputErrors = {}; const amountValues = getAmountValues(values); const decimalSeparator = toLocaleDigit('.'); const outputCurrency = policy?.outputCurrency ?? CONST.CURRENCY.USD; const amountRegex = RegExp(String.raw`^-?\d{0,8}([${getPermittedDecimalSeparator(decimalSeparator)}]\d{0,${CurrencyUtils.getCurrencyDecimals(outputCurrency)}})?$`, 'i'); Object.keys(amountValues).forEach((key) => { - const value = amountValues[key]; + const value = amountValues[key as keyof AmountValues]; const filteredValue = filterInput(value, amountRegex); if (ValidationUtils.isRequiredFulfilled(filteredValue.toString())) { return; } - errors[key] = 'common.error.invalidAmount'; + errors[key as keyof AmountValues] = 'common.error.invalidAmount'; }); return errors; }; const submit = useCallback( - (values: ReimbursementAccountDraftValues) => { + (values: FormOnyxValues) => { const amount1 = filterInput(values.amount1 ?? ''); const amount2 = filterInput(values.amount2 ?? ''); const amount3 = filterInput(values.amount3 ?? ''); @@ -99,7 +108,7 @@ function BankAccountValidationForm({requiresTwoFactorAuth, reimbursementAccount, void; }; -const PERSONAL_INFO_STEP_KEYS = CONST.BANK_ACCOUNT.PERSONAL_INFO_STEP.INPUT_KEY; +const PERSONAL_INFO_STEP_KEYS = INPUT_IDS.PERSONAL_INFO_STEP; const bodyContent: Array> = [FullName, DateOfBirth, SocialSecurityNumber, Address, Confirmation]; function PersonalInfo({reimbursementAccount, reimbursementAccountDraft, onBackButtonPress}: PersonalInfoProps, ref: React.ForwardedRef) { @@ -93,6 +95,7 @@ function PersonalInfo({reimbursementAccount, reimbursementAccountDraft, onBackBu PersonalInfo.displayName = 'PersonalInfo'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/PersonalInfo/substeps/Address.tsx b/src/pages/ReimbursementAccount/PersonalInfo/substeps/Address.tsx index 736c1dc372aa..824ed950bd9f 100644 --- a/src/pages/ReimbursementAccount/PersonalInfo/substeps/Address.tsx +++ b/src/pages/ReimbursementAccount/PersonalInfo/substeps/Address.tsx @@ -3,6 +3,7 @@ import {View} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit'; @@ -11,11 +12,9 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as ValidationUtils from '@libs/ValidationUtils'; import AddressForm from '@pages/ReimbursementAccount/AddressForm'; import HelpLinks from '@pages/ReimbursementAccount/PersonalInfo/HelpLinks'; -import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; import type {ReimbursementAccount} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; type AddressOnyxProps = { /** Reimbursement account from ONYX */ @@ -24,7 +23,7 @@ type AddressOnyxProps = { type AddressProps = AddressOnyxProps & SubStepProps; -const PERSONAL_INFO_STEP_KEY = CONST.BANK_ACCOUNT.PERSONAL_INFO_STEP.INPUT_KEY; +const PERSONAL_INFO_STEP_KEY = INPUT_IDS.PERSONAL_INFO_STEP; const INPUT_KEYS = { street: PERSONAL_INFO_STEP_KEY.STREET, @@ -35,7 +34,7 @@ const INPUT_KEYS = { const STEP_FIELDS = [PERSONAL_INFO_STEP_KEY.STREET, PERSONAL_INFO_STEP_KEY.CITY, PERSONAL_INFO_STEP_KEY.STATE, PERSONAL_INFO_STEP_KEY.ZIP_CODE]; -const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => { +const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); if (values.requestorAddressStreet && !ValidationUtils.isValidAddress(values.requestorAddressStreet)) { @@ -94,6 +93,7 @@ function Address({reimbursementAccount, onNext, isEditing}: AddressProps) { Address.displayName = 'Address'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/PersonalInfo/substeps/Confirmation.tsx b/src/pages/ReimbursementAccount/PersonalInfo/substeps/Confirmation.tsx index 37a049d408ac..bf838d81b929 100644 --- a/src/pages/ReimbursementAccount/PersonalInfo/substeps/Confirmation.tsx +++ b/src/pages/ReimbursementAccount/PersonalInfo/substeps/Confirmation.tsx @@ -15,7 +15,9 @@ import * as ErrorUtils from '@libs/ErrorUtils'; import getSubstepValues from '@pages/ReimbursementAccount/utils/getSubstepValues'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccount, ReimbursementAccountForm} from '@src/types/onyx'; +import type {ReimbursementAccountForm} from '@src/types/form'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; +import type {ReimbursementAccount} from '@src/types/onyx'; type ConfirmationOnyxProps = { /** Reimbursement account from ONYX */ @@ -27,7 +29,7 @@ type ConfirmationOnyxProps = { type ConfirmationProps = ConfirmationOnyxProps & SubStepProps; -const PERSONAL_INFO_STEP_KEYS = CONST.BANK_ACCOUNT.PERSONAL_INFO_STEP.INPUT_KEY; +const PERSONAL_INFO_STEP_KEYS = INPUT_IDS.PERSONAL_INFO_STEP; const PERSONAL_INFO_STEP_INDEXES = CONST.REIMBURSEMENT_ACCOUNT_SUBSTEP_INDEX.PERSONAL_INFO; function Confirmation({reimbursementAccount, reimbursementAccountDraft, onNext, onMove}: ConfirmationProps) { @@ -127,6 +129,7 @@ function Confirmation({reimbursementAccount, reimbursementAccountDraft, onNext, Confirmation.displayName = 'Confirmation'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/PersonalInfo/substeps/DateOfBirth.tsx b/src/pages/ReimbursementAccount/PersonalInfo/substeps/DateOfBirth.tsx index 0d06123b1d7e..1aa7a083b20d 100644 --- a/src/pages/ReimbursementAccount/PersonalInfo/substeps/DateOfBirth.tsx +++ b/src/pages/ReimbursementAccount/PersonalInfo/substeps/DateOfBirth.tsx @@ -5,6 +5,7 @@ import {withOnyx} from 'react-native-onyx'; import DatePicker from '@components/DatePicker'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import useLocalize from '@hooks/useLocalize'; import useReimbursementAccountStepFormSubmit from '@hooks/useReimbursementAccountStepFormSubmit'; @@ -14,9 +15,9 @@ import * as ValidationUtils from '@libs/ValidationUtils'; import HelpLinks from '@pages/ReimbursementAccount/PersonalInfo/HelpLinks'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; -import type {ReimbursementAccount, ReimbursementAccountForm} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; +import type {ReimbursementAccountForm} from '@src/types/form'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; +import type {ReimbursementAccount} from '@src/types/onyx'; type DateOfBirthOnyxProps = { /** Reimbursement account from ONYX */ @@ -28,10 +29,10 @@ type DateOfBirthOnyxProps = { type DateOfBirthProps = DateOfBirthOnyxProps & SubStepProps; -const PERSONAL_INFO_DOB_KEY = CONST.BANK_ACCOUNT.PERSONAL_INFO_STEP.INPUT_KEY.DOB; +const PERSONAL_INFO_DOB_KEY = INPUT_IDS.PERSONAL_INFO_STEP.DOB; const STEP_FIELDS = [PERSONAL_INFO_DOB_KEY]; -const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => { +const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); if (values.dob) { @@ -89,6 +90,7 @@ function DateOfBirth({reimbursementAccount, reimbursementAccountDraft, onNext, i DateOfBirth.displayName = 'DateOfBirth'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/PersonalInfo/substeps/FullName.tsx b/src/pages/ReimbursementAccount/PersonalInfo/substeps/FullName.tsx index a8a499db2e60..3f0470a873e2 100644 --- a/src/pages/ReimbursementAccount/PersonalInfo/substeps/FullName.tsx +++ b/src/pages/ReimbursementAccount/PersonalInfo/substeps/FullName.tsx @@ -4,6 +4,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; @@ -14,9 +15,8 @@ import * as ValidationUtils from '@libs/ValidationUtils'; import HelpLinks from '@pages/ReimbursementAccount/PersonalInfo/HelpLinks'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; import type {ReimbursementAccount} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; type FullNameOnyxProps = { /** Reimbursement account from ONYX */ @@ -25,10 +25,10 @@ type FullNameOnyxProps = { type FullNameProps = FullNameOnyxProps & SubStepProps; -const PERSONAL_INFO_STEP_KEY = CONST.BANK_ACCOUNT.PERSONAL_INFO_STEP.INPUT_KEY; +const PERSONAL_INFO_STEP_KEY = INPUT_IDS.PERSONAL_INFO_STEP; const STEP_FIELDS = [PERSONAL_INFO_STEP_KEY.FIRST_NAME, PERSONAL_INFO_STEP_KEY.LAST_NAME]; -const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => { +const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); if (values.firstName && !ValidationUtils.isValidPersonName(values.firstName)) { errors.firstName = 'bankAccount.error.firstName'; @@ -97,6 +97,7 @@ function FullName({reimbursementAccount, onNext, isEditing}: FullNameProps) { FullName.displayName = 'FullName'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/PersonalInfo/substeps/SocialSecurityNumber.tsx b/src/pages/ReimbursementAccount/PersonalInfo/substeps/SocialSecurityNumber.tsx index d201c12865fa..02407dbce467 100644 --- a/src/pages/ReimbursementAccount/PersonalInfo/substeps/SocialSecurityNumber.tsx +++ b/src/pages/ReimbursementAccount/PersonalInfo/substeps/SocialSecurityNumber.tsx @@ -4,6 +4,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import Text from '@components/Text'; import TextInput from '@components/TextInput'; import useLocalize from '@hooks/useLocalize'; @@ -14,9 +15,8 @@ import * as ValidationUtils from '@libs/ValidationUtils'; import HelpLinks from '@pages/ReimbursementAccount/PersonalInfo/HelpLinks'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; import type {ReimbursementAccount} from '@src/types/onyx'; -import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -import type {ReimbursementAccountDraftValues} from '@src/types/onyx/ReimbursementAccountDraft'; type SocialSecurityNumberOnyxProps = { /** Reimbursement account from ONYX */ @@ -25,10 +25,10 @@ type SocialSecurityNumberOnyxProps = { type SocialSecurityNumberProps = SocialSecurityNumberOnyxProps & SubStepProps; -const PERSONAL_INFO_STEP_KEY = CONST.BANK_ACCOUNT.PERSONAL_INFO_STEP.INPUT_KEY; +const PERSONAL_INFO_STEP_KEY = INPUT_IDS.PERSONAL_INFO_STEP; const STEP_FIELDS = [PERSONAL_INFO_STEP_KEY.SSN_LAST_4]; -const validate = (values: ReimbursementAccountDraftValues): OnyxCommon.Errors => { +const validate = (values: FormOnyxValues): FormInputErrors => { const errors = ValidationUtils.getFieldRequiredErrors(values, STEP_FIELDS); if (values.ssnLast4 && !ValidationUtils.isValidSSNLastFour(values.ssnLast4)) { @@ -84,6 +84,7 @@ function SocialSecurityNumber({reimbursementAccount, onNext, isEditing}: SocialS SocialSecurityNumber.displayName = 'SocialSecurityNumber'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/VerifyIdentity/VerifyIdentity.tsx b/src/pages/ReimbursementAccount/VerifyIdentity/VerifyIdentity.tsx index 7411e2b0b820..b318f0463d94 100644 --- a/src/pages/ReimbursementAccount/VerifyIdentity/VerifyIdentity.tsx +++ b/src/pages/ReimbursementAccount/VerifyIdentity/VerifyIdentity.tsx @@ -15,7 +15,6 @@ import * as BankAccounts from '@userActions/BankAccounts'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {ReimbursementAccount} from '@src/types/onyx'; -import type {OnfidoData} from '@src/types/onyx/ReimbursementAccountDraft'; type VerifyIdentityOnyxProps = { /** Reimbursement account from ONYX */ @@ -40,7 +39,7 @@ function VerifyIdentity({reimbursementAccount, onBackButtonPress, onfidoApplican const {translate} = useLocalize(); const handleOnfidoSuccess = useCallback( - (onfidoData: OnfidoData) => { + (onfidoData: Record) => { BankAccounts.verifyIdentityForBankAccount(Number(reimbursementAccount?.achData?.bankAccountID ?? '0'), {...onfidoData, applicantID: onfidoApplicantID}); BankAccounts.updateReimbursementAccountDraft({isOnfidoSetupComplete: true}); }, @@ -89,6 +88,7 @@ function VerifyIdentity({reimbursementAccount, onBackButtonPress, onfidoApplican VerifyIdentity.displayName = 'VerifyIdentity'; export default withOnyx({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/ReimbursementAccount/utils/getInitialSubstepForBusinessInfo.ts b/src/pages/ReimbursementAccount/utils/getInitialSubstepForBusinessInfo.ts index 789ba9bfdd22..b7c2bedde10f 100644 --- a/src/pages/ReimbursementAccount/utils/getInitialSubstepForBusinessInfo.ts +++ b/src/pages/ReimbursementAccount/utils/getInitialSubstepForBusinessInfo.ts @@ -1,7 +1,7 @@ -import CONST from '@src/CONST'; -import type {CompanyStepProps} from '@src/types/onyx/ReimbursementAccountDraft'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; +import type {CompanyStepProps} from '@src/types/form/ReimbursementAccountForm'; -const businessInfoStepKeys = CONST.BANK_ACCOUNT.BUSINESS_INFO_STEP.INPUT_KEY; +const businessInfoStepKeys = INPUT_IDS.BUSINESS_INFO_STEP; /** * Returns the initial substep for the Business Info step based on already existing data diff --git a/src/pages/ReimbursementAccount/utils/getInitialSubstepForPersonalInfo.ts b/src/pages/ReimbursementAccount/utils/getInitialSubstepForPersonalInfo.ts index 0c221343f968..2b30c6533977 100644 --- a/src/pages/ReimbursementAccount/utils/getInitialSubstepForPersonalInfo.ts +++ b/src/pages/ReimbursementAccount/utils/getInitialSubstepForPersonalInfo.ts @@ -1,7 +1,7 @@ -import CONST from '@src/CONST'; -import type {RequestorStepProps} from '@src/types/onyx/ReimbursementAccountDraft'; +import INPUT_IDS from '@src/types/form/ReimbursementAccountForm'; +import type {RequestorStepProps} from '@src/types/form/ReimbursementAccountForm'; -const personalInfoKeys = CONST.BANK_ACCOUNT.PERSONAL_INFO_STEP.INPUT_KEY; +const personalInfoKeys = INPUT_IDS.PERSONAL_INFO_STEP; /** * Returns the initial substep for the Personal Info step based on already existing data diff --git a/src/pages/ReimbursementAccount/utils/getSubstepValues.ts b/src/pages/ReimbursementAccount/utils/getSubstepValues.ts index 14c3ee008709..8007218b41bb 100644 --- a/src/pages/ReimbursementAccount/utils/getSubstepValues.ts +++ b/src/pages/ReimbursementAccount/utils/getSubstepValues.ts @@ -1,18 +1,19 @@ import type {OnyxEntry} from 'react-native-onyx'; -import type {ReimbursementAccount, ReimbursementAccountDraft} from '@src/types/onyx'; +import type {ReimbursementAccountForm} from '@src/types/form'; +import type {ReimbursementAccount} from '@src/types/onyx'; import type {ACHData} from '@src/types/onyx/ReimbursementAccount'; -function getSubstepValues( +function getSubstepValues( inputKeys: Record, - reimbursementAccountDraft: OnyxEntry, + reimbursementAccountDraft: OnyxEntry, reimbursementAccount: OnyxEntry, -): {[K in T]: ReimbursementAccountDraft[K]} { +): {[K in T]: ReimbursementAccountForm[K]} { return Object.entries(inputKeys).reduce( (acc, [, value]) => ({ ...acc, [value]: reimbursementAccountDraft?.[value] ?? reimbursementAccount?.achData?.[value as keyof ACHData] ?? '', }), - {} as {[K in T]: ReimbursementAccountDraft[K]}, + {} as {[K in T]: ReimbursementAccountForm[K]}, ); } diff --git a/src/pages/ReimbursementAccount/utils/getValuesForBeneficialOwner.ts b/src/pages/ReimbursementAccount/utils/getValuesForBeneficialOwner.ts index a998e8c2d0b7..3733a6727c54 100644 --- a/src/pages/ReimbursementAccount/utils/getValuesForBeneficialOwner.ts +++ b/src/pages/ReimbursementAccount/utils/getValuesForBeneficialOwner.ts @@ -1,5 +1,5 @@ import CONST from '@src/CONST'; -import type {ReimbursementAccountDraft} from '@src/types/onyx'; +import type {ReimbursementAccountForm} from '@src/types/form'; type BeneficialOwnerValues = { firstName: string; @@ -12,7 +12,7 @@ type BeneficialOwnerValues = { zipCode: string; }; -function getValuesForBeneficialOwner(beneficialOwnerBeingModifiedID: string, reimbursementAccountDraft: ReimbursementAccountDraft | null): BeneficialOwnerValues { +function getValuesForBeneficialOwner(beneficialOwnerBeingModifiedID: string, reimbursementAccountDraft: ReimbursementAccountForm | null): BeneficialOwnerValues { if (!reimbursementAccountDraft) { return { firstName: '', diff --git a/src/pages/RoomDescriptionPage.tsx b/src/pages/RoomDescriptionPage.tsx index bc46587814e3..6300b8c4cdce 100644 --- a/src/pages/RoomDescriptionPage.tsx +++ b/src/pages/RoomDescriptionPage.tsx @@ -20,6 +20,7 @@ import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import INPUT_IDS from '@src/types/form/ReportDescriptionForm'; import type * as OnyxTypes from '@src/types/onyx'; type RoomDescriptionPageProps = { @@ -83,7 +84,7 @@ function RoomDescriptionPage({report, policies}: RoomDescriptionPageProps) { ) => { + const onSubmit = (values: FormOnyxValues) => { const policyID = isProduction ? CONST.TEACHERS_UNITE.PROD_POLICY_ID : CONST.TEACHERS_UNITE.TEST_POLICY_ID; TeachersUnite.addSchoolPrincipal(values.firstName.trim(), values.partnerUserID.trim(), values.lastName.trim(), policyID); }; @@ -46,8 +47,8 @@ function IntroSchoolPrincipalPage(props: IntroSchoolPrincipalPageProps) { * @returns - An object containing the errors for each inputID */ const validate = useCallback( - (values: OnyxFormValuesFields) => { - const errors: Partial, string>> = {}; + (values: FormOnyxValues) => { + const errors: FormInputErrors = {}; if (!values.firstName || !ValidationUtils.isValidPersonName(values.firstName)) { ErrorUtils.addErrorMessage(errors, 'firstName', 'bankAccount.error.firstName'); @@ -94,8 +95,8 @@ function IntroSchoolPrincipalPage(props: IntroSchoolPrincipalPageProps) { ) => { + const onSubmit = (values: FormOnyxValues) => { const phoneLogin = LoginUtils.getPhoneLogin(values.partnerUserID); const validateIfnumber = LoginUtils.validateNumber(phoneLogin); const contactMethod = (validateIfnumber || values.partnerUserID).trim().toLowerCase(); @@ -53,7 +54,7 @@ function KnowATeacherPage(props: KnowATeacherPageProps) { * @returns - An object containing the errors for each inputID */ const validate = useCallback( - (values: OnyxFormValuesFields) => { + (values: FormOnyxValues) => { const errors = {}; const phoneLogin = LoginUtils.getPhoneLogin(values.partnerUserID); const validateIfNumber = LoginUtils.validateNumber(phoneLogin); @@ -100,7 +101,7 @@ function KnowATeacherPage(props: KnowATeacherPageProps) { (loginInputRef.current = el)} - inputID="phoneOrEmail" + inputID={INPUT_IDS.PHONE_OR_EMAIL} autoCapitalize="none" enterKeyHint="done" maxLength={CONST.LOGIN_CHARACTER_LIMIT} diff --git a/src/pages/settings/Profile/CustomStatus/SetDatePage.js b/src/pages/settings/Profile/CustomStatus/SetDatePage.js index e0cd23af4953..5b95ec757617 100644 --- a/src/pages/settings/Profile/CustomStatus/SetDatePage.js +++ b/src/pages/settings/Profile/CustomStatus/SetDatePage.js @@ -15,6 +15,7 @@ import Navigation from '@libs/Navigation/Navigation'; import * as ValidationUtils from '@libs/ValidationUtils'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import INPUT_IDS from '@src/types/form/SettingsStatusClearDateForm'; const propTypes = { ...withLocalizePropTypes, @@ -61,7 +62,7 @@ function SetDatePage({translate, customStatus}) { > ) => { + (values: FormOnyxValues) => { const errors = {}; // We should skip validation hence we return an empty errors and we skip Form submission on the onSubmit method @@ -97,7 +98,7 @@ function RoomNamePage({report, policy, reports}: RoomNamePageProps) { diff --git a/src/pages/settings/Security/CloseAccountPage.tsx b/src/pages/settings/Security/CloseAccountPage.tsx index b3a7e3cae3a0..84934aa01089 100644 --- a/src/pages/settings/Security/CloseAccountPage.tsx +++ b/src/pages/settings/Security/CloseAccountPage.tsx @@ -7,7 +7,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import ConfirmModal from '@components/ConfirmModal'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; -import type {OnyxFormValuesFields} from '@components/Form/types'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import Text from '@components/Text'; @@ -22,8 +22,8 @@ import * as User from '@userActions/User'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type SCREENS from '@src/SCREENS'; +import INPUT_IDS from '@src/types/form/CloseAccountForm'; import type {Session} from '@src/types/onyx'; -import type {Errors} from '@src/types/onyx/OnyxCommon'; type CloseAccountPageOnyxProps = { /** Session of currently logged in user */ @@ -54,7 +54,7 @@ function CloseAccountPage({session}: CloseAccountPageProps) { hideConfirmModal(); }; - const showConfirmModal = (values: OnyxFormValuesFields) => { + const showConfirmModal = (values: FormOnyxValues) => { setConfirmModalVisibility(true); setReasonForLeaving(values.reasonForLeaving); }; @@ -66,10 +66,9 @@ function CloseAccountPage({session}: CloseAccountPageProps) { */ const sanitizePhoneOrEmail = (phoneOrEmail: string): string => phoneOrEmail.replace(/\s+/g, '').toLowerCase(); - const validate = (values: OnyxFormValuesFields): Errors => { - const requiredFields = ['phoneOrEmail']; + const validate = (values: FormOnyxValues): FormInputErrors => { const userEmailOrPhone = formatPhoneNumber(session?.email); - const errors = ValidationUtils.getFieldRequiredErrors(values, requiredFields); + const errors = ValidationUtils.getFieldRequiredErrors(values, ['phoneOrEmail']); if (values.phoneOrEmail && sanitizePhoneOrEmail(userEmailOrPhone) !== sanitizePhoneOrEmail(values.phoneOrEmail)) { errors.phoneOrEmail = 'closeAccountPage.enterYourDefaultContactMethod'; @@ -100,7 +99,7 @@ function CloseAccountPage({session}: CloseAccountPageProps) { {translate('closeAccountPage.reasonForLeavingPrompt')} ( diff --git a/src/pages/settings/Wallet/Card/BaseGetPhysicalCard.tsx b/src/pages/settings/Wallet/Card/BaseGetPhysicalCard.tsx index c1d8faf7e9ff..06d68ff575c2 100644 --- a/src/pages/settings/Wallet/Card/BaseGetPhysicalCard.tsx +++ b/src/pages/settings/Wallet/Card/BaseGetPhysicalCard.tsx @@ -15,7 +15,8 @@ import Navigation from '@libs/Navigation/Navigation'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; -import type {CardList, GetPhysicalCardForm, LoginList, PrivatePersonalDetails, Session} from '@src/types/onyx'; +import type {GetPhysicalCardForm} from '@src/types/form'; +import type {CardList, LoginList, PrivatePersonalDetails, Session} from '@src/types/onyx'; import type {Errors} from '@src/types/onyx/OnyxCommon'; import type ChildrenProps from '@src/types/utils/ChildrenProps'; diff --git a/src/pages/settings/Wallet/Card/GetPhysicalCardAddress.tsx b/src/pages/settings/Wallet/Card/GetPhysicalCardAddress.tsx index e90df5bed1f2..5f3dbb3fa6c3 100644 --- a/src/pages/settings/Wallet/Card/GetPhysicalCardAddress.tsx +++ b/src/pages/settings/Wallet/Card/GetPhysicalCardAddress.tsx @@ -9,7 +9,7 @@ import type {SettingsNavigatorParamList} from '@navigation/types'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type {GetPhysicalCardForm} from '@src/types/onyx'; +import type {GetPhysicalCardForm} from '@src/types/form'; import BaseGetPhysicalCard from './BaseGetPhysicalCard'; import type {RenderContentProps} from './BaseGetPhysicalCard'; diff --git a/src/pages/settings/Wallet/Card/GetPhysicalCardConfirm.tsx b/src/pages/settings/Wallet/Card/GetPhysicalCardConfirm.tsx index 9095da7db0d1..c6b4bc2272d1 100644 --- a/src/pages/settings/Wallet/Card/GetPhysicalCardConfirm.tsx +++ b/src/pages/settings/Wallet/Card/GetPhysicalCardConfirm.tsx @@ -14,7 +14,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type {GetPhysicalCardForm} from '@src/types/onyx'; +import type {GetPhysicalCardForm} from '@src/types/form'; import BaseGetPhysicalCard from './BaseGetPhysicalCard'; const goToGetPhysicalCardName = (domain: string) => { diff --git a/src/pages/settings/Wallet/Card/GetPhysicalCardName.tsx b/src/pages/settings/Wallet/Card/GetPhysicalCardName.tsx index 40252da7dac8..1667aa8d36d3 100644 --- a/src/pages/settings/Wallet/Card/GetPhysicalCardName.tsx +++ b/src/pages/settings/Wallet/Card/GetPhysicalCardName.tsx @@ -12,7 +12,8 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; -import type {GetPhysicalCardForm} from '@src/types/onyx'; +import type {GetPhysicalCardForm} from '@src/types/form'; +import INPUT_IDS from '@src/types/form/GetPhysicalCardForm'; import BaseGetPhysicalCard from './BaseGetPhysicalCard'; type OnValidateResult = { @@ -67,8 +68,8 @@ function GetPhysicalCardName({ > diff --git a/src/pages/tasks/TaskDescriptionPage.js b/src/pages/tasks/TaskDescriptionPage.js index add2cf3da057..b8b48abd09ff 100644 --- a/src/pages/tasks/TaskDescriptionPage.js +++ b/src/pages/tasks/TaskDescriptionPage.js @@ -23,6 +23,7 @@ import reportPropTypes from '@pages/reportPropTypes'; import * as Task from '@userActions/Task'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/EditTaskForm'; const propTypes = { /** The report currently being looked at */ @@ -116,8 +117,8 @@ function TaskDescriptionPage(props) { ({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/workspace/WorkspaceInviteMessagePage.tsx b/src/pages/workspace/WorkspaceInviteMessagePage.tsx index d2666bd6fa24..adb7914fcac8 100644 --- a/src/pages/workspace/WorkspaceInviteMessagePage.tsx +++ b/src/pages/workspace/WorkspaceInviteMessagePage.tsx @@ -8,6 +8,7 @@ import type {GestureResponderEvent} from 'react-native/Libraries/Types/CoreEvent import FullPageNotFoundView from '@components/BlockingViews/FullPageNotFoundView'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; +import type {FormInputErrors} from '@components/Form/types'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import MultipleAvatars from '@components/MultipleAvatars'; import PressableWithoutFeedback from '@components/Pressable/PressableWithoutFeedback'; @@ -29,8 +30,8 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type SCREENS from '@src/SCREENS'; +import INPUT_IDS from '@src/types/form/WorkspaceInviteMessageForm'; import type {InvitedEmailsToAccountIDs, PersonalDetailsList} from '@src/types/onyx'; -import type {Errors} from '@src/types/onyx/OnyxCommon'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; import SearchInputManager from './SearchInputManager'; import withPolicyAndFullscreenLoading from './withPolicyAndFullscreenLoading'; @@ -41,10 +42,10 @@ type WorkspaceInviteMessagePageOnyxProps = { allPersonalDetails: OnyxEntry; /** An object containing the accountID for every invited user email */ - invitedEmailsToAccountIDsDraft: OnyxEntry; + invitedEmailsToAccountIDsDraft: OnyxEntry; /** Updated workspace invite message */ - workspaceInviteMessageDraft: OnyxEntry; + workspaceInviteMessageDraft: OnyxEntry; }; type WorkspaceInviteMessagePageProps = WithPolicyAndFullscreenLoadingProps & @@ -97,8 +98,8 @@ function WorkspaceInviteMessagePage({workspaceInviteMessageDraft, invitedEmailsT Link.openExternalLink(CONST.PRIVACY_URL); }; - const validate = (): Errors => { - const errorFields: Errors = {}; + const validate = (): FormInputErrors => { + const errorFields: FormInputErrors = {}; if (isEmptyObject(invitedEmailsToAccountIDsDraft)) { errorFields.welcomeMessage = 'workspace.inviteMessage.inviteNoMembersError'; } @@ -167,7 +168,7 @@ function WorkspaceInviteMessagePage({workspaceInviteMessageDraft, invitedEmailsT ; /** An object containing the accountID for every invited user email */ - invitedEmailsToAccountIDsDraft: OnyxEntry; + invitedEmailsToAccountIDsDraft: OnyxEntry; }; type WorkspaceInvitePageProps = WithPolicyAndFullscreenLoadingProps & WorkspaceInvitePageOnyxProps & StackScreenProps; diff --git a/src/pages/workspace/WorkspaceNamePage.tsx b/src/pages/workspace/WorkspaceNamePage.tsx index 6d7a18ef21f2..dc2f8ebb4560 100644 --- a/src/pages/workspace/WorkspaceNamePage.tsx +++ b/src/pages/workspace/WorkspaceNamePage.tsx @@ -2,7 +2,7 @@ import React, {useCallback} from 'react'; import {Keyboard, View} from 'react-native'; import FormProvider from '@components/Form/FormProvider'; import InputWrapper from '@components/Form/InputWrapper'; -import type {OnyxFormValuesFields} from '@components/Form/types'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import HeaderWithBackButton from '@components/HeaderWithBackButton'; import ScreenWrapper from '@components/ScreenWrapper'; import TextInput from '@components/TextInput'; @@ -14,6 +14,7 @@ import * as ValidationUtils from '@libs/ValidationUtils'; import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; +import INPUT_IDS from '@src/types/form/WorkspaceSettingsForm'; import withPolicy from './withPolicy'; import type {WithPolicyProps} from './withPolicy'; @@ -24,7 +25,7 @@ function WorkspaceNamePage({policy}: Props) { const {translate} = useLocalize(); const submit = useCallback( - (values: OnyxFormValuesFields) => { + (values: FormOnyxValues) => { if (!policy || policy.isPolicyUpdating) { return; } @@ -36,8 +37,8 @@ function WorkspaceNamePage({policy}: Props) { [policy], ); - const validate = useCallback((values: OnyxFormValuesFields) => { - const errors: Record = {}; + const validate = useCallback((values: FormOnyxValues) => { + const errors: FormInputErrors = {}; const name = values.name.trim(); if (!ValidationUtils.isRequiredFulfilled(name)) { @@ -75,7 +76,7 @@ function WorkspaceNamePage({policy}: Props) { ({ + // @ts-expect-error: ONYXKEYS.REIMBURSEMENT_ACCOUNT is conflicting with ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM reimbursementAccount: { key: ONYXKEYS.REIMBURSEMENT_ACCOUNT, }, diff --git a/src/pages/workspace/reimburse/WorkspaceRateAndUnitPage/RatePage.tsx b/src/pages/workspace/reimburse/WorkspaceRateAndUnitPage/RatePage.tsx index 37723fe654c0..2d9d52c63e26 100644 --- a/src/pages/workspace/reimburse/WorkspaceRateAndUnitPage/RatePage.tsx +++ b/src/pages/workspace/reimburse/WorkspaceRateAndUnitPage/RatePage.tsx @@ -4,7 +4,7 @@ import type {OnyxEntry} from 'react-native-onyx'; import AmountForm from '@components/AmountForm'; import FormProvider from '@components/Form/FormProvider'; import InputWrapperWithRef from '@components/Form/InputWrapper'; -import type {OnyxFormValuesFields} from '@components/Form/types'; +import type {FormInputErrors, FormOnyxValues} from '@components/Form/types'; import useLocalize from '@hooks/useLocalize'; import useThemeStyles from '@hooks/useThemeStyles'; import compose from '@libs/compose'; @@ -20,6 +20,7 @@ import * as Policy from '@userActions/Policy'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; +import INPUT_IDS from '@src/types/form/WorkspaceRateAndUnitForm'; import type {WorkspaceRateAndUnit} from '@src/types/onyx'; type WorkspaceRatePageBaseProps = WithPolicyProps; @@ -42,15 +43,15 @@ function WorkspaceRatePage(props: WorkspaceRatePageProps) { // eslint-disable-next-line react-hooks/exhaustive-deps }, []); - const submit = (values: OnyxFormValuesFields) => { - const rate = values.rate as string; + const submit = (values: FormOnyxValues) => { + const rate = values.rate; Policy.setRateForReimburseView((parseFloat(rate) * CONST.POLICY.CUSTOM_UNIT_RATE_BASE_OFFSET).toFixed(1)); Navigation.navigate(ROUTES.WORKSPACE_RATE_AND_UNIT.getRoute(props.policy?.id ?? '')); }; - const validate = (values: OnyxFormValuesFields) => { - const errors: {rate?: string} = {}; - const rate = values.rate as string; + const validate = (values: FormOnyxValues): FormInputErrors => { + const errors: FormInputErrors = {}; + const rate = values.rate; const parsedRate = MoneyRequestUtils.replaceAllDigits(rate, toLocaleDigit); const decimalSeparator = toLocaleDigit('.'); const outputCurrency = props.policy?.outputCurrency ?? CONST.CURRENCY.USD; @@ -94,7 +95,7 @@ function WorkspaceRatePage(props: WorkspaceRatePageProps) { > ; + +export type {AddDebitCardForm}; +export default INPUT_IDS; diff --git a/src/types/form/CloseAccountForm.ts b/src/types/form/CloseAccountForm.ts new file mode 100644 index 000000000000..f6922df1d062 --- /dev/null +++ b/src/types/form/CloseAccountForm.ts @@ -0,0 +1,14 @@ +import type Form from './Form'; + +const INPUT_IDS = { + REASON_FOR_LEAVING: 'reasonForLeaving', + PHONE_OR_EMAIL: 'phoneOrEmail', +} as const; + +type CloseAccountForm = Form<{ + [INPUT_IDS.REASON_FOR_LEAVING]: string; + [INPUT_IDS.PHONE_OR_EMAIL]: string; +}>; + +export type {CloseAccountForm}; +export default INPUT_IDS; diff --git a/src/types/form/DateOfBirthForm.ts b/src/types/form/DateOfBirthForm.ts new file mode 100644 index 000000000000..01678669f176 --- /dev/null +++ b/src/types/form/DateOfBirthForm.ts @@ -0,0 +1,13 @@ +import type Form from './Form'; + +const INPUT_IDS = { + DOB: 'dob', +} as const; + +type DateOfBirthForm = Form<{ + /** Date of birth */ + [INPUT_IDS.DOB]: string; +}>; + +export type {DateOfBirthForm}; +export default INPUT_IDS; diff --git a/src/types/form/DisplayNameForm.ts b/src/types/form/DisplayNameForm.ts new file mode 100644 index 000000000000..3f9738c45a34 --- /dev/null +++ b/src/types/form/DisplayNameForm.ts @@ -0,0 +1,14 @@ +import type Form from './Form'; + +const INPUT_IDS = { + FIRST_NAME: 'firstName', + LAST_NAME: 'lastName', +} as const; + +type DisplayNameForm = Form<{ + [INPUT_IDS.FIRST_NAME]: string; + [INPUT_IDS.LAST_NAME]: string; +}>; + +export type {DisplayNameForm}; +export default INPUT_IDS; diff --git a/src/types/form/EditTaskForm.ts b/src/types/form/EditTaskForm.ts new file mode 100644 index 000000000000..05de0310c784 --- /dev/null +++ b/src/types/form/EditTaskForm.ts @@ -0,0 +1,14 @@ +import type Form from './Form'; + +const INPUT_IDS = { + TITLE: 'title', + DESCRIPTION: 'description', +} as const; + +type EditTaskForm = Form<{ + [INPUT_IDS.TITLE]: string; + [INPUT_IDS.DESCRIPTION]: string; +}>; + +export type {EditTaskForm}; +export default INPUT_IDS; diff --git a/src/types/form/Form.ts b/src/types/form/Form.ts new file mode 100644 index 000000000000..d80eb65f4215 --- /dev/null +++ b/src/types/form/Form.ts @@ -0,0 +1,19 @@ +import type {FormValue} from '@components/Form/types'; +import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; + +type BaseForm = { + /** Controls the loading state of the form */ + isLoading?: boolean; + + /** Server side errors keyed by microtime */ + errors?: OnyxCommon.Errors | null; + + /** Field-specific server side errors keyed by microtime */ + errorFields?: OnyxCommon.ErrorFields | null; +}; + +type FormValues = Record; +type Form = TFormValues & BaseForm; + +export default Form; +export type {BaseForm}; diff --git a/src/types/form/GetPhysicalCardForm.ts b/src/types/form/GetPhysicalCardForm.ts new file mode 100644 index 000000000000..091113eb4763 --- /dev/null +++ b/src/types/form/GetPhysicalCardForm.ts @@ -0,0 +1,24 @@ +import type Form from './Form'; +import ADDRESS_INPUT_IDS from './HomeAddressForm'; + +const INPUT_IDS = { + ...ADDRESS_INPUT_IDS, + LEGAL_FIRST_NAME: 'legalFirstName', + LEGAL_LAST_NAME: 'legalLastName', + PHONE_NUMBER: 'phoneNumber', +} as const; + +type GetPhysicalCardForm = Form<{ + [INPUT_IDS.ADDRESS_LINE_1]?: string; + [INPUT_IDS.ADDRESS_LINE_2]?: string; + [INPUT_IDS.COUNTRY]?: string; + [INPUT_IDS.STATE]?: string; + [INPUT_IDS.CITY]?: string; + [INPUT_IDS.ZIP_POST_CODE]?: string; + [INPUT_IDS.LEGAL_FIRST_NAME]?: string; + [INPUT_IDS.LEGAL_LAST_NAME]?: string; + [INPUT_IDS.PHONE_NUMBER]?: string; +}>; + +export type {GetPhysicalCardForm}; +export default INPUT_IDS; diff --git a/src/types/form/HomeAddressForm.ts b/src/types/form/HomeAddressForm.ts new file mode 100644 index 000000000000..4e819146faf7 --- /dev/null +++ b/src/types/form/HomeAddressForm.ts @@ -0,0 +1,22 @@ +import type Form from './Form'; + +const INPUT_IDS = { + ADDRESS_LINE_1: 'addressLine1', + ADDRESS_LINE_2: 'addressLine2', + COUNTRY: 'country', + STATE: 'state', + CITY: 'city', + ZIP_POST_CODE: 'zipPostCode', +} as const; + +type HomeAddressForm = Form<{ + [INPUT_IDS.ADDRESS_LINE_1]: string; + [INPUT_IDS.ADDRESS_LINE_2]: string; + [INPUT_IDS.COUNTRY]: string; + [INPUT_IDS.STATE]: string; + [INPUT_IDS.CITY]: string; + [INPUT_IDS.ZIP_POST_CODE]: string; +}>; + +export type {HomeAddressForm}; +export default INPUT_IDS; diff --git a/src/types/form/IKnowTeacherForm.ts b/src/types/form/IKnowTeacherForm.ts new file mode 100644 index 000000000000..7d6ba4b9079a --- /dev/null +++ b/src/types/form/IKnowTeacherForm.ts @@ -0,0 +1,16 @@ +import type Form from './Form'; + +const INPUT_IDS = { + FIRST_NAME: 'firstName', + LAST_NAME: 'lastName', + PARTNER_USER_ID: 'partnerUserID', +} as const; + +type IKnowTeacherForm = Form<{ + [INPUT_IDS.FIRST_NAME]: string; + [INPUT_IDS.LAST_NAME]: string; + [INPUT_IDS.PARTNER_USER_ID]: string; +}>; + +export type {IKnowTeacherForm}; +export default INPUT_IDS; diff --git a/src/types/form/IntroSchoolPrincipalForm.ts b/src/types/form/IntroSchoolPrincipalForm.ts new file mode 100644 index 000000000000..61742a98c6fd --- /dev/null +++ b/src/types/form/IntroSchoolPrincipalForm.ts @@ -0,0 +1,16 @@ +import type Form from './Form'; + +const INPUT_IDS = { + FIRST_NAME: 'firstName', + LAST_NAME: 'lastName', + PARTNER_USER_ID: 'partnerUserID', +} as const; + +type IntroSchoolPrincipalForm = Form<{ + [INPUT_IDS.FIRST_NAME]: string; + [INPUT_IDS.LAST_NAME]: string; + [INPUT_IDS.PARTNER_USER_ID]: string; +}>; + +export type {IntroSchoolPrincipalForm}; +export default INPUT_IDS; diff --git a/src/types/form/LegalNameForm.ts b/src/types/form/LegalNameForm.ts new file mode 100644 index 000000000000..8ca9e44a7754 --- /dev/null +++ b/src/types/form/LegalNameForm.ts @@ -0,0 +1,14 @@ +import type Form from './Form'; + +const INPUT_IDS = { + LEGAL_FIRST_NAME: 'legalFirstName', + LEGAL_LAST_NAME: 'legalLastName', +} as const; + +type LegalNameForm = Form<{ + [INPUT_IDS.LEGAL_FIRST_NAME]: string; + [INPUT_IDS.LEGAL_LAST_NAME]: string; +}>; + +export type {LegalNameForm}; +export default INPUT_IDS; diff --git a/src/types/form/MoneyRequestAmountForm.ts b/src/types/form/MoneyRequestAmountForm.ts new file mode 100644 index 000000000000..b6aaf68d1695 --- /dev/null +++ b/src/types/form/MoneyRequestAmountForm.ts @@ -0,0 +1,6 @@ +import type Form from './Form'; + +type MoneyRequestAmountForm = Form; + +// eslint-disable-next-line import/prefer-default-export +export type {MoneyRequestAmountForm}; diff --git a/src/types/form/MoneyRequestCreatedForm.ts b/src/types/form/MoneyRequestCreatedForm.ts new file mode 100644 index 000000000000..b7df7362a888 --- /dev/null +++ b/src/types/form/MoneyRequestCreatedForm.ts @@ -0,0 +1,14 @@ +import type Form from './Form'; + +const INPUT_IDS = { + CREATED: 'created', + MONEY_REQUEST_CREATED: 'moneyRequestCreated', +} as const; + +type MoneyRequestCreatedForm = Form<{ + [INPUT_IDS.CREATED]: string; + [INPUT_IDS.MONEY_REQUEST_CREATED]: string; +}>; + +export type {MoneyRequestCreatedForm}; +export default INPUT_IDS; diff --git a/src/types/form/MoneyRequestDescriptionForm.ts b/src/types/form/MoneyRequestDescriptionForm.ts new file mode 100644 index 000000000000..df8ae5d225f3 --- /dev/null +++ b/src/types/form/MoneyRequestDescriptionForm.ts @@ -0,0 +1,14 @@ +import type Form from './Form'; + +const INPUT_IDS = { + COMMENT: 'comment', + MONEY_REQUEST_COMMENT: 'moneyRequestComment', +} as const; + +type MoneyRequestDescriptionForm = Form<{ + [INPUT_IDS.COMMENT]: string; + [INPUT_IDS.MONEY_REQUEST_COMMENT]: string; +}>; + +export type {MoneyRequestDescriptionForm}; +export default INPUT_IDS; diff --git a/src/types/form/MoneyRequestMerchantForm.ts b/src/types/form/MoneyRequestMerchantForm.ts new file mode 100644 index 000000000000..0dd194037b7d --- /dev/null +++ b/src/types/form/MoneyRequestMerchantForm.ts @@ -0,0 +1,14 @@ +import type Form from './Form'; + +const INPUT_IDS = { + MERCHANT: 'merchant', + MONEY_REQUEST_MERCHANT: 'moneyRequestMerchant', +} as const; + +type MoneyRequestMerchantForm = Form<{ + [INPUT_IDS.MERCHANT]: string; + [INPUT_IDS.MONEY_REQUEST_MERCHANT]: string; +}>; + +export type {MoneyRequestMerchantForm}; +export default INPUT_IDS; diff --git a/src/types/form/NewContactMethodForm.ts b/src/types/form/NewContactMethodForm.ts new file mode 100644 index 000000000000..baa67cec1cbf --- /dev/null +++ b/src/types/form/NewContactMethodForm.ts @@ -0,0 +1,12 @@ +import type Form from './Form'; + +const INPUT_IDS = { + PHONE_OR_EMAIL: 'phoneOrEmail', +} as const; + +type NewContactMethodForm = Form<{ + [INPUT_IDS.PHONE_OR_EMAIL]: string; +}>; + +export type {NewContactMethodForm}; +export default INPUT_IDS; diff --git a/src/types/form/NewRoomForm.ts b/src/types/form/NewRoomForm.ts new file mode 100644 index 000000000000..8fe047f8a7e4 --- /dev/null +++ b/src/types/form/NewRoomForm.ts @@ -0,0 +1,20 @@ +import type Form from './Form'; + +const INPUT_IDS = { + ROOM_NAME: 'roomName', + REPORT_DESCRIPTION: 'reportDescription', + POLICY_ID: 'policyID', + WRITE_CAPABILITY: 'writeCapability', + VISIBILITY: 'visibility', +} as const; + +type NewRoomForm = Form<{ + [INPUT_IDS.ROOM_NAME]?: string; + [INPUT_IDS.REPORT_DESCRIPTION]?: string; + [INPUT_IDS.POLICY_ID]?: string; + [INPUT_IDS.WRITE_CAPABILITY]?: string; + [INPUT_IDS.VISIBILITY]?: string; +}>; + +export type {NewRoomForm}; +export default INPUT_IDS; diff --git a/src/types/form/NewTaskForm.ts b/src/types/form/NewTaskForm.ts new file mode 100644 index 000000000000..b281a79321fb --- /dev/null +++ b/src/types/form/NewTaskForm.ts @@ -0,0 +1,14 @@ +import type Form from './Form'; + +const INPUT_IDS = { + TASK_TITLE: 'taskTitle', + TASK_DESCRIPTION: 'taskDescription', +} as const; + +type NewTaskForm = Form<{ + [INPUT_IDS.TASK_TITLE]: string; + [INPUT_IDS.TASK_DESCRIPTION]: string; +}>; + +export type {NewTaskForm}; +export default INPUT_IDS; diff --git a/src/types/form/PersonalBankAccountForm.ts b/src/types/form/PersonalBankAccountForm.ts new file mode 100644 index 000000000000..8c41233c1681 --- /dev/null +++ b/src/types/form/PersonalBankAccountForm.ts @@ -0,0 +1,6 @@ +import type Form from './Form'; + +type PersonalBankAccountForm = Form; + +// eslint-disable-next-line import/prefer-default-export +export type {PersonalBankAccountForm}; diff --git a/src/types/form/PrivateNotesForm.ts b/src/types/form/PrivateNotesForm.ts new file mode 100644 index 000000000000..2961b693ef6b --- /dev/null +++ b/src/types/form/PrivateNotesForm.ts @@ -0,0 +1,12 @@ +import type Form from './Form'; + +const INPUT_IDS = { + PRIVATE_NOTES: 'privateNotes', +} as const; + +type PrivateNotesForm = Form<{ + [INPUT_IDS.PRIVATE_NOTES]: string; +}>; + +export type {PrivateNotesForm}; +export default INPUT_IDS; diff --git a/src/types/form/ProfileSettingsForm.ts b/src/types/form/ProfileSettingsForm.ts new file mode 100644 index 000000000000..87d44cece5c4 --- /dev/null +++ b/src/types/form/ProfileSettingsForm.ts @@ -0,0 +1,6 @@ +import type Form from './Form'; + +type ProfileSettingsForm = Form; + +// eslint-disable-next-line import/prefer-default-export +export type {ProfileSettingsForm}; diff --git a/src/types/form/ReimbursementAccountForm.ts b/src/types/form/ReimbursementAccountForm.ts new file mode 100644 index 000000000000..ff45795992c4 --- /dev/null +++ b/src/types/form/ReimbursementAccountForm.ts @@ -0,0 +1,128 @@ +import type Form from './Form'; + +const INPUT_IDS = { + BANK_INFO_STEP: { + ROUTING_NUMBER: 'routingNumber', + ACCOUNT_NUMBER: 'accountNumber', + PLAID_MASK: 'plaidMask', + IS_SAVINGS: 'isSavings', + BANK_NAME: 'bankName', + PLAID_ACCOUNT_ID: 'plaidAccountID', + PLAID_ACCESS_TOKEN: 'plaidAccessToken', + SELECTED_PLAID_ACCOUNT_ID: 'selectedPlaidAccountID', + }, + PERSONAL_INFO_STEP: { + FIRST_NAME: 'firstName', + LAST_NAME: 'lastName', + DOB: 'dob', + SSN_LAST_4: 'ssnLast4', + STREET: 'requestorAddressStreet', + CITY: 'requestorAddressCity', + STATE: 'requestorAddressState', + ZIP_CODE: 'requestorAddressZipCode', + }, + BUSINESS_INFO_STEP: { + COMPANY_NAME: 'companyName', + COMPANY_TAX_ID: 'companyTaxID', + COMPANY_WEBSITE: 'website', + COMPANY_PHONE: 'companyPhone', + STREET: 'addressStreet', + CITY: 'addressCity', + STATE: 'addressState', + ZIP_CODE: 'addressZipCode', + INCORPORATION_TYPE: 'incorporationType', + INCORPORATION_DATE: 'incorporationDate', + INCORPORATION_STATE: 'incorporationState', + HAS_NO_CONNECTION_TO_CANNABIS: 'hasNoConnectionToCannabis', + }, + COMPLETE_VERIFICATION: { + IS_AUTHORIZED_TO_USE_BANK_ACCOUNT: 'isAuthorizedToUseBankAccount', + CERTIFY_TRUE_INFORMATION: 'certifyTrueInformation', + ACCEPT_TERMS_AND_CONDITIONS: 'acceptTermsAndConditions', + }, + BENEFICIAL_OWNER_INFO_STEP: { + OWNS_MORE_THAN_25_PERCENT: 'ownsMoreThan25Percent', + HAS_OTHER_BENEFICIAL_OWNERS: 'hasOtherBeneficialOwners', + BENEFICIAL_OWNERS: 'beneficialOwners', + }, + AMOUNT1: 'amount1', + AMOUNT2: 'amount2', + AMOUNT3: 'amount3', +} as const; + +// BeneficialOwnerDraftData is saved under dynamic key which consists of prefix, beneficial owner ID and input key +type BeneficialOwnerDataKey = `beneficialOwner_${string}_${string}`; +type AdditionalDraftData = {selectedPlaidAccountID?: string; bankAccountID?: number}; + +type BankAccountStepProps = { + [INPUT_IDS.BANK_INFO_STEP.ACCOUNT_NUMBER]?: string; + [INPUT_IDS.BANK_INFO_STEP.ROUTING_NUMBER]?: string; + [INPUT_IDS.BANK_INFO_STEP.PLAID_ACCOUNT_ID]?: string; + [INPUT_IDS.BANK_INFO_STEP.PLAID_MASK]?: string; +}; + +type CompanyStepProps = { + [INPUT_IDS.BUSINESS_INFO_STEP.COMPANY_NAME]?: string; + [INPUT_IDS.BUSINESS_INFO_STEP.STREET]?: string; + [INPUT_IDS.BUSINESS_INFO_STEP.CITY]?: string; + [INPUT_IDS.BUSINESS_INFO_STEP.STATE]?: string; + [INPUT_IDS.BUSINESS_INFO_STEP.ZIP_CODE]?: string; + [INPUT_IDS.BUSINESS_INFO_STEP.COMPANY_PHONE]?: string; + [INPUT_IDS.BUSINESS_INFO_STEP.COMPANY_WEBSITE]?: string; + [INPUT_IDS.BUSINESS_INFO_STEP.COMPANY_TAX_ID]?: string; + [INPUT_IDS.BUSINESS_INFO_STEP.INCORPORATION_TYPE]?: string; + [INPUT_IDS.BUSINESS_INFO_STEP.INCORPORATION_DATE]?: string; + [INPUT_IDS.BUSINESS_INFO_STEP.INCORPORATION_STATE]?: string; + [INPUT_IDS.BUSINESS_INFO_STEP.HAS_NO_CONNECTION_TO_CANNABIS]?: boolean; +}; + +type RequestorStepProps = { + [INPUT_IDS.PERSONAL_INFO_STEP.FIRST_NAME]?: string; + [INPUT_IDS.PERSONAL_INFO_STEP.LAST_NAME]?: string; + [INPUT_IDS.PERSONAL_INFO_STEP.STREET]?: string; + [INPUT_IDS.PERSONAL_INFO_STEP.CITY]?: string; + [INPUT_IDS.PERSONAL_INFO_STEP.STATE]?: string; + [INPUT_IDS.PERSONAL_INFO_STEP.ZIP_CODE]?: string; + [INPUT_IDS.PERSONAL_INFO_STEP.DOB]?: string; + [INPUT_IDS.PERSONAL_INFO_STEP.SSN_LAST_4]?: string; +}; + +type BeneficialOwnersStepProps = { + [INPUT_IDS.BENEFICIAL_OWNER_INFO_STEP.OWNS_MORE_THAN_25_PERCENT]?: boolean; + [INPUT_IDS.BENEFICIAL_OWNER_INFO_STEP.HAS_OTHER_BENEFICIAL_OWNERS]?: boolean; + [INPUT_IDS.BENEFICIAL_OWNER_INFO_STEP.BENEFICIAL_OWNERS]?: string; + [key: BeneficialOwnerDataKey]: string; + beneficialOwnerKeys?: string[]; +}; + +type ACHContractStepProps = { + [INPUT_IDS.COMPLETE_VERIFICATION.ACCEPT_TERMS_AND_CONDITIONS]?: boolean; + [INPUT_IDS.COMPLETE_VERIFICATION.CERTIFY_TRUE_INFORMATION]?: boolean; + [INPUT_IDS.COMPLETE_VERIFICATION.IS_AUTHORIZED_TO_USE_BANK_ACCOUNT]?: boolean; +}; + +type ReimbursementAccountProps = { + [INPUT_IDS.BANK_INFO_STEP.IS_SAVINGS]?: boolean; + [INPUT_IDS.BANK_INFO_STEP.BANK_NAME]?: string; + [INPUT_IDS.BANK_INFO_STEP.PLAID_ACCESS_TOKEN]?: string; + [INPUT_IDS.AMOUNT1]?: string; + [INPUT_IDS.AMOUNT2]?: string; + [INPUT_IDS.AMOUNT3]?: string; +}; + +type ReimbursementAccountForm = AdditionalDraftData & + BeneficialOwnersStepProps & + Form; + +export type { + ReimbursementAccountForm, + AdditionalDraftData, + BeneficialOwnerDataKey, + BankAccountStepProps, + CompanyStepProps, + RequestorStepProps, + BeneficialOwnersStepProps, + ACHContractStepProps, + ReimbursementAccountProps, +}; +export default INPUT_IDS; diff --git a/src/types/form/ReportDescriptionForm.ts b/src/types/form/ReportDescriptionForm.ts new file mode 100644 index 000000000000..18f42ad80182 --- /dev/null +++ b/src/types/form/ReportDescriptionForm.ts @@ -0,0 +1,12 @@ +import type Form from './Form'; + +const INPUT_IDS = { + REPORT_DESCRIPTION: 'reportDescription', +} as const; + +type ReportDescriptionForm = Form<{ + [INPUT_IDS.REPORT_DESCRIPTION]: string; +}>; + +export type {ReportDescriptionForm}; +export default INPUT_IDS; diff --git a/src/types/form/ReportFieldEditForm.ts b/src/types/form/ReportFieldEditForm.ts new file mode 100644 index 000000000000..3dce5456875c --- /dev/null +++ b/src/types/form/ReportFieldEditForm.ts @@ -0,0 +1,6 @@ +import type Form from './Form'; + +type ReportFieldEditForm = Form>; + +// eslint-disable-next-line import/prefer-default-export +export type {ReportFieldEditForm}; diff --git a/src/types/form/ReportVirtualCardFraudForm.ts b/src/types/form/ReportVirtualCardFraudForm.ts new file mode 100644 index 000000000000..994e0ad66643 --- /dev/null +++ b/src/types/form/ReportVirtualCardFraudForm.ts @@ -0,0 +1,6 @@ +import type Form from './Form'; + +type ReportVirtualCardFraudForm = Form; + +// eslint-disable-next-line import/prefer-default-export +export type {ReportVirtualCardFraudForm}; diff --git a/src/types/form/RequestPhysicalCardForm.ts b/src/types/form/RequestPhysicalCardForm.ts new file mode 100644 index 000000000000..58377e136049 --- /dev/null +++ b/src/types/form/RequestPhysicalCardForm.ts @@ -0,0 +1,6 @@ +import type Form from './Form'; + +type RequestPhysicalCardForm = Form; + +// eslint-disable-next-line import/prefer-default-export +export type {RequestPhysicalCardForm}; diff --git a/src/types/form/RoomNameForm.ts b/src/types/form/RoomNameForm.ts new file mode 100644 index 000000000000..0a128d2c175f --- /dev/null +++ b/src/types/form/RoomNameForm.ts @@ -0,0 +1,12 @@ +import type Form from './Form'; + +const INPUT_IDS = { + ROOM_NAME: 'roomName', +} as const; + +type RoomNameForm = Form<{ + [INPUT_IDS.ROOM_NAME]: string; +}>; + +export type {RoomNameForm}; +export default INPUT_IDS; diff --git a/src/types/form/RoomSettingsForm.ts b/src/types/form/RoomSettingsForm.ts new file mode 100644 index 000000000000..3ef94786ef9a --- /dev/null +++ b/src/types/form/RoomSettingsForm.ts @@ -0,0 +1,6 @@ +import type Form from './Form'; + +type RoomSettingsForm = Form; + +// eslint-disable-next-line import/prefer-default-export +export type {RoomSettingsForm}; diff --git a/src/types/form/SettingsStatusClearDateForm.ts b/src/types/form/SettingsStatusClearDateForm.ts new file mode 100644 index 000000000000..fdb191cb4bc5 --- /dev/null +++ b/src/types/form/SettingsStatusClearDateForm.ts @@ -0,0 +1,12 @@ +import type Form from './Form'; + +const INPUT_IDS = { + DATE_TIME: 'dateTime', +} as const; + +type SettingsStatusClearDateForm = Form<{ + [INPUT_IDS.DATE_TIME]: string; +}>; + +export type {SettingsStatusClearDateForm}; +export default INPUT_IDS; diff --git a/src/types/form/SettingsStatusSetClearAfterForm.ts b/src/types/form/SettingsStatusSetClearAfterForm.ts new file mode 100644 index 000000000000..0a5a0d654376 --- /dev/null +++ b/src/types/form/SettingsStatusSetClearAfterForm.ts @@ -0,0 +1,6 @@ +import type Form from './Form'; + +type SettingsStatusSetClearAfterForm = Form; + +// eslint-disable-next-line import/prefer-default-export +export type {SettingsStatusSetClearAfterForm}; diff --git a/src/types/form/SettingsStatusSetForm.ts b/src/types/form/SettingsStatusSetForm.ts new file mode 100644 index 000000000000..9aeec26c4887 --- /dev/null +++ b/src/types/form/SettingsStatusSetForm.ts @@ -0,0 +1,6 @@ +import type Form from './Form'; + +type SettingsStatusSetForm = Form; + +// eslint-disable-next-line import/prefer-default-export +export type {SettingsStatusSetForm}; diff --git a/src/types/form/WaypointForm.ts b/src/types/form/WaypointForm.ts new file mode 100644 index 000000000000..b9a8fd3a400e --- /dev/null +++ b/src/types/form/WaypointForm.ts @@ -0,0 +1,6 @@ +import type Form from './Form'; + +type WaypointForm = Form; + +// eslint-disable-next-line import/prefer-default-export +export type {WaypointForm}; diff --git a/src/types/form/WorkspaceInviteMessageForm.ts b/src/types/form/WorkspaceInviteMessageForm.ts new file mode 100644 index 000000000000..268e29224f35 --- /dev/null +++ b/src/types/form/WorkspaceInviteMessageForm.ts @@ -0,0 +1,12 @@ +import type Form from './Form'; + +const INPUT_IDS = { + WELCOME_MESSAGE: 'welcomeMessage', +} as const; + +type WorkspaceInviteMessageForm = Form<{ + [INPUT_IDS.WELCOME_MESSAGE]: string; +}>; + +export type {WorkspaceInviteMessageForm}; +export default INPUT_IDS; diff --git a/src/types/form/WorkspaceRateAndUnitForm.ts b/src/types/form/WorkspaceRateAndUnitForm.ts new file mode 100644 index 000000000000..52f13d3a1415 --- /dev/null +++ b/src/types/form/WorkspaceRateAndUnitForm.ts @@ -0,0 +1,14 @@ +import type Form from './Form'; + +const INPUT_IDS = { + RATE: 'rate', + UNIT: 'unit', +} as const; + +type WorkspaceRateAndUnitForm = Form<{ + [INPUT_IDS.RATE]: string; + [INPUT_IDS.UNIT]: string; +}>; + +export type {WorkspaceRateAndUnitForm}; +export default INPUT_IDS; diff --git a/src/types/form/WorkspaceSettingsForm.ts b/src/types/form/WorkspaceSettingsForm.ts new file mode 100644 index 000000000000..a3714583477a --- /dev/null +++ b/src/types/form/WorkspaceSettingsForm.ts @@ -0,0 +1,12 @@ +import type Form from './Form'; + +const INPUT_IDS = { + NAME: 'name', +} as const; + +type WorkspaceSettingsForm = Form<{ + [INPUT_IDS.NAME]: string; +}>; + +export type {WorkspaceSettingsForm}; +export default INPUT_IDS; diff --git a/src/types/form/index.ts b/src/types/form/index.ts new file mode 100644 index 000000000000..eb691bcc8ca4 --- /dev/null +++ b/src/types/form/index.ts @@ -0,0 +1,35 @@ +export type {AddDebitCardForm} from './AddDebitCardForm'; +export type {CloseAccountForm} from './CloseAccountForm'; +export type {DateOfBirthForm} from './DateOfBirthForm'; +export type {DisplayNameForm} from './DisplayNameForm'; +export type {EditTaskForm} from './EditTaskForm'; +export type {GetPhysicalCardForm} from './GetPhysicalCardForm'; +export type {HomeAddressForm} from './HomeAddressForm'; +export type {IKnowTeacherForm} from './IKnowTeacherForm'; +export type {IntroSchoolPrincipalForm} from './IntroSchoolPrincipalForm'; +export type {LegalNameForm} from './LegalNameForm'; +export type {MoneyRequestAmountForm} from './MoneyRequestAmountForm'; +export type {MoneyRequestCreatedForm} from './MoneyRequestCreatedForm'; +export type {MoneyRequestDescriptionForm} from './MoneyRequestDescriptionForm'; +export type {MoneyRequestMerchantForm} from './MoneyRequestMerchantForm'; +export type {NewContactMethodForm} from './NewContactMethodForm'; +export type {NewRoomForm} from './NewRoomForm'; +export type {NewTaskForm} from './NewTaskForm'; +export type {PersonalBankAccountForm} from './PersonalBankAccountForm'; +export type {PrivateNotesForm} from './PrivateNotesForm'; +export type {ProfileSettingsForm} from './ProfileSettingsForm'; +export type {ReimbursementAccountForm} from './ReimbursementAccountForm'; +export type {ReportDescriptionForm} from './ReportDescriptionForm'; +export type {ReportFieldEditForm} from './ReportFieldEditForm'; +export type {ReportVirtualCardFraudForm} from './ReportVirtualCardFraudForm'; +export type {RequestPhysicalCardForm} from './RequestPhysicalCardForm'; +export type {RoomNameForm} from './RoomNameForm'; +export type {RoomSettingsForm} from './RoomSettingsForm'; +export type {SettingsStatusClearDateForm} from './SettingsStatusClearDateForm'; +export type {SettingsStatusSetClearAfterForm} from './SettingsStatusSetClearAfterForm'; +export type {SettingsStatusSetForm} from './SettingsStatusSetForm'; +export type {WaypointForm} from './WaypointForm'; +export type {WorkspaceInviteMessageForm} from './WorkspaceInviteMessageForm'; +export type {WorkspaceRateAndUnitForm} from './WorkspaceRateAndUnitForm'; +export type {WorkspaceSettingsForm} from './WorkspaceSettingsForm'; +export type {default as Form} from './Form'; diff --git a/src/types/modules/react-native-onyx.d.ts b/src/types/modules/react-native-onyx.d.ts index ba5774aa8539..ade71706a8e8 100644 --- a/src/types/modules/react-native-onyx.d.ts +++ b/src/types/modules/react-native-onyx.d.ts @@ -1,10 +1,10 @@ import type Onyx from 'react-native-onyx'; -import type {OnyxCollectionKey, OnyxKey, OnyxValues} from '@src/ONYXKEYS'; +import type {OnyxCollectionKey, OnyxFormDraftKey, OnyxFormKey, OnyxValueKey, OnyxValues} from '@src/ONYXKEYS'; declare module 'react-native-onyx' { // eslint-disable-next-line @typescript-eslint/consistent-type-definitions interface CustomTypeOptions { - keys: OnyxKey; + keys: OnyxValueKey | OnyxFormKey | OnyxFormDraftKey; collectionKeys: OnyxCollectionKey; values: OnyxValues; } diff --git a/src/types/onyx/Form.ts b/src/types/onyx/Form.ts deleted file mode 100644 index cb50965fbcfc..000000000000 --- a/src/types/onyx/Form.ts +++ /dev/null @@ -1,127 +0,0 @@ -import type * as OnyxCommon from './OnyxCommon'; -import type PersonalBankAccount from './PersonalBankAccount'; -import type {OnfidoData} from './ReimbursementAccountDraft'; -import type ReimbursementAccountDraft from './ReimbursementAccountDraft'; - -type FormValueType = string | boolean | Date | OnyxCommon.Errors | OnfidoData | string[] | number; - -type BaseForm = { - /** Controls the loading state of the form */ - isLoading?: boolean; - - /** Server side errors keyed by microtime */ - errors?: OnyxCommon.Errors | null; - - /** Field-specific server side errors keyed by microtime */ - errorFields?: OnyxCommon.ErrorFields | null; -}; - -type Form = Record> = TFormValues & BaseForm; - -type AddDebitCardForm = Form<{ - /** Whether the form has been submitted */ - setupComplete: boolean; -}>; - -type DateOfBirthForm = Form<{ - /** Date of birth */ - dob?: string; -}>; - -type DisplayNameForm = Form<{ - firstName: string; - lastName: string; -}>; - -type NewRoomForm = Form<{ - roomName?: string; - reportDescription?: string; - policyID?: string; - writeCapability?: string; - visibility?: string; -}>; - -type IKnowATeacherForm = Form<{ - firstName: string; - lastName: string; - partnerUserID: string; -}>; - -type IntroSchoolPrincipalForm = Form<{ - firstName: string; - lastName: string; - partnerUserID: string; -}>; - -type PrivateNotesForm = Form<{ - privateNotes: string; -}>; - -type GetPhysicalCardForm = Form<{ - /** Address line 1 for delivery */ - addressLine1?: string; - - /** Address line 2 for delivery */ - addressLine2?: string; - - /** City for delivery */ - city?: string; - - /** Country for delivery */ - country?: string; - - /** First name for delivery */ - legalFirstName?: string; - - /** Last name for delivery */ - legalLastName?: string; - - /** Phone number for delivery */ - phoneNumber?: string; - - /** State for delivery */ - state?: string; - - /** Zip code for delivery */ - zipPostCode?: string; -}>; - -type PersonalBankAccountForm = Form; - -type WorkspaceSettingsForm = Form<{ - name: string; -}>; - -type ReportFieldEditForm = Form>; - -type CloseAccountForm = Form<{ - reasonForLeaving: string; - phoneOrEmail: string; -}>; - -type RoomNameForm = Form<{ - roomName: string; -}>; - -type ReimbursementAccountForm = Form; - -export default Form; - -export type { - AddDebitCardForm, - DateOfBirthForm, - PrivateNotesForm, - DisplayNameForm, - FormValueType, - GetPhysicalCardForm, - NewRoomForm, - BaseForm, - IKnowATeacherForm, - IntroSchoolPrincipalForm, - PersonalBankAccountForm, - WorkspaceSettingsForm, - ReportFieldEditForm, - CloseAccountForm, - RoomNameForm, - ReimbursementAccountForm, -}; diff --git a/src/types/onyx/ReimbursementAccount.ts b/src/types/onyx/ReimbursementAccount.ts index 495458149b67..173200ba681a 100644 --- a/src/types/onyx/ReimbursementAccount.ts +++ b/src/types/onyx/ReimbursementAccount.ts @@ -1,8 +1,8 @@ import type {ValueOf} from 'type-fest'; import type CONST from '@src/CONST'; +import type {ACHContractStepProps, BeneficialOwnersStepProps, CompanyStepProps, RequestorStepProps} from '@src/types/form/ReimbursementAccountForm'; import type {BankName} from './Bank'; import type * as OnyxCommon from './OnyxCommon'; -import type {ACHContractStepProps, BeneficialOwnersStepProps, CompanyStepProps, RequestorStepProps} from './ReimbursementAccountDraft'; type BankAccountStep = ValueOf; diff --git a/src/types/onyx/ReimbursementAccountDraft.ts b/src/types/onyx/ReimbursementAccountDraft.ts deleted file mode 100644 index 2748c662c9e2..000000000000 --- a/src/types/onyx/ReimbursementAccountDraft.ts +++ /dev/null @@ -1,91 +0,0 @@ -import type {OnyxFormValuesFields} from '@components/Form/types'; -import type ONYXKEYS from '@src/ONYXKEYS'; - -type OnfidoData = Record; -type ReimbursementAccountDraftValues = OnyxFormValuesFields; - -type BankAccountStepProps = { - accountNumber?: string; - routingNumber?: string; - acceptTerms?: boolean; - plaidAccountID?: string; - plaidMask?: string; -}; - -type CompanyStepProps = { - companyName?: string; - addressStreet?: string; - addressCity?: string; - addressState?: string; - addressZipCode?: string; - companyPhone?: string; - website?: string; - companyTaxID?: string; - incorporationType?: string; - incorporationDate?: string; - incorporationState?: string; - hasNoConnectionToCannabis?: boolean; -}; - -type RequestorStepProps = { - firstName?: string; - lastName?: string; - requestorAddressStreet?: string; - requestorAddressCity?: string; - requestorAddressState?: string; - requestorAddressZipCode?: string; - dob?: string; - ssnLast4?: string; - isOnfidoSetupComplete?: boolean; - onfidoData?: OnfidoData; -}; - -type BeneficialOwnersStepProps = { - ownsMoreThan25Percent?: boolean; - hasOtherBeneficialOwners?: boolean; - beneficialOwners?: string; - beneficialOwnerKeys?: string[]; -}; - -type ACHContractStepProps = { - acceptTermsAndConditions?: boolean; - certifyTrueInformation?: boolean; - isAuthorizedToUseBankAccount?: boolean; -}; - -type ReimbursementAccountProps = { - bankAccountID?: number; - isSavings?: boolean; - bankName?: string; - plaidAccessToken?: string; - amount1?: string; - amount2?: string; - amount3?: string; -}; - -// BeneficialOwnerDraftData is saved under dynamic key which consists of prefix, beneficial owner ID and input key -type BeneficialOwnerDataKey = `beneficialOwner_${string}_${string}`; -type BeneficialOwnerDraftData = Record; - -type ReimbursementAccountDraft = BankAccountStepProps & - CompanyStepProps & - RequestorStepProps & - BeneficialOwnersStepProps & - ACHContractStepProps & - ReimbursementAccountProps & - BeneficialOwnerDraftData & { - selectedPlaidAccountID?: string; - }; - -export default ReimbursementAccountDraft; -export type { - ACHContractStepProps, - BeneficialOwnersStepProps, - RequestorStepProps, - OnfidoData, - BankAccountStepProps, - CompanyStepProps, - ReimbursementAccountProps, - BeneficialOwnerDraftData, - ReimbursementAccountDraftValues, -}; diff --git a/src/types/onyx/index.ts b/src/types/onyx/index.ts index 8e88c54c448d..caa4c35747bf 100644 --- a/src/types/onyx/index.ts +++ b/src/types/onyx/index.ts @@ -10,22 +10,6 @@ import type Credentials from './Credentials'; import type Currency from './Currency'; import type CustomStatusDraft from './CustomStatusDraft'; import type Download from './Download'; -import type { - AddDebitCardForm, - CloseAccountForm, - DateOfBirthForm, - DisplayNameForm, - GetPhysicalCardForm, - IKnowATeacherForm, - IntroSchoolPrincipalForm, - NewRoomForm, - PrivateNotesForm, - ReimbursementAccountForm, - ReportFieldEditForm, - RoomNameForm, - WorkspaceSettingsForm, -} from './Form'; -import type Form from './Form'; import type FrequentlyUsedEmoji from './FrequentlyUsedEmoji'; import type {FundList} from './Fund'; import type Fund from './Fund'; @@ -56,7 +40,6 @@ import type RecentlyUsedReportFields from './RecentlyUsedReportFields'; import type RecentlyUsedTags from './RecentlyUsedTags'; import type RecentWaypoint from './RecentWaypoint'; import type ReimbursementAccount from './ReimbursementAccount'; -import type ReimbursementAccountDraft from './ReimbursementAccountDraft'; import type Report from './Report'; import type {ReportActions} from './ReportAction'; import type ReportAction from './ReportAction'; @@ -89,8 +72,6 @@ import type WorkspaceRateAndUnit from './WorkspaceRateAndUnit'; export type { Account, AccountData, - AddDebitCardForm, - DisplayNameForm, BankAccount, BankAccountList, Beta, @@ -100,14 +81,10 @@ export type { Credentials, Currency, CustomStatusDraft, - CloseAccountForm, - DateOfBirthForm, Download, - Form, FrequentlyUsedEmoji, Fund, FundList, - GetPhysicalCardForm, IntroSelected, IOU, Locale, @@ -135,8 +112,6 @@ export type { RecentlyUsedCategories, RecentlyUsedTags, ReimbursementAccount, - ReimbursementAccountDraft, - ReimbursementAccountForm, Report, ReportAction, ReportActionReactions, @@ -165,17 +140,10 @@ export type { WalletTerms, WalletTransfer, WorkspaceRateAndUnit, - WorkspaceSettingsForm, ReportUserIsTyping, PolicyReportField, PolicyReportFields, RecentlyUsedReportFields, LastPaymentMethod, - NewRoomForm, - IKnowATeacherForm, - IntroSchoolPrincipalForm, InvitedEmailsToAccountIDs, - PrivateNotesForm, - ReportFieldEditForm, - RoomNameForm, }; diff --git a/src/types/utils/AssertTypesEqual.ts b/src/types/utils/AssertTypesEqual.ts new file mode 100644 index 000000000000..935a7a812f86 --- /dev/null +++ b/src/types/utils/AssertTypesEqual.ts @@ -0,0 +1,10 @@ +import type {IsEqual} from 'type-fest'; + +type MismatchError = "Error: Types don't match"; +/** + * The 'AssertTypesEqual' type here enforces that `T1` and `T2` match exactly. + * If `T1` or `T2` are different this type will cause a compile-time error + */ +type AssertTypesEqual extends true ? T1 : TMismatchError, TMismatchError = MismatchError> = T1 & T2; + +export default AssertTypesEqual;