Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

[TS Migration] Improve Form #35584

Merged
merged 54 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
4f109b2
Use more accurate type for ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT form
blazejkustra Feb 1, 2024
5a9b7fa
Clean form onyx values
blazejkustra Feb 1, 2024
1865489
Move InputWrapperProps to InputWrapper file
blazejkustra Feb 1, 2024
ea73d4f
Add more generic types to FormWrapper
blazejkustra Feb 1, 2024
8a06c0a
Move RegisterInput to FormContext file
blazejkustra Feb 1, 2024
ede25e5
Improve Form types, rename utility types
blazejkustra Feb 1, 2024
35356da
Fix type errors in validation functions
blazejkustra Feb 1, 2024
c5e9982
Merge branch 'main' into ts/improve-form
blazejkustra Feb 2, 2024
fbadba9
Clean ONYXKEYS
blazejkustra Feb 2, 2024
6e2bf36
Remove OnyxFormKeyWithoutDraft, now OnyxFormKey and OnyxFormDraftKey …
blazejkustra Feb 2, 2024
e4caa67
Use OnyxKey instead of OnyxKeys
blazejkustra Feb 2, 2024
06ee35e
Add ts-expect-error to all reimburesementAccount usage
blazejkustra Feb 2, 2024
8b4f885
Merge branch 'main' into ts/improve-form
blazejkustra Feb 2, 2024
8db9304
Fix eslint
blazejkustra Feb 2, 2024
488c935
Merge branch 'main' into ts/improve-form
blazejkustra Feb 5, 2024
94e6d41
Fix CloseAccountForm
blazejkustra Feb 5, 2024
b894733
Fix onyxkeys
blazejkustra Feb 5, 2024
ffd0a26
Add AssertTypesEqual utility type
blazejkustra Feb 5, 2024
4488723
Migrate input ids to constant object
blazejkustra Feb 5, 2024
87e4ea1
Add remaining inputs
blazejkustra Feb 5, 2024
16529f2
Merge branch 'main' into ts/improve-form
blazejkustra Feb 5, 2024
0a07743
Move isFocused prop
blazejkustra Feb 5, 2024
30a91f0
Use INPUT_IDS in markdown as well
blazejkustra Feb 5, 2024
ede62bd
Simplify FormOnyxKeys type
blazejkustra Feb 6, 2024
06394df
Add custom error to AssertOnyxKeys
blazejkustra Feb 6, 2024
4708fae
Merge branch 'main' into ts/improve-form
blazejkustra Feb 6, 2024
ef0b5de
Fix package-lock
blazejkustra Feb 6, 2024
737b148
Merge branch 'main' into ts/improve-form
blazejkustra Feb 6, 2024
cd2e3e5
Move input ids to separate files
blazejkustra Feb 6, 2024
dcf3fb9
Make INPUT_IDS as default export
blazejkustra Feb 6, 2024
bd4bb07
Fxi inputs imports
blazejkustra Feb 6, 2024
16c1089
Add new form imports in ONYXKEYS
blazejkustra Feb 6, 2024
e9be3f4
Add new form imports in ONYXKEYS
blazejkustra Feb 6, 2024
8b932c3
Merge branch 'main' into ts/improve-form
blazejkustra Feb 6, 2024
bec9ded
Fix typecheck failing
blazejkustra Feb 6, 2024
b9130ee
Merge branch 'main' into ts/improve-form
blazejkustra Feb 7, 2024
a931897
Merge branch 'main' into ts/improve-form
blazejkustra Feb 8, 2024
dfb9ae9
Move form types to src/types/form
blazejkustra Feb 8, 2024
b9b1b00
Move BaseForm type to src/types/form
blazejkustra Feb 8, 2024
d1baa7b
Fix imports
blazejkustra Feb 8, 2024
b0449c0
Merge branch 'main' into ts/improve-form
blazejkustra Feb 8, 2024
f716077
Adjust form docs
blazejkustra Feb 8, 2024
8062eb8
Remove unused imports
blazejkustra Feb 8, 2024
72407eb
Merge branch 'main' into ts/improve-form
blazejkustra Feb 9, 2024
a10a841
Merge branch 'main' into ts/improve-form
blazejkustra Feb 9, 2024
b138cc1
Merge branch 'main' into ts/improve-form
blazejkustra Feb 12, 2024
0d10ba1
Fix typecheck and lint
blazejkustra Feb 12, 2024
575c163
Fix prettier
blazejkustra Feb 12, 2024
dbd6335
Merge branch 'main' into ts/improve-form
blazejkustra Feb 12, 2024
611b6f3
Merge branch 'main' into ts/improve-form
blazejkustra Feb 13, 2024
a95392a
Clean up typescript after merging bank refactor
blazejkustra Feb 13, 2024
fe4aace
Add remaining input
blazejkustra Feb 13, 2024
e11690d
Merge branch 'main' into ts/improve-form
blazejkustra Feb 13, 2024
820e63e
Fix prettier
blazejkustra Feb 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
214 changes: 103 additions & 111 deletions src/ONYXKEYS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -228,9 +228,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',
blazejkustra marked this conversation as resolved.
Show resolved Hide resolved

// The access token to be used with the Mapbox library
MAPBOX_ACCESS_TOKEN: 'mapboxAccessToken',

Expand Down Expand Up @@ -370,12 +367,85 @@ const ONYXKEYS = {
},
} as const;

type OnyxKeysMap = typeof ONYXKEYS;
type OnyxCollectionKey = ValueOf<OnyxKeysMap['COLLECTION']>;
type OnyxKey = DeepValueOf<Omit<OnyxKeysMap, 'COLLECTION'>>;
type OnyxFormKey = ValueOf<OnyxKeysMap['FORMS']>;
type AllOnyxKeys = DeepValueOf<typeof ONYXKEYS>;

type OnyxFormValuesMapping = {
[ONYXKEYS.FORMS.ADD_DEBIT_CARD_FORM]: OnyxTypes.AddDebitCardForm;
[ONYXKEYS.FORMS.WORKSPACE_SETTINGS_FORM]: OnyxTypes.WorkspaceSettingsForm;
[ONYXKEYS.FORMS.WORKSPACE_RATE_AND_UNIT_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.PROFILE_SETTINGS_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.DISPLAY_NAME_FORM]: OnyxTypes.DisplayNameForm;
[ONYXKEYS.FORMS.ROOM_NAME_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.WELCOME_MESSAGE_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.LEGAL_NAME_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.WORKSPACE_INVITE_MESSAGE_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.DATE_OF_BIRTH_FORM]: OnyxTypes.DateOfBirthForm;
[ONYXKEYS.FORMS.HOME_ADDRESS_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.NEW_ROOM_FORM]: OnyxTypes.NewRoomForm;
[ONYXKEYS.FORMS.ROOM_SETTINGS_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.NEW_TASK_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.EDIT_TASK_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.MONEY_REQUEST_DESCRIPTION_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.MONEY_REQUEST_MERCHANT_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.MONEY_REQUEST_AMOUNT_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.MONEY_REQUEST_DATE_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.NEW_CONTACT_METHOD_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.WAYPOINT_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.SETTINGS_STATUS_SET_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.SETTINGS_STATUS_CLEAR_DATE_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.SETTINGS_STATUS_SET_CLEAR_AFTER_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.PRIVATE_NOTES_FORM]: OnyxTypes.PrivateNotesForm;
[ONYXKEYS.FORMS.I_KNOW_A_TEACHER_FORM]: OnyxTypes.IKnowATeacherForm;
[ONYXKEYS.FORMS.INTRO_SCHOOL_PRINCIPAL_FORM]: OnyxTypes.IntroSchoolPrincipalForm;
[ONYXKEYS.FORMS.REPORT_VIRTUAL_CARD_FRAUD]: OnyxTypes.Form;
[ONYXKEYS.FORMS.REPORT_PHYSICAL_CARD_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.GET_PHYSICAL_CARD_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.REPORT_FIELD_EDIT_FORM]: OnyxTypes.ReportFieldEditForm;
[ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.PERSONAL_BANK_ACCOUNT]: OnyxTypes.Form;
};

type OnyxFormDraftValuesMapping = {
[K in keyof OnyxFormValuesMapping as `${K}Draft`]: OnyxFormValuesMapping[K];
};

type OnyxValues = {
type OnyxCollectionValuesMapping = {
[ONYXKEYS.COLLECTION.DOWNLOAD]: OnyxTypes.Download;
[ONYXKEYS.COLLECTION.POLICY]: OnyxTypes.Policy;
[ONYXKEYS.COLLECTION.POLICY_DRAFTS]: OnyxTypes.Policy;
[ONYXKEYS.COLLECTION.POLICY_CATEGORIES]: OnyxTypes.PolicyCategory;
[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]: Record<string, number>;
[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.SPLIT_TRANSACTION_DRAFT]: OnyxTypes.Transaction;
[ONYXKEYS.COLLECTION.POLICY_RECENTLY_USED_TAGS]: OnyxTypes.RecentlyUsedTags;
[ONYXKEYS.COLLECTION.SELECTED_TAB]: string;
[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS]: OnyxTypes.TransactionViolation[];
[ONYXKEYS.COLLECTION.PRIVATE_NOTES_DRAFT]: string;
[ONYXKEYS.COLLECTION.NEXT_STEP]: OnyxTypes.ReportNextStep;
[ONYXKEYS.COLLECTION.POLICY_TAX_RATE]: string[];
[ONYXKEYS.COLLECTION.WORKSPACE_INVITE_MESSAGE_DRAFT]: string;
};

type OnyxValuesMapping = {
[ONYXKEYS.ACCOUNT]: OnyxTypes.Account;
[ONYXKEYS.ACCOUNT_MANAGER_REPORT_ID]: string;
[ONYXKEYS.NVP_IS_FIRST_TIME_NEW_EXPENSIFY_USER]: boolean;
Expand Down Expand Up @@ -453,111 +523,33 @@ type OnyxValues = {
[ONYXKEYS.LAST_VISITED_PATH]: string | undefined;
[ONYXKEYS.RECENTLY_USED_REPORT_FIELDS]: OnyxTypes.RecentlyUsedReportFields;
[ONYXKEYS.UPDATE_REQUIRED]: boolean;
[ONYXKEYS.IS_SEARCHING_FOR_REPORTS]: 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.PolicyCategory;
[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]: Record<string, number>;
[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.POLICY_RECENTLY_USED_TAGS]: OnyxTypes.RecentlyUsedTags;
[ONYXKEYS.COLLECTION.SELECTED_TAB]: string;
[ONYXKEYS.COLLECTION.TRANSACTION_VIOLATIONS]: OnyxTypes.TransactionViolation[];
[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.Form;
[ONYXKEYS.FORMS.CLOSE_ACCOUNT_FORM_DRAFT]: OnyxTypes.Form;
[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.Form;
[ONYXKEYS.FORMS.ROOM_NAME_FORM_DRAFT]: OnyxTypes.Form;
[ONYXKEYS.FORMS.WELCOME_MESSAGE_FORM]: OnyxTypes.Form;
[ONYXKEYS.FORMS.WELCOME_MESSAGE_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.Form;
[ONYXKEYS.FORMS.GET_PHYSICAL_CARD_FORM_DRAFT]: OnyxTypes.Form;
[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.Form;
[ONYXKEYS.FORMS.REIMBURSEMENT_ACCOUNT_FORM_DRAFT]: OnyxTypes.Form;
[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<TOnyxKey extends OnyxKey> = OnyxEntry<OnyxValues[TOnyxKey]>;
blazejkustra marked this conversation as resolved.
Show resolved Hide resolved

/**
* This utility type `EnsureOnyxKeysMatch` takes a type argument `T` which extends the intersection of
* `OnyxKey` and `AllOnyxKeys`. This means `T` needs to be a subset of `OnyxKey` and `AllOnyxKeys`
* which ensures that `OnyxKey` and `AllOnyxKeys` are identical.
*/
type EnsureOnyxKeysMatch<T extends OnyxKey & AllOnyxKeys> = T;

type OnyxKeyValue<TOnyxKey extends (OnyxKey | OnyxCollectionKey) & keyof OnyxValues> = OnyxEntry<OnyxValues[TOnyxKey]>;
/**
* The 'OnyxKeysValidator' type here enforces that `OnyxKey` and `AllOnyxKeys` match exactly.
* If `OnyxKey` or `AllOnyxKeys` contains a key that the other one doesn't,
* this type will cause a compile-time error
*/
type OnyxKeysValidator = EnsureOnyxKeysMatch<OnyxKey | AllOnyxKeys>;
blazejkustra marked this conversation as resolved.
Show resolved Hide resolved

export default ONYXKEYS;
export type {OnyxKey, OnyxCollectionKey, OnyxValues, OnyxKeyValue, OnyxFormKey, OnyxKeysMap};
export type {OnyxValues, OnyxKey, OnyxCollectionKey, OnyxValue, OnyxValueKey, OnyxFormKey, OnyxFormDraftKey, OnyxKeysValidator};
4 changes: 3 additions & 1 deletion src/components/Form/FormContext.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {createContext} from 'react';
import type {RegisterInput} from './types';
import type {Form} from '@src/types/onyx';
import type {InputComponentBaseProps} from './types';

type RegisterInput = (inputID: keyof Form, inputProps: InputComponentBaseProps) => InputComponentBaseProps;
type FormContext = {
registerInput: RegisterInput;
};
Expand Down
30 changes: 14 additions & 16 deletions src/components/Form/FormProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ import CONST from '@src/CONST';
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 {isEmptyObject} from '@src/types/utils/EmptyObject';
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.
Expand Down Expand Up @@ -51,10 +49,10 @@ type FormProviderOnyxProps = {
type FormProviderProps<TFormID extends OnyxFormKey = OnyxFormKey> = FormProviderOnyxProps &
FormProps<TFormID> & {
/** Children to render. */
children: ((props: {inputValues: OnyxFormValues<TFormID>}) => ReactNode) | ReactNode;
children: ((props: {inputValues: FormOnyxValues<TFormID>}) => ReactNode) | ReactNode;

/** Callback to validate the form */
validate?: (values: OnyxFormValuesFields<TFormID>) => Errors;
validate?: (values: FormOnyxValues<TFormID>) => FormInputErrors<TFormID>;

/** Should validate function be called when input loose focus */
shouldValidateOnBlur?: boolean;
Expand All @@ -64,7 +62,7 @@ type FormProviderProps<TFormID extends OnyxFormKey = OnyxFormKey> = FormProvider
};

type FormRef<TFormID extends OnyxFormKey = OnyxFormKey> = {
resetForm: (optionalValue: OnyxFormValues<TFormID>) => void;
resetForm: (optionalValue: FormOnyxValues<TFormID>) => void;
};

function FormProvider(
roryabraham marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -86,11 +84,11 @@ function FormProvider(
const inputRefs = useRef<InputRefs>({});
const touchedInputs = useRef<Record<string, boolean>>({});
const [inputValues, setInputValues] = useState<Form>(() => ({...draftValues}));
const [errors, setErrors] = useState<Errors>({});
const [errors, setErrors] = useState<FormInputErrors>({});
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) {
Expand Down Expand Up @@ -184,13 +182,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;
});
Expand All @@ -203,9 +201,9 @@ function FormProvider(
resetForm,
}));

const registerInput = useCallback<RegisterInput>(
<TInputProps extends BaseInputProps>(inputID: keyof Form, inputProps: TInputProps): TInputProps => {
const newRef: MutableRefObject<BaseInputProps> = inputRefs.current[inputID] ?? inputProps.ref ?? createRef();
const registerInput = useCallback(
(inputID: keyof Form, inputProps: InputComponentBaseProps): InputComponentBaseProps => {
const newRef: MutableRefObject<InputComponentBaseProps> = inputRefs.current[inputID] ?? inputProps.ref ?? createRef();
if (inputRefs.current[inputID] !== newRef) {
inputRefs.current[inputID] = newRef;
}
Expand Down Expand Up @@ -234,7 +232,7 @@ function FormProvider(
...inputProps,
ref:
typeof inputRef === 'function'
? (node: BaseInputProps) => {
? (node: InputComponentBaseProps) => {
inputRef(node);
newRef.current = node;
}
Expand Down Expand Up @@ -298,7 +296,7 @@ function FormProvider(
}
inputProps.onBlur?.(event);
},
onInputChange: (value: FormValueType, key?: string) => {
onInputChange: (value, key) => {
const inputKey = key ?? inputID;
setInputValues((prevState) => {
const newState = {
Expand All @@ -313,7 +311,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);
},
Expand Down
Loading
Loading