diff --git a/.github/workflows/reassurePerformanceTests.yml b/.github/workflows/reassurePerformanceTests.yml index 64b4536d9241..ebe31f41f3d8 100644 --- a/.github/workflows/reassurePerformanceTests.yml +++ b/.github/workflows/reassurePerformanceTests.yml @@ -33,6 +33,7 @@ jobs: npx reassure --baseline git switch --force --detach - git merge --no-commit --allow-unrelated-histories "$BASELINE_BRANCH" -X ours + git checkout --ours . npm install --force npx reassure --branch diff --git a/.nvmrc b/.nvmrc index 43bff1f8cf98..d5a159609d09 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -20.9.0 \ No newline at end of file +20.10.0 diff --git a/README.md b/README.md index f6629af8604d..b69786d64f13 100644 --- a/README.md +++ b/README.md @@ -58,6 +58,7 @@ If you're using another operating system, you will need to ensure `mkcert` is in ## Running the iOS app 📱 For an M1 Mac, read this [SO](https://stackoverflow.com/questions/64901180/how-to-run-cocoapods-on-apple-silicon-m1) for installing cocoapods. +* If you haven't already, install Xcode tools and make sure to install the optional "iOS Platform" package as well. This installation may take awhile. * Install project gems, including cocoapods, using bundler to ensure everyone uses the same versions. In the project root, run: `bundle install` * If you get the error `Could not find 'bundler'`, install the bundler gem first: `gem install bundler` and try again. * If you are using MacOS and get the error `Gem::FilePermissionError` when trying to install the bundler gem, you're likely using system Ruby, which requires administrator permission to modify. To get around this, install another version of Ruby with a version manager like [rbenv](https://github.com/rbenv/rbenv#installation). diff --git a/contributingGuides/CONTRIBUTING.md b/contributingGuides/CONTRIBUTING.md index 9eb16099f535..25f54c668b24 100644 --- a/contributingGuides/CONTRIBUTING.md +++ b/contributingGuides/CONTRIBUTING.md @@ -123,7 +123,7 @@ Additionally if you want to discuss an idea with the open source community witho ``` 11. [Open a pull request](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork), and make sure to fill in the required fields. 12. An Expensify engineer and a member from the Contributor-Plus team will be assigned to your pull request automatically to review. -13. Daily updates on weekdays are highly recommended. If you know you won’t be able to provide updates for > 1 week, please comment on the PR or issue how long you plan to be out so that we may plan accordingly. We understand everyone needs a little vacation here and there. Any issue that doesn't receive an update for 1 full week may be considered abandoned and the original contract terminated. +13. Daily updates on weekdays are highly recommended. If you know you won’t be able to provide updates within 48 hours, please comment on the PR or issue stating how long you plan to be out so that we may plan accordingly. We understand everyone needs a little vacation here and there. Any issue that doesn't receive an update for 5 days (including weekend days) may be considered abandoned and the original contract terminated. #### Submit your pull request for final review 14. When you are ready to submit your pull request for final review, make sure the following checks pass: diff --git a/docs/articles/expensify-classic/workspace-and-domain-settings/Budgets.md b/docs/articles/expensify-classic/workspace-and-domain-settings/Budgets.md index 30adac589dc0..b3f0ad3c6f6f 100644 --- a/docs/articles/expensify-classic/workspace-and-domain-settings/Budgets.md +++ b/docs/articles/expensify-classic/workspace-and-domain-settings/Budgets.md @@ -44,7 +44,7 @@ Expensify’s Budgets feature allows you to: {% include faq-begin.md %} ## Can I import budgets as a CSV? -At this time, you cannot import budgets via CSV since we don’t import categories or tags from direct accounting integrations. +At this time, you cannot import budgets via CSV. ## When will I be notified as a budget is hit? Notifications are sent twice: diff --git a/package-lock.json b/package-lock.json index c1328d498c79..9419023dd1ef 100644 --- a/package-lock.json +++ b/package-lock.json @@ -95,7 +95,7 @@ "react-native-linear-gradient": "^2.8.1", "react-native-localize": "^2.2.6", "react-native-modal": "^13.0.0", - "react-native-onyx": "1.0.118", + "react-native-onyx": "1.0.118-1", "react-native-pager-view": "6.2.2", "react-native-pdf": "6.7.3", "react-native-performance": "^5.1.0", @@ -241,8 +241,8 @@ "yaml": "^2.2.1" }, "engines": { - "node": "20.9.0", - "npm": "10.1.0" + "node": "20.10.0", + "npm": "10.2.3" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -45103,17 +45103,17 @@ } }, "node_modules/react-native-onyx": { - "version": "1.0.118", - "resolved": "https://registry.npmjs.org/react-native-onyx/-/react-native-onyx-1.0.118.tgz", - "integrity": "sha512-w54jO+Bpu1ElHsrxZXIIpcBqNkrUvuVCQmwWdfOW5LvO4UwsPSwmMxzExbUZ4ip+7CROmm10IgXFaAoyfeYSVQ==", + "version": "1.0.118-1", + "resolved": "https://registry.npmjs.org/react-native-onyx/-/react-native-onyx-1.0.118-1.tgz", + "integrity": "sha512-1bGxbnRKDAb3lP6mVNFtzHLlSjRMTPC8tqTJNwC6vDUVHtXNIjbKkA80Ws+esXAcVhsyHiwsz2P9t18C+Jq+0w==", "dependencies": { "ascii-table": "0.0.9", "fast-equals": "^4.0.3", "underscore": "^1.13.6" }, "engines": { - "node": ">=16.15.1 <=20.9.0", - "npm": ">=8.11.0 <=10.1.0" + "node": ">=16.15.1 <=20.10.0", + "npm": ">=8.11.0 <=10.2.3" }, "peerDependencies": { "idb-keyval": "^6.2.1", @@ -85969,9 +85969,9 @@ } }, "react-native-onyx": { - "version": "1.0.118", - "resolved": "https://registry.npmjs.org/react-native-onyx/-/react-native-onyx-1.0.118.tgz", - "integrity": "sha512-w54jO+Bpu1ElHsrxZXIIpcBqNkrUvuVCQmwWdfOW5LvO4UwsPSwmMxzExbUZ4ip+7CROmm10IgXFaAoyfeYSVQ==", + "version": "1.0.118-1", + "resolved": "https://registry.npmjs.org/react-native-onyx/-/react-native-onyx-1.0.118-1.tgz", + "integrity": "sha512-1bGxbnRKDAb3lP6mVNFtzHLlSjRMTPC8tqTJNwC6vDUVHtXNIjbKkA80Ws+esXAcVhsyHiwsz2P9t18C+Jq+0w==", "requires": { "ascii-table": "0.0.9", "fast-equals": "^4.0.3", diff --git a/package.json b/package.json index 96de7fb0ab77..301b31029257 100644 --- a/package.json +++ b/package.json @@ -143,7 +143,7 @@ "react-native-linear-gradient": "^2.8.1", "react-native-localize": "^2.2.6", "react-native-modal": "^13.0.0", - "react-native-onyx": "1.0.118", + "react-native-onyx": "1.0.118-1", "react-native-pager-view": "6.2.2", "react-native-pdf": "6.7.3", "react-native-performance": "^5.1.0", @@ -316,7 +316,7 @@ ] }, "engines": { - "node": "20.9.0", - "npm": "10.1.0" + "node": "20.10.0", + "npm": "10.2.3" } } diff --git a/src/CONST.ts b/src/CONST.ts index ff3934c31943..5625381d2869 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -3057,13 +3057,6 @@ const CONST = { */ MAX_OPTIONS_SELECTOR_PAGE_LENGTH: 500, - /** - * Performance test setup - run the same test multiple times to get a more accurate result - */ - PERFORMANCE_TESTS: { - RUNS: 20, - }, - /** * Bank account names */ diff --git a/src/components/PurposeForUsingExpensifyModal.tsx b/src/components/PurposeForUsingExpensifyModal.tsx index a8cab171ffca..c02815d74153 100644 --- a/src/components/PurposeForUsingExpensifyModal.tsx +++ b/src/components/PurposeForUsingExpensifyModal.tsx @@ -60,14 +60,14 @@ const messageCopy = { [CONST.INTRO_CHOICES.CHAT_SPLIT]: 'Hi there, to split an expense such as with a friend, please:\n' + '\n' + - 'Press the big green + button\n' + - 'Choose *Request money*\n' + - 'Indicate how much was spent, either manually, by scanning a receipt, or by tracking distance\n' + - 'Enter the email address or phone number of your friend\n' + - 'Press *Split* next to their name\n' + - 'Repeat as many times as you like for each of your friends\n' + - 'Press *Add to split* when done adding friends\n' + - 'Press Split to split the bill\n' + + '1. Press the big green + button\n' + + '2. Choose *Request money*\n' + + '3. Indicate how much was spent, either manually, by scanning a receipt, or by tracking distance\n' + + '4. Enter the email address or phone number of your friend\n' + + '5. Press *Split* next to their name\n' + + '6. Repeat as many times as you like for each of your friends\n' + + '7. Press *Add to split* when done adding friends\n' + + '8. Press Split to split the bill\n' + '\n' + "This will send a money request to each of your friends for however much they owe you, and we'll take care of getting you paid back. Thanks for asking, and let me know how it goes!", }; diff --git a/src/components/SelectionList/BaseSelectionList.tsx b/src/components/SelectionList/BaseSelectionList.tsx index d97c47c84ee7..5d9c4cfb99c5 100644 --- a/src/components/SelectionList/BaseSelectionList.tsx +++ b/src/components/SelectionList/BaseSelectionList.tsx @@ -43,7 +43,7 @@ function BaseSelectionList( onScrollBeginDrag, headerMessage = '', confirmButtonText = '', - onConfirm = () => {}, + onConfirm, headerContent, footerContent, showScrollIndicator = false, @@ -363,6 +363,11 @@ function BaseSelectionList( return; } + // scroll is unnecessary if multiple options cannot be selected + if (!canSelectMultiple) { + return; + } + // set the focus on the first item when the sections list is changed if (sections.length > 0) { updateAndScrollToFocusedIndex(0); @@ -379,10 +384,10 @@ function BaseSelectionList( }); /** Calls confirm action when pressing CTRL (CMD) + Enter */ - useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.CTRL_ENTER, onConfirm, { + useKeyboardShortcut(CONST.KEYBOARD_SHORTCUTS.CTRL_ENTER, onConfirm ?? selectFocusedOption, { captureOnInputs: true, shouldBubble: !flattenedSections.allOptions[focusedIndex], - isActive: !disableKeyboardShortcuts && !!onConfirm && isFocused, + isActive: !disableKeyboardShortcuts && isFocused, }); return ( diff --git a/src/hooks/useResponsiveLayout.ts b/src/hooks/useResponsiveLayout.ts index dd782a9dbba5..f00890116d47 100644 --- a/src/hooks/useResponsiveLayout.ts +++ b/src/hooks/useResponsiveLayout.ts @@ -1,25 +1,21 @@ -import type {ParamListBase, RouteProp} from '@react-navigation/native'; -import {useRoute} from '@react-navigation/native'; +import {navigationRef} from '@libs/Navigation/Navigation'; +import NAVIGATORS from '@src/NAVIGATORS'; import useWindowDimensions from './useWindowDimensions'; -type RouteParams = ParamListBase & { - params: {isInRHP?: boolean}; -}; type ResponsiveLayoutResult = { shouldUseNarrowLayout: boolean; + isSmallScreenWidth: boolean; + isInModal: boolean; }; /** - * Hook to determine if we are on mobile devices or in the RHP + * Hook to determine if we are on mobile devices or in the Modal Navigator */ export default function useResponsiveLayout(): ResponsiveLayoutResult { const {isSmallScreenWidth} = useWindowDimensions(); - try { - // eslint-disable-next-line react-hooks/rules-of-hooks - const {params} = useRoute>(); - return {shouldUseNarrowLayout: isSmallScreenWidth || (params?.isInRHP ?? false)}; - } catch (error) { - return { - shouldUseNarrowLayout: isSmallScreenWidth, - }; - } + const state = navigationRef?.getRootState(); + const lastRoute = state?.routes?.at(-1); + const lastRouteName = lastRoute?.name; + const isInModal = lastRouteName === NAVIGATORS.LEFT_MODAL_NAVIGATOR || lastRouteName === NAVIGATORS.RIGHT_MODAL_NAVIGATOR; + const shouldUseNarrowLayout = isSmallScreenWidth || isInModal; + return {shouldUseNarrowLayout, isSmallScreenWidth, isInModal}; } diff --git a/src/languages/en.ts b/src/languages/en.ts index fc426002809a..0363198c5007 100755 --- a/src/languages/en.ts +++ b/src/languages/en.ts @@ -1288,8 +1288,8 @@ export default { dob: 'Please select a valid date of birth', age: 'Must be over 18 years old', ssnLast4: 'Please enter valid last 4 digits of SSN', - firstName: 'Please enter valid first name', - lastName: 'Please enter valid last name', + firstName: 'Please enter a valid first name', + lastName: 'Please enter a valid last name', noDefaultDepositAccountOrDebitCardAvailable: 'Please add a default deposit bank account or debit card', validationAmounts: 'The validation amounts you entered are incorrect. Please double-check your bank statement and try again.', }, diff --git a/src/libs/API.ts b/src/libs/API/index.ts similarity index 89% rename from src/libs/API.ts rename to src/libs/API/index.ts index 4305469eafd5..dbbcf790edf0 100644 --- a/src/libs/API.ts +++ b/src/libs/API/index.ts @@ -1,15 +1,15 @@ import type {OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; -import type {ValueOf} from 'type-fest'; +import Log from '@libs/Log'; +import * as Middleware from '@libs/Middleware'; +import * as SequentialQueue from '@libs/Network/SequentialQueue'; +import * as Pusher from '@libs/Pusher/pusher'; +import * as Request from '@libs/Request'; import CONST from '@src/CONST'; import type OnyxRequest from '@src/types/onyx/Request'; import type Response from '@src/types/onyx/Response'; -import pkg from '../../package.json'; -import Log from './Log'; -import * as Middleware from './Middleware'; -import * as SequentialQueue from './Network/SequentialQueue'; -import * as Pusher from './Pusher/pusher'; -import * as Request from './Request'; +import pkg from '../../../package.json'; +import type {ApiRequest, ApiRequestCommandParameters, ReadCommand, SideEffectRequestCommand, WriteCommand} from './types'; // Setup API middlewares. Each request made will pass through a series of middleware functions that will get called in sequence (each one passing the result of the previous to the next). // Note: The ordering here is intentional as we want to Log, Recheck Connection, Reauthenticate, and Save the Response in Onyx. Errors thrown in one middleware will bubble to the next. @@ -38,8 +38,6 @@ type OnyxData = { finallyData?: OnyxUpdate[]; }; -type ApiRequestType = ValueOf; - /** * All calls to API.write() will be persisted to disk as JSON with the params, successData, and failureData (or finallyData, if included in place of the former two values). * This is so that if the network is unavailable or the app is closed, we can send the WRITE request later. @@ -54,7 +52,7 @@ type ApiRequestType = ValueOf; * @param [onyxData.failureData] - Onyx instructions that will be passed to Onyx.update() when the response has jsonCode !== 200. * @param [onyxData.finallyData] - Onyx instructions that will be passed to Onyx.update() when the response has jsonCode === 200 or jsonCode !== 200. */ -function write(command: string, apiCommandParameters: Record = {}, onyxData: OnyxData = {}) { +function write(command: TCommand, apiCommandParameters: ApiRequestCommandParameters[TCommand], onyxData: OnyxData = {}) { Log.info('Called API write', false, {command, ...apiCommandParameters}); const {optimisticData, ...onyxDataWithoutOptimisticData} = onyxData; @@ -112,11 +110,11 @@ function write(command: string, apiCommandParameters: Record = * response back to the caller or to trigger reconnection callbacks when re-authentication is required. * @returns */ -function makeRequestWithSideEffects( - command: string, - apiCommandParameters = {}, +function makeRequestWithSideEffects( + command: TCommand, + apiCommandParameters: ApiRequestCommandParameters[TCommand], onyxData: OnyxData = {}, - apiRequestType: ApiRequestType = CONST.API_REQUEST_TYPE.MAKE_REQUEST_WITH_SIDE_EFFECTS, + apiRequestType: ApiRequest = CONST.API_REQUEST_TYPE.MAKE_REQUEST_WITH_SIDE_EFFECTS, ): Promise { Log.info('Called API makeRequestWithSideEffects', false, {command, ...apiCommandParameters}); const {optimisticData, ...onyxDataWithoutOptimisticData} = onyxData; @@ -157,7 +155,7 @@ function makeRequestWithSideEffects( * @param [onyxData.failureData] - Onyx instructions that will be passed to Onyx.update() when the response has jsonCode !== 200. * @param [onyxData.finallyData] - Onyx instructions that will be passed to Onyx.update() when the response has jsonCode === 200 or jsonCode !== 200. */ -function read(command: string, apiCommandParameters: Record, onyxData: OnyxData = {}) { +function read(command: TCommand, apiCommandParameters: ApiRequestCommandParameters[TCommand], onyxData: OnyxData = {}) { // Ensure all write requests on the sequential queue have finished responding before running read requests. // Responses from read requests can overwrite the optimistic data inserted by // write requests that use the same Onyx keys and haven't responded yet. diff --git a/src/libs/API/parameters/AcceptWalletTermsParams.ts b/src/libs/API/parameters/AcceptWalletTermsParams.ts new file mode 100644 index 000000000000..897f002eb77a --- /dev/null +++ b/src/libs/API/parameters/AcceptWalletTermsParams.ts @@ -0,0 +1,6 @@ +type AcceptWalletTermsParams = { + hasAcceptedTerms: boolean; + reportID: string; +}; + +export default AcceptWalletTermsParams; diff --git a/src/libs/API/parameters/ActivatePhysicalExpensifyCardParams.ts b/src/libs/API/parameters/ActivatePhysicalExpensifyCardParams.ts new file mode 100644 index 000000000000..98d7f9f4ae32 --- /dev/null +++ b/src/libs/API/parameters/ActivatePhysicalExpensifyCardParams.ts @@ -0,0 +1,5 @@ +type ActivatePhysicalExpensifyCardParams = { + cardLastFourDigits: string; + cardID: number; +}; +export default ActivatePhysicalExpensifyCardParams; diff --git a/src/libs/API/parameters/AddCommentOrAttachementParams.ts b/src/libs/API/parameters/AddCommentOrAttachementParams.ts new file mode 100644 index 000000000000..58faf9fdfc9c --- /dev/null +++ b/src/libs/API/parameters/AddCommentOrAttachementParams.ts @@ -0,0 +1,13 @@ +type AddCommentOrAttachementParams = { + reportID: string; + reportActionID?: string; + commentReportActionID?: string | null; + reportComment?: string; + file?: File; + timezone?: string; + shouldAllowActionableMentionWhispers?: boolean; + clientCreatedTime?: string; + isOldDotConciergeChat?: boolean; +}; + +export default AddCommentOrAttachementParams; diff --git a/src/libs/API/parameters/AddEmojiReactionParams.ts b/src/libs/API/parameters/AddEmojiReactionParams.ts new file mode 100644 index 000000000000..fa31da9538ad --- /dev/null +++ b/src/libs/API/parameters/AddEmojiReactionParams.ts @@ -0,0 +1,10 @@ +type AddEmojiReactionParams = { + reportID: string; + skinTone: string | number; + emojiCode: string; + reportActionID: string; + createdAt: string; + useEmojiReactions: boolean; +}; + +export default AddEmojiReactionParams; diff --git a/src/libs/API/parameters/AddMembersToWorkspaceParams.ts b/src/libs/API/parameters/AddMembersToWorkspaceParams.ts new file mode 100644 index 000000000000..4e96fd07d301 --- /dev/null +++ b/src/libs/API/parameters/AddMembersToWorkspaceParams.ts @@ -0,0 +1,8 @@ +type AddMembersToWorkspaceParams = { + employees: string; + welcomeNote: string; + policyID: string; + reportCreationData?: string; +}; + +export default AddMembersToWorkspaceParams; diff --git a/src/libs/API/parameters/AddNewContactMethodParams.ts b/src/libs/API/parameters/AddNewContactMethodParams.ts new file mode 100644 index 000000000000..f5cd7824c191 --- /dev/null +++ b/src/libs/API/parameters/AddNewContactMethodParams.ts @@ -0,0 +1,3 @@ +type AddNewContactMethodParams = {partnerUserID: string}; + +export default AddNewContactMethodParams; diff --git a/src/libs/API/parameters/AddPaymentCardParams.ts b/src/libs/API/parameters/AddPaymentCardParams.ts new file mode 100644 index 000000000000..1c9b1fc4fa30 --- /dev/null +++ b/src/libs/API/parameters/AddPaymentCardParams.ts @@ -0,0 +1,14 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type AddPaymentCardParams = { + cardNumber: string; + cardYear: string; + cardMonth: string; + cardCVV: string; + addressName: string; + addressZip: string; + currency: ValueOf; + isP2PDebitCard: boolean; +}; +export default AddPaymentCardParams; diff --git a/src/libs/API/parameters/AddPersonalBankAccountParams.ts b/src/libs/API/parameters/AddPersonalBankAccountParams.ts new file mode 100644 index 000000000000..1fa8fc0eb48d --- /dev/null +++ b/src/libs/API/parameters/AddPersonalBankAccountParams.ts @@ -0,0 +1,12 @@ +type AddPersonalBankAccountParams = { + addressName: string; + routingNumber: string; + accountNumber: string; + isSavings: boolean; + setupType: string; + bank?: string; + plaidAccountID: string; + plaidAccessToken: string; +}; + +export default AddPersonalBankAccountParams; diff --git a/src/libs/API/parameters/AddSchoolPrincipalParams.ts b/src/libs/API/parameters/AddSchoolPrincipalParams.ts new file mode 100644 index 000000000000..5602dd22973c --- /dev/null +++ b/src/libs/API/parameters/AddSchoolPrincipalParams.ts @@ -0,0 +1,9 @@ +type AddSchoolPrincipalParams = { + firstName: string; + lastName: string; + partnerUserID: string; + policyID: string; + reportCreationData: string; +}; + +export default AddSchoolPrincipalParams; diff --git a/src/libs/API/parameters/AddWorkspaceRoomParams.ts b/src/libs/API/parameters/AddWorkspaceRoomParams.ts new file mode 100644 index 000000000000..f7cbff9565ef --- /dev/null +++ b/src/libs/API/parameters/AddWorkspaceRoomParams.ts @@ -0,0 +1,15 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; +import type {WriteCapability} from '@src/types/onyx/Report'; + +type AddWorkspaceRoomParams = { + reportID: string; + createdReportActionID: string; + policyID?: string; + reportName?: string; + visibility?: ValueOf; + writeCapability?: WriteCapability; + welcomeMessage?: string; +}; + +export default AddWorkspaceRoomParams; diff --git a/src/libs/API/parameters/AnswerQuestionsForWalletParams.ts b/src/libs/API/parameters/AnswerQuestionsForWalletParams.ts new file mode 100644 index 000000000000..34a08d7c54ee --- /dev/null +++ b/src/libs/API/parameters/AnswerQuestionsForWalletParams.ts @@ -0,0 +1,6 @@ +type AnswerQuestionsForWalletParams = { + idologyAnswers: string; + idNumber: string; +}; + +export default AnswerQuestionsForWalletParams; diff --git a/src/libs/API/parameters/AuthenticatePusherParams.ts b/src/libs/API/parameters/AuthenticatePusherParams.ts new file mode 100644 index 000000000000..95e930431ccd --- /dev/null +++ b/src/libs/API/parameters/AuthenticatePusherParams.ts @@ -0,0 +1,10 @@ +type AuthenticatePusherParams = { + // eslint-disable-next-line @typescript-eslint/naming-convention + socket_id: string; + // eslint-disable-next-line @typescript-eslint/naming-convention + channel_name: string; + shouldRetry: boolean; + forceNetworkRequest: boolean; +}; + +export default AuthenticatePusherParams; diff --git a/src/libs/API/parameters/BankAccountHandlePlaidErrorParams.ts b/src/libs/API/parameters/BankAccountHandlePlaidErrorParams.ts new file mode 100644 index 000000000000..02ee6cd75219 --- /dev/null +++ b/src/libs/API/parameters/BankAccountHandlePlaidErrorParams.ts @@ -0,0 +1,7 @@ +type BankAccountHandlePlaidErrorParams = { + bankAccountID: number; + error: string; + errorDescription: string; + plaidRequestID: string; +}; +export default BankAccountHandlePlaidErrorParams; diff --git a/src/libs/API/parameters/BeginAppleSignInParams.ts b/src/libs/API/parameters/BeginAppleSignInParams.ts new file mode 100644 index 000000000000..c427d99fcef9 --- /dev/null +++ b/src/libs/API/parameters/BeginAppleSignInParams.ts @@ -0,0 +1,9 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type BeginAppleSignInParams = { + idToken: string | undefined | null; + preferredLocale: ValueOf | null; +}; + +export default BeginAppleSignInParams; diff --git a/src/libs/API/parameters/BeginGoogleSignInParams.ts b/src/libs/API/parameters/BeginGoogleSignInParams.ts new file mode 100644 index 000000000000..fae84d76b0d9 --- /dev/null +++ b/src/libs/API/parameters/BeginGoogleSignInParams.ts @@ -0,0 +1,9 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type BeginGoogleSignInParams = { + token: string | null; + preferredLocale: ValueOf | null; +}; + +export default BeginGoogleSignInParams; diff --git a/src/libs/API/parameters/BeginSignInParams.ts b/src/libs/API/parameters/BeginSignInParams.ts new file mode 100644 index 000000000000..2f85a3335c62 --- /dev/null +++ b/src/libs/API/parameters/BeginSignInParams.ts @@ -0,0 +1,5 @@ +type BeginSignInParams = { + email: string; +}; + +export default BeginSignInParams; diff --git a/src/libs/API/parameters/CancelTaskParams.ts b/src/libs/API/parameters/CancelTaskParams.ts new file mode 100644 index 000000000000..fc753cd2ea5b --- /dev/null +++ b/src/libs/API/parameters/CancelTaskParams.ts @@ -0,0 +1,6 @@ +type CancelTaskParams = { + cancelledTaskReportActionID?: string; + taskReportID?: string; +}; + +export default CancelTaskParams; diff --git a/src/libs/API/parameters/ChronosRemoveOOOEventParams.ts b/src/libs/API/parameters/ChronosRemoveOOOEventParams.ts new file mode 100644 index 000000000000..4a4f8fe6008a --- /dev/null +++ b/src/libs/API/parameters/ChronosRemoveOOOEventParams.ts @@ -0,0 +1,6 @@ +type ChronosRemoveOOOEventParams = { + googleEventID: string; + reportActionID: string; +}; + +export default ChronosRemoveOOOEventParams; diff --git a/src/libs/API/parameters/CloseAccountParams.ts b/src/libs/API/parameters/CloseAccountParams.ts new file mode 100644 index 000000000000..643d5468778f --- /dev/null +++ b/src/libs/API/parameters/CloseAccountParams.ts @@ -0,0 +1,3 @@ +type CloseAccountParams = {message: string}; + +export default CloseAccountParams; diff --git a/src/libs/API/parameters/CompleteEngagementModalParams.ts b/src/libs/API/parameters/CompleteEngagementModalParams.ts new file mode 100644 index 000000000000..cffbc0a5ba66 --- /dev/null +++ b/src/libs/API/parameters/CompleteEngagementModalParams.ts @@ -0,0 +1,10 @@ +type CompleteEngagementModalParams = { + reportID: string; + reportActionID?: string; + commentReportActionID?: string | null; + reportComment?: string; + engagementChoice: string; + timezone?: string; +}; + +export default CompleteEngagementModalParams; diff --git a/src/libs/API/parameters/CompleteTaskParams.ts b/src/libs/API/parameters/CompleteTaskParams.ts new file mode 100644 index 000000000000..2312588a6b83 --- /dev/null +++ b/src/libs/API/parameters/CompleteTaskParams.ts @@ -0,0 +1,6 @@ +type CompleteTaskParams = { + taskReportID?: string; + completedTaskReportActionID?: string; +}; + +export default CompleteTaskParams; diff --git a/src/libs/API/parameters/ConnectBankAccountManuallyParams.ts b/src/libs/API/parameters/ConnectBankAccountManuallyParams.ts new file mode 100644 index 000000000000..4f166cfd3aa9 --- /dev/null +++ b/src/libs/API/parameters/ConnectBankAccountManuallyParams.ts @@ -0,0 +1,7 @@ +type ConnectBankAccountManuallyParams = { + bankAccountID: number; + accountNumber?: string; + routingNumber?: string; + plaidMask?: string; +}; +export default ConnectBankAccountManuallyParams; diff --git a/src/libs/API/parameters/ConnectBankAccountWithPlaidParams.ts b/src/libs/API/parameters/ConnectBankAccountWithPlaidParams.ts new file mode 100644 index 000000000000..63df9d280412 --- /dev/null +++ b/src/libs/API/parameters/ConnectBankAccountWithPlaidParams.ts @@ -0,0 +1,10 @@ +type ConnectBankAccountWithPlaidParams = { + bankAccountID: number; + routingNumber: string; + accountNumber: string; + bank?: string; + plaidAccountID: string; + plaidAccessToken: string; +}; + +export default ConnectBankAccountWithPlaidParams; diff --git a/src/libs/API/parameters/CreateTaskParams.ts b/src/libs/API/parameters/CreateTaskParams.ts new file mode 100644 index 000000000000..0ead163c623b --- /dev/null +++ b/src/libs/API/parameters/CreateTaskParams.ts @@ -0,0 +1,15 @@ +type CreateTaskParams = { + parentReportActionID?: string; + parentReportID?: string; + taskReportID?: string; + createdTaskReportActionID?: string; + title?: string; + description?: string; + assignee?: string; + assigneeAccountID?: number; + assigneeChatReportID?: string; + assigneeChatReportActionID?: string; + assigneeChatCreatedReportActionID?: string; +}; + +export default CreateTaskParams; diff --git a/src/libs/API/parameters/CreateWorkspaceFromIOUPaymentParams.ts b/src/libs/API/parameters/CreateWorkspaceFromIOUPaymentParams.ts new file mode 100644 index 000000000000..761a6c2f5008 --- /dev/null +++ b/src/libs/API/parameters/CreateWorkspaceFromIOUPaymentParams.ts @@ -0,0 +1,20 @@ +type CreateWorkspaceFromIOUPaymentParams = { + policyID: string; + announceChatReportID: string; + adminsChatReportID: string; + expenseChatReportID: string; + ownerEmail: string; + makeMeAdmin: boolean; + policyName: string; + type: string; + announceCreatedReportActionID: string; + adminsCreatedReportActionID: string; + expenseCreatedReportActionID: string; + customUnitID: string; + customUnitRateID: string; + iouReportID: string; + memberData: string; + reportActionID: string; +}; + +export default CreateWorkspaceFromIOUPaymentParams; diff --git a/src/libs/API/parameters/CreateWorkspaceParams.ts b/src/libs/API/parameters/CreateWorkspaceParams.ts new file mode 100644 index 000000000000..c86598b48953 --- /dev/null +++ b/src/libs/API/parameters/CreateWorkspaceParams.ts @@ -0,0 +1,17 @@ +type CreateWorkspaceParams = { + policyID: string; + announceChatReportID: string; + adminsChatReportID: string; + expenseChatReportID: string; + ownerEmail: string; + makeMeAdmin: boolean; + policyName: string; + type: string; + announceCreatedReportActionID: string; + adminsCreatedReportActionID: string; + expenseCreatedReportActionID: string; + customUnitID: string; + customUnitRateID: string; +}; + +export default CreateWorkspaceParams; diff --git a/src/libs/API/parameters/DeleteCommentParams.ts b/src/libs/API/parameters/DeleteCommentParams.ts new file mode 100644 index 000000000000..d51546eec86f --- /dev/null +++ b/src/libs/API/parameters/DeleteCommentParams.ts @@ -0,0 +1,6 @@ +type DeleteCommentParams = { + reportID: string; + reportActionID: string; +}; + +export default DeleteCommentParams; diff --git a/src/libs/API/parameters/DeleteContactMethodParams.ts b/src/libs/API/parameters/DeleteContactMethodParams.ts new file mode 100644 index 000000000000..274c3ba73512 --- /dev/null +++ b/src/libs/API/parameters/DeleteContactMethodParams.ts @@ -0,0 +1,3 @@ +type DeleteContactMethodParams = {partnerUserID: string}; + +export default DeleteContactMethodParams; diff --git a/src/libs/API/parameters/DeleteMembersFromWorkspaceParams.ts b/src/libs/API/parameters/DeleteMembersFromWorkspaceParams.ts new file mode 100644 index 000000000000..6566d2b917b4 --- /dev/null +++ b/src/libs/API/parameters/DeleteMembersFromWorkspaceParams.ts @@ -0,0 +1,6 @@ +type DeleteMembersFromWorkspaceParams = { + emailList: string; + policyID: string; +}; + +export default DeleteMembersFromWorkspaceParams; diff --git a/src/libs/API/parameters/DeletePaymentBankAccountParams.ts b/src/libs/API/parameters/DeletePaymentBankAccountParams.ts new file mode 100644 index 000000000000..737a61ccc16b --- /dev/null +++ b/src/libs/API/parameters/DeletePaymentBankAccountParams.ts @@ -0,0 +1,3 @@ +type DeletePaymentBankAccountParams = {bankAccountID: number}; + +export default DeletePaymentBankAccountParams; diff --git a/src/libs/API/parameters/DeletePaymentCardParams.ts b/src/libs/API/parameters/DeletePaymentCardParams.ts new file mode 100644 index 000000000000..e82edfbf525a --- /dev/null +++ b/src/libs/API/parameters/DeletePaymentCardParams.ts @@ -0,0 +1,4 @@ +type DeletePaymentCardParams = { + fundID: number; +}; +export default DeletePaymentCardParams; diff --git a/src/libs/API/parameters/DeleteWorkspaceAvatarParams.ts b/src/libs/API/parameters/DeleteWorkspaceAvatarParams.ts new file mode 100644 index 000000000000..1e0c26fbb49c --- /dev/null +++ b/src/libs/API/parameters/DeleteWorkspaceAvatarParams.ts @@ -0,0 +1,5 @@ +type DeleteWorkspaceAvatarParams = { + policyID: string; +}; + +export default DeleteWorkspaceAvatarParams; diff --git a/src/libs/API/parameters/DeleteWorkspaceParams.ts b/src/libs/API/parameters/DeleteWorkspaceParams.ts new file mode 100644 index 000000000000..c535e8123d25 --- /dev/null +++ b/src/libs/API/parameters/DeleteWorkspaceParams.ts @@ -0,0 +1,5 @@ +type DeleteWorkspaceParams = { + policyID: string; +}; + +export default DeleteWorkspaceParams; diff --git a/src/libs/API/parameters/EditTaskAssigneeParams.ts b/src/libs/API/parameters/EditTaskAssigneeParams.ts new file mode 100644 index 000000000000..cfac73067587 --- /dev/null +++ b/src/libs/API/parameters/EditTaskAssigneeParams.ts @@ -0,0 +1,10 @@ +type EditTaskAssigneeParams = { + taskReportID?: string; + assignee?: string; + editedTaskReportActionID?: string; + assigneeChatReportID?: string; + assigneeChatReportActionID?: string; + assigneeChatCreatedReportActionID?: string; +}; + +export default EditTaskAssigneeParams; diff --git a/src/libs/API/parameters/EditTaskParams.ts b/src/libs/API/parameters/EditTaskParams.ts new file mode 100644 index 000000000000..01595b7928c5 --- /dev/null +++ b/src/libs/API/parameters/EditTaskParams.ts @@ -0,0 +1,8 @@ +type EditTaskParams = { + taskReportID?: string; + title?: string; + description?: string; + editedTaskReportActionID?: string; +}; + +export default EditTaskParams; diff --git a/src/libs/API/parameters/ExpandURLPreviewParams.ts b/src/libs/API/parameters/ExpandURLPreviewParams.ts new file mode 100644 index 000000000000..1b0e7e6fc78d --- /dev/null +++ b/src/libs/API/parameters/ExpandURLPreviewParams.ts @@ -0,0 +1,6 @@ +type ExpandURLPreviewParams = { + reportID: string; + reportActionID: string; +}; + +export default ExpandURLPreviewParams; diff --git a/src/libs/API/parameters/FlagCommentParams.ts b/src/libs/API/parameters/FlagCommentParams.ts new file mode 100644 index 000000000000..1789ffb16c8c --- /dev/null +++ b/src/libs/API/parameters/FlagCommentParams.ts @@ -0,0 +1,7 @@ +type FlagCommentParams = { + severity: string; + reportActionID: string; + isDevRequest: boolean; +}; + +export default FlagCommentParams; diff --git a/src/libs/API/parameters/GetMissingOnyxMessagesParams.ts b/src/libs/API/parameters/GetMissingOnyxMessagesParams.ts new file mode 100644 index 000000000000..38df5a37ba97 --- /dev/null +++ b/src/libs/API/parameters/GetMissingOnyxMessagesParams.ts @@ -0,0 +1,6 @@ +type GetMissingOnyxMessagesParams = { + updateIDFrom: number; + updateIDTo: number | string; +}; + +export default GetMissingOnyxMessagesParams; diff --git a/src/libs/API/parameters/GetNewerActionsParams.ts b/src/libs/API/parameters/GetNewerActionsParams.ts new file mode 100644 index 000000000000..76ab1938b640 --- /dev/null +++ b/src/libs/API/parameters/GetNewerActionsParams.ts @@ -0,0 +1,6 @@ +type GetNewerActionsParams = { + reportID: string; + reportActionID: string; +}; + +export default GetNewerActionsParams; diff --git a/src/libs/API/parameters/GetOlderActionsParams.ts b/src/libs/API/parameters/GetOlderActionsParams.ts new file mode 100644 index 000000000000..4e585ba8afdd --- /dev/null +++ b/src/libs/API/parameters/GetOlderActionsParams.ts @@ -0,0 +1,6 @@ +type GetOlderActionsParams = { + reportID: string; + reportActionID: string; +}; + +export default GetOlderActionsParams; diff --git a/src/libs/API/parameters/GetReportPrivateNoteParams.ts b/src/libs/API/parameters/GetReportPrivateNoteParams.ts new file mode 100644 index 000000000000..3e52119c164f --- /dev/null +++ b/src/libs/API/parameters/GetReportPrivateNoteParams.ts @@ -0,0 +1,5 @@ +type GetReportPrivateNoteParams = { + reportID: string; +}; + +export default GetReportPrivateNoteParams; diff --git a/src/libs/API/parameters/GetRouteForDraftParams.ts b/src/libs/API/parameters/GetRouteForDraftParams.ts new file mode 100644 index 000000000000..5a213c3f2d49 --- /dev/null +++ b/src/libs/API/parameters/GetRouteForDraftParams.ts @@ -0,0 +1,6 @@ +type GetRouteForDraftParams = { + transactionID: string; + waypoints: string; +}; + +export default GetRouteForDraftParams; diff --git a/src/libs/API/parameters/GetRouteParams.ts b/src/libs/API/parameters/GetRouteParams.ts new file mode 100644 index 000000000000..d6ff7b972e0d --- /dev/null +++ b/src/libs/API/parameters/GetRouteParams.ts @@ -0,0 +1,6 @@ +type GetRouteParams = { + transactionID: string; + waypoints: string; +}; + +export default GetRouteParams; diff --git a/src/libs/API/parameters/GetStatementPDFParams.ts b/src/libs/API/parameters/GetStatementPDFParams.ts new file mode 100644 index 000000000000..3fa8bb732531 --- /dev/null +++ b/src/libs/API/parameters/GetStatementPDFParams.ts @@ -0,0 +1,5 @@ +type GetStatementPDFParams = { + period: string; +}; + +export default GetStatementPDFParams; diff --git a/src/libs/API/parameters/HandleRestrictedEventParams.ts b/src/libs/API/parameters/HandleRestrictedEventParams.ts new file mode 100644 index 000000000000..808220f07747 --- /dev/null +++ b/src/libs/API/parameters/HandleRestrictedEventParams.ts @@ -0,0 +1,5 @@ +type HandleRestrictedEventParams = { + eventName: string; +}; + +export default HandleRestrictedEventParams; diff --git a/src/libs/API/parameters/InviteToRoomParams.ts b/src/libs/API/parameters/InviteToRoomParams.ts new file mode 100644 index 000000000000..b1af3a4fc3df --- /dev/null +++ b/src/libs/API/parameters/InviteToRoomParams.ts @@ -0,0 +1,6 @@ +type InviteToRoomParams = { + reportID: string; + inviteeEmails: string[]; +}; + +export default InviteToRoomParams; diff --git a/src/libs/API/parameters/LeaveRoomParams.ts b/src/libs/API/parameters/LeaveRoomParams.ts new file mode 100644 index 000000000000..0d0483eca88a --- /dev/null +++ b/src/libs/API/parameters/LeaveRoomParams.ts @@ -0,0 +1,5 @@ +type LeaveRoomParams = { + reportID: string; +}; + +export default LeaveRoomParams; diff --git a/src/libs/API/parameters/LogOutParams.ts b/src/libs/API/parameters/LogOutParams.ts new file mode 100644 index 000000000000..7cb81080b19f --- /dev/null +++ b/src/libs/API/parameters/LogOutParams.ts @@ -0,0 +1,9 @@ +type LogOutParams = { + authToken: string | null; + partnerUserID: string; + partnerName: string; + partnerPassword: string; + shouldRetry: boolean; +}; + +export default LogOutParams; diff --git a/src/libs/API/parameters/MakeDefaultPaymentMethodParams.ts b/src/libs/API/parameters/MakeDefaultPaymentMethodParams.ts new file mode 100644 index 000000000000..9cc07214845c --- /dev/null +++ b/src/libs/API/parameters/MakeDefaultPaymentMethodParams.ts @@ -0,0 +1,5 @@ +type MakeDefaultPaymentMethodParams = { + bankAccountID: number; + fundID: number; +}; +export default MakeDefaultPaymentMethodParams; diff --git a/src/libs/API/parameters/MarkAsUnreadParams.ts b/src/libs/API/parameters/MarkAsUnreadParams.ts new file mode 100644 index 000000000000..0a4a0d98c18c --- /dev/null +++ b/src/libs/API/parameters/MarkAsUnreadParams.ts @@ -0,0 +1,6 @@ +type MarkAsUnreadParams = { + reportID: string; + lastReadTime: string; +}; + +export default MarkAsUnreadParams; diff --git a/src/libs/API/parameters/OpenAppParams.ts b/src/libs/API/parameters/OpenAppParams.ts new file mode 100644 index 000000000000..ac0100109c51 --- /dev/null +++ b/src/libs/API/parameters/OpenAppParams.ts @@ -0,0 +1,6 @@ +type OpenAppParams = { + policyIDList: string[]; + enablePriorityModeFilter: boolean; +}; + +export default OpenAppParams; diff --git a/src/libs/API/parameters/OpenDraftWorkspaceRequestParams.ts b/src/libs/API/parameters/OpenDraftWorkspaceRequestParams.ts new file mode 100644 index 000000000000..b9f098da9dae --- /dev/null +++ b/src/libs/API/parameters/OpenDraftWorkspaceRequestParams.ts @@ -0,0 +1,5 @@ +type OpenDraftWorkspaceRequestParams = { + policyID: string; +}; + +export default OpenDraftWorkspaceRequestParams; diff --git a/src/libs/API/parameters/OpenOldDotLinkParams.ts b/src/libs/API/parameters/OpenOldDotLinkParams.ts new file mode 100644 index 000000000000..873b1550368f --- /dev/null +++ b/src/libs/API/parameters/OpenOldDotLinkParams.ts @@ -0,0 +1,5 @@ +type OpenOldDotLinkParams = { + shouldRetry?: boolean; +}; + +export default OpenOldDotLinkParams; diff --git a/src/libs/API/parameters/OpenPlaidBankAccountSelectorParams.ts b/src/libs/API/parameters/OpenPlaidBankAccountSelectorParams.ts new file mode 100644 index 000000000000..c92d72460fa9 --- /dev/null +++ b/src/libs/API/parameters/OpenPlaidBankAccountSelectorParams.ts @@ -0,0 +1,8 @@ +type OpenPlaidBankAccountSelectorParams = { + publicToken: string; + allowDebit: boolean; + bank: string; + bankAccountID: number; +}; + +export default OpenPlaidBankAccountSelectorParams; diff --git a/src/libs/API/parameters/OpenPlaidBankLoginParams.ts b/src/libs/API/parameters/OpenPlaidBankLoginParams.ts new file mode 100644 index 000000000000..f76e05423d03 --- /dev/null +++ b/src/libs/API/parameters/OpenPlaidBankLoginParams.ts @@ -0,0 +1,7 @@ +type OpenPlaidBankLoginParams = { + redirectURI: string | undefined; + allowDebit: boolean; + bankAccountID: number; +}; + +export default OpenPlaidBankLoginParams; diff --git a/src/libs/API/parameters/OpenProfileParams.ts b/src/libs/API/parameters/OpenProfileParams.ts new file mode 100644 index 000000000000..f42ea8234fc8 --- /dev/null +++ b/src/libs/API/parameters/OpenProfileParams.ts @@ -0,0 +1,5 @@ +type OpenProfileParams = { + timezone: string; +}; + +export default OpenProfileParams; diff --git a/src/libs/API/parameters/OpenPublicProfilePageParams.ts b/src/libs/API/parameters/OpenPublicProfilePageParams.ts new file mode 100644 index 000000000000..3bb50c563e28 --- /dev/null +++ b/src/libs/API/parameters/OpenPublicProfilePageParams.ts @@ -0,0 +1,5 @@ +type OpenPublicProfilePageParams = { + accountID: number; +}; + +export default OpenPublicProfilePageParams; diff --git a/src/libs/API/parameters/OpenReimbursementAccountPageParams.ts b/src/libs/API/parameters/OpenReimbursementAccountPageParams.ts new file mode 100644 index 000000000000..d831609b2e0a --- /dev/null +++ b/src/libs/API/parameters/OpenReimbursementAccountPageParams.ts @@ -0,0 +1,12 @@ +import type {BankAccountStep, BankAccountSubStep} from '@src/types/onyx/ReimbursementAccount'; + +type ReimbursementAccountStep = BankAccountStep | ''; +type ReimbursementAccountSubStep = BankAccountSubStep | ''; + +type OpenReimbursementAccountPageParams = { + stepToOpen: ReimbursementAccountStep; + subStep: ReimbursementAccountSubStep; + localCurrentStep: ReimbursementAccountStep; +}; + +export default OpenReimbursementAccountPageParams; diff --git a/src/libs/API/parameters/OpenReportParams.ts b/src/libs/API/parameters/OpenReportParams.ts new file mode 100644 index 000000000000..477a002516de --- /dev/null +++ b/src/libs/API/parameters/OpenReportParams.ts @@ -0,0 +1,12 @@ +type OpenReportParams = { + reportID: string; + emailList?: string; + accountIDList?: string; + parentReportActionID?: string; + shouldRetry?: boolean; + createdReportActionID?: string; + clientLastReadTime?: string; + idempotencyKey?: string; +}; + +export default OpenReportParams; diff --git a/src/libs/API/parameters/OpenRoomMembersPageParams.ts b/src/libs/API/parameters/OpenRoomMembersPageParams.ts new file mode 100644 index 000000000000..7ea1afb9bdb9 --- /dev/null +++ b/src/libs/API/parameters/OpenRoomMembersPageParams.ts @@ -0,0 +1,5 @@ +type OpenRoomMembersPageParams = { + reportID: string; +}; + +export default OpenRoomMembersPageParams; diff --git a/src/libs/API/parameters/OpenWorkspaceInvitePageParams.ts b/src/libs/API/parameters/OpenWorkspaceInvitePageParams.ts new file mode 100644 index 000000000000..0b622bee75b7 --- /dev/null +++ b/src/libs/API/parameters/OpenWorkspaceInvitePageParams.ts @@ -0,0 +1,6 @@ +type OpenWorkspaceInvitePageParams = { + policyID: string; + clientMemberEmails: string; +}; + +export default OpenWorkspaceInvitePageParams; diff --git a/src/libs/API/parameters/OpenWorkspaceMembersPageParams.ts b/src/libs/API/parameters/OpenWorkspaceMembersPageParams.ts new file mode 100644 index 000000000000..2dab31ac356b --- /dev/null +++ b/src/libs/API/parameters/OpenWorkspaceMembersPageParams.ts @@ -0,0 +1,6 @@ +type OpenWorkspaceMembersPageParams = { + policyID: string; + clientMemberEmails: string; +}; + +export default OpenWorkspaceMembersPageParams; diff --git a/src/libs/API/parameters/OpenWorkspaceParams.ts b/src/libs/API/parameters/OpenWorkspaceParams.ts new file mode 100644 index 000000000000..3ea0d4b3dabe --- /dev/null +++ b/src/libs/API/parameters/OpenWorkspaceParams.ts @@ -0,0 +1,6 @@ +type OpenWorkspaceParams = { + policyID: string; + clientMemberAccountIDs: string; +}; + +export default OpenWorkspaceParams; diff --git a/src/libs/API/parameters/OpenWorkspaceReimburseViewParams.ts b/src/libs/API/parameters/OpenWorkspaceReimburseViewParams.ts new file mode 100644 index 000000000000..317241c8842f --- /dev/null +++ b/src/libs/API/parameters/OpenWorkspaceReimburseViewParams.ts @@ -0,0 +1,5 @@ +type OpenWorkspaceReimburseViewParams = { + policyID: string; +}; + +export default OpenWorkspaceReimburseViewParams; diff --git a/src/libs/API/parameters/OptInOutToPushNotificationsParams.ts b/src/libs/API/parameters/OptInOutToPushNotificationsParams.ts new file mode 100644 index 000000000000..758152abc2af --- /dev/null +++ b/src/libs/API/parameters/OptInOutToPushNotificationsParams.ts @@ -0,0 +1,5 @@ +type OptInOutToPushNotificationsParams = { + deviceID: string | null; +}; + +export default OptInOutToPushNotificationsParams; diff --git a/src/libs/API/parameters/PaymentCardParams.ts b/src/libs/API/parameters/PaymentCardParams.ts new file mode 100644 index 000000000000..3e705994e9fa --- /dev/null +++ b/src/libs/API/parameters/PaymentCardParams.ts @@ -0,0 +1,3 @@ +type PaymentCardParams = {expirationDate: string; cardNumber: string; securityCode: string; nameOnCard: string; addressZipCode: string}; + +export default PaymentCardParams; diff --git a/src/libs/API/parameters/ReadNewestActionParams.ts b/src/libs/API/parameters/ReadNewestActionParams.ts new file mode 100644 index 000000000000..590dfce25a4e --- /dev/null +++ b/src/libs/API/parameters/ReadNewestActionParams.ts @@ -0,0 +1,6 @@ +type ReadNewestActionParams = { + reportID: string; + lastReadTime: string; +}; + +export default ReadNewestActionParams; diff --git a/src/libs/API/parameters/ReconnectAppParams.ts b/src/libs/API/parameters/ReconnectAppParams.ts new file mode 100644 index 000000000000..8c5b7d6c0da9 --- /dev/null +++ b/src/libs/API/parameters/ReconnectAppParams.ts @@ -0,0 +1,7 @@ +type ReconnectAppParams = { + mostRecentReportActionLastModified?: string; + updateIDFrom?: number; + policyIDList: string[]; +}; + +export default ReconnectAppParams; diff --git a/src/libs/API/parameters/ReconnectToReportParams.ts b/src/libs/API/parameters/ReconnectToReportParams.ts new file mode 100644 index 000000000000..e7701cd36ca9 --- /dev/null +++ b/src/libs/API/parameters/ReconnectToReportParams.ts @@ -0,0 +1,5 @@ +type ReconnectToReportParams = { + reportID: string; +}; + +export default ReconnectToReportParams; diff --git a/src/libs/API/parameters/ReferTeachersUniteVolunteerParams.ts b/src/libs/API/parameters/ReferTeachersUniteVolunteerParams.ts new file mode 100644 index 000000000000..0eb31c47865d --- /dev/null +++ b/src/libs/API/parameters/ReferTeachersUniteVolunteerParams.ts @@ -0,0 +1,8 @@ +type ReferTeachersUniteVolunteerParams = { + reportID: string; + firstName: string; + lastName: string; + partnerUserID: string; +}; + +export default ReferTeachersUniteVolunteerParams; diff --git a/src/libs/API/parameters/RemoveEmojiReactionParams.ts b/src/libs/API/parameters/RemoveEmojiReactionParams.ts new file mode 100644 index 000000000000..5d474dff713b --- /dev/null +++ b/src/libs/API/parameters/RemoveEmojiReactionParams.ts @@ -0,0 +1,8 @@ +type RemoveEmojiReactionParams = { + reportID: string; + reportActionID: string; + emojiCode: string; + useEmojiReactions: boolean; +}; + +export default RemoveEmojiReactionParams; diff --git a/src/libs/API/parameters/RemoveFromRoomParams.ts b/src/libs/API/parameters/RemoveFromRoomParams.ts new file mode 100644 index 000000000000..6bf94a534dbd --- /dev/null +++ b/src/libs/API/parameters/RemoveFromRoomParams.ts @@ -0,0 +1,6 @@ +type RemoveFromRoomParams = { + reportID: string; + targetAccountIDs: number[]; +}; + +export default RemoveFromRoomParams; diff --git a/src/libs/API/parameters/ReopenTaskParams.ts b/src/libs/API/parameters/ReopenTaskParams.ts new file mode 100644 index 000000000000..ecdff74504f7 --- /dev/null +++ b/src/libs/API/parameters/ReopenTaskParams.ts @@ -0,0 +1,6 @@ +type ReopenTaskParams = { + taskReportID?: string; + reopenedTaskReportActionID?: string; +}; + +export default ReopenTaskParams; diff --git a/src/libs/API/parameters/ReportVirtualExpensifyCardFraudParams.ts b/src/libs/API/parameters/ReportVirtualExpensifyCardFraudParams.ts new file mode 100644 index 000000000000..350795d46355 --- /dev/null +++ b/src/libs/API/parameters/ReportVirtualExpensifyCardFraudParams.ts @@ -0,0 +1,4 @@ +type ReportVirtualExpensifyCardFraudParams = { + cardID: number; +}; +export default ReportVirtualExpensifyCardFraudParams; diff --git a/src/libs/API/parameters/RequestAccountValidationLinkParams.ts b/src/libs/API/parameters/RequestAccountValidationLinkParams.ts new file mode 100644 index 000000000000..be33c5648685 --- /dev/null +++ b/src/libs/API/parameters/RequestAccountValidationLinkParams.ts @@ -0,0 +1,5 @@ +type RequestAccountValidationLinkParams = { + email?: string; +}; + +export default RequestAccountValidationLinkParams; diff --git a/src/libs/API/parameters/RequestContactMethodValidateCodeParams.ts b/src/libs/API/parameters/RequestContactMethodValidateCodeParams.ts new file mode 100644 index 000000000000..13a26b717619 --- /dev/null +++ b/src/libs/API/parameters/RequestContactMethodValidateCodeParams.ts @@ -0,0 +1,3 @@ +type RequestContactMethodValidateCodeParams = {email: string}; + +export default RequestContactMethodValidateCodeParams; diff --git a/src/libs/API/parameters/RequestNewValidateCodeParams.ts b/src/libs/API/parameters/RequestNewValidateCodeParams.ts new file mode 100644 index 000000000000..329b234023d0 --- /dev/null +++ b/src/libs/API/parameters/RequestNewValidateCodeParams.ts @@ -0,0 +1,5 @@ +type RequestNewValidateCodeParams = { + email?: string; +}; + +export default RequestNewValidateCodeParams; diff --git a/src/libs/API/parameters/RequestPhysicalExpensifyCardParams.ts b/src/libs/API/parameters/RequestPhysicalExpensifyCardParams.ts new file mode 100644 index 000000000000..91995b6e37aa --- /dev/null +++ b/src/libs/API/parameters/RequestPhysicalExpensifyCardParams.ts @@ -0,0 +1,13 @@ +type RequestPhysicalExpensifyCardParams = { + authToken: string; + legalFirstName: string; + legalLastName: string; + phoneNumber: string; + addressCity: string; + addressCountry: string; + addressState: string; + addressStreet: string; + addressZip: string; +}; + +export default RequestPhysicalExpensifyCardParams; diff --git a/src/libs/API/parameters/RequestReplacementExpensifyCardParams.ts b/src/libs/API/parameters/RequestReplacementExpensifyCardParams.ts new file mode 100644 index 000000000000..bc86923a83a4 --- /dev/null +++ b/src/libs/API/parameters/RequestReplacementExpensifyCardParams.ts @@ -0,0 +1,6 @@ +type RequestReplacementExpensifyCardParams = { + cardID: number; + reason: string; +}; + +export default RequestReplacementExpensifyCardParams; diff --git a/src/libs/API/parameters/RequestUnlinkValidationLinkParams.ts b/src/libs/API/parameters/RequestUnlinkValidationLinkParams.ts new file mode 100644 index 000000000000..2a37f7119304 --- /dev/null +++ b/src/libs/API/parameters/RequestUnlinkValidationLinkParams.ts @@ -0,0 +1,5 @@ +type RequestUnlinkValidationLinkParams = { + email?: string; +}; + +export default RequestUnlinkValidationLinkParams; diff --git a/src/libs/API/parameters/ResolveActionableMentionWhisperParams.ts b/src/libs/API/parameters/ResolveActionableMentionWhisperParams.ts new file mode 100644 index 000000000000..87dfc934eb5f --- /dev/null +++ b/src/libs/API/parameters/ResolveActionableMentionWhisperParams.ts @@ -0,0 +1,9 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type ResolveActionableMentionWhisperParams = { + reportActionID: string; + resolution: ValueOf; +}; + +export default ResolveActionableMentionWhisperParams; diff --git a/src/libs/API/parameters/RevealExpensifyCardDetailsParams.ts b/src/libs/API/parameters/RevealExpensifyCardDetailsParams.ts new file mode 100644 index 000000000000..ec698fc85269 --- /dev/null +++ b/src/libs/API/parameters/RevealExpensifyCardDetailsParams.ts @@ -0,0 +1,3 @@ +type RevealExpensifyCardDetailsParams = {cardID: number}; + +export default RevealExpensifyCardDetailsParams; diff --git a/src/libs/API/parameters/SearchForReportsParams.ts b/src/libs/API/parameters/SearchForReportsParams.ts new file mode 100644 index 000000000000..b6d1bbadb1dc --- /dev/null +++ b/src/libs/API/parameters/SearchForReportsParams.ts @@ -0,0 +1,5 @@ +type SearchForReportsParams = { + searchInput: string; +}; + +export default SearchForReportsParams; diff --git a/src/libs/API/parameters/SendPerformanceTimingParams.ts b/src/libs/API/parameters/SendPerformanceTimingParams.ts new file mode 100644 index 000000000000..aebdaa40c8bb --- /dev/null +++ b/src/libs/API/parameters/SendPerformanceTimingParams.ts @@ -0,0 +1,7 @@ +type SendPerformanceTimingParams = { + name: string; + value: number; + platform: string; +}; + +export default SendPerformanceTimingParams; diff --git a/src/libs/API/parameters/SetContactMethodAsDefaultParams.ts b/src/libs/API/parameters/SetContactMethodAsDefaultParams.ts new file mode 100644 index 000000000000..03a33eb81c36 --- /dev/null +++ b/src/libs/API/parameters/SetContactMethodAsDefaultParams.ts @@ -0,0 +1,5 @@ +type SetContactMethodAsDefaultParams = { + partnerUserID: string; +}; + +export default SetContactMethodAsDefaultParams; diff --git a/src/libs/API/parameters/SetNameValuePairParams.ts b/src/libs/API/parameters/SetNameValuePairParams.ts new file mode 100644 index 000000000000..bc83d431224b --- /dev/null +++ b/src/libs/API/parameters/SetNameValuePairParams.ts @@ -0,0 +1,6 @@ +type SetNameValuePairParams = { + name: string; + value: boolean; +}; + +export default SetNameValuePairParams; diff --git a/src/libs/API/parameters/SignInUserParams.ts b/src/libs/API/parameters/SignInUserParams.ts new file mode 100644 index 000000000000..9fe973c42862 --- /dev/null +++ b/src/libs/API/parameters/SignInUserParams.ts @@ -0,0 +1,12 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type SignInUserParams = { + twoFactorAuthCode?: string; + email?: string; + preferredLocale: ValueOf | null; + validateCode?: string; + deviceInfo: string; +}; + +export default SignInUserParams; diff --git a/src/libs/API/parameters/SignInUserWithLinkParams.ts b/src/libs/API/parameters/SignInUserWithLinkParams.ts new file mode 100644 index 000000000000..ae3589d4e305 --- /dev/null +++ b/src/libs/API/parameters/SignInUserWithLinkParams.ts @@ -0,0 +1,12 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type SignInUserWithLinkParams = { + accountID: number; + validateCode?: string; + twoFactorAuthCode?: string; + preferredLocale: ValueOf | null; + deviceInfo: string; +}; + +export default SignInUserWithLinkParams; diff --git a/src/libs/API/parameters/SignInWithShortLivedAuthTokenParams.ts b/src/libs/API/parameters/SignInWithShortLivedAuthTokenParams.ts new file mode 100644 index 000000000000..447c0ede0399 --- /dev/null +++ b/src/libs/API/parameters/SignInWithShortLivedAuthTokenParams.ts @@ -0,0 +1,7 @@ +type SignInWithShortLivedAuthTokenParams = { + authToken: string; + oldPartnerUserID: string; + skipReauthentication: boolean; +}; + +export default SignInWithShortLivedAuthTokenParams; diff --git a/src/libs/API/parameters/TogglePinnedChatParams.ts b/src/libs/API/parameters/TogglePinnedChatParams.ts new file mode 100644 index 000000000000..338a77172dd6 --- /dev/null +++ b/src/libs/API/parameters/TogglePinnedChatParams.ts @@ -0,0 +1,6 @@ +type TogglePinnedChatParams = { + reportID: string; + pinnedValue: boolean; +}; + +export default TogglePinnedChatParams; diff --git a/src/libs/API/parameters/TransferWalletBalanceParams.ts b/src/libs/API/parameters/TransferWalletBalanceParams.ts new file mode 100644 index 000000000000..c25268d92bf3 --- /dev/null +++ b/src/libs/API/parameters/TransferWalletBalanceParams.ts @@ -0,0 +1,6 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type TransferWalletBalanceParams = Partial, number | undefined>>; + +export default TransferWalletBalanceParams; diff --git a/src/libs/API/parameters/UnlinkLoginParams.ts b/src/libs/API/parameters/UnlinkLoginParams.ts new file mode 100644 index 000000000000..1a60e480bb18 --- /dev/null +++ b/src/libs/API/parameters/UnlinkLoginParams.ts @@ -0,0 +1,6 @@ +type UnlinkLoginParams = { + accountID: number; + validateCode: string; +}; + +export default UnlinkLoginParams; diff --git a/src/libs/API/parameters/UpdateAutomaticTimezoneParams.ts b/src/libs/API/parameters/UpdateAutomaticTimezoneParams.ts new file mode 100644 index 000000000000..07c13e0cf55e --- /dev/null +++ b/src/libs/API/parameters/UpdateAutomaticTimezoneParams.ts @@ -0,0 +1,4 @@ +type UpdateAutomaticTimezoneParams = { + timezone: string; +}; +export default UpdateAutomaticTimezoneParams; diff --git a/src/libs/API/parameters/UpdateBeneficialOwnersForBankAccountParams.ts b/src/libs/API/parameters/UpdateBeneficialOwnersForBankAccountParams.ts new file mode 100644 index 000000000000..414c87ee8989 --- /dev/null +++ b/src/libs/API/parameters/UpdateBeneficialOwnersForBankAccountParams.ts @@ -0,0 +1,5 @@ +import type {ACHContractStepProps} from '@src/types/onyx/ReimbursementAccountDraft'; + +type UpdateBeneficialOwnersForBankAccountParams = ACHContractStepProps; + +export default UpdateBeneficialOwnersForBankAccountParams; diff --git a/src/libs/API/parameters/UpdateChatPriorityModeParams.ts b/src/libs/API/parameters/UpdateChatPriorityModeParams.ts new file mode 100644 index 000000000000..8bbb7bf6943c --- /dev/null +++ b/src/libs/API/parameters/UpdateChatPriorityModeParams.ts @@ -0,0 +1,9 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type UpdateChatPriorityModeParams = { + value: ValueOf; + automatic: boolean; +}; + +export default UpdateChatPriorityModeParams; diff --git a/src/libs/API/parameters/UpdateCommentParams.ts b/src/libs/API/parameters/UpdateCommentParams.ts new file mode 100644 index 000000000000..e4ba9391ccd4 --- /dev/null +++ b/src/libs/API/parameters/UpdateCommentParams.ts @@ -0,0 +1,7 @@ +type UpdateCommentParams = { + reportID: string; + reportComment: string; + reportActionID: string; +}; + +export default UpdateCommentParams; diff --git a/src/libs/API/parameters/UpdateCompanyInformationForBankAccountParams.ts b/src/libs/API/parameters/UpdateCompanyInformationForBankAccountParams.ts new file mode 100644 index 000000000000..7588039a9abf --- /dev/null +++ b/src/libs/API/parameters/UpdateCompanyInformationForBankAccountParams.ts @@ -0,0 +1,8 @@ +import type {BankAccountStepProps, CompanyStepProps, ReimbursementAccountProps} from '@src/types/onyx/ReimbursementAccountDraft'; + +type BankAccountCompanyInformation = BankAccountStepProps & CompanyStepProps & ReimbursementAccountProps; + +type UpdateCompanyInformationForBankAccountParams = BankAccountCompanyInformation & {policyID: string}; + +export default UpdateCompanyInformationForBankAccountParams; +export type {BankAccountCompanyInformation}; diff --git a/src/libs/API/parameters/UpdateDateOfBirthParams.ts b/src/libs/API/parameters/UpdateDateOfBirthParams.ts new file mode 100644 index 000000000000..e98336d16bff --- /dev/null +++ b/src/libs/API/parameters/UpdateDateOfBirthParams.ts @@ -0,0 +1,4 @@ +type UpdateDateOfBirthParams = { + dob?: string; +}; +export default UpdateDateOfBirthParams; diff --git a/src/libs/API/parameters/UpdateDisplayNameParams.ts b/src/libs/API/parameters/UpdateDisplayNameParams.ts new file mode 100644 index 000000000000..0febd6765fc0 --- /dev/null +++ b/src/libs/API/parameters/UpdateDisplayNameParams.ts @@ -0,0 +1,5 @@ +type UpdateDisplayNameParams = { + firstName: string; + lastName: string; +}; +export default UpdateDisplayNameParams; diff --git a/src/libs/API/parameters/UpdateFrequentlyUsedEmojisParams.ts b/src/libs/API/parameters/UpdateFrequentlyUsedEmojisParams.ts new file mode 100644 index 000000000000..f790ada3aad9 --- /dev/null +++ b/src/libs/API/parameters/UpdateFrequentlyUsedEmojisParams.ts @@ -0,0 +1,3 @@ +type UpdateFrequentlyUsedEmojisParams = {value: string}; + +export default UpdateFrequentlyUsedEmojisParams; diff --git a/src/libs/API/parameters/UpdateHomeAddressParams.ts b/src/libs/API/parameters/UpdateHomeAddressParams.ts new file mode 100644 index 000000000000..7de71fe67c58 --- /dev/null +++ b/src/libs/API/parameters/UpdateHomeAddressParams.ts @@ -0,0 +1,11 @@ +type UpdateHomeAddressParams = { + homeAddressStreet: string; + addressStreet2: string; + homeAddressCity: string; + addressState: string; + addressZipCode: string; + addressCountry: string; + addressStateLong?: string; +}; + +export default UpdateHomeAddressParams; diff --git a/src/libs/API/parameters/UpdateLegalNameParams.ts b/src/libs/API/parameters/UpdateLegalNameParams.ts new file mode 100644 index 000000000000..2c55cec13cc4 --- /dev/null +++ b/src/libs/API/parameters/UpdateLegalNameParams.ts @@ -0,0 +1,6 @@ +type UpdateLegalNameParams = { + legalFirstName: string; + legalLastName: string; +}; + +export default UpdateLegalNameParams; diff --git a/src/libs/API/parameters/UpdateNewsletterSubscriptionParams.ts b/src/libs/API/parameters/UpdateNewsletterSubscriptionParams.ts new file mode 100644 index 000000000000..311d3a5518df --- /dev/null +++ b/src/libs/API/parameters/UpdateNewsletterSubscriptionParams.ts @@ -0,0 +1,3 @@ +type UpdateNewsletterSubscriptionParams = {isSubscribed: boolean}; + +export default UpdateNewsletterSubscriptionParams; diff --git a/src/libs/API/parameters/UpdatePersonalDetailsForWalletParams.ts b/src/libs/API/parameters/UpdatePersonalDetailsForWalletParams.ts new file mode 100644 index 000000000000..d874dced4a92 --- /dev/null +++ b/src/libs/API/parameters/UpdatePersonalDetailsForWalletParams.ts @@ -0,0 +1,13 @@ +type UpdatePersonalDetailsForWalletParams = { + phoneNumber: string; + legalFirstName: string; + legalLastName: string; + addressStreet: string; + addressCity: string; + addressState: string; + addressZip: string; + dob: string; + ssn: string; +}; + +export default UpdatePersonalDetailsForWalletParams; diff --git a/src/libs/API/parameters/UpdatePersonalInformationForBankAccountParams.ts b/src/libs/API/parameters/UpdatePersonalInformationForBankAccountParams.ts new file mode 100644 index 000000000000..4de2e462fc7a --- /dev/null +++ b/src/libs/API/parameters/UpdatePersonalInformationForBankAccountParams.ts @@ -0,0 +1,5 @@ +import type {RequestorStepProps} from '@src/types/onyx/ReimbursementAccountDraft'; + +type UpdatePersonalInformationForBankAccountParams = RequestorStepProps; + +export default UpdatePersonalInformationForBankAccountParams; diff --git a/src/libs/API/parameters/UpdatePolicyRoomNameParams.ts b/src/libs/API/parameters/UpdatePolicyRoomNameParams.ts new file mode 100644 index 000000000000..65b858b7c20f --- /dev/null +++ b/src/libs/API/parameters/UpdatePolicyRoomNameParams.ts @@ -0,0 +1,6 @@ +type UpdatePolicyRoomNameParams = { + reportID: string; + policyRoomName: string; +}; + +export default UpdatePolicyRoomNameParams; diff --git a/src/libs/API/parameters/UpdatePreferredEmojiSkinToneParams.ts b/src/libs/API/parameters/UpdatePreferredEmojiSkinToneParams.ts new file mode 100644 index 000000000000..a769e3635bfa --- /dev/null +++ b/src/libs/API/parameters/UpdatePreferredEmojiSkinToneParams.ts @@ -0,0 +1,5 @@ +type UpdatePreferredEmojiSkinToneParams = { + value: number; +}; + +export default UpdatePreferredEmojiSkinToneParams; diff --git a/src/libs/API/parameters/UpdatePreferredLocaleParams.ts b/src/libs/API/parameters/UpdatePreferredLocaleParams.ts new file mode 100644 index 000000000000..5dd991dea3b5 --- /dev/null +++ b/src/libs/API/parameters/UpdatePreferredLocaleParams.ts @@ -0,0 +1,10 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; + +type Locale = ValueOf; + +type UpdatePreferredLocaleParams = { + value: Locale; +}; + +export default UpdatePreferredLocaleParams; diff --git a/src/libs/API/parameters/UpdatePronounsParams.ts b/src/libs/API/parameters/UpdatePronounsParams.ts new file mode 100644 index 000000000000..f7ac30a5b2ef --- /dev/null +++ b/src/libs/API/parameters/UpdatePronounsParams.ts @@ -0,0 +1,5 @@ +type UpdatePronounsParams = { + pronouns: string; +}; + +export default UpdatePronounsParams; diff --git a/src/libs/API/parameters/UpdateReportNotificationPreferenceParams.ts b/src/libs/API/parameters/UpdateReportNotificationPreferenceParams.ts new file mode 100644 index 000000000000..c58746b316fe --- /dev/null +++ b/src/libs/API/parameters/UpdateReportNotificationPreferenceParams.ts @@ -0,0 +1,8 @@ +import type {NotificationPreference} from '@src/types/onyx/Report'; + +type UpdateReportNotificationPreferenceParams = { + reportID: string; + notificationPreference: NotificationPreference; +}; + +export default UpdateReportNotificationPreferenceParams; diff --git a/src/libs/API/parameters/UpdateReportPrivateNoteParams.ts b/src/libs/API/parameters/UpdateReportPrivateNoteParams.ts new file mode 100644 index 000000000000..30fad3bec3ab --- /dev/null +++ b/src/libs/API/parameters/UpdateReportPrivateNoteParams.ts @@ -0,0 +1,6 @@ +type UpdateReportPrivateNoteParams = { + reportID: string; + privateNotes: string; +}; + +export default UpdateReportPrivateNoteParams; diff --git a/src/libs/API/parameters/UpdateReportWriteCapabilityParams.ts b/src/libs/API/parameters/UpdateReportWriteCapabilityParams.ts new file mode 100644 index 000000000000..30b85b15aa3b --- /dev/null +++ b/src/libs/API/parameters/UpdateReportWriteCapabilityParams.ts @@ -0,0 +1,8 @@ +import type {WriteCapability} from '@src/types/onyx/Report'; + +type UpdateReportWriteCapabilityParams = { + reportID: string; + writeCapability: WriteCapability; +}; + +export default UpdateReportWriteCapabilityParams; diff --git a/src/libs/API/parameters/UpdateSelectedTimezoneParams.ts b/src/libs/API/parameters/UpdateSelectedTimezoneParams.ts new file mode 100644 index 000000000000..595e14f7c54c --- /dev/null +++ b/src/libs/API/parameters/UpdateSelectedTimezoneParams.ts @@ -0,0 +1,5 @@ +type UpdateSelectedTimezoneParams = { + timezone: string; +}; + +export default UpdateSelectedTimezoneParams; diff --git a/src/libs/API/parameters/UpdateStatusParams.ts b/src/libs/API/parameters/UpdateStatusParams.ts new file mode 100644 index 000000000000..ba812e554cd7 --- /dev/null +++ b/src/libs/API/parameters/UpdateStatusParams.ts @@ -0,0 +1,7 @@ +type UpdateStatusParams = { + text?: string; + emojiCode: string; + clearAfter?: string; +}; + +export default UpdateStatusParams; diff --git a/src/libs/API/parameters/UpdateThemeParams.ts b/src/libs/API/parameters/UpdateThemeParams.ts new file mode 100644 index 000000000000..10a8c243d6e4 --- /dev/null +++ b/src/libs/API/parameters/UpdateThemeParams.ts @@ -0,0 +1,5 @@ +type UpdateThemeParams = { + value: string; +}; + +export default UpdateThemeParams; diff --git a/src/libs/API/parameters/UpdateUserAvatarParams.ts b/src/libs/API/parameters/UpdateUserAvatarParams.ts new file mode 100644 index 000000000000..2dce38e8763c --- /dev/null +++ b/src/libs/API/parameters/UpdateUserAvatarParams.ts @@ -0,0 +1,7 @@ +import type {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types'; + +type UpdateUserAvatarParams = { + file: File | CustomRNImageManipulatorResult; +}; + +export default UpdateUserAvatarParams; diff --git a/src/libs/API/parameters/UpdateWelcomeMessageParams.ts b/src/libs/API/parameters/UpdateWelcomeMessageParams.ts new file mode 100644 index 000000000000..a2d3b59fe3fa --- /dev/null +++ b/src/libs/API/parameters/UpdateWelcomeMessageParams.ts @@ -0,0 +1,6 @@ +type UpdateWelcomeMessageParams = { + reportID: string; + welcomeMessage: string; +}; + +export default UpdateWelcomeMessageParams; diff --git a/src/libs/API/parameters/UpdateWorkspaceAvatarParams.ts b/src/libs/API/parameters/UpdateWorkspaceAvatarParams.ts new file mode 100644 index 000000000000..a4c1edf83dab --- /dev/null +++ b/src/libs/API/parameters/UpdateWorkspaceAvatarParams.ts @@ -0,0 +1,6 @@ +type UpdateWorkspaceAvatarParams = { + policyID: string; + file: File; +}; + +export default UpdateWorkspaceAvatarParams; diff --git a/src/libs/API/parameters/UpdateWorkspaceCustomUnitAndRateParams.ts b/src/libs/API/parameters/UpdateWorkspaceCustomUnitAndRateParams.ts new file mode 100644 index 000000000000..22bbd20c7308 --- /dev/null +++ b/src/libs/API/parameters/UpdateWorkspaceCustomUnitAndRateParams.ts @@ -0,0 +1,8 @@ +type UpdateWorkspaceCustomUnitAndRateParams = { + policyID: string; + lastModified: number; + customUnit: string; + customUnitRate: string; +}; + +export default UpdateWorkspaceCustomUnitAndRateParams; diff --git a/src/libs/API/parameters/UpdateWorkspaceGeneralSettingsParams.ts b/src/libs/API/parameters/UpdateWorkspaceGeneralSettingsParams.ts new file mode 100644 index 000000000000..9aeb4be97a43 --- /dev/null +++ b/src/libs/API/parameters/UpdateWorkspaceGeneralSettingsParams.ts @@ -0,0 +1,7 @@ +type UpdateWorkspaceGeneralSettingsParams = { + policyID: string; + workspaceName: string; + currency: string; +}; + +export default UpdateWorkspaceGeneralSettingsParams; diff --git a/src/libs/API/parameters/ValidateBankAccountWithTransactionsParams.ts b/src/libs/API/parameters/ValidateBankAccountWithTransactionsParams.ts new file mode 100644 index 000000000000..546889b7a68e --- /dev/null +++ b/src/libs/API/parameters/ValidateBankAccountWithTransactionsParams.ts @@ -0,0 +1,6 @@ +type ValidateBankAccountWithTransactionsParams = { + bankAccountID: number; + validateCode: string; +}; + +export default ValidateBankAccountWithTransactionsParams; diff --git a/src/libs/API/parameters/ValidateLoginParams.ts b/src/libs/API/parameters/ValidateLoginParams.ts new file mode 100644 index 000000000000..361c374e4e32 --- /dev/null +++ b/src/libs/API/parameters/ValidateLoginParams.ts @@ -0,0 +1,6 @@ +type ValidateLoginParams = { + accountID: number; + validateCode: string; +}; + +export default ValidateLoginParams; diff --git a/src/libs/API/parameters/ValidateSecondaryLoginParams.ts b/src/libs/API/parameters/ValidateSecondaryLoginParams.ts new file mode 100644 index 000000000000..870a756da524 --- /dev/null +++ b/src/libs/API/parameters/ValidateSecondaryLoginParams.ts @@ -0,0 +1,3 @@ +type ValidateSecondaryLoginParams = {partnerUserID: string; validateCode: string}; + +export default ValidateSecondaryLoginParams; diff --git a/src/libs/API/parameters/ValidateTwoFactorAuthParams.ts b/src/libs/API/parameters/ValidateTwoFactorAuthParams.ts new file mode 100644 index 000000000000..dad8f53089dd --- /dev/null +++ b/src/libs/API/parameters/ValidateTwoFactorAuthParams.ts @@ -0,0 +1,5 @@ +type ValidateTwoFactorAuthParams = { + twoFactorAuthCode: string; +}; + +export default ValidateTwoFactorAuthParams; diff --git a/src/libs/API/parameters/VerifyIdentityForBankAccountParams.ts b/src/libs/API/parameters/VerifyIdentityForBankAccountParams.ts new file mode 100644 index 000000000000..424cef92c08f --- /dev/null +++ b/src/libs/API/parameters/VerifyIdentityForBankAccountParams.ts @@ -0,0 +1,5 @@ +type VerifyIdentityForBankAccountParams = { + bankAccountID: number; + onfidoData: string; +}; +export default VerifyIdentityForBankAccountParams; diff --git a/src/libs/API/parameters/VerifyIdentityParams.ts b/src/libs/API/parameters/VerifyIdentityParams.ts new file mode 100644 index 000000000000..04ddf17bed87 --- /dev/null +++ b/src/libs/API/parameters/VerifyIdentityParams.ts @@ -0,0 +1,5 @@ +type VerifyIdentityParams = { + onfidoData: string; +}; + +export default VerifyIdentityParams; diff --git a/src/libs/API/parameters/index.ts b/src/libs/API/parameters/index.ts new file mode 100644 index 000000000000..039398c0fbf6 --- /dev/null +++ b/src/libs/API/parameters/index.ts @@ -0,0 +1,124 @@ +export type {default as ActivatePhysicalExpensifyCardParams} from './ActivatePhysicalExpensifyCardParams'; +export type {default as AddNewContactMethodParams} from './AddNewContactMethodParams'; +export type {default as AddPaymentCardParams} from './AddPaymentCardParams'; +export type {default as AddPersonalBankAccountParams} from './AddPersonalBankAccountParams'; +export type {default as AddSchoolPrincipalParams} from './AddSchoolPrincipalParams'; +export type {default as AuthenticatePusherParams} from './AuthenticatePusherParams'; +export type {default as BankAccountHandlePlaidErrorParams} from './BankAccountHandlePlaidErrorParams'; +export type {default as BeginAppleSignInParams} from './BeginAppleSignInParams'; +export type {default as BeginGoogleSignInParams} from './BeginGoogleSignInParams'; +export type {default as BeginSignInParams} from './BeginSignInParams'; +export type {default as CloseAccountParams} from './CloseAccountParams'; +export type {default as ConnectBankAccountManuallyParams} from './ConnectBankAccountManuallyParams'; +export type {default as ConnectBankAccountWithPlaidParams} from './ConnectBankAccountWithPlaidParams'; +export type {default as DeleteContactMethodParams} from './DeleteContactMethodParams'; +export type {default as DeletePaymentBankAccountParams} from './DeletePaymentBankAccountParams'; +export type {default as DeletePaymentCardParams} from './DeletePaymentCardParams'; +export type {default as ExpandURLPreviewParams} from './ExpandURLPreviewParams'; +export type {default as GetMissingOnyxMessagesParams} from './GetMissingOnyxMessagesParams'; +export type {default as GetNewerActionsParams} from './GetNewerActionsParams'; +export type {default as GetOlderActionsParams} from './GetOlderActionsParams'; +export type {default as GetReportPrivateNoteParams} from './GetReportPrivateNoteParams'; +export type {default as GetRouteForDraftParams} from './GetRouteForDraftParams'; +export type {default as GetRouteParams} from './GetRouteParams'; +export type {default as GetStatementPDFParams} from './GetStatementPDFParams'; +export type {default as HandleRestrictedEventParams} from './HandleRestrictedEventParams'; +export type {default as LogOutParams} from './LogOutParams'; +export type {default as MakeDefaultPaymentMethodParams} from './MakeDefaultPaymentMethodParams'; +export type {default as OpenAppParams} from './OpenAppParams'; +export type {default as OpenOldDotLinkParams} from './OpenOldDotLinkParams'; +export type {default as OpenPlaidBankAccountSelectorParams} from './OpenPlaidBankAccountSelectorParams'; +export type {default as OpenPlaidBankLoginParams} from './OpenPlaidBankLoginParams'; +export type {default as OpenProfileParams} from './OpenProfileParams'; +export type {default as OpenPublicProfilePageParams} from './OpenPublicProfilePageParams'; +export type {default as OpenReimbursementAccountPageParams} from './OpenReimbursementAccountPageParams'; +export type {default as OpenReportParams} from './OpenReportParams'; +export type {default as OpenRoomMembersPageParams} from './OpenRoomMembersPageParams'; +export type {default as PaymentCardParams} from './PaymentCardParams'; +export type {default as ReconnectAppParams} from './ReconnectAppParams'; +export type {default as ReferTeachersUniteVolunteerParams} from './ReferTeachersUniteVolunteerParams'; +export type {default as ReportVirtualExpensifyCardFraudParams} from './ReportVirtualExpensifyCardFraudParams'; +export type {default as RequestContactMethodValidateCodeParams} from './RequestContactMethodValidateCodeParams'; +export type {default as RequestNewValidateCodeParams} from './RequestNewValidateCodeParams'; +export type {default as RequestPhysicalExpensifyCardParams} from './RequestPhysicalExpensifyCardParams'; +export type {default as RequestReplacementExpensifyCardParams} from './RequestReplacementExpensifyCardParams'; +export type {default as RequestUnlinkValidationLinkParams} from './RequestUnlinkValidationLinkParams'; +export type {default as RequestAccountValidationLinkParams} from './RequestAccountValidationLinkParams'; +export type {default as ResolveActionableMentionWhisperParams} from './ResolveActionableMentionWhisperParams'; +export type {default as RevealExpensifyCardDetailsParams} from './RevealExpensifyCardDetailsParams'; +export type {default as SearchForReportsParams} from './SearchForReportsParams'; +export type {default as SendPerformanceTimingParams} from './SendPerformanceTimingParams'; +export type {default as SetContactMethodAsDefaultParams} from './SetContactMethodAsDefaultParams'; +export type {default as SignInUserWithLinkParams} from './SignInUserWithLinkParams'; +export type {default as SignInWithShortLivedAuthTokenParams} from './SignInWithShortLivedAuthTokenParams'; +export type {default as UnlinkLoginParams} from './UnlinkLoginParams'; +export type {default as UpdateAutomaticTimezoneParams} from './UpdateAutomaticTimezoneParams'; +export type {default as UpdateChatPriorityModeParams} from './UpdateChatPriorityModeParams'; +export type {default as UpdateDateOfBirthParams} from './UpdateDateOfBirthParams'; +export type {default as UpdateDisplayNameParams} from './UpdateDisplayNameParams'; +export type {default as UpdateFrequentlyUsedEmojisParams} from './UpdateFrequentlyUsedEmojisParams'; +export type {default as UpdateHomeAddressParams} from './UpdateHomeAddressParams'; +export type {default as UpdateLegalNameParams} from './UpdateLegalNameParams'; +export type {default as UpdateNewsletterSubscriptionParams} from './UpdateNewsletterSubscriptionParams'; +export type {default as UpdatePersonalInformationForBankAccountParams} from './UpdatePersonalInformationForBankAccountParams'; +export type {default as UpdatePreferredEmojiSkinToneParams} from './UpdatePreferredEmojiSkinToneParams'; +export type {default as UpdatePreferredLocaleParams} from './UpdatePreferredLocaleParams'; +export type {default as UpdatePronounsParams} from './UpdatePronounsParams'; +export type {default as UpdateSelectedTimezoneParams} from './UpdateSelectedTimezoneParams'; +export type {default as UpdateStatusParams} from './UpdateStatusParams'; +export type {default as UpdateThemeParams} from './UpdateThemeParams'; +export type {default as UpdateUserAvatarParams} from './UpdateUserAvatarParams'; +export type {default as ValidateBankAccountWithTransactionsParams} from './ValidateBankAccountWithTransactionsParams'; +export type {default as ValidateLoginParams} from './ValidateLoginParams'; +export type {default as ValidateSecondaryLoginParams} from './ValidateSecondaryLoginParams'; +export type {default as ValidateTwoFactorAuthParams} from './ValidateTwoFactorAuthParams'; +export type {default as VerifyIdentityForBankAccountParams} from './VerifyIdentityForBankAccountParams'; +export type {default as AnswerQuestionsForWalletParams} from './AnswerQuestionsForWalletParams'; +export type {default as AddCommentOrAttachementParams} from './AddCommentOrAttachementParams'; +export type {default as OptInOutToPushNotificationsParams} from './OptInOutToPushNotificationsParams'; +export type {default as ReconnectToReportParams} from './ReconnectToReportParams'; +export type {default as ReadNewestActionParams} from './ReadNewestActionParams'; +export type {default as MarkAsUnreadParams} from './MarkAsUnreadParams'; +export type {default as TogglePinnedChatParams} from './TogglePinnedChatParams'; +export type {default as DeleteCommentParams} from './DeleteCommentParams'; +export type {default as UpdateCommentParams} from './UpdateCommentParams'; +export type {default as UpdateReportNotificationPreferenceParams} from './UpdateReportNotificationPreferenceParams'; +export type {default as UpdateWelcomeMessageParams} from './UpdateWelcomeMessageParams'; +export type {default as UpdateReportWriteCapabilityParams} from './UpdateReportWriteCapabilityParams'; +export type {default as AddWorkspaceRoomParams} from './AddWorkspaceRoomParams'; +export type {default as UpdatePolicyRoomNameParams} from './UpdatePolicyRoomNameParams'; +export type {default as AddEmojiReactionParams} from './AddEmojiReactionParams'; +export type {default as RemoveEmojiReactionParams} from './RemoveEmojiReactionParams'; +export type {default as LeaveRoomParams} from './LeaveRoomParams'; +export type {default as InviteToRoomParams} from './InviteToRoomParams'; +export type {default as RemoveFromRoomParams} from './RemoveFromRoomParams'; +export type {default as FlagCommentParams} from './FlagCommentParams'; +export type {default as UpdateReportPrivateNoteParams} from './UpdateReportPrivateNoteParams'; +export type {default as UpdateCompanyInformationForBankAccountParams} from './UpdateCompanyInformationForBankAccountParams'; +export type {default as UpdatePersonalDetailsForWalletParams} from './UpdatePersonalDetailsForWalletParams'; +export type {default as VerifyIdentityParams} from './VerifyIdentityParams'; +export type {default as AcceptWalletTermsParams} from './AcceptWalletTermsParams'; +export type {default as ChronosRemoveOOOEventParams} from './ChronosRemoveOOOEventParams'; +export type {default as TransferWalletBalanceParams} from './TransferWalletBalanceParams'; +export type {default as DeleteWorkspaceParams} from './DeleteWorkspaceParams'; +export type {default as CreateWorkspaceParams} from './CreateWorkspaceParams'; +export type {default as UpdateWorkspaceGeneralSettingsParams} from './UpdateWorkspaceGeneralSettingsParams'; +export type {default as DeleteWorkspaceAvatarParams} from './DeleteWorkspaceAvatarParams'; +export type {default as UpdateWorkspaceAvatarParams} from './UpdateWorkspaceAvatarParams'; +export type {default as AddMembersToWorkspaceParams} from './AddMembersToWorkspaceParams'; +export type {default as DeleteMembersFromWorkspaceParams} from './DeleteMembersFromWorkspaceParams'; +export type {default as OpenWorkspaceParams} from './OpenWorkspaceParams'; +export type {default as OpenWorkspaceReimburseViewParams} from './OpenWorkspaceReimburseViewParams'; +export type {default as OpenWorkspaceInvitePageParams} from './OpenWorkspaceInvitePageParams'; +export type {default as OpenWorkspaceMembersPageParams} from './OpenWorkspaceMembersPageParams'; +export type {default as OpenDraftWorkspaceRequestParams} from './OpenDraftWorkspaceRequestParams'; +export type {default as UpdateWorkspaceCustomUnitAndRateParams} from './UpdateWorkspaceCustomUnitAndRateParams'; +export type {default as CreateWorkspaceFromIOUPaymentParams} from './CreateWorkspaceFromIOUPaymentParams'; +export type {default as CreateTaskParams} from './CreateTaskParams'; +export type {default as CancelTaskParams} from './CancelTaskParams'; +export type {default as EditTaskAssigneeParams} from './EditTaskAssigneeParams'; +export type {default as EditTaskParams} from './EditTaskParams'; +export type {default as ReopenTaskParams} from './ReopenTaskParams'; +export type {default as CompleteTaskParams} from './CompleteTaskParams'; +export type {default as CompleteEngagementModalParams} from './CompleteEngagementModalParams'; +export type {default as SetNameValuePairParams} from './SetNameValuePairParams'; diff --git a/src/libs/API/types.ts b/src/libs/API/types.ts new file mode 100644 index 000000000000..f58ebc30b4a2 --- /dev/null +++ b/src/libs/API/types.ts @@ -0,0 +1,318 @@ +import type {ValueOf} from 'type-fest'; +import type CONST from '@src/CONST'; +import type {EmptyObject} from '@src/types/utils/EmptyObject'; +import type * as Parameters from './parameters'; +import type SignInUserParams from './parameters/SignInUserParams'; +import type UpdateBeneficialOwnersForBankAccountParams from './parameters/UpdateBeneficialOwnersForBankAccountParams'; + +type ApiRequest = ValueOf; + +const WRITE_COMMANDS = { + UPDATE_PREFERRED_LOCALE: 'UpdatePreferredLocale', + RECONNECT_APP: 'ReconnectApp', + OPEN_PROFILE: 'OpenProfile', + HANDLE_RESTRICTED_EVENT: 'HandleRestrictedEvent', + OPEN_REPORT: 'OpenReport', + DELETE_PAYMENT_BANK_ACCOUNT: 'DeletePaymentBankAccount', + UPDATE_PERSONAL_INFORMATION_FOR_BANK_ACCOUNT: 'UpdatePersonalInformationForBankAccount', + VALIDATE_BANK_ACCOUNT_WITH_TRANSACTIONS: 'ValidateBankAccountWithTransactions', + UPDATE_COMPANY_INFORMATION_FOR_BANK_ACCOUNT: 'UpdateCompanyInformationForBankAccount', + UPDATE_BENEFICIAL_OWNERS_FOR_BANK_ACCOUNT: 'UpdateBeneficialOwnersForBankAccount', + CONNECT_BANK_ACCOUNT_MANUALLY: 'ConnectBankAccountManually', + VERIFY_IDENTITY_FOR_BANK_ACCOUNT: 'VerifyIdentityForBankAccount', + BANK_ACCOUNT_HANDLE_PLAID_ERROR: 'BankAccount_HandlePlaidError', + REPORT_VIRTUAL_EXPENSIFY_CARD_FRAUD: 'ReportVirtualExpensifyCardFraud', + REQUEST_REPLACEMENT_EXPENSIFY_CARD: 'RequestReplacementExpensifyCard', + ACTIVATE_PHYSICAL_EXPENSIFY_CARD: 'ActivatePhysicalExpensifyCard', + CHRONOS_REMOVE_OOO_EVENT: 'Chronos_RemoveOOOEvent', + MAKE_DEFAULT_PAYMENT_METHOD: 'MakeDefaultPaymentMethod', + ADD_PAYMENT_CARD: 'AddPaymentCard', + TRANSFER_WALLET_BALANCE: 'TransferWalletBalance', + DELETE_PAYMENT_CARD: 'DeletePaymentCard', + UPDATE_PRONOUNS: 'UpdatePronouns', + UPDATE_DISPLAY_NAME: 'UpdateDisplayName', + UPDATE_LEGAL_NAME: 'UpdateLegalName', + UPDATE_DATE_OF_BIRTH: 'UpdateDateOfBirth', + UPDATE_HOME_ADDRESS: 'UpdateHomeAddress', + UPDATE_AUTOMATIC_TIMEZONE: 'UpdateAutomaticTimezone', + UPDATE_SELECTED_TIMEZONE: 'UpdateSelectedTimezone', + UPDATE_USER_AVATAR: 'UpdateUserAvatar', + DELETE_USER_AVATAR: 'DeleteUserAvatar', + REFER_TEACHERS_UNITE_VOLUNTEER: 'ReferTeachersUniteVolunteer', + ADD_SCHOOL_PRINCIPAL: 'AddSchoolPrincipal', + CLOSE_ACCOUNT: 'CloseAccount', + REQUEST_CONTACT_METHOD_VALIDATE_CODE: 'RequestContactMethodValidateCode', + UPDATE_NEWSLETTER_SUBSCRIPTION: 'UpdateNewsletterSubscription', + DELETE_CONTACT_METHOD: 'DeleteContactMethod', + ADD_NEW_CONTACT_METHOD: 'AddNewContactMethod', + VALIDATE_LOGIN: 'ValidateLogin', + VALIDATE_SECONDARY_LOGIN: 'ValidateSecondaryLogin', + UPDATE_PREFERRED_EMOJI_SKIN_TONE: 'UpdatePreferredEmojiSkinTone', + UPDATE_FREQUENTLY_USED_EMOJIS: 'UpdateFrequentlyUsedEmojis', + UPDATE_CHAT_PRIORITY_MODE: 'UpdateChatPriorityMode', + SET_CONTACT_METHOD_AS_DEFAULT: 'SetContactMethodAsDefault', + UPDATE_THEME: 'UpdateTheme', + UPDATE_STATUS: 'UpdateStatus', + CLEAR_STATUS: 'ClearStatus', + UPDATE_PERSONAL_DETAILS_FOR_WALLET: 'UpdatePersonalDetailsForWallet', + VERIFY_IDENTITY: 'VerifyIdentity', + ACCEPT_WALLET_TERMS: 'AcceptWalletTerms', + ANSWER_QUESTIONS_FOR_WALLET: 'AnswerQuestionsForWallet', + REQUEST_PHYSICAL_EXPENSIFY_CARD: 'RequestPhysicalExpensifyCard', + LOG_OUT: 'LogOut', + REQUEST_ACCOUNT_VALIDATION_LINK: 'RequestAccountValidationLink', + REQUEST_NEW_VALIDATE_CODE: 'RequestNewValidateCode', + SIGN_IN_WITH_APPLE: 'SignInWithApple', + SIGN_IN_WITH_GOOGLE: 'SignInWithGoogle', + SIGN_IN_USER: 'SigninUser', + SIGN_IN_USER_WITH_LINK: 'SigninUserWithLink', + REQUEST_UNLINK_VALIDATION_LINK: 'RequestUnlinkValidationLink', + UNLINK_LOGIN: 'UnlinkLogin', + ENABLE_TWO_FACTOR_AUTH: 'EnableTwoFactorAuth', + DISABLE_TWO_FACTOR_AUTH: 'DisableTwoFactorAuth', + TWO_FACTOR_AUTH_VALIDATE: 'TwoFactorAuth_Validate', + ADD_COMMENT: 'AddComment', + ADD_ATTACHMENT: 'AddAttachment', + CONNECT_BANK_ACCOUNT_WITH_PLAID: 'ConnectBankAccountWithPlaid', + ADD_PERSONAL_BANK_ACCOUNT: 'AddPersonalBankAccount', + OPT_IN_TO_PUSH_NOTIFICATIONS: 'OptInToPushNotifications', + OPT_OUT_OF_PUSH_NOTIFICATIONS: 'OptOutOfPushNotifications', + RECONNECT_TO_REPORT: 'ReconnectToReport', + READ_NEWEST_ACTION: 'ReadNewestAction', + MARK_AS_UNREAD: 'MarkAsUnread', + TOGGLE_PINNED_CHAT: 'TogglePinnedChat', + DELETE_COMMENT: 'DeleteComment', + UPDATE_COMMENT: 'UpdateComment', + UPDATE_REPORT_NOTIFICATION_PREFERENCE: 'UpdateReportNotificationPreference', + UPDATE_WELCOME_MESSAGE: 'UpdateWelcomeMessage', + UPDATE_REPORT_WRITE_CAPABILITY: 'UpdateReportWriteCapability', + ADD_WORKSPACE_ROOM: 'AddWorkspaceRoom', + UPDATE_POLICY_ROOM_NAME: 'UpdatePolicyRoomName', + ADD_EMOJI_REACTION: 'AddEmojiReaction', + REMOVE_EMOJI_REACTION: 'RemoveEmojiReaction', + LEAVE_ROOM: 'LeaveRoom', + INVITE_TO_ROOM: 'InviteToRoom', + REMOVE_FROM_ROOM: 'RemoveFromRoom', + FLAG_COMMENT: 'FlagComment', + UPDATE_REPORT_PRIVATE_NOTE: 'UpdateReportPrivateNote', + RESOLVE_ACTIONABLE_MENTION_WHISPER: 'ResolveActionableMentionWhisper', + DELETE_WORKSPACE: 'DeleteWorkspace', + DELETE_MEMBERS_FROM_WORKSPACE: 'DeleteMembersFromWorkspace', + ADD_MEMBERS_TO_WORKSPACE: 'AddMembersToWorkspace', + UPDATE_WORKSPACE_AVATAR: 'UpdateWorkspaceAvatar', + DELETE_WORKSPACE_AVATAR: 'DeleteWorkspaceAvatar', + UPDATE_WORKSPACE_GENERAL_SETTINGS: 'UpdateWorkspaceGeneralSettings', + UPDATE_WORKSPACE_CUSTOM_UNIT_AND_RATE: 'UpdateWorkspaceCustomUnitAndRate', + CREATE_WORKSPACE: 'CreateWorkspace', + CREATE_WORKSPACE_FROM_IOU_PAYMENT: 'CreateWorkspaceFromIOUPayment', + CREATE_TASK: 'CreateTask', + CANCEL_TASK: 'CancelTask', + EDIT_TASK_ASSIGNEE: 'EditTaskAssignee', + EDIT_TASK: 'EditTask', + REOPEN_TASK: 'ReopenTask', + COMPLETE_TASK: 'CompleteTask', + COMPLETE_ENGAGEMENT_MODAL: 'CompleteEngagementModal', + SET_NAME_VALUE_PAIR: 'SetNameValuePair', +} as const; + +type WriteCommand = ValueOf; + +type WriteCommandParameters = { + [WRITE_COMMANDS.UPDATE_PREFERRED_LOCALE]: Parameters.UpdatePreferredLocaleParams; + [WRITE_COMMANDS.RECONNECT_APP]: Parameters.ReconnectAppParams; + [WRITE_COMMANDS.OPEN_PROFILE]: Parameters.OpenProfileParams; + [WRITE_COMMANDS.HANDLE_RESTRICTED_EVENT]: Parameters.HandleRestrictedEventParams; + [WRITE_COMMANDS.OPEN_REPORT]: Parameters.OpenReportParams; + [WRITE_COMMANDS.DELETE_PAYMENT_BANK_ACCOUNT]: Parameters.DeletePaymentBankAccountParams; + [WRITE_COMMANDS.UPDATE_PERSONAL_INFORMATION_FOR_BANK_ACCOUNT]: Parameters.UpdatePersonalInformationForBankAccountParams; + [WRITE_COMMANDS.VALIDATE_BANK_ACCOUNT_WITH_TRANSACTIONS]: Parameters.ValidateBankAccountWithTransactionsParams; + [WRITE_COMMANDS.UPDATE_COMPANY_INFORMATION_FOR_BANK_ACCOUNT]: Parameters.UpdateCompanyInformationForBankAccountParams; + [WRITE_COMMANDS.UPDATE_BENEFICIAL_OWNERS_FOR_BANK_ACCOUNT]: UpdateBeneficialOwnersForBankAccountParams; + [WRITE_COMMANDS.CONNECT_BANK_ACCOUNT_MANUALLY]: Parameters.ConnectBankAccountManuallyParams; + [WRITE_COMMANDS.VERIFY_IDENTITY_FOR_BANK_ACCOUNT]: Parameters.VerifyIdentityForBankAccountParams; + [WRITE_COMMANDS.BANK_ACCOUNT_HANDLE_PLAID_ERROR]: Parameters.BankAccountHandlePlaidErrorParams; + [WRITE_COMMANDS.REPORT_VIRTUAL_EXPENSIFY_CARD_FRAUD]: Parameters.ReportVirtualExpensifyCardFraudParams; + [WRITE_COMMANDS.REQUEST_REPLACEMENT_EXPENSIFY_CARD]: Parameters.RequestReplacementExpensifyCardParams; + [WRITE_COMMANDS.ACTIVATE_PHYSICAL_EXPENSIFY_CARD]: Parameters.ActivatePhysicalExpensifyCardParams; + [WRITE_COMMANDS.MAKE_DEFAULT_PAYMENT_METHOD]: Parameters.MakeDefaultPaymentMethodParams; + [WRITE_COMMANDS.ADD_PAYMENT_CARD]: Parameters.AddPaymentCardParams; + [WRITE_COMMANDS.DELETE_PAYMENT_CARD]: Parameters.DeletePaymentCardParams; + [WRITE_COMMANDS.UPDATE_PRONOUNS]: Parameters.UpdatePronounsParams; + [WRITE_COMMANDS.UPDATE_DISPLAY_NAME]: Parameters.UpdateDisplayNameParams; + [WRITE_COMMANDS.UPDATE_LEGAL_NAME]: Parameters.UpdateLegalNameParams; + [WRITE_COMMANDS.UPDATE_DATE_OF_BIRTH]: Parameters.UpdateDateOfBirthParams; + [WRITE_COMMANDS.UPDATE_HOME_ADDRESS]: Parameters.UpdateHomeAddressParams; + [WRITE_COMMANDS.UPDATE_AUTOMATIC_TIMEZONE]: Parameters.UpdateAutomaticTimezoneParams; + [WRITE_COMMANDS.UPDATE_SELECTED_TIMEZONE]: Parameters.UpdateSelectedTimezoneParams; + [WRITE_COMMANDS.UPDATE_USER_AVATAR]: Parameters.UpdateUserAvatarParams; + [WRITE_COMMANDS.DELETE_USER_AVATAR]: EmptyObject; + [WRITE_COMMANDS.REFER_TEACHERS_UNITE_VOLUNTEER]: Parameters.ReferTeachersUniteVolunteerParams; + [WRITE_COMMANDS.ADD_SCHOOL_PRINCIPAL]: Parameters.AddSchoolPrincipalParams; + [WRITE_COMMANDS.CLOSE_ACCOUNT]: Parameters.CloseAccountParams; + [WRITE_COMMANDS.REQUEST_CONTACT_METHOD_VALIDATE_CODE]: Parameters.RequestContactMethodValidateCodeParams; + [WRITE_COMMANDS.UPDATE_NEWSLETTER_SUBSCRIPTION]: Parameters.UpdateNewsletterSubscriptionParams; + [WRITE_COMMANDS.DELETE_CONTACT_METHOD]: Parameters.DeleteContactMethodParams; + [WRITE_COMMANDS.ADD_NEW_CONTACT_METHOD]: Parameters.AddNewContactMethodParams; + [WRITE_COMMANDS.VALIDATE_LOGIN]: Parameters.ValidateLoginParams; + [WRITE_COMMANDS.VALIDATE_SECONDARY_LOGIN]: Parameters.ValidateSecondaryLoginParams; + [WRITE_COMMANDS.UPDATE_PREFERRED_EMOJI_SKIN_TONE]: Parameters.UpdatePreferredEmojiSkinToneParams; + [WRITE_COMMANDS.UPDATE_FREQUENTLY_USED_EMOJIS]: Parameters.UpdateFrequentlyUsedEmojisParams; + [WRITE_COMMANDS.UPDATE_CHAT_PRIORITY_MODE]: Parameters.UpdateChatPriorityModeParams; + [WRITE_COMMANDS.SET_CONTACT_METHOD_AS_DEFAULT]: Parameters.SetContactMethodAsDefaultParams; + [WRITE_COMMANDS.UPDATE_THEME]: Parameters.UpdateThemeParams; + [WRITE_COMMANDS.UPDATE_STATUS]: Parameters.UpdateStatusParams; + [WRITE_COMMANDS.CLEAR_STATUS]: EmptyObject; + [WRITE_COMMANDS.UPDATE_PERSONAL_DETAILS_FOR_WALLET]: Parameters.UpdatePersonalDetailsForWalletParams; + [WRITE_COMMANDS.VERIFY_IDENTITY]: Parameters.VerifyIdentityParams; + [WRITE_COMMANDS.ACCEPT_WALLET_TERMS]: Parameters.AcceptWalletTermsParams; + [WRITE_COMMANDS.ANSWER_QUESTIONS_FOR_WALLET]: Parameters.AnswerQuestionsForWalletParams; + [WRITE_COMMANDS.REQUEST_PHYSICAL_EXPENSIFY_CARD]: Parameters.RequestPhysicalExpensifyCardParams; + [WRITE_COMMANDS.LOG_OUT]: Parameters.LogOutParams; + [WRITE_COMMANDS.REQUEST_ACCOUNT_VALIDATION_LINK]: Parameters.RequestAccountValidationLinkParams; + [WRITE_COMMANDS.REQUEST_NEW_VALIDATE_CODE]: Parameters.RequestNewValidateCodeParams; + [WRITE_COMMANDS.SIGN_IN_WITH_APPLE]: Parameters.BeginAppleSignInParams; + [WRITE_COMMANDS.SIGN_IN_WITH_GOOGLE]: Parameters.BeginGoogleSignInParams; + [WRITE_COMMANDS.SIGN_IN_USER]: SignInUserParams; + [WRITE_COMMANDS.SIGN_IN_USER_WITH_LINK]: Parameters.SignInUserWithLinkParams; + [WRITE_COMMANDS.REQUEST_UNLINK_VALIDATION_LINK]: Parameters.RequestUnlinkValidationLinkParams; + [WRITE_COMMANDS.UNLINK_LOGIN]: Parameters.UnlinkLoginParams; + [WRITE_COMMANDS.ENABLE_TWO_FACTOR_AUTH]: EmptyObject; + [WRITE_COMMANDS.DISABLE_TWO_FACTOR_AUTH]: EmptyObject; + [WRITE_COMMANDS.TWO_FACTOR_AUTH_VALIDATE]: Parameters.ValidateTwoFactorAuthParams; + [WRITE_COMMANDS.ADD_COMMENT]: Parameters.AddCommentOrAttachementParams; + [WRITE_COMMANDS.ADD_ATTACHMENT]: Parameters.AddCommentOrAttachementParams; + [WRITE_COMMANDS.CONNECT_BANK_ACCOUNT_WITH_PLAID]: Parameters.ConnectBankAccountWithPlaidParams; + [WRITE_COMMANDS.ADD_PERSONAL_BANK_ACCOUNT]: Parameters.AddPersonalBankAccountParams; + [WRITE_COMMANDS.OPT_IN_TO_PUSH_NOTIFICATIONS]: Parameters.OptInOutToPushNotificationsParams; + [WRITE_COMMANDS.OPT_OUT_OF_PUSH_NOTIFICATIONS]: Parameters.OptInOutToPushNotificationsParams; + [WRITE_COMMANDS.RECONNECT_TO_REPORT]: Parameters.ReconnectToReportParams; + [WRITE_COMMANDS.READ_NEWEST_ACTION]: Parameters.ReadNewestActionParams; + [WRITE_COMMANDS.MARK_AS_UNREAD]: Parameters.MarkAsUnreadParams; + [WRITE_COMMANDS.TOGGLE_PINNED_CHAT]: Parameters.TogglePinnedChatParams; + [WRITE_COMMANDS.DELETE_COMMENT]: Parameters.DeleteCommentParams; + [WRITE_COMMANDS.UPDATE_COMMENT]: Parameters.UpdateCommentParams; + [WRITE_COMMANDS.UPDATE_REPORT_NOTIFICATION_PREFERENCE]: Parameters.UpdateReportNotificationPreferenceParams; + [WRITE_COMMANDS.UPDATE_WELCOME_MESSAGE]: Parameters.UpdateWelcomeMessageParams; + [WRITE_COMMANDS.UPDATE_REPORT_WRITE_CAPABILITY]: Parameters.UpdateReportWriteCapabilityParams; + [WRITE_COMMANDS.ADD_WORKSPACE_ROOM]: Parameters.AddWorkspaceRoomParams; + [WRITE_COMMANDS.UPDATE_POLICY_ROOM_NAME]: Parameters.UpdatePolicyRoomNameParams; + [WRITE_COMMANDS.ADD_EMOJI_REACTION]: Parameters.AddEmojiReactionParams; + [WRITE_COMMANDS.REMOVE_EMOJI_REACTION]: Parameters.RemoveEmojiReactionParams; + [WRITE_COMMANDS.LEAVE_ROOM]: Parameters.LeaveRoomParams; + [WRITE_COMMANDS.INVITE_TO_ROOM]: Parameters.InviteToRoomParams; + [WRITE_COMMANDS.REMOVE_FROM_ROOM]: Parameters.RemoveFromRoomParams; + [WRITE_COMMANDS.FLAG_COMMENT]: Parameters.FlagCommentParams; + [WRITE_COMMANDS.UPDATE_REPORT_PRIVATE_NOTE]: Parameters.UpdateReportPrivateNoteParams; + [WRITE_COMMANDS.RESOLVE_ACTIONABLE_MENTION_WHISPER]: Parameters.ResolveActionableMentionWhisperParams; + [WRITE_COMMANDS.CHRONOS_REMOVE_OOO_EVENT]: Parameters.ChronosRemoveOOOEventParams; + [WRITE_COMMANDS.TRANSFER_WALLET_BALANCE]: Parameters.TransferWalletBalanceParams; + [WRITE_COMMANDS.DELETE_WORKSPACE]: Parameters.DeleteWorkspaceParams; + [WRITE_COMMANDS.DELETE_MEMBERS_FROM_WORKSPACE]: Parameters.DeleteMembersFromWorkspaceParams; + [WRITE_COMMANDS.ADD_MEMBERS_TO_WORKSPACE]: Parameters.AddMembersToWorkspaceParams; + [WRITE_COMMANDS.UPDATE_WORKSPACE_AVATAR]: Parameters.UpdateWorkspaceAvatarParams; + [WRITE_COMMANDS.DELETE_WORKSPACE_AVATAR]: Parameters.DeleteWorkspaceAvatarParams; + [WRITE_COMMANDS.UPDATE_WORKSPACE_GENERAL_SETTINGS]: Parameters.UpdateWorkspaceGeneralSettingsParams; + [WRITE_COMMANDS.UPDATE_WORKSPACE_CUSTOM_UNIT_AND_RATE]: Parameters.UpdateWorkspaceCustomUnitAndRateParams; + [WRITE_COMMANDS.CREATE_WORKSPACE]: Parameters.CreateWorkspaceParams; + [WRITE_COMMANDS.CREATE_WORKSPACE_FROM_IOU_PAYMENT]: Parameters.CreateWorkspaceFromIOUPaymentParams; + [WRITE_COMMANDS.CREATE_TASK]: Parameters.CreateTaskParams; + [WRITE_COMMANDS.CANCEL_TASK]: Parameters.CancelTaskParams; + [WRITE_COMMANDS.EDIT_TASK_ASSIGNEE]: Parameters.EditTaskAssigneeParams; + [WRITE_COMMANDS.EDIT_TASK]: Parameters.EditTaskParams; + [WRITE_COMMANDS.REOPEN_TASK]: Parameters.ReopenTaskParams; + [WRITE_COMMANDS.COMPLETE_TASK]: Parameters.CompleteTaskParams; + [WRITE_COMMANDS.COMPLETE_ENGAGEMENT_MODAL]: Parameters.CompleteEngagementModalParams; + [WRITE_COMMANDS.SET_NAME_VALUE_PAIR]: Parameters.SetNameValuePairParams; +}; + +const READ_COMMANDS = { + OPEN_APP: 'OpenApp', + OPEN_REIMBURSEMENT_ACCOUNT_PAGE: 'OpenReimbursementAccountPage', + OPEN_WORKSPACE_VIEW: 'OpenWorkspaceView', + GET_MAPBOX_ACCESS_TOKEN: 'GetMapboxAccessToken', + OPEN_PAYMENTS_PAGE: 'OpenPaymentsPage', + OPEN_PERSONAL_DETAILS_PAGE: 'OpenPersonalDetailsPage', + OPEN_PUBLIC_PROFILE_PAGE: 'OpenPublicProfilePage', + OPEN_PLAID_BANK_LOGIN: 'OpenPlaidBankLogin', + OPEN_PLAID_BANK_ACCOUNT_SELECTOR: 'OpenPlaidBankAccountSelector', + GET_OLDER_ACTIONS: 'GetOlderActions', + GET_NEWER_ACTIONS: 'GetNewerActions', + EXPAND_URL_PREVIEW: 'ExpandURLPreview', + GET_REPORT_PRIVATE_NOTE: 'GetReportPrivateNote', + OPEN_ROOM_MEMBERS_PAGE: 'OpenRoomMembersPage', + SEARCH_FOR_REPORTS: 'SearchForReports', + SEND_PERFORMANCE_TIMING: 'SendPerformanceTiming', + GET_ROUTE: 'GetRoute', + GET_ROUTE_FOR_DRAFT: 'GetRouteForDraft', + GET_STATEMENT_PDF: 'GetStatementPDF', + OPEN_ONFIDO_FLOW: 'OpenOnfidoFlow', + OPEN_INITIAL_SETTINGS_PAGE: 'OpenInitialSettingsPage', + OPEN_ENABLE_PAYMENTS_PAGE: 'OpenEnablePaymentsPage', + BEGIN_SIGNIN: 'BeginSignIn', + SIGN_IN_WITH_SHORT_LIVED_AUTH_TOKEN: 'SignInWithShortLivedAuthToken', + OPEN_WORKSPACE_REIMBURSE_VIEW: 'OpenWorkspaceReimburseView', + OPEN_WORKSPACE: 'OpenWorkspace', + OPEN_WORKSPACE_MEMBERS_PAGE: 'OpenWorkspaceMembersPage', + OPEN_WORKSPACE_INVITE_PAGE: 'OpenWorkspaceInvitePage', + OPEN_DRAFT_WORKSPACE_REQUEST: 'OpenDraftWorkspaceRequest', +} as const; + +type ReadCommand = ValueOf; + +type ReadCommandParameters = { + [READ_COMMANDS.OPEN_APP]: Parameters.OpenAppParams; + [READ_COMMANDS.OPEN_REIMBURSEMENT_ACCOUNT_PAGE]: Parameters.OpenReimbursementAccountPageParams; + [READ_COMMANDS.OPEN_WORKSPACE_VIEW]: EmptyObject; + [READ_COMMANDS.GET_MAPBOX_ACCESS_TOKEN]: EmptyObject; + [READ_COMMANDS.OPEN_PAYMENTS_PAGE]: EmptyObject; + [READ_COMMANDS.OPEN_PERSONAL_DETAILS_PAGE]: EmptyObject; + [READ_COMMANDS.OPEN_PUBLIC_PROFILE_PAGE]: Parameters.OpenPublicProfilePageParams; + [READ_COMMANDS.OPEN_PLAID_BANK_LOGIN]: Parameters.OpenPlaidBankLoginParams; + [READ_COMMANDS.OPEN_PLAID_BANK_ACCOUNT_SELECTOR]: Parameters.OpenPlaidBankAccountSelectorParams; + [READ_COMMANDS.GET_OLDER_ACTIONS]: Parameters.GetOlderActionsParams; + [READ_COMMANDS.GET_NEWER_ACTIONS]: Parameters.GetNewerActionsParams; + [READ_COMMANDS.EXPAND_URL_PREVIEW]: Parameters.ExpandURLPreviewParams; + [READ_COMMANDS.GET_REPORT_PRIVATE_NOTE]: Parameters.GetReportPrivateNoteParams; + [READ_COMMANDS.OPEN_ROOM_MEMBERS_PAGE]: Parameters.OpenRoomMembersPageParams; + [READ_COMMANDS.SEARCH_FOR_REPORTS]: Parameters.SearchForReportsParams; + [READ_COMMANDS.SEND_PERFORMANCE_TIMING]: Parameters.SendPerformanceTimingParams; + [READ_COMMANDS.GET_ROUTE]: Parameters.GetRouteParams; + [READ_COMMANDS.GET_ROUTE_FOR_DRAFT]: Parameters.GetRouteForDraftParams; + [READ_COMMANDS.GET_STATEMENT_PDF]: Parameters.GetStatementPDFParams; + [READ_COMMANDS.OPEN_ONFIDO_FLOW]: EmptyObject; + [READ_COMMANDS.OPEN_INITIAL_SETTINGS_PAGE]: EmptyObject; + [READ_COMMANDS.OPEN_ENABLE_PAYMENTS_PAGE]: EmptyObject; + [READ_COMMANDS.BEGIN_SIGNIN]: Parameters.BeginSignInParams; + [READ_COMMANDS.SIGN_IN_WITH_SHORT_LIVED_AUTH_TOKEN]: Parameters.SignInWithShortLivedAuthTokenParams; + [READ_COMMANDS.OPEN_WORKSPACE_REIMBURSE_VIEW]: Parameters.OpenWorkspaceReimburseViewParams; + [READ_COMMANDS.OPEN_WORKSPACE]: Parameters.OpenWorkspaceParams; + [READ_COMMANDS.OPEN_WORKSPACE_MEMBERS_PAGE]: Parameters.OpenWorkspaceMembersPageParams; + [READ_COMMANDS.OPEN_WORKSPACE_INVITE_PAGE]: Parameters.OpenWorkspaceInvitePageParams; + [READ_COMMANDS.OPEN_DRAFT_WORKSPACE_REQUEST]: Parameters.OpenDraftWorkspaceRequestParams; +}; + +const SIDE_EFFECT_REQUEST_COMMANDS = { + AUTHENTICATE_PUSHER: 'AuthenticatePusher', + OPEN_REPORT: 'OpenReport', + OPEN_OLD_DOT_LINK: 'OpenOldDotLink', + REVEAL_EXPENSIFY_CARD_DETAILS: 'RevealExpensifyCardDetails', + GET_MISSING_ONYX_MESSAGES: 'GetMissingOnyxMessages', + RECONNECT_APP: 'ReconnectApp', +} as const; + +type SideEffectRequestCommand = ValueOf; + +type SideEffectRequestCommandParameters = { + [SIDE_EFFECT_REQUEST_COMMANDS.AUTHENTICATE_PUSHER]: Parameters.AuthenticatePusherParams; + [SIDE_EFFECT_REQUEST_COMMANDS.OPEN_REPORT]: Parameters.OpenReportParams; + [SIDE_EFFECT_REQUEST_COMMANDS.OPEN_OLD_DOT_LINK]: Parameters.OpenOldDotLinkParams; + [SIDE_EFFECT_REQUEST_COMMANDS.REVEAL_EXPENSIFY_CARD_DETAILS]: Parameters.RevealExpensifyCardDetailsParams; + [SIDE_EFFECT_REQUEST_COMMANDS.GET_MISSING_ONYX_MESSAGES]: Parameters.GetMissingOnyxMessagesParams; + [SIDE_EFFECT_REQUEST_COMMANDS.RECONNECT_APP]: Parameters.ReconnectAppParams; +}; + +type ApiRequestCommandParameters = WriteCommandParameters & ReadCommandParameters & SideEffectRequestCommandParameters; + +export {WRITE_COMMANDS, READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS}; + +export type {ApiRequest, ApiRequestCommandParameters, WriteCommand, ReadCommand, SideEffectRequestCommand}; diff --git a/src/libs/ComposerUtils/index.ts b/src/libs/ComposerUtils/index.ts index 32ebca9afee8..94bba5d0d00c 100644 --- a/src/libs/ComposerUtils/index.ts +++ b/src/libs/ComposerUtils/index.ts @@ -14,6 +14,14 @@ function insertText(text: string, selection: Selection, textToInsert: string): s return text.slice(0, selection.start) + textToInsert + text.slice(selection.end, text.length); } +/** + * Insert a white space at given index of text + * @param text - text that needs whitespace to be appended to + */ +function insertWhiteSpaceAtIndex(text: string, index: number) { + return `${text.slice(0, index)} ${text.slice(index)}`; +} + /** * Check whether we can skip trigger hotkeys on some specific devices. */ @@ -23,4 +31,22 @@ function canSkipTriggerHotkeys(isSmallScreenWidth: boolean, isKeyboardShown: boo return (isSmallScreenWidth && DeviceCapabilities.canUseTouchScreen()) || isKeyboardShown; } -export {getNumberOfLines, updateNumberOfLines, insertText, canSkipTriggerHotkeys}; +/** + * Finds the length of common suffix between two texts + */ +function findCommonSuffixLength(str1: string, str2: string, cursorPosition: number) { + let commonSuffixLength = 0; + const minLength = Math.min(str1.length - cursorPosition, str2.length); + + for (let i = 1; i <= minLength; i++) { + if (str1.charAt(str1.length - i) === str2.charAt(str2.length - i)) { + commonSuffixLength++; + } else { + break; + } + } + + return commonSuffixLength; +} + +export {getNumberOfLines, updateNumberOfLines, insertText, canSkipTriggerHotkeys, insertWhiteSpaceAtIndex, findCommonSuffixLength}; diff --git a/src/libs/HttpUtils.ts b/src/libs/HttpUtils.ts index 22e342ac847b..a69647b7b5b1 100644 --- a/src/libs/HttpUtils.ts +++ b/src/libs/HttpUtils.ts @@ -6,6 +6,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import type {RequestType} from '@src/types/onyx/Request'; import type Response from '@src/types/onyx/Response'; import * as NetworkActions from './actions/Network'; +import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS} from './API/types'; import * as ApiUtils from './ApiUtils'; import HttpsError from './Errors/HttpsError'; @@ -29,7 +30,7 @@ let cancellationController = new AbortController(); /** * The API commands that require the skew calculation */ -const addSkewList = ['OpenReport', 'ReconnectApp', 'OpenApp']; +const addSkewList: string[] = [SIDE_EFFECT_REQUEST_COMMANDS.OPEN_REPORT, SIDE_EFFECT_REQUEST_COMMANDS.RECONNECT_APP, READ_COMMANDS.OPEN_APP]; /** * Regex to get API command from the command diff --git a/src/libs/IOUUtils.ts b/src/libs/IOUUtils.ts index 11dd0f5badda..c0fb4c6195b1 100644 --- a/src/libs/IOUUtils.ts +++ b/src/libs/IOUUtils.ts @@ -3,9 +3,7 @@ import type {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; import ROUTES from '@src/ROUTES'; import type {Report, Transaction} from '@src/types/onyx'; -import * as IOU from './actions/IOU'; import * as CurrencyUtils from './CurrencyUtils'; -import * as FileUtils from './fileDownload/FileUtils'; import Navigation from './Navigation/Navigation'; import * as TransactionUtils from './TransactionUtils'; @@ -24,32 +22,6 @@ function navigateToStartMoneyRequestStep(requestType: ValueOf void; -// eslint-disable-next-line rulesdir/no-negated-variables -function navigateToStartStepIfScanFileCannotBeRead( - receiptFilename: string, - receiptPath: string, - onSuccess: SuccessCallback, - requestType: ValueOf, - iouType: ValueOf, - transactionID: string, - reportID: string, -) { - if (!receiptFilename || !receiptPath) { - return; - } - - const onFailure = () => { - IOU.setMoneyRequestReceipt(transactionID, '', '', true); - if (requestType === CONST.IOU.REQUEST_TYPE.MANUAL) { - Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_SCAN.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID, Navigation.getActiveRouteWithoutParams())); - return; - } - navigateToStartMoneyRequestStep(requestType, iouType, transactionID, reportID); - }; - FileUtils.readFileAsync(receiptPath, receiptFilename, onSuccess, onFailure); -} - /** * Calculates the amount per user given a list of participants * @@ -127,4 +99,4 @@ function isValidMoneyRequestType(iouType: string): boolean { return moneyRequestType.includes(iouType); } -export {calculateAmount, updateIOUOwnerAndTotal, isIOUReportPendingCurrencyConversion, isValidMoneyRequestType, navigateToStartMoneyRequestStep, navigateToStartStepIfScanFileCannotBeRead}; +export {calculateAmount, updateIOUOwnerAndTotal, isIOUReportPendingCurrencyConversion, isValidMoneyRequestType, navigateToStartMoneyRequestStep}; diff --git a/src/libs/Middleware/Logging.ts b/src/libs/Middleware/Logging.ts index 27a904f692ed..97f4a21866c5 100644 --- a/src/libs/Middleware/Logging.ts +++ b/src/libs/Middleware/Logging.ts @@ -1,3 +1,4 @@ +import {SIDE_EFFECT_REQUEST_COMMANDS} from '@libs/API/types'; import Log from '@libs/Log'; import CONST from '@src/CONST'; import type Request from '@src/types/onyx/Request'; @@ -87,7 +88,7 @@ const Logging: Middleware = (response, request) => { // This error seems to only throw on dev when localhost:8080 tries to access the production web server. It's unclear whether this can happen on production or if // it's a sign that the web server is down. Log.hmmm('[Network] API request error: Gateway Timeout error', logParams); - } else if (request.command === 'AuthenticatePusher') { + } else if (request.command === SIDE_EFFECT_REQUEST_COMMANDS.AUTHENTICATE_PUSHER) { // AuthenticatePusher requests can return with fetch errors and no message. It happens because we return a non 200 header like 403 Forbidden. // This is common to see if we are subscribing to a bad channel related to something the user shouldn't be able to access. There's no additional information // we can get about these requests. diff --git a/src/libs/Middleware/SaveResponseInOnyx.ts b/src/libs/Middleware/SaveResponseInOnyx.ts index a9182745098b..8e357b0f2251 100644 --- a/src/libs/Middleware/SaveResponseInOnyx.ts +++ b/src/libs/Middleware/SaveResponseInOnyx.ts @@ -1,3 +1,4 @@ +import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS} from '@libs/API/types'; import * as MemoryOnlyKeys from '@userActions/MemoryOnlyKeys/MemoryOnlyKeys'; import * as OnyxUpdates from '@userActions/OnyxUpdates'; import CONST from '@src/CONST'; @@ -6,7 +7,7 @@ import type Middleware from './types'; // If we're executing any of these requests, we don't need to trigger our OnyxUpdates flow to update the current data even if our current value is out of // date because all these requests are updating the app to the most current state. -const requestsToIgnoreLastUpdateID = ['OpenApp', 'ReconnectApp', 'GetMissingOnyxMessages']; +const requestsToIgnoreLastUpdateID: string[] = [READ_COMMANDS.OPEN_APP, SIDE_EFFECT_REQUEST_COMMANDS.RECONNECT_APP, SIDE_EFFECT_REQUEST_COMMANDS.GET_MISSING_ONYX_MESSAGES]; const SaveResponseInOnyx: Middleware = (requestResponse, request) => requestResponse.then((response = {}) => { diff --git a/src/libs/Network/NetworkStore.ts b/src/libs/Network/NetworkStore.ts index 59a52dfd01c4..5b93c9adc11a 100644 --- a/src/libs/Network/NetworkStore.ts +++ b/src/libs/Network/NetworkStore.ts @@ -1,4 +1,5 @@ import Onyx from 'react-native-onyx'; +import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS} from '@libs/API/types'; import ONYXKEYS from '@src/ONYXKEYS'; import type Credentials from '@src/types/onyx/Credentials'; @@ -95,7 +96,7 @@ function getAuthToken(): string | null { } function isSupportRequest(command: string): boolean { - return ['OpenApp', 'ReconnectApp', 'OpenReport'].includes(command); + return [READ_COMMANDS.OPEN_APP, SIDE_EFFECT_REQUEST_COMMANDS.RECONNECT_APP, SIDE_EFFECT_REQUEST_COMMANDS.OPEN_REPORT].some((cmd) => cmd === command); } function getSupportAuthToken(): string | null { diff --git a/src/libs/OptionsListUtils.ts b/src/libs/OptionsListUtils.ts index 2621e4d7f12b..6332a57deec0 100644 --- a/src/libs/OptionsListUtils.ts +++ b/src/libs/OptionsListUtils.ts @@ -1563,7 +1563,7 @@ function getOptions( if (includePersonalDetails) { // Next loop over all personal details removing any that are selectedUsers or recentChats allPersonalDetailsOptions.forEach((personalDetailOption) => { - if (optionsToExclude.some((optionToExclude) => optionToExclude.login === personalDetailOption.login)) { + if (optionsToExclude.some((optionToExclude) => optionToExclude.login === addSMSDomainIfPhoneNumber(personalDetailOption.login ?? ''))) { return; } const {searchText, participantsList, isChatRoom} = personalDetailOption; diff --git a/src/libs/ReportActionsUtils.ts b/src/libs/ReportActionsUtils.ts index 5a838cf8fbd5..5a1e029d2233 100644 --- a/src/libs/ReportActionsUtils.ts +++ b/src/libs/ReportActionsUtils.ts @@ -111,10 +111,6 @@ function isModifiedExpenseAction(reportAction: OnyxEntry): boolean return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.MODIFIEDEXPENSE; } -function isSubmittedExpenseAction(reportAction: OnyxEntry): boolean { - return reportAction?.actionName === CONST.REPORT.ACTIONS.TYPE.SUBMITTED; -} - function isWhisperAction(reportAction: OnyxEntry): boolean { return (reportAction?.whisperedToAccountIDs ?? []).length > 0; } @@ -857,7 +853,6 @@ export { isDeletedParentAction, isMessageDeleted, isModifiedExpenseAction, - isSubmittedExpenseAction, isMoneyRequestAction, isNotifiableReportAction, isPendingRemove, diff --git a/src/libs/ReportUtils.ts b/src/libs/ReportUtils.ts index 8bd8d2870903..4123c2b67aac 100644 --- a/src/libs/ReportUtils.ts +++ b/src/libs/ReportUtils.ts @@ -4493,6 +4493,36 @@ function isGroupChat(report: OnyxEntry): boolean { ); } +/** + * Assume any report without a reportID is unusable. + */ +function isValidReport(report?: OnyxEntry): boolean { + return Boolean(report?.reportID); +} + +/** + * Check to see if we are a participant of this report. + */ +function isReportParticipant(accountID: number, report: OnyxEntry): boolean { + if (!accountID) { + return false; + } + + // If we have a DM AND the accountID we are checking is the current user THEN we won't find them as a participant and must assume they are a participant + if (isDM(report) && accountID === currentUserAccountID) { + return true; + } + + const possibleAccountIDs = report?.participantAccountIDs ?? []; + if (report?.ownerAccountID) { + possibleAccountIDs.push(report?.ownerAccountID); + } + if (report?.managerID) { + possibleAccountIDs.push(report?.managerID); + } + return possibleAccountIDs.includes(accountID); +} + function shouldUseFullTitleToDisplay(report: OnyxEntry): boolean { return isMoneyRequestReport(report) || isPolicyExpenseChat(report) || isChatRoom(report) || isChatThread(report) || isTaskReport(report); } @@ -4872,6 +4902,8 @@ export { doesReportBelongToWorkspace, getChildReportNotificationPreference, getAllAncestorReportActions, + isReportParticipant, + isValidReport, isReportFieldOfTypeTitle, }; diff --git a/src/libs/actions/App.ts b/src/libs/actions/App.ts index 768dc530cc51..930c31fde287 100644 --- a/src/libs/actions/App.ts +++ b/src/libs/actions/App.ts @@ -6,6 +6,16 @@ import type {OnyxCollection, OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import * as API from '@libs/API'; +import type { + GetMissingOnyxMessagesParams, + HandleRestrictedEventParams, + OpenAppParams, + OpenOldDotLinkParams, + OpenProfileParams, + ReconnectAppParams, + UpdatePreferredLocaleParams, +} from '@libs/API/parameters'; +import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as Browser from '@libs/Browser'; import DateUtils from '@libs/DateUtils'; import Log from '@libs/Log'; @@ -103,15 +113,11 @@ function setLocale(locale: Locale) { }, ]; - type UpdatePreferredLocaleParams = { - value: Locale; - }; - const parameters: UpdatePreferredLocaleParams = { value: locale, }; - API.write('UpdatePreferredLocale', parameters, {optimisticData}); + API.write(WRITE_COMMANDS.UPDATE_PREFERRED_LOCALE, parameters, {optimisticData}); } function setLocaleAndNavigate(locale: Locale) { @@ -203,13 +209,9 @@ function getOnyxDataForOpenOrReconnect(isOpenApp = false): OnyxData { */ function openApp() { getPolicyParamsForOpenOrReconnect().then((policyParams: PolicyParamsForOpenOrReconnect) => { - type OpenAppParams = PolicyParamsForOpenOrReconnect & { - enablePriorityModeFilter: boolean; - }; - const params: OpenAppParams = {enablePriorityModeFilter: true, ...policyParams}; - API.read('OpenApp', params, getOnyxDataForOpenOrReconnect(true)); + API.read(READ_COMMANDS.OPEN_APP, params, getOnyxDataForOpenOrReconnect(true)); }); } @@ -220,12 +222,6 @@ function openApp() { function reconnectApp(updateIDFrom: OnyxEntry = 0) { console.debug(`[OnyxUpdates] App reconnecting with updateIDFrom: ${updateIDFrom}`); getPolicyParamsForOpenOrReconnect().then((policyParams) => { - type ReconnectParams = { - mostRecentReportActionLastModified?: string; - updateIDFrom?: number; - }; - type ReconnectAppParams = PolicyParamsForOpenOrReconnect & ReconnectParams; - const params: ReconnectAppParams = {...policyParams}; // When the app reconnects we do a fast "sync" of the LHN and only return chats that have new messages. We achieve this by sending the most recent reportActionID. @@ -243,7 +239,7 @@ function reconnectApp(updateIDFrom: OnyxEntry = 0) { params.updateIDFrom = updateIDFrom; } - API.write('ReconnectApp', params, getOnyxDataForOpenOrReconnect()); + API.write(WRITE_COMMANDS.RECONNECT_APP, params, getOnyxDataForOpenOrReconnect()); }); } @@ -255,8 +251,6 @@ function reconnectApp(updateIDFrom: OnyxEntry = 0) { function finalReconnectAppAfterActivatingReliableUpdates(): Promise { console.debug(`[OnyxUpdates] Executing last reconnect app with promise`); return getPolicyParamsForOpenOrReconnect().then((policyParams) => { - type ReconnectAppParams = PolicyParamsForOpenOrReconnect & {mostRecentReportActionLastModified?: string}; - const params: ReconnectAppParams = {...policyParams}; // When the app reconnects we do a fast "sync" of the LHN and only return chats that have new messages. We achieve this by sending the most recent reportActionID. @@ -273,7 +267,7 @@ function finalReconnectAppAfterActivatingReliableUpdates(): Promise { console.debug(`[OnyxUpdates] Fetching missing updates updateIDFrom: ${updateIDFrom} and updateIDTo: ${updateIDTo}`); - type GetMissingOnyxMessagesParams = { - updateIDFrom: number; - updateIDTo: number | string; - }; - const parameters: GetMissingOnyxMessagesParams = { updateIDFrom, updateIDTo, @@ -299,7 +288,7 @@ function getMissingOnyxUpdates(updateIDFrom = 0, updateIDTo: number | string = 0 // DO NOT FOLLOW THIS PATTERN!!!!! // It was absolutely necessary in order to block OnyxUpdates while fetching the missing updates from the server or else the udpates aren't applied in the proper order. // eslint-disable-next-line rulesdir/no-api-side-effects-method - return API.makeRequestWithSideEffects('GetMissingOnyxMessages', parameters, getOnyxDataForOpenOrReconnect()); + return API.makeRequestWithSideEffects(SIDE_EFFECT_REQUEST_COMMANDS.GET_MISSING_ONYX_MESSAGES, parameters, getOnyxDataForOpenOrReconnect()); } /** @@ -436,17 +425,13 @@ function openProfile(personalDetails: OnyxTypes.PersonalDetails) { newTimezoneData = DateUtils.formatToSupportedTimezone(newTimezoneData); - type OpenProfileParams = { - timezone: string; - }; - const parameters: OpenProfileParams = { timezone: JSON.stringify(newTimezoneData), }; // We expect currentUserAccountID to be a number because it doesn't make sense to open profile if currentUserAccountID is not set if (typeof currentUserAccountID === 'number') { - API.write('OpenProfile', parameters, { + API.write(WRITE_COMMANDS.OPEN_PROFILE, parameters, { optimisticData: [ { onyxMethod: Onyx.METHOD.MERGE, @@ -489,14 +474,10 @@ function beginDeepLinkRedirect(shouldAuthenticateWithCurrentAccount = true) { return; } - type OpenOldDotLinkParams = { - shouldRetry: boolean; - }; - const parameters: OpenOldDotLinkParams = {shouldRetry: false}; // eslint-disable-next-line rulesdir/no-api-side-effects-method - API.makeRequestWithSideEffects('OpenOldDotLink', parameters, {}).then((response) => { + API.makeRequestWithSideEffects(SIDE_EFFECT_REQUEST_COMMANDS.OPEN_OLD_DOT_LINK, parameters, {}).then((response) => { if (!response) { Log.alert( 'Trying to redirect via deep link, but the response is empty. User likely not authenticated.', @@ -518,13 +499,9 @@ function beginDeepLinkRedirectAfterTransition(shouldAuthenticateWithCurrentAccou } function handleRestrictedEvent(eventName: string) { - type HandleRestrictedEventParams = { - eventName: string; - }; - const parameters: HandleRestrictedEventParams = {eventName}; - API.write('HandleRestrictedEvent', parameters); + API.write(WRITE_COMMANDS.HANDLE_RESTRICTED_EVENT, parameters); } export { diff --git a/src/libs/actions/BankAccounts.ts b/src/libs/actions/BankAccounts.ts index 1ce6bc38191f..58509379b232 100644 --- a/src/libs/actions/BankAccounts.ts +++ b/src/libs/actions/BankAccounts.ts @@ -1,5 +1,20 @@ import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; +import type { + AddPersonalBankAccountParams, + BankAccountHandlePlaidErrorParams, + ConnectBankAccountManuallyParams, + ConnectBankAccountWithPlaidParams, + DeletePaymentBankAccountParams, + OpenReimbursementAccountPageParams, + UpdateCompanyInformationForBankAccountParams, + UpdatePersonalInformationForBankAccountParams, + ValidateBankAccountWithTransactionsParams, + VerifyIdentityForBankAccountParams, +} from '@libs/API/parameters'; +import type UpdateBeneficialOwnersForBankAccountParams from '@libs/API/parameters/UpdateBeneficialOwnersForBankAccountParams'; +import type {BankAccountCompanyInformation} from '@libs/API/parameters/UpdateCompanyInformationForBankAccountParams'; +import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as ErrorUtils from '@libs/ErrorUtils'; import Navigation from '@libs/Navigation/Navigation'; import * as PlaidDataProps from '@pages/ReimbursementAccount/plaidDataPropTypes'; @@ -8,7 +23,7 @@ import ONYXKEYS from '@src/ONYXKEYS'; import ROUTES from '@src/ROUTES'; import type PlaidBankAccount from '@src/types/onyx/PlaidBankAccount'; import type {BankAccountStep, BankAccountSubStep} from '@src/types/onyx/ReimbursementAccount'; -import type {ACHContractStepProps, BankAccountStepProps, CompanyStepProps, OnfidoData, ReimbursementAccountProps, RequestorStepProps} from '@src/types/onyx/ReimbursementAccountDraft'; +import type {OnfidoData} from '@src/types/onyx/ReimbursementAccountDraft'; import type {OnyxData} from '@src/types/onyx/Request'; import * as ReimbursementAccount from './ReimbursementAccount'; @@ -27,8 +42,6 @@ export { export {openPlaidBankAccountSelector, openPlaidBankLogin} from './Plaid'; export {openOnfidoFlow, answerQuestionsForWallet, verifyIdentity, acceptWalletTerms} from './Wallet'; -type BankAccountCompanyInformation = BankAccountStepProps & CompanyStepProps & ReimbursementAccountProps; - type ReimbursementAccountStep = BankAccountStep | ''; type ReimbursementAccountSubStep = BankAccountSubStep | ''; @@ -123,17 +136,6 @@ function getVBBADataForOnyx(currentStep?: BankAccountStep): OnyxData { * Submit Bank Account step with Plaid data so php can perform some checks. */ function connectBankAccountWithPlaid(bankAccountID: number, selectedPlaidBankAccount: PlaidBankAccount) { - const commandName = 'ConnectBankAccountWithPlaid'; - - type ConnectBankAccountWithPlaidParams = { - bankAccountID: number; - routingNumber: string; - accountNumber: string; - bank?: string; - plaidAccountID: string; - plaidAccessToken: string; - }; - const parameters: ConnectBankAccountWithPlaidParams = { bankAccountID, routingNumber: selectedPlaidBankAccount.routingNumber, @@ -143,7 +145,7 @@ function connectBankAccountWithPlaid(bankAccountID: number, selectedPlaidBankAcc plaidAccessToken: selectedPlaidBankAccount.plaidAccessToken, }; - API.write(commandName, parameters, getVBBADataForOnyx()); + API.write(WRITE_COMMANDS.CONNECT_BANK_ACCOUNT_WITH_PLAID, parameters, getVBBADataForOnyx()); } /** @@ -152,19 +154,6 @@ function connectBankAccountWithPlaid(bankAccountID: number, selectedPlaidBankAcc * TODO: offline pattern for this command will have to be added later once the pattern B design doc is complete */ function addPersonalBankAccount(account: PlaidBankAccount) { - const commandName = 'AddPersonalBankAccount'; - - type AddPersonalBankAccountParams = { - addressName: string; - routingNumber: string; - accountNumber: string; - isSavings: boolean; - setupType: string; - bank?: string; - plaidAccountID: string; - plaidAccessToken: string; - }; - const parameters: AddPersonalBankAccountParams = { addressName: account.addressName, routingNumber: account.routingNumber, @@ -211,12 +200,10 @@ function addPersonalBankAccount(account: PlaidBankAccount) { ], }; - API.write(commandName, parameters, onyxData); + API.write(WRITE_COMMANDS.ADD_PERSONAL_BANK_ACCOUNT, parameters, onyxData); } function deletePaymentBankAccount(bankAccountID: number) { - type DeletePaymentBankAccountParams = {bankAccountID: number}; - const parameters: DeletePaymentBankAccountParams = {bankAccountID}; const onyxData: OnyxData = { @@ -239,7 +226,7 @@ function deletePaymentBankAccount(bankAccountID: number) { ], }; - API.write('DeletePaymentBankAccount', parameters, onyxData); + API.write(WRITE_COMMANDS.DELETE_PAYMENT_BANK_ACCOUNT, parameters, onyxData); } /** @@ -247,16 +234,11 @@ function deletePaymentBankAccount(bankAccountID: number) { * * This action is called by the requestor step in the Verified Bank Account flow */ -function updatePersonalInformationForBankAccount(params: RequestorStepProps) { - API.write('UpdatePersonalInformationForBankAccount', params, getVBBADataForOnyx(CONST.BANK_ACCOUNT.STEP.REQUESTOR)); +function updatePersonalInformationForBankAccount(params: UpdatePersonalInformationForBankAccountParams) { + API.write(WRITE_COMMANDS.UPDATE_PERSONAL_INFORMATION_FOR_BANK_ACCOUNT, params, getVBBADataForOnyx(CONST.BANK_ACCOUNT.STEP.REQUESTOR)); } function validateBankAccount(bankAccountID: number, validateCode: string) { - type ValidateBankAccountWithTransactionsParams = { - bankAccountID: number; - validateCode: string; - }; - const parameters: ValidateBankAccountWithTransactionsParams = { bankAccountID, validateCode, @@ -293,7 +275,7 @@ function validateBankAccount(bankAccountID: number, validateCode: string) { ], }; - API.write('ValidateBankAccountWithTransactions', parameters, onyxData); + API.write(WRITE_COMMANDS.VALIDATE_BANK_ACCOUNT_WITH_TRANSACTIONS, parameters, onyxData); } function clearReimbursementAccount() { @@ -331,37 +313,29 @@ function openReimbursementAccountPage(stepToOpen: ReimbursementAccountStep, subS ], }; - type OpenReimbursementAccountPageParams = { - stepToOpen: ReimbursementAccountStep; - subStep: ReimbursementAccountSubStep; - localCurrentStep: ReimbursementAccountStep; - }; - const parameters: OpenReimbursementAccountPageParams = { stepToOpen, subStep, localCurrentStep, }; - return API.read('OpenReimbursementAccountPage', parameters, onyxData); + return API.read(READ_COMMANDS.OPEN_REIMBURSEMENT_ACCOUNT_PAGE, parameters, onyxData); } /** * Updates the bank account in the database with the company step data */ function updateCompanyInformationForBankAccount(bankAccount: BankAccountCompanyInformation, policyID: string) { - type UpdateCompanyInformationForBankAccountParams = BankAccountCompanyInformation & {policyID: string}; - const parameters: UpdateCompanyInformationForBankAccountParams = {...bankAccount, policyID}; - API.write('UpdateCompanyInformationForBankAccount', parameters, getVBBADataForOnyx(CONST.BANK_ACCOUNT.STEP.COMPANY)); + API.write(WRITE_COMMANDS.UPDATE_COMPANY_INFORMATION_FOR_BANK_ACCOUNT, parameters, getVBBADataForOnyx(CONST.BANK_ACCOUNT.STEP.COMPANY)); } /** * Add beneficial owners for the bank account, accept the ACH terms and conditions and verify the accuracy of the information provided */ -function updateBeneficialOwnersForBankAccount(params: ACHContractStepProps) { - API.write('UpdateBeneficialOwnersForBankAccount', params, getVBBADataForOnyx()); +function updateBeneficialOwnersForBankAccount(params: UpdateBeneficialOwnersForBankAccountParams) { + API.write(WRITE_COMMANDS.UPDATE_BENEFICIAL_OWNERS_FOR_BANK_ACCOUNT, params, getVBBADataForOnyx()); } /** @@ -369,13 +343,6 @@ function updateBeneficialOwnersForBankAccount(params: ACHContractStepProps) { * */ function connectBankAccountManually(bankAccountID: number, accountNumber?: string, routingNumber?: string, plaidMask?: string) { - type ConnectBankAccountManuallyParams = { - bankAccountID: number; - accountNumber?: string; - routingNumber?: string; - plaidMask?: string; - }; - const parameters: ConnectBankAccountManuallyParams = { bankAccountID, accountNumber, @@ -383,29 +350,24 @@ function connectBankAccountManually(bankAccountID: number, accountNumber?: strin plaidMask, }; - API.write('ConnectBankAccountManually', parameters, getVBBADataForOnyx(CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT)); + API.write(WRITE_COMMANDS.CONNECT_BANK_ACCOUNT_MANUALLY, parameters, getVBBADataForOnyx(CONST.BANK_ACCOUNT.STEP.BANK_ACCOUNT)); } /** * Verify the user's identity via Onfido */ function verifyIdentityForBankAccount(bankAccountID: number, onfidoData: OnfidoData) { - type VerifyIdentityForBankAccountParams = { - bankAccountID: number; - onfidoData: string; - }; - const parameters: VerifyIdentityForBankAccountParams = { bankAccountID, onfidoData: JSON.stringify(onfidoData), }; - API.write('VerifyIdentityForBankAccount', parameters, getVBBADataForOnyx()); + API.write(WRITE_COMMANDS.VERIFY_IDENTITY_FOR_BANK_ACCOUNT, parameters, getVBBADataForOnyx()); } function openWorkspaceView() { API.read( - 'OpenWorkspaceView', + READ_COMMANDS.OPEN_WORKSPACE_VIEW, {}, { optimisticData: [ @@ -440,13 +402,6 @@ function openWorkspaceView() { } function handlePlaidError(bankAccountID: number, error: string, errorDescription: string, plaidRequestID: string) { - type BankAccountHandlePlaidErrorParams = { - bankAccountID: number; - error: string; - errorDescription: string; - plaidRequestID: string; - }; - const parameters: BankAccountHandlePlaidErrorParams = { bankAccountID, error, @@ -454,7 +409,7 @@ function handlePlaidError(bankAccountID: number, error: string, errorDescription plaidRequestID, }; - API.write('BankAccount_HandlePlaidError', parameters); + API.write(WRITE_COMMANDS.BANK_ACCOUNT_HANDLE_PLAID_ERROR, parameters); } /** diff --git a/src/libs/actions/Card.ts b/src/libs/actions/Card.ts index aa892d3817aa..38a421409ade 100644 --- a/src/libs/actions/Card.ts +++ b/src/libs/actions/Card.ts @@ -1,6 +1,8 @@ import Onyx from 'react-native-onyx'; import type {OnyxUpdate} from 'react-native-onyx'; import * as API from '@libs/API'; +import type {ActivatePhysicalExpensifyCardParams, ReportVirtualExpensifyCardFraudParams, RequestReplacementExpensifyCardParams, RevealExpensifyCardDetailsParams} from '@libs/API/parameters'; +import {SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as Localize from '@libs/Localize'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -39,15 +41,11 @@ function reportVirtualExpensifyCardFraud(cardID: number) { }, ]; - type ReportVirtualExpensifyCardFraudParams = { - cardID: number; - }; - const parameters: ReportVirtualExpensifyCardFraudParams = { cardID, }; - API.write('ReportVirtualExpensifyCardFraud', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.REPORT_VIRTUAL_EXPENSIFY_CARD_FRAUD, parameters, {optimisticData, successData, failureData}); } /** @@ -87,17 +85,12 @@ function requestReplacementExpensifyCard(cardID: number, reason: ReplacementReas }, ]; - type RequestReplacementExpensifyCardParams = { - cardID: number; - reason: string; - }; - const parameters: RequestReplacementExpensifyCardParams = { cardID, reason, }; - API.write('RequestReplacementExpensifyCard', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.REQUEST_REPLACEMENT_EXPENSIFY_CARD, parameters, {optimisticData, successData, failureData}); } /** @@ -141,17 +134,12 @@ function activatePhysicalExpensifyCard(cardLastFourDigits: string, cardID: numbe }, ]; - type ActivatePhysicalExpensifyCardParams = { - cardLastFourDigits: string; - cardID: number; - }; - const parameters: ActivatePhysicalExpensifyCardParams = { cardLastFourDigits, cardID, }; - API.write('ActivatePhysicalExpensifyCard', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.ACTIVATE_PHYSICAL_EXPENSIFY_CARD, parameters, {optimisticData, successData, failureData}); } /** @@ -173,12 +161,10 @@ function clearCardListErrors(cardID: number) { */ function revealVirtualCardDetails(cardID: number): Promise { return new Promise((resolve, reject) => { - type RevealExpensifyCardDetailsParams = {cardID: number}; - const parameters: RevealExpensifyCardDetailsParams = {cardID}; // eslint-disable-next-line rulesdir/no-api-side-effects-method - API.makeRequestWithSideEffects('RevealExpensifyCardDetails', parameters) + API.makeRequestWithSideEffects(SIDE_EFFECT_REQUEST_COMMANDS.REVEAL_EXPENSIFY_CARD_DETAILS, parameters) .then((response) => { if (response?.jsonCode !== CONST.JSON_CODE.SUCCESS) { reject(Localize.translateLocal('cardPage.cardDetailsLoadingFailure')); diff --git a/src/libs/actions/Chronos.ts b/src/libs/actions/Chronos.ts index 0bb949687e6d..548b8398beec 100644 --- a/src/libs/actions/Chronos.ts +++ b/src/libs/actions/Chronos.ts @@ -1,6 +1,8 @@ import type {OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; +import type {ChronosRemoveOOOEventParams} from '@libs/API/parameters'; +import {WRITE_COMMANDS} from '@libs/API/types'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {ChronosOOOEvent} from '@src/types/onyx/OriginalMessage'; @@ -46,14 +48,12 @@ const removeEvent = (reportID: string, reportActionID: string, eventID: string, }, ]; - API.write( - 'Chronos_RemoveOOOEvent', - { - googleEventID: eventID, - reportActionID, - }, - {optimisticData, successData, failureData}, - ); + const parameters: ChronosRemoveOOOEventParams = { + googleEventID: eventID, + reportActionID, + }; + + API.write(WRITE_COMMANDS.CHRONOS_REMOVE_OOO_EVENT, parameters, {optimisticData, successData, failureData}); }; export { diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js index eb9541edcad2..5297d9aa4463 100644 --- a/src/libs/actions/IOU.js +++ b/src/libs/actions/IOU.js @@ -10,6 +10,7 @@ import * as API from '@libs/API'; import * as CurrencyUtils from '@libs/CurrencyUtils'; import DateUtils from '@libs/DateUtils'; import * as ErrorUtils from '@libs/ErrorUtils'; +import * as FileUtils from '@libs/fileDownload/FileUtils'; import * as IOUUtils from '@libs/IOUUtils'; import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; import * as Localize from '@libs/Localize'; @@ -311,6 +312,29 @@ function getReceiptError(receipt, filename, isScanRequest = true) { : ErrorUtils.getMicroSecondOnyxErrorObject({error: CONST.IOU.RECEIPT_ERROR, source: receipt.source, filename}); } +/** + * Return the object to update hasOutstandingChildRequest + * @param {Object} [policy] + * @param {Boolean} needsToBeManuallySubmitted + * @returns {Object} + */ +function getOutstandingChildRequest(policy, needsToBeManuallySubmitted) { + if (!needsToBeManuallySubmitted) { + return { + hasOutstandingChildRequest: false, + }; + } + + if (PolicyUtils.isPolicyAdmin(policy)) { + return { + hasOutstandingChildRequest: true, + }; + } + + // We don't need to update hasOutstandingChildRequest in this case + return {}; +} + /** * Builds the Onyx data for a money request. * @@ -329,7 +353,7 @@ function getReceiptError(receipt, filename, isScanRequest = true) { * @param {Object} policy - May be undefined, an empty object, or an object matching the Policy type (src/types/onyx/Policy.ts) * @param {Array} policyTags * @param {Array} policyCategories - * @param {Boolean} hasOutstandingChildRequest + * @param {Boolean} needsToBeManuallySubmitted * @returns {Array} - An array containing the optimistic data, success data, and failure data. */ function buildOnyxDataForMoneyRequest( @@ -348,9 +372,10 @@ function buildOnyxDataForMoneyRequest( policy, policyTags, policyCategories, - hasOutstandingChildRequest = false, + needsToBeManuallySubmitted = true, ) { const isScanRequest = TransactionUtils.isScanRequest(transaction); + const outstandingChildRequest = getOutstandingChildRequest(needsToBeManuallySubmitted, policy); const optimisticData = [ { // Use SET for new reports because it doesn't exist yet, is faster and we need the data to be available when we navigate to the chat page @@ -361,7 +386,7 @@ function buildOnyxDataForMoneyRequest( lastReadTime: DateUtils.getDBTime(), lastMessageTranslationKey: '', iouReportID: iouReport.reportID, - hasOutstandingChildRequest, + ...outstandingChildRequest, ...(isNewChatReport ? {pendingFields: {createChat: CONST.RED_BRICK_ROAD_PENDING_ACTION.ADD}} : {}), }, }, @@ -506,6 +531,7 @@ function buildOnyxDataForMoneyRequest( iouReportID: chatReport.iouReportID, lastReadTime: chatReport.lastReadTime, pendingFields: null, + hasOutstandingChildRequest: chatReport.hasOutstandingChildRequest, ...(isNewChatReport ? { errorFields: { @@ -687,7 +713,7 @@ function getMoneyRequestInformation( let iouReport = isNewIOUReport ? null : allReports[`${ONYXKEYS.COLLECTION.REPORT}${chatReport.iouReportID}`]; // Check if the Scheduled Submit is enabled in case of expense report - let needsToBeManuallySubmitted = false; + let needsToBeManuallySubmitted = true; let isFromPaidPolicy = false; if (isPolicyExpenseChat) { isFromPaidPolicy = PolicyUtils.isPaidGroupPolicy(policy); @@ -806,10 +832,6 @@ function getMoneyRequestInformation( } : undefined; - // The policy expense chat should have the GBR only when its a paid policy and the scheduled submit is turned off - // so the employee has to submit to their manager manually. - const hasOutstandingChildRequest = isPolicyExpenseChat && needsToBeManuallySubmitted; - // STEP 5: Build Onyx Data const [optimisticData, successData, failureData] = buildOnyxDataForMoneyRequest( chatReport, @@ -827,7 +849,7 @@ function getMoneyRequestInformation( policy, policyTags, policyCategories, - hasOutstandingChildRequest, + needsToBeManuallySubmitted, ); return { @@ -1823,6 +1845,9 @@ function startSplitBill(participants, currentUserLogin, currentUserAccountID, co CONST.TRANSACTION.PARTIAL_TRANSACTION_MERCHANT, receiptObject, filename, + undefined, + category, + tag, ); // Note: The created action must be optimistically generated before the IOU action so there's no chance that the created action appears after the IOU action in the chat @@ -2624,7 +2649,7 @@ function deleteMoneyRequest(transactionID, reportAction, isSingleTransactionView amount: CurrencyUtils.convertToDisplayString(updatedIOUReport.total, updatedIOUReport.currency), }); updatedReportPreviewAction.message[0].text = messageText; - updatedReportPreviewAction.message[0].html = messageText; + updatedReportPreviewAction.message[0].html = shouldDeleteIOUReport ? '' : messageText; if (reportPreviewAction.childMoneyRequestCount > 0) { updatedReportPreviewAction.childMoneyRequestCount = reportPreviewAction.childMoneyRequestCount - 1; @@ -3698,6 +3723,32 @@ function getIOUReportID(iou, route) { return lodashGet(route, 'params.reportID') || lodashGet(iou, 'participants.0.reportID', ''); } +/** + * @param {String} receiptFilename + * @param {String} receiptPath + * @param {Function} onSuccess + * @param {String} requestType + * @param {String} iouType + * @param {String} transactionID + * @param {String} reportID + */ +// eslint-disable-next-line rulesdir/no-negated-variables +function navigateToStartStepIfScanFileCannotBeRead(receiptFilename, receiptPath, onSuccess, requestType, iouType, transactionID, reportID) { + if (!receiptFilename || !receiptPath) { + return; + } + + const onFailure = () => { + setMoneyRequestReceipt(transactionID, '', '', true); + if (requestType === CONST.IOU.REQUEST_TYPE.MANUAL) { + Navigation.navigate(ROUTES.MONEY_REQUEST_STEP_SCAN.getRoute(CONST.IOU.ACTION.CREATE, iouType, transactionID, reportID, Navigation.getActiveRouteWithoutParams())); + return; + } + IOUUtils.navigateToStartMoneyRequestStep(requestType, iouType, transactionID, reportID); + }; + FileUtils.readFileAsync(receiptPath, receiptFilename, onSuccess, onFailure); +} + export { setMoneyRequestParticipants, createDistanceRequest, @@ -3757,4 +3808,5 @@ export { detachReceipt, getIOUReportID, editMoneyRequest, + navigateToStartStepIfScanFileCannotBeRead, }; diff --git a/src/libs/actions/Link.ts b/src/libs/actions/Link.ts index 186c9beed970..ae95424f5776 100644 --- a/src/libs/actions/Link.ts +++ b/src/libs/actions/Link.ts @@ -1,5 +1,6 @@ import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; +import {SIDE_EFFECT_REQUEST_COMMANDS} from '@libs/API/types'; import asyncOpenURL from '@libs/asyncOpenURL'; import * as Environment from '@libs/Environment/Environment'; import Navigation from '@libs/Navigation/Navigation'; @@ -55,7 +56,7 @@ function openOldDotLink(url: string) { // If shortLivedAuthToken is not accessible, fallback to opening the link without the token. asyncOpenURL( // eslint-disable-next-line rulesdir/no-api-side-effects-method - API.makeRequestWithSideEffects('OpenOldDotLink', {}, {}) + API.makeRequestWithSideEffects(SIDE_EFFECT_REQUEST_COMMANDS.OPEN_OLD_DOT_LINK, {}, {}) .then((response) => (response ? buildOldDotURL(url, response.shortLivedAuthToken) : buildOldDotURL(url))) .catch(() => buildOldDotURL(url)), (oldDotURL) => oldDotURL, diff --git a/src/libs/actions/MapboxToken.ts b/src/libs/actions/MapboxToken.ts index 54f99b58fbeb..3b98f79698ba 100644 --- a/src/libs/actions/MapboxToken.ts +++ b/src/libs/actions/MapboxToken.ts @@ -4,6 +4,7 @@ import {AppState} from 'react-native'; import Onyx from 'react-native-onyx'; import * as ActiveClientManager from '@libs/ActiveClientManager'; import * as API from '@libs/API'; +import {READ_COMMANDS} from '@libs/API/types'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {MapboxAccessToken, Network} from '@src/types/onyx'; @@ -38,7 +39,7 @@ const setExpirationTimer = () => { return; } console.debug(`[MapboxToken] Fetching a new token after waiting ${REFRESH_INTERVAL / 1000 / 60} minutes`); - API.read('GetMapboxAccessToken', {}, {}); + API.read(READ_COMMANDS.GET_MAPBOX_ACCESS_TOKEN, {}, {}); }, REFRESH_INTERVAL); }; @@ -51,7 +52,7 @@ const clearToken = () => { }; const fetchToken = () => { - API.read('GetMapboxAccessToken', {}, {}); + API.read(READ_COMMANDS.GET_MAPBOX_ACCESS_TOKEN, {}, {}); isCurrentlyFetchingToken = true; }; diff --git a/src/libs/actions/PaymentMethods.ts b/src/libs/actions/PaymentMethods.ts index b9632d05d581..1eebed9a9df4 100644 --- a/src/libs/actions/PaymentMethods.ts +++ b/src/libs/actions/PaymentMethods.ts @@ -4,9 +4,10 @@ import type {GestureResponderEvent} from 'react-native'; import type {OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx/lib/types'; -import type {ValueOf} from 'type-fest'; import type {TransferMethod} from '@components/KYCWall/types'; import * as API from '@libs/API'; +import type {AddPaymentCardParams, DeletePaymentCardParams, MakeDefaultPaymentMethodParams, PaymentCardParams, TransferWalletBalanceParams} from '@libs/API/parameters'; +import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as CardUtils from '@libs/CardUtils'; import Navigation from '@libs/Navigation/Navigation'; import CONST from '@src/CONST'; @@ -63,7 +64,7 @@ function openWalletPage() { ]; return API.read( - 'OpenPaymentsPage', + READ_COMMANDS.OPEN_PAYMENTS_PAGE, {}, { optimisticData, @@ -134,24 +135,17 @@ function getMakeDefaultPaymentOnyxData( * */ function makeDefaultPaymentMethod(bankAccountID: number, fundID: number, previousPaymentMethod: PaymentMethod, currentPaymentMethod: PaymentMethod) { - type MakeDefaultPaymentMethodParams = { - bankAccountID: number; - fundID: number; - }; - const parameters: MakeDefaultPaymentMethodParams = { bankAccountID, fundID, }; - API.write('MakeDefaultPaymentMethod', parameters, { + API.write(WRITE_COMMANDS.MAKE_DEFAULT_PAYMENT_METHOD, parameters, { optimisticData: getMakeDefaultPaymentOnyxData(bankAccountID, fundID, previousPaymentMethod, currentPaymentMethod, true), failureData: getMakeDefaultPaymentOnyxData(bankAccountID, fundID, previousPaymentMethod, currentPaymentMethod, false), }); } -type PaymentCardParams = {expirationDate: string; cardNumber: string; securityCode: string; nameOnCard: string; addressZipCode: string}; - /** * Calls the API to add a new card. * @@ -160,17 +154,6 @@ function addPaymentCard(params: PaymentCardParams) { const cardMonth = CardUtils.getMonthFromExpirationDateString(params.expirationDate); const cardYear = CardUtils.getYearFromExpirationDateString(params.expirationDate); - type AddPaymentCardParams = { - cardNumber: string; - cardYear: string; - cardMonth: string; - cardCVV: string; - addressName: string; - addressZip: string; - currency: ValueOf; - isP2PDebitCard: boolean; - }; - const parameters: AddPaymentCardParams = { cardNumber: params.cardNumber, cardYear, @@ -206,7 +189,7 @@ function addPaymentCard(params: PaymentCardParams) { }, ]; - API.write('AddPaymentCard', parameters, { + API.write(WRITE_COMMANDS.ADD_PAYMENT_CARD, parameters, { optimisticData, successData, failureData, @@ -232,9 +215,7 @@ function transferWalletBalance(paymentMethod: PaymentMethod) { const paymentMethodIDKey = paymentMethod.accountType === CONST.PAYMENT_METHODS.PERSONAL_BANK_ACCOUNT ? CONST.PAYMENT_METHOD_ID_KEYS.BANK_ACCOUNT : CONST.PAYMENT_METHOD_ID_KEYS.DEBIT_CARD; - type TransferWalletBalanceParameters = Partial, number | undefined>>; - - const parameters: TransferWalletBalanceParameters = { + const parameters: TransferWalletBalanceParams = { [paymentMethodIDKey]: paymentMethod.methodID, }; @@ -272,7 +253,7 @@ function transferWalletBalance(paymentMethod: PaymentMethod) { }, ]; - API.write('TransferWalletBalance', parameters, { + API.write(WRITE_COMMANDS.TRANSFER_WALLET_BALANCE, parameters, { optimisticData, successData, failureData, @@ -358,10 +339,6 @@ function clearWalletTermsError() { } function deletePaymentCard(fundID: number) { - type DeletePaymentCardParams = { - fundID: number; - }; - const parameters: DeletePaymentCardParams = { fundID, }; @@ -374,7 +351,7 @@ function deletePaymentCard(fundID: number) { }, ]; - API.write('DeletePaymentCard', parameters, { + API.write(WRITE_COMMANDS.DELETE_PAYMENT_CARD, parameters, { optimisticData, }); } diff --git a/src/libs/actions/PersonalDetails.ts b/src/libs/actions/PersonalDetails.ts index 508cca34fb88..e7d9b48c46e9 100644 --- a/src/libs/actions/PersonalDetails.ts +++ b/src/libs/actions/PersonalDetails.ts @@ -2,6 +2,18 @@ import Str from 'expensify-common/lib/str'; import type {OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; +import type { + OpenPublicProfilePageParams, + UpdateAutomaticTimezoneParams, + UpdateDateOfBirthParams, + UpdateDisplayNameParams, + UpdateHomeAddressParams, + UpdateLegalNameParams, + UpdatePronounsParams, + UpdateSelectedTimezoneParams, + UpdateUserAvatarParams, +} from '@libs/API/parameters'; +import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import type {CustomRNImageManipulatorResult} from '@libs/cropOrRotateImage/types'; import DateUtils from '@libs/DateUtils'; import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; @@ -107,13 +119,9 @@ function getCountryISO(countryName: string): string { function updatePronouns(pronouns: string) { if (currentUserAccountID) { - type UpdatePronounsParams = { - pronouns: string; - }; - const parameters: UpdatePronounsParams = {pronouns}; - API.write('UpdatePronouns', parameters, { + API.write(WRITE_COMMANDS.UPDATE_PRONOUNS, parameters, { optimisticData: [ { onyxMethod: Onyx.METHOD.MERGE, @@ -133,14 +141,9 @@ function updatePronouns(pronouns: string) { function updateDisplayName(firstName: string, lastName: string) { if (currentUserAccountID) { - type UpdateDisplayNameParams = { - firstName: string; - lastName: string; - }; - const parameters: UpdateDisplayNameParams = {firstName, lastName}; - API.write('UpdateDisplayName', parameters, { + API.write(WRITE_COMMANDS.UPDATE_DISPLAY_NAME, parameters, { optimisticData: [ { onyxMethod: Onyx.METHOD.MERGE, @@ -164,14 +167,9 @@ function updateDisplayName(firstName: string, lastName: string) { } function updateLegalName(legalFirstName: string, legalLastName: string) { - type UpdateLegalNameParams = { - legalFirstName: string; - legalLastName: string; - }; - const parameters: UpdateLegalNameParams = {legalFirstName, legalLastName}; - API.write('UpdateLegalName', parameters, { + API.write(WRITE_COMMANDS.UPDATE_LEGAL_NAME, parameters, { optimisticData: [ { onyxMethod: Onyx.METHOD.MERGE, @@ -191,13 +189,9 @@ function updateLegalName(legalFirstName: string, legalLastName: string) { * @param dob - date of birth */ function updateDateOfBirth({dob}: DateOfBirthForm) { - type UpdateDateOfBirthParams = { - dob?: string; - }; - const parameters: UpdateDateOfBirthParams = {dob}; - API.write('UpdateDateOfBirth', parameters, { + API.write(WRITE_COMMANDS.UPDATE_DATE_OF_BIRTH, parameters, { optimisticData: [ { onyxMethod: Onyx.METHOD.MERGE, @@ -213,16 +207,6 @@ function updateDateOfBirth({dob}: DateOfBirthForm) { } function updateAddress(street: string, street2: string, city: string, state: string, zip: string, country: string) { - type UpdateHomeAddressParams = { - homeAddressStreet: string; - addressStreet2: string; - homeAddressCity: string; - addressState: string; - addressZipCode: string; - addressCountry: string; - addressStateLong?: string; - }; - const parameters: UpdateHomeAddressParams = { homeAddressStreet: street, addressStreet2: street2, @@ -238,7 +222,7 @@ function updateAddress(street: string, street2: string, city: string, state: str parameters.addressStateLong = state; } - API.write('UpdateHomeAddress', parameters, { + API.write(WRITE_COMMANDS.UPDATE_HOME_ADDRESS, parameters, { optimisticData: [ { onyxMethod: Onyx.METHOD.MERGE, @@ -272,15 +256,12 @@ function updateAutomaticTimezone(timezone: Timezone) { return; } - type UpdateAutomaticTimezoneParams = { - timezone: string; - }; const formatedTimezone = DateUtils.formatToSupportedTimezone(timezone); const parameters: UpdateAutomaticTimezoneParams = { timezone: JSON.stringify(formatedTimezone), }; - API.write('UpdateAutomaticTimezone', parameters, { + API.write(WRITE_COMMANDS.UPDATE_AUTOMATIC_TIMEZONE, parameters, { optimisticData: [ { onyxMethod: Onyx.METHOD.MERGE, @@ -304,16 +285,12 @@ function updateSelectedTimezone(selectedTimezone: SelectedTimezone) { selected: selectedTimezone, }; - type UpdateSelectedTimezoneParams = { - timezone: string; - }; - const parameters: UpdateSelectedTimezoneParams = { timezone: JSON.stringify(timezone), }; if (currentUserAccountID) { - API.write('UpdateSelectedTimezone', parameters, { + API.write(WRITE_COMMANDS.UPDATE_SELECTED_TIMEZONE, parameters, { optimisticData: [ { onyxMethod: Onyx.METHOD.MERGE, @@ -365,11 +342,7 @@ function openPersonalDetailsPage() { }, ]; - type OpenPersonalDetailsPageParams = Record; - - const parameters: OpenPersonalDetailsPageParams = {}; - - API.read('OpenPersonalDetailsPage', parameters, {optimisticData, successData, failureData}); + API.read(READ_COMMANDS.OPEN_PERSONAL_DETAILS_PAGE, {}, {optimisticData, successData, failureData}); } /** @@ -414,13 +387,9 @@ function openPublicProfilePage(accountID: number) { }, ]; - type OpenPublicProfilePageParams = { - accountID: number; - }; - const parameters: OpenPublicProfilePageParams = {accountID}; - API.read('OpenPublicProfilePage', parameters, {optimisticData, successData, failureData}); + API.read(READ_COMMANDS.OPEN_PUBLIC_PROFILE_PAGE, parameters, {optimisticData, successData, failureData}); } /** @@ -481,13 +450,9 @@ function updateAvatar(file: File | CustomRNImageManipulatorResult) { }, ]; - type UpdateUserAvatarParams = { - file: File | CustomRNImageManipulatorResult; - }; - const parameters: UpdateUserAvatarParams = {file}; - API.write('UpdateUserAvatar', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.UPDATE_USER_AVATAR, parameters, {optimisticData, successData, failureData}); } /** @@ -526,11 +491,7 @@ function deleteAvatar() { }, ]; - type DeleteUserAvatarParams = Record; - - const parameters: DeleteUserAvatarParams = {}; - - API.write('DeleteUserAvatar', parameters, {optimisticData, failureData}); + API.write(WRITE_COMMANDS.DELETE_USER_AVATAR, {}, {optimisticData, failureData}); } /** diff --git a/src/libs/actions/Plaid.ts b/src/libs/actions/Plaid.ts index 8c35c391790a..78bc91618215 100644 --- a/src/libs/actions/Plaid.ts +++ b/src/libs/actions/Plaid.ts @@ -1,5 +1,7 @@ import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; +import type {OpenPlaidBankAccountSelectorParams, OpenPlaidBankLoginParams} from '@libs/API/parameters'; +import {READ_COMMANDS} from '@libs/API/types'; import getPlaidLinkTokenParameters from '@libs/getPlaidLinkTokenParameters'; import * as PlaidDataProps from '@pages/ReimbursementAccount/plaidDataPropTypes'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -10,11 +12,13 @@ import ONYXKEYS from '@src/ONYXKEYS'; function openPlaidBankLogin(allowDebit: boolean, bankAccountID: number) { // redirect_uri needs to be in kebab case convention because that's how it's passed to the backend const {redirectURI} = getPlaidLinkTokenParameters(); - const params = { + + const params: OpenPlaidBankLoginParams = { redirectURI, allowDebit, bankAccountID, }; + const optimisticData = [ { onyxMethod: Onyx.METHOD.SET, @@ -35,51 +39,49 @@ function openPlaidBankLogin(allowDebit: boolean, bankAccountID: number) { }, ]; - API.read('OpenPlaidBankLogin', params, {optimisticData}); + API.read(READ_COMMANDS.OPEN_PLAID_BANK_LOGIN, params, {optimisticData}); } function openPlaidBankAccountSelector(publicToken: string, bankName: string, allowDebit: boolean, bankAccountID: number) { - API.read( - 'OpenPlaidBankAccountSelector', - { - publicToken, - allowDebit, - bank: bankName, - bankAccountID, - }, - { - optimisticData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.PLAID_DATA, - value: { - isLoading: true, - errors: null, - bankName, - }, + const parameters: OpenPlaidBankAccountSelectorParams = { + publicToken, + allowDebit, + bank: bankName, + bankAccountID, + }; + + API.read(READ_COMMANDS.OPEN_PLAID_BANK_ACCOUNT_SELECTOR, parameters, { + optimisticData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PLAID_DATA, + value: { + isLoading: true, + errors: null, + bankName, }, - ], - successData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.PLAID_DATA, - value: { - isLoading: false, - errors: null, - }, + }, + ], + successData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PLAID_DATA, + value: { + isLoading: false, + errors: null, }, - ], - failureData: [ - { - onyxMethod: Onyx.METHOD.MERGE, - key: ONYXKEYS.PLAID_DATA, - value: { - isLoading: false, - }, + }, + ], + failureData: [ + { + onyxMethod: Onyx.METHOD.MERGE, + key: ONYXKEYS.PLAID_DATA, + value: { + isLoading: false, }, - ], - }, - ); + }, + ], + }); } export {openPlaidBankAccountSelector, openPlaidBankLogin}; diff --git a/src/libs/actions/Policy.ts b/src/libs/actions/Policy.ts index b47891e64350..d84fccfb196c 100644 --- a/src/libs/actions/Policy.ts +++ b/src/libs/actions/Policy.ts @@ -8,6 +8,23 @@ import type {OnyxCollection, OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {NullishDeep, OnyxEntry} from 'react-native-onyx/lib/types'; import * as API from '@libs/API'; +import type { + AddMembersToWorkspaceParams, + CreateWorkspaceFromIOUPaymentParams, + CreateWorkspaceParams, + DeleteMembersFromWorkspaceParams, + DeleteWorkspaceAvatarParams, + DeleteWorkspaceParams, + OpenDraftWorkspaceRequestParams, + OpenWorkspaceInvitePageParams, + OpenWorkspaceMembersPageParams, + OpenWorkspaceParams, + OpenWorkspaceReimburseViewParams, + UpdateWorkspaceAvatarParams, + UpdateWorkspaceCustomUnitAndRateParams, + UpdateWorkspaceGeneralSettingsParams, +} from '@libs/API/parameters'; +import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import DateUtils from '@libs/DateUtils'; import * as ErrorUtils from '@libs/ErrorUtils'; import Log from '@libs/Log'; @@ -276,13 +293,9 @@ function deleteWorkspace(policyID: string, reports: Report[], policyName: string }); }); - type DeleteWorkspaceParams = { - policyID: string; - }; - const params: DeleteWorkspaceParams = {policyID}; - API.write('DeleteWorkspace', params, {optimisticData, failureData}); + API.write(WRITE_COMMANDS.DELETE_WORKSPACE, params, {optimisticData, failureData}); // Reset the lastAccessedWorkspacePolicyID if (policyID === lastAccessedWorkspacePolicyID) { @@ -492,17 +505,12 @@ function removeMembers(accountIDs: number[], policyID: string) { }); }); - type DeleteMembersFromWorkspaceParams = { - emailList: string; - policyID: string; - }; - const params: DeleteMembersFromWorkspaceParams = { emailList: accountIDs.map((accountID) => allPersonalDetails?.[accountID]?.login).join(','), policyID, }; - API.write('DeleteMembersFromWorkspace', params, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.DELETE_MEMBERS_FROM_WORKSPACE, params, {optimisticData, successData, failureData}); } /** @@ -669,13 +677,6 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: Record ...announceRoomMembers.onyxFailureData, ]; - type AddMembersToWorkspaceParams = { - employees: string; - welcomeNote: string; - policyID: string; - reportCreationData?: string; - }; - const params: AddMembersToWorkspaceParams = { employees: JSON.stringify(logins.map((login) => ({email: login}))), welcomeNote: new ExpensiMark().replace(welcomeNote), @@ -684,7 +685,7 @@ function addMembersToWorkspace(invitedEmailsToAccountIDs: Record if (!isEmptyObject(membersChats.reportCreationData)) { params.reportCreationData = JSON.stringify(membersChats.reportCreationData); } - API.write('AddMembersToWorkspace', params, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.ADD_MEMBERS_TO_WORKSPACE, params, {optimisticData, successData, failureData}); } /** @@ -728,17 +729,12 @@ function updateWorkspaceAvatar(policyID: string, file: File) { }, ]; - type UpdateWorkspaceAvatarParams = { - policyID: string; - file: File; - }; - const params: UpdateWorkspaceAvatarParams = { policyID, file, }; - API.write('UpdateWorkspaceAvatar', params, {optimisticData, finallyData, failureData}); + API.write(WRITE_COMMANDS.UPDATE_WORKSPACE_AVATAR, params, {optimisticData, finallyData, failureData}); } /** @@ -783,13 +779,9 @@ function deleteWorkspaceAvatar(policyID: string) { }, ]; - type DeleteWorkspaceAvatarParams = { - policyID: string; - }; - const params: DeleteWorkspaceAvatarParams = {policyID}; - API.write('DeleteWorkspaceAvatar', params, {optimisticData, finallyData, failureData}); + API.write(WRITE_COMMANDS.DELETE_WORKSPACE_AVATAR, params, {optimisticData, finallyData, failureData}); } /** @@ -886,19 +878,13 @@ function updateGeneralSettings(policyID: string, name: string, currency: string) }, ]; - type UpdateWorkspaceGeneralSettingsParams = { - policyID: string; - workspaceName: string; - currency: string; - }; - const params: UpdateWorkspaceGeneralSettingsParams = { policyID, workspaceName: name, currency, }; - API.write('UpdateWorkspaceGeneralSettings', params, { + API.write(WRITE_COMMANDS.UPDATE_WORKSPACE_GENERAL_SETTINGS, params, { optimisticData, finallyData, failureData, @@ -1018,21 +1004,14 @@ function updateWorkspaceCustomUnitAndRate(policyID: string, currentCustomUnit: C const {pendingAction, errors, ...newRates} = newCustomUnitParam.rates ?? {}; newCustomUnitParam.rates = newRates; - type UpdateWorkspaceCustomUnitAndRate = { - policyID: string; - lastModified: number; - customUnit: string; - customUnitRate: string; - }; - - const params: UpdateWorkspaceCustomUnitAndRate = { + const params: UpdateWorkspaceCustomUnitAndRateParams = { policyID, lastModified, customUnit: JSON.stringify(newCustomUnitParam), customUnitRate: JSON.stringify(newCustomUnitParam.rates), }; - API.write('UpdateWorkspaceCustomUnitAndRate', params, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.UPDATE_WORKSPACE_CUSTOM_UNIT_AND_RATE, params, {optimisticData, successData, failureData}); } /** @@ -1417,22 +1396,6 @@ function createWorkspace(policyOwnerEmail = '', makeMeAdmin = false, policyName }, ]; - type CreateWorkspaceParams = { - policyID: string; - announceChatReportID: string; - adminsChatReportID: string; - expenseChatReportID: string; - ownerEmail: string; - makeMeAdmin: boolean; - policyName: string; - type: string; - announceCreatedReportActionID: string; - adminsCreatedReportActionID: string; - expenseCreatedReportActionID: string; - customUnitID: string; - customUnitRateID: string; - }; - const params: CreateWorkspaceParams = { policyID, announceChatReportID, @@ -1449,7 +1412,7 @@ function createWorkspace(policyOwnerEmail = '', makeMeAdmin = false, policyName customUnitRateID, }; - API.write('CreateWorkspace', params, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.CREATE_WORKSPACE, params, {optimisticData, successData, failureData}); return adminsChatReportID; } @@ -1480,13 +1443,9 @@ function openWorkspaceReimburseView(policyID: string) { }, ]; - type OpenWorkspaceReimburseViewParams = { - policyID: string; - }; - const params: OpenWorkspaceReimburseViewParams = {policyID}; - API.read('OpenWorkspaceReimburseView', params, {successData, failureData}); + API.read(READ_COMMANDS.OPEN_WORKSPACE_REIMBURSE_VIEW, params, {successData, failureData}); } /** @@ -1498,17 +1457,12 @@ function openWorkspace(policyID: string, clientMemberAccountIDs: number[]) { return; } - type OpenWorkspaceParams = { - policyID: string; - clientMemberAccountIDs: string; - }; - const params: OpenWorkspaceParams = { policyID, clientMemberAccountIDs: JSON.stringify(clientMemberAccountIDs), }; - API.read('OpenWorkspace', params); + API.read(READ_COMMANDS.OPEN_WORKSPACE, params); } function openWorkspaceMembersPage(policyID: string, clientMemberEmails: string[]) { @@ -1517,17 +1471,12 @@ function openWorkspaceMembersPage(policyID: string, clientMemberEmails: string[] return; } - type OpenWorkspaceMembersPageParams = { - policyID: string; - clientMemberEmails: string; - }; - const params: OpenWorkspaceMembersPageParams = { policyID, clientMemberEmails: JSON.stringify(clientMemberEmails), }; - API.read('OpenWorkspaceMembersPage', params); + API.read(READ_COMMANDS.OPEN_WORKSPACE_MEMBERS_PAGE, params); } function openWorkspaceInvitePage(policyID: string, clientMemberEmails: string[]) { @@ -1536,27 +1485,18 @@ function openWorkspaceInvitePage(policyID: string, clientMemberEmails: string[]) return; } - type OpenWorkspaceInvitePageParams = { - policyID: string; - clientMemberEmails: string; - }; - const params: OpenWorkspaceInvitePageParams = { policyID, clientMemberEmails: JSON.stringify(clientMemberEmails), }; - API.read('OpenWorkspaceInvitePage', params); + API.read(READ_COMMANDS.OPEN_WORKSPACE_INVITE_PAGE, params); } function openDraftWorkspaceRequest(policyID: string) { - type OpenDraftWorkspaceRequestParams = { - policyID: string; - }; - const params: OpenDraftWorkspaceRequestParams = {policyID}; - API.read('OpenDraftWorkspaceRequest', params); + API.read(READ_COMMANDS.OPEN_DRAFT_WORKSPACE_REQUEST, params); } function setWorkspaceInviteMembersDraft(policyID: string, invitedEmailsToAccountIDs: Record) { @@ -2018,26 +1958,7 @@ function createWorkspaceFromIOUPayment(iouReport: Report): string | undefined { value: {[movedReportAction.reportActionID]: null}, }); - type CreateWorkspaceFromIOUPayment = { - policyID: string; - announceChatReportID: string; - adminsChatReportID: string; - expenseChatReportID: string; - ownerEmail: string; - makeMeAdmin: boolean; - policyName: string; - type: string; - announceCreatedReportActionID: string; - adminsCreatedReportActionID: string; - expenseCreatedReportActionID: string; - customUnitID: string; - customUnitRateID: string; - iouReportID: string; - memberData: string; - reportActionID: string; - }; - - const params: CreateWorkspaceFromIOUPayment = { + const params: CreateWorkspaceFromIOUPaymentParams = { policyID, announceChatReportID, adminsChatReportID, @@ -2056,7 +1977,7 @@ function createWorkspaceFromIOUPayment(iouReport: Report): string | undefined { reportActionID: movedReportAction.reportActionID, }; - API.write('CreateWorkspaceFromIOUPayment', params, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.CREATE_WORKSPACE_FROM_IOU_PAYMENT, params, {optimisticData, successData, failureData}); return policyID; } diff --git a/src/libs/actions/PriorityMode.ts b/src/libs/actions/PriorityMode.ts index 1d38d09e08a1..7ae174ac8606 100644 --- a/src/libs/actions/PriorityMode.ts +++ b/src/libs/actions/PriorityMode.ts @@ -3,6 +3,7 @@ import type {OnyxCollection} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import * as CollectionUtils from '@libs/CollectionUtils'; import Log from '@libs/Log'; +import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Report} from '@src/types/onyx'; @@ -120,7 +121,21 @@ function tryFocusModeUpdate() { return; } - const reportCount = Object.keys(allReports ?? {}).length; + const validReports = []; + Object.keys(allReports ?? {}).forEach((key) => { + const report = allReports?.[key]; + if (!report) { + return; + } + + if (!ReportUtils.isValidReport(report) || !ReportUtils.isReportParticipant(currentUserAccountID ?? 0, report)) { + return; + } + + validReports.push(report); + }); + + const reportCount = validReports.length; if (reportCount < CONST.REPORT.MAX_COUNT_BEFORE_FOCUS_UPDATE) { Log.info('Not switching user to optimized focus mode as they do not have enough reports', false, {reportCount}); return; diff --git a/src/libs/actions/PushNotification.ts b/src/libs/actions/PushNotification.ts index 888892fdc188..bc4d4eb05c5a 100644 --- a/src/libs/actions/PushNotification.ts +++ b/src/libs/actions/PushNotification.ts @@ -1,5 +1,6 @@ import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; +import {WRITE_COMMANDS} from '@libs/API/types'; import ONYXKEYS from '@src/ONYXKEYS'; import * as Device from './Device'; @@ -19,7 +20,7 @@ Onyx.connect({ */ function setPushNotificationOptInStatus(isOptingIn: boolean) { Device.getDeviceID().then((deviceID) => { - const commandName = isOptingIn ? 'OptInToPushNotifications' : 'OptOutOfPushNotifications'; + const commandName = isOptingIn ? WRITE_COMMANDS.OPT_IN_TO_PUSH_NOTIFICATIONS : WRITE_COMMANDS.OPT_OUT_OF_PUSH_NOTIFICATIONS; const optimisticData = [ { onyxMethod: Onyx.METHOD.MERGE, diff --git a/src/libs/actions/Report.ts b/src/libs/actions/Report.ts index e084a99df0c7..6222c09a898e 100644 --- a/src/libs/actions/Report.ts +++ b/src/libs/actions/Report.ts @@ -10,6 +10,38 @@ import type {PartialDeep, ValueOf} from 'type-fest'; import type {Emoji} from '@assets/emojis/types'; import * as ActiveClientManager from '@libs/ActiveClientManager'; import * as API from '@libs/API'; +import type { + AddCommentOrAttachementParams, + AddEmojiReactionParams, + AddWorkspaceRoomParams, + CompleteEngagementModalParams, + DeleteCommentParams, + ExpandURLPreviewParams, + FlagCommentParams, + GetNewerActionsParams, + GetOlderActionsParams, + GetReportPrivateNoteParams, + InviteToRoomParams, + LeaveRoomParams, + MarkAsUnreadParams, + OpenReportParams, + OpenRoomMembersPageParams, + ReadNewestActionParams, + ReconnectToReportParams, + RemoveEmojiReactionParams, + RemoveFromRoomParams, + ResolveActionableMentionWhisperParams, + SearchForReportsParams, + SetNameValuePairParams, + TogglePinnedChatParams, + UpdateCommentParams, + UpdatePolicyRoomNameParams, + UpdateReportNotificationPreferenceParams, + UpdateReportPrivateNoteParams, + UpdateReportWriteCapabilityParams, + UpdateWelcomeMessageParams, +} from '@libs/API/parameters'; +import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as CollectionUtils from '@libs/CollectionUtils'; import DateUtils from '@libs/DateUtils'; import * as EmojiUtils from '@libs/EmojiUtils'; @@ -32,7 +64,7 @@ import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Route} from '@src/ROUTES'; import ROUTES from '@src/ROUTES'; -import type {PersonalDetails, PersonalDetailsList, ReportActionReactions, ReportUserIsTyping} from '@src/types/onyx'; +import type {PersonalDetails, PersonalDetailsList, ReportActionReactions, ReportMetadata, ReportUserIsTyping} from '@src/types/onyx'; import type {Decision, OriginalMessageIOU} from '@src/types/onyx/OriginalMessage'; import type {NotificationPreference, WriteCapability} from '@src/types/onyx/Report'; import type Report from '@src/types/onyx/Report'; @@ -125,6 +157,13 @@ Onyx.connect({ }, }); +let reportMetadata: OnyxCollection = {}; +Onyx.connect({ + key: ONYXKEYS.COLLECTION.REPORT_METADATA, + waitForCollectionCallback: true, + callback: (value) => (reportMetadata = value), +}); + const allReports: OnyxCollection = {}; let conciergeChatReportID: string | undefined; const typingWatchTimers: Record = {}; @@ -298,7 +337,7 @@ function addActions(reportID: string, text = '', file?: File) { let reportCommentText = ''; let reportCommentAction: OptimisticAddCommentReportAction | undefined; let attachmentAction: OptimisticAddCommentReportAction | undefined; - let commandName = 'AddComment'; + let commandName: typeof WRITE_COMMANDS.ADD_COMMENT | typeof WRITE_COMMANDS.ADD_ATTACHMENT = WRITE_COMMANDS.ADD_COMMENT; if (text) { const reportComment = ReportUtils.buildOptimisticAddCommentReportAction(text); @@ -309,7 +348,7 @@ function addActions(reportID: string, text = '', file?: File) { if (file) { // When we are adding an attachment we will call AddAttachment. // It supports sending an attachment with an optional comment and AddComment supports adding a single text comment only. - commandName = 'AddAttachment'; + commandName = WRITE_COMMANDS.ADD_ATTACHMENT; const attachment = ReportUtils.buildOptimisticAddCommentReportAction('', file); attachmentAction = attachment.reportAction; } @@ -344,19 +383,7 @@ function addActions(reportID: string, text = '', file?: File) { optimisticReportActions[attachmentAction.reportActionID] = attachmentAction; } - type AddCommentOrAttachementParameters = { - reportID: string; - reportActionID?: string; - commentReportActionID?: string | null; - reportComment?: string; - file?: File; - timezone?: string; - shouldAllowActionableMentionWhispers?: boolean; - clientCreatedTime?: string; - isOldDotConciergeChat?: boolean; - }; - - const parameters: AddCommentOrAttachementParameters = { + const parameters: AddCommentOrAttachementParams = { reportID, reportActionID: file ? attachmentAction?.reportActionID : reportCommentAction?.reportActionID, commentReportActionID: file && reportCommentAction ? reportCommentAction.reportActionID : null, @@ -506,8 +533,6 @@ function openReport( reportName: allReports?.[reportID]?.reportName ?? CONST.REPORT.DEFAULT_REPORT_NAME, }; - const commandName = 'OpenReport'; - const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -559,23 +584,12 @@ function openReport( }, ]; - type OpenReportParameters = { - reportID: string; - emailList?: string; - accountIDList?: string; - parentReportActionID?: string; - shouldRetry?: boolean; - createdReportActionID?: string; - clientLastReadTime?: string; - idempotencyKey?: string; - }; - - const parameters: OpenReportParameters = { + const parameters: OpenReportParams = { reportID, emailList: participantLoginList ? participantLoginList.join(',') : '', accountIDList: participantAccountIDList ? participantAccountIDList.join(',') : '', parentReportActionID, - idempotencyKey: `${commandName}_${reportID}`, + idempotencyKey: `${SIDE_EFFECT_REQUEST_COMMANDS.OPEN_REPORT}_${reportID}`, }; if (isFromDeepLink) { @@ -680,12 +694,12 @@ function openReport( if (isFromDeepLink) { // eslint-disable-next-line rulesdir/no-api-side-effects-method - API.makeRequestWithSideEffects(commandName, parameters, {optimisticData, successData, failureData}).finally(() => { + API.makeRequestWithSideEffects(SIDE_EFFECT_REQUEST_COMMANDS.OPEN_REPORT, parameters, {optimisticData, successData, failureData}).finally(() => { Onyx.set(ONYXKEYS.IS_CHECKING_PUBLIC_ROOM, false); }); } else { // eslint-disable-next-line rulesdir/no-multiple-api-calls - API.write(commandName, parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.OPEN_REPORT, parameters, {optimisticData, successData, failureData}); } } @@ -809,15 +823,11 @@ function reconnect(reportID: string) { }, ]; - type ReconnectToReportParameters = { - reportID: string; - }; - - const parameters: ReconnectToReportParameters = { + const parameters: ReconnectToReportParams = { reportID, }; - API.write('ReconnectToReport', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.RECONNECT_TO_REPORT, parameters, {optimisticData, successData, failureData}); } /** @@ -855,17 +865,12 @@ function getOlderActions(reportID: string, reportActionID: string) { }, ]; - type GetOlderActionsParameters = { - reportID: string; - reportActionID: string; - }; - - const parameters: GetOlderActionsParameters = { + const parameters: GetOlderActionsParams = { reportID, reportActionID, }; - API.read('GetOlderActions', parameters, {optimisticData, successData, failureData}); + API.read(READ_COMMANDS.GET_OLDER_ACTIONS, parameters, {optimisticData, successData, failureData}); } /** @@ -903,34 +908,24 @@ function getNewerActions(reportID: string, reportActionID: string) { }, ]; - type GetNewerActionsParameters = { - reportID: string; - reportActionID: string; - }; - - const parameters: GetNewerActionsParameters = { + const parameters: GetNewerActionsParams = { reportID, reportActionID, }; - API.read('GetNewerActions', parameters, {optimisticData, successData, failureData}); + API.read(READ_COMMANDS.GET_NEWER_ACTIONS, parameters, {optimisticData, successData, failureData}); } /** * Gets metadata info about links in the provided report action */ function expandURLPreview(reportID: string, reportActionID: string) { - type ExpandURLPreviewParameters = { - reportID: string; - reportActionID: string; - }; - - const parameters: ExpandURLPreviewParameters = { + const parameters: ExpandURLPreviewParams = { reportID, reportActionID, }; - API.read('ExpandURLPreview', parameters); + API.read(READ_COMMANDS.EXPAND_URL_PREVIEW, parameters); } /** Marks the new report actions as read */ @@ -947,17 +942,12 @@ function readNewestAction(reportID: string, shouldEmitEvent = true) { }, ]; - type ReadNewestActionParameters = { - reportID: string; - lastReadTime: string; - }; - - const parameters: ReadNewestActionParameters = { + const parameters: ReadNewestActionParams = { reportID, lastReadTime, }; - API.write('ReadNewestAction', parameters, {optimisticData}); + API.write(WRITE_COMMANDS.READ_NEWEST_ACTION, parameters, {optimisticData}); if (!shouldEmitEvent) { return; @@ -998,17 +988,12 @@ function markCommentAsUnread(reportID: string, reportActionCreated: string) { }, ]; - type MarkAsUnreadParameters = { - reportID: string; - lastReadTime: string; - }; - - const parameters: MarkAsUnreadParameters = { + const parameters: MarkAsUnreadParams = { reportID, lastReadTime, }; - API.write('MarkAsUnread', parameters, {optimisticData}); + API.write(WRITE_COMMANDS.MARK_AS_UNREAD, parameters, {optimisticData}); DeviceEventEmitter.emit(`unreadAction_${reportID}`, lastReadTime); } @@ -1025,17 +1010,12 @@ function togglePinnedState(reportID: string, isPinnedChat: boolean) { }, ]; - type TogglePinnedChatParameters = { - reportID: string; - pinnedValue: boolean; - }; - - const parameters: TogglePinnedChatParameters = { + const parameters: TogglePinnedChatParams = { reportID, pinnedValue, }; - API.write('TogglePinnedChat', parameters, {optimisticData}); + API.write(WRITE_COMMANDS.TOGGLE_PINNED_CHAT, parameters, {optimisticData}); } /** @@ -1218,17 +1198,12 @@ function deleteReportComment(reportID: string, reportAction: ReportAction) { } } - type DeleteCommentParameters = { - reportID: string; - reportActionID: string; - }; - - const parameters: DeleteCommentParameters = { + const parameters: DeleteCommentParams = { reportID: originalReportID, reportActionID, }; - API.write('DeleteComment', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.DELETE_COMMENT, parameters, {optimisticData, successData, failureData}); } /** @@ -1371,19 +1346,13 @@ function editReportComment(reportID: string, originalReportAction: OnyxEntry; - writeCapability?: WriteCapability; - welcomeMessage?: string; - }; - - const parameters: AddWorkspaceRoomParameters = { + const parameters: AddWorkspaceRoomParams = { policyID: policyReport.policyID, reportName: policyReport.reportName, visibility: policyReport.visibility, @@ -1685,7 +1629,7 @@ function addPolicyReport(policyReport: ReportUtils.OptimisticChatReport) { welcomeMessage: policyReport.welcomeMessage, }; - API.write('AddWorkspaceRoom', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.ADD_WORKSPACE_ROOM, parameters, {optimisticData, successData, failureData}); Navigation.dismissModal(policyReport.reportID); } @@ -1775,14 +1719,9 @@ function updatePolicyRoomNameAndNavigate(policyRoomReport: Report, policyRoomNam }, ]; - type UpdatePolicyRoomNameParameters = { - reportID: string; - policyRoomName: string; - }; - - const parameters: UpdatePolicyRoomNameParameters = {reportID, policyRoomName}; + const parameters: UpdatePolicyRoomNameParams = {reportID, policyRoomName}; - API.write('UpdatePolicyRoomName', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.UPDATE_POLICY_ROOM_NAME, parameters, {optimisticData, successData, failureData}); Navigation.goBack(ROUTES.REPORT_SETTINGS.getRoute(reportID)); } @@ -1942,16 +1881,7 @@ function addEmojiReaction(reportID: string, reportActionID: string, emoji: Emoji }, ]; - type AddEmojiReactionParameters = { - reportID: string; - skinTone: string | number; - emojiCode: string; - reportActionID: string; - createdAt: string; - useEmojiReactions: boolean; - }; - - const parameters: AddEmojiReactionParameters = { + const parameters: AddEmojiReactionParams = { reportID, skinTone, emojiCode: emoji.name, @@ -1961,7 +1891,7 @@ function addEmojiReaction(reportID: string, reportActionID: string, emoji: Emoji useEmojiReactions: true, }; - API.write('AddEmojiReaction', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.ADD_EMOJI_REACTION, parameters, {optimisticData, successData, failureData}); } /** @@ -1983,14 +1913,7 @@ function removeEmojiReaction(reportID: string, reportActionID: string, emoji: Em }, ]; - type RemoveEmojiReactionParameters = { - reportID: string; - reportActionID: string; - emojiCode: string; - useEmojiReactions: boolean; - }; - - const parameters: RemoveEmojiReactionParameters = { + const parameters: RemoveEmojiReactionParams = { reportID, reportActionID, emojiCode: emoji.name, @@ -1998,7 +1921,7 @@ function removeEmojiReaction(reportID: string, reportActionID: string, emoji: Em useEmojiReactions: true, }; - API.write('RemoveEmojiReaction', parameters, {optimisticData}); + API.write(WRITE_COMMANDS.REMOVE_EMOJI_REACTION, parameters, {optimisticData}); } /** @@ -2162,17 +2085,36 @@ function leaveRoom(reportID: string, isWorkspaceMemberLeavingWorkspaceRoom = fal }); } - type LeaveRoomParameters = { - reportID: string; - }; - - const parameters: LeaveRoomParameters = { + const parameters: LeaveRoomParams = { reportID, }; - API.write('LeaveRoom', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.LEAVE_ROOM, parameters, {optimisticData, successData, failureData}); + + const sortedReportsByLastRead = ReportUtils.sortReportsByLastRead(Object.values(allReports ?? {}) as Report[], reportMetadata); + + // We want to filter out the current report, hidden reports and empty chats + const filteredReportsByLastRead = sortedReportsByLastRead.filter( + (sortedReport) => + sortedReport?.reportID !== reportID && + sortedReport?.notificationPreference !== CONST.REPORT.NOTIFICATION_PREFERENCE.HIDDEN && + ReportUtils.shouldReportBeInOptionList({ + report: sortedReport, + currentReportId: '', + isInGSDMode: false, + betas: [], + policies: {}, + excludeEmptyChats: true, + doesReportHaveViolations: false, + }), + ); + const lastAccessedReportID = filteredReportsByLastRead.at(-1)?.reportID; - if (isWorkspaceMemberLeavingWorkspaceRoom) { + if (lastAccessedReportID) { + // We should call Navigation.goBack to pop the current route first before navigating to Concierge. + Navigation.goBack(ROUTES.HOME); + Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(lastAccessedReportID)); + } else { const participantAccountIDs = PersonalDetailsUtils.getAccountIDsByLogins([CONST.EMAIL.CONCIERGE]); const chat = ReportUtils.getChatByParticipants(participantAccountIDs); if (chat?.reportID) { @@ -2229,17 +2171,12 @@ function inviteToRoom(reportID: string, inviteeEmailsToAccountIDs: Record, se }, ]; - type FlagCommentParameters = { - severity: string; - reportActionID: string; - isDevRequest: boolean; - }; - - const parameters: FlagCommentParameters = { + const parameters: FlagCommentParams = { severity, reportActionID, // This check is to prevent flooding Concierge with test flags @@ -2396,7 +2322,7 @@ function flagComment(reportID: string, reportAction: OnyxEntry, se isDevRequest: Environment.isDevelopment(), }; - API.write('FlagComment', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.FLAG_COMMENT, parameters, {optimisticData, successData, failureData}); } /** Updates a given user's private notes on a report */ @@ -2446,14 +2372,9 @@ const updatePrivateNotes = (reportID: string, accountID: number, note: string) = }, ]; - type UpdateReportPrivateNoteParameters = { - reportID: string; - privateNotes: string; - }; - - const parameters: UpdateReportPrivateNoteParameters = {reportID, privateNotes: note}; + const parameters: UpdateReportPrivateNoteParams = {reportID, privateNotes: note}; - API.write('UpdateReportPrivateNote', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.UPDATE_REPORT_PRIVATE_NOTE, parameters, {optimisticData, successData, failureData}); }; /** Fetches all the private notes for a given report */ @@ -2496,13 +2417,9 @@ function getReportPrivateNote(reportID: string) { }, ]; - type GetReportPrivateNoteParameters = { - reportID: string; - }; - - const parameters: GetReportPrivateNoteParameters = {reportID}; + const parameters: GetReportPrivateNoteParams = {reportID}; - API.read('GetReportPrivateNote', parameters, {optimisticData, successData, failureData}); + API.read(READ_COMMANDS.GET_REPORT_PRIVATE_NOTE, parameters, {optimisticData, successData, failureData}); } /** @@ -2512,7 +2429,6 @@ function getReportPrivateNote(reportID: string) { * - Creates an optimistic report comment from concierge */ function completeEngagementModal(text: string, choice: ValueOf) { - const commandName = 'CompleteEngagementModal'; const conciergeAccountID = PersonalDetailsUtils.getAccountIDsByLogins([CONST.EMAIL.CONCIERGE])[0]; const reportComment = ReportUtils.buildOptimisticAddCommentReportAction(text, undefined, conciergeAccountID); const reportCommentAction: OptimisticAddCommentReportAction = reportComment.reportAction; @@ -2545,16 +2461,7 @@ function completeEngagementModal(text: string, choice: ValueOf; - }; - const parameters: ResolveActionableMentionWhisperParams = { reportActionID: reportAction.reportActionID, resolution, }; - API.write('ResolveActionableMentionWhisper', parameters, {optimisticData, failureData}); + API.write(WRITE_COMMANDS.RESOLVE_ACTIONABLE_MENTION_WHISPER, parameters, {optimisticData, failureData}); } export { diff --git a/src/libs/actions/Session/index.ts b/src/libs/actions/Session/index.ts index bde2954e191a..4fbeba0abaa6 100644 --- a/src/libs/actions/Session/index.ts +++ b/src/libs/actions/Session/index.ts @@ -7,6 +7,22 @@ import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import * as PersistedRequests from '@libs/actions/PersistedRequests'; import * as API from '@libs/API'; +import type { + AuthenticatePusherParams, + BeginAppleSignInParams, + BeginGoogleSignInParams, + BeginSignInParams, + LogOutParams, + RequestAccountValidationLinkParams, + RequestNewValidateCodeParams, + RequestUnlinkValidationLinkParams, + SignInUserWithLinkParams, + SignInWithShortLivedAuthTokenParams, + UnlinkLoginParams, + ValidateTwoFactorAuthParams, +} from '@libs/API/parameters'; +import type SignInUserParams from '@libs/API/parameters/SignInUserParams'; +import {READ_COMMANDS, SIDE_EFFECT_REQUEST_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as Authentication from '@libs/Authentication'; import * as ErrorUtils from '@libs/ErrorUtils'; import HttpUtils from '@libs/HttpUtils'; @@ -70,14 +86,6 @@ Onyx.connect({ function signOut() { Log.info('Flushing logs before signing out', true, {}, true); - type LogOutParams = { - authToken: string | null; - partnerUserID: string; - partnerName: string; - partnerPassword: string; - shouldRetry: boolean; - }; - const params: LogOutParams = { // Send current authToken because we will immediately clear it once triggering this command authToken: NetworkStore.getAuthToken(), @@ -87,7 +95,7 @@ function signOut() { shouldRetry: false, }; - API.write('LogOut', params); + API.write(WRITE_COMMANDS.LOG_OUT, params); clearCache().then(() => { Log.info('Cleared all cache data', true, {}, true); }); @@ -177,13 +185,9 @@ function resendValidationLink(login = credentials.login) { }, ]; - type ResendValidationLinkParams = { - email?: string; - }; - - const params: ResendValidationLinkParams = {email: login}; + const params: RequestAccountValidationLinkParams = {email: login}; - API.write('RequestAccountValidationLink', params, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.REQUEST_ACCOUNT_VALIDATION_LINK, params, {optimisticData, successData, failureData}); } /** @@ -210,13 +214,9 @@ function resendValidateCode(login = credentials.login) { }, ]; - type RequestNewValidateCodeParams = { - email?: string; - }; - const params: RequestNewValidateCodeParams = {email: login}; - API.write('RequestNewValidateCode', params, {optimisticData, finallyData}); + API.write(WRITE_COMMANDS.REQUEST_NEW_VALIDATE_CODE, params, {optimisticData, finallyData}); } type OnyxData = { @@ -279,13 +279,9 @@ function signInAttemptState(): OnyxData { function beginSignIn(email: string) { const {optimisticData, successData, failureData} = signInAttemptState(); - type BeginSignInParams = { - email: string; - }; - const params: BeginSignInParams = {email}; - API.read('BeginSignIn', params, {optimisticData, successData, failureData}); + API.read(READ_COMMANDS.BEGIN_SIGNIN, params, {optimisticData, successData, failureData}); } /** @@ -295,14 +291,9 @@ function beginSignIn(email: string) { function beginAppleSignIn(idToken: string | undefined | null) { const {optimisticData, successData, failureData} = signInAttemptState(); - type BeginAppleSignInParams = { - idToken: typeof idToken; - preferredLocale: ValueOf | null; - }; - const params: BeginAppleSignInParams = {idToken, preferredLocale}; - API.write('SignInWithApple', params, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.SIGN_IN_WITH_APPLE, params, {optimisticData, successData, failureData}); } /** @@ -312,14 +303,9 @@ function beginAppleSignIn(idToken: string | undefined | null) { function beginGoogleSignIn(token: string | null) { const {optimisticData, successData, failureData} = signInAttemptState(); - type BeginGoogleSignInParams = { - token: string | null; - preferredLocale: ValueOf | null; - }; - const params: BeginGoogleSignInParams = {token, preferredLocale}; - API.write('SignInWithGoogle', params, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.SIGN_IN_WITH_GOOGLE, params, {optimisticData, successData, failureData}); } /** @@ -373,15 +359,9 @@ function signInWithShortLivedAuthToken(email: string, authToken: string) { // scene 2: the user is transitioning to desktop app from a different account on web app. const oldPartnerUserID = credentials.login === email && credentials.autoGeneratedLogin ? credentials.autoGeneratedLogin : ''; - type SignInWithShortLivedAuthTokenParams = { - authToken: string; - oldPartnerUserID: string; - skipReauthentication: boolean; - }; - const params: SignInWithShortLivedAuthTokenParams = {authToken, oldPartnerUserID, skipReauthentication: true}; - API.read('SignInWithShortLivedAuthToken', params, {optimisticData, successData, failureData}); + API.read(READ_COMMANDS.SIGN_IN_WITH_SHORT_LIVED_AUTH_TOKEN, params, {optimisticData, successData, failureData}); } /** @@ -434,14 +414,6 @@ function signIn(validateCode: string, twoFactorAuthCode?: string) { ]; Device.getDeviceInfoWithID().then((deviceInfo) => { - type SignInUserParams = { - twoFactorAuthCode?: string; - email?: string; - preferredLocale: ValueOf | null; - validateCode?: string; - deviceInfo: string; - }; - const params: SignInUserParams = { twoFactorAuthCode, email: credentials.login, @@ -454,7 +426,7 @@ function signIn(validateCode: string, twoFactorAuthCode?: string) { params.validateCode = validateCode || credentials.validateCode; } - API.write('SigninUser', params, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.SIGN_IN_USER, params, {optimisticData, successData, failureData}); }); } @@ -520,14 +492,6 @@ function signInWithValidateCode(accountID: number, code: string, twoFactorAuthCo }, ]; Device.getDeviceInfoWithID().then((deviceInfo) => { - type SignInUserWithLinkParams = { - accountID: number; - validateCode?: string; - twoFactorAuthCode?: string; - preferredLocale: ValueOf | null; - deviceInfo: string; - }; - const params: SignInUserWithLinkParams = { accountID, validateCode, @@ -536,7 +500,7 @@ function signInWithValidateCode(accountID: number, code: string, twoFactorAuthCo deviceInfo, }; - API.write('SigninUserWithLink', params, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.SIGN_IN_USER_WITH_LINK, params, {optimisticData, successData, failureData}); }); } @@ -652,7 +616,7 @@ function setAccountError(error: string) { const reauthenticatePusher = throttle( () => { Log.info('[Pusher] Re-authenticating and then reconnecting'); - Authentication.reauthenticate('AuthenticatePusher') + Authentication.reauthenticate(SIDE_EFFECT_REQUEST_COMMANDS.AUTHENTICATE_PUSHER) .then(Pusher.reconnect) .catch(() => { console.debug('[PusherConnectionManager]', 'Unable to re-authenticate Pusher because we are offline.'); @@ -665,15 +629,6 @@ const reauthenticatePusher = throttle( function authenticatePusher(socketID: string, channelName: string, callback: ChannelAuthorizationCallback) { Log.info('[PusherAuthorizer] Attempting to authorize Pusher', false, {channelName}); - type AuthenticatePusherParams = { - // eslint-disable-next-line @typescript-eslint/naming-convention - socket_id: string; - // eslint-disable-next-line @typescript-eslint/naming-convention - channel_name: string; - shouldRetry: boolean; - forceNetworkRequest: boolean; - }; - const params: AuthenticatePusherParams = { // eslint-disable-next-line @typescript-eslint/naming-convention socket_id: socketID, @@ -685,7 +640,7 @@ function authenticatePusher(socketID: string, channelName: string, callback: Cha // We use makeRequestWithSideEffects here because we need to authorize to Pusher (an external service) each time a user connects to any channel. // eslint-disable-next-line rulesdir/no-api-side-effects-method - API.makeRequestWithSideEffects('AuthenticatePusher', params) + API.makeRequestWithSideEffects(SIDE_EFFECT_REQUEST_COMMANDS.AUTHENTICATE_PUSHER, params) .then((response) => { if (response?.jsonCode === CONST.JSON_CODE.NOT_AUTHENTICATED) { Log.hmmm('[PusherAuthorizer] Unable to authenticate Pusher because authToken is expired'); @@ -749,13 +704,9 @@ function requestUnlinkValidationLink() { }, ]; - type RequestUnlinkValidationLinkParams = { - email?: string; - }; - const params: RequestUnlinkValidationLinkParams = {email: credentials.login}; - API.write('RequestUnlinkValidationLink', params, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.REQUEST_UNLINK_VALIDATION_LINK, params, {optimisticData, successData, failureData}); } function unlinkLogin(accountID: number, validateCode: string) { @@ -796,17 +747,12 @@ function unlinkLogin(accountID: number, validateCode: string) { }, ]; - type UnlinkLoginParams = { - accountID: number; - validateCode: string; - }; - const params: UnlinkLoginParams = { accountID, validateCode, }; - API.write('UnlinkLogin', params, { + API.write(WRITE_COMMANDS.UNLINK_LOGIN, params, { optimisticData, successData, failureData, @@ -847,7 +793,7 @@ function toggleTwoFactorAuth(enable: boolean) { }, ]; - API.write(enable ? 'EnableTwoFactorAuth' : 'DisableTwoFactorAuth', {}, {optimisticData, successData, failureData}); + API.write(enable ? WRITE_COMMANDS.ENABLE_TWO_FACTOR_AUTH : WRITE_COMMANDS.DISABLE_TWO_FACTOR_AUTH, {}, {optimisticData, successData, failureData}); } function validateTwoFactorAuth(twoFactorAuthCode: string) { @@ -881,13 +827,9 @@ function validateTwoFactorAuth(twoFactorAuthCode: string) { }, ]; - type ValidateTwoFactorAuthParams = { - twoFactorAuthCode: string; - }; - const params: ValidateTwoFactorAuthParams = {twoFactorAuthCode}; - API.write('TwoFactorAuth_Validate', params, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.TWO_FACTOR_AUTH_VALIDATE, params, {optimisticData, successData, failureData}); } /** diff --git a/src/libs/actions/Task.ts b/src/libs/actions/Task.ts index b2f6b57f390a..a7aab98f02c6 100644 --- a/src/libs/actions/Task.ts +++ b/src/libs/actions/Task.ts @@ -3,6 +3,8 @@ import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import * as Expensicons from '@components/Icon/Expensicons'; import * as API from '@libs/API'; +import type {CancelTaskParams, CompleteTaskParams, CreateTaskParams, EditTaskAssigneeParams, EditTaskParams, ReopenTaskParams} from '@libs/API/parameters'; +import {WRITE_COMMANDS} from '@libs/API/types'; import DateUtils from '@libs/DateUtils'; import * as ErrorUtils from '@libs/ErrorUtils'; import * as LocalePhoneNumber from '@libs/LocalePhoneNumber'; @@ -226,21 +228,7 @@ function createTaskAndNavigate( clearOutTaskInfo(); - type CreateTaskParameters = { - parentReportActionID?: string; - parentReportID?: string; - taskReportID?: string; - createdTaskReportActionID?: string; - title?: string; - description?: string; - assignee?: string; - assigneeAccountID?: number; - assigneeChatReportID?: string; - assigneeChatReportActionID?: string; - assigneeChatCreatedReportActionID?: string; - }; - - const parameters: CreateTaskParameters = { + const parameters: CreateTaskParams = { parentReportActionID: optimisticAddCommentReport.reportAction.reportActionID, parentReportID, taskReportID: optimisticTaskReport.reportID, @@ -254,7 +242,7 @@ function createTaskAndNavigate( assigneeChatCreatedReportActionID: assigneeChatReportOnyxData?.optimisticChatCreatedReportAction?.reportActionID, }; - API.write('CreateTask', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.CREATE_TASK, parameters, {optimisticData, successData, failureData}); Navigation.dismissModal(parentReportID); } @@ -316,17 +304,12 @@ function completeTask(taskReport: OnyxEntry) { }, ]; - type CompleteTaskParameters = { - taskReportID?: string; - completedTaskReportActionID?: string; - }; - - const parameters: CompleteTaskParameters = { + const parameters: CompleteTaskParams = { taskReportID, completedTaskReportActionID: completedTaskReportAction.reportActionID, }; - API.write('CompleteTask', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.COMPLETE_TASK, parameters, {optimisticData, successData, failureData}); } /** @@ -388,17 +371,12 @@ function reopenTask(taskReport: OnyxEntry) { }, ]; - type ReopenTaskParameters = { - taskReportID?: string; - reopenedTaskReportActionID?: string; - }; - - const parameters: ReopenTaskParameters = { + const parameters: ReopenTaskParams = { taskReportID, reopenedTaskReportActionID: reopenedTaskReportAction.reportActionID, }; - API.write('ReopenTask', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.REOPEN_TASK, parameters, {optimisticData, successData, failureData}); } function editTask(report: OnyxTypes.Report, {title, description}: OnyxTypes.Task) { @@ -461,21 +439,14 @@ function editTask(report: OnyxTypes.Report, {title, description}: OnyxTypes.Task }, ]; - type EditTaskParameters = { - taskReportID?: string; - title?: string; - description?: string; - editedTaskReportActionID?: string; - }; - - const parameters: EditTaskParameters = { + const parameters: EditTaskParams = { taskReportID: report.reportID, title: reportName, description: reportDescription, editedTaskReportActionID: editTaskReportAction.reportActionID, }; - API.write('EditTask', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.EDIT_TASK, parameters, {optimisticData, successData, failureData}); } function editTaskAssignee(report: OnyxTypes.Report, ownerAccountID: number, assigneeEmail: string, assigneeAccountID = 0, assigneeChatReport: OnyxEntry = null) { @@ -555,16 +526,7 @@ function editTaskAssignee(report: OnyxTypes.Report, ownerAccountID: number, assi failureData.push(...assigneeChatReportOnyxData.failureData); } - type EditTaskAssigneeParameters = { - taskReportID?: string; - assignee?: string; - editedTaskReportActionID?: string; - assigneeChatReportID?: string; - assigneeChatReportActionID?: string; - assigneeChatCreatedReportActionID?: string; - }; - - const parameters: EditTaskAssigneeParameters = { + const parameters: EditTaskAssigneeParams = { taskReportID: report.reportID, assignee: assigneeEmail, editedTaskReportActionID: editTaskReportAction.reportActionID, @@ -573,7 +535,7 @@ function editTaskAssignee(report: OnyxTypes.Report, ownerAccountID: number, assi assigneeChatCreatedReportActionID: assigneeChatReportOnyxData?.optimisticChatCreatedReportAction?.reportActionID, }; - API.write('EditTaskAssignee', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.EDIT_TASK_ASSIGNEE, parameters, {optimisticData, successData, failureData}); } /** @@ -868,17 +830,12 @@ function deleteTask(taskReportID: string, taskTitle: string, originalStateNum: n }, ]; - type CancelTaskParameters = { - cancelledTaskReportActionID?: string; - taskReportID?: string; - }; - - const parameters: CancelTaskParameters = { + const parameters: CancelTaskParams = { cancelledTaskReportActionID: optimisticReportActionID, taskReportID, }; - API.write('CancelTask', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.CANCEL_TASK, parameters, {optimisticData, successData, failureData}); if (shouldDeleteTaskReport) { Navigation.goBack(ROUTES.REPORT_WITH_ID.getRoute(parentReport?.reportID ?? '')); diff --git a/src/libs/actions/TeachersUnite.ts b/src/libs/actions/TeachersUnite.ts index 14b1a6455349..055d1f2b53a2 100644 --- a/src/libs/actions/TeachersUnite.ts +++ b/src/libs/actions/TeachersUnite.ts @@ -1,6 +1,8 @@ import Onyx from 'react-native-onyx'; import type {OnyxEntry, OnyxUpdate} from 'react-native-onyx'; import * as API from '@libs/API'; +import type {AddSchoolPrincipalParams, ReferTeachersUniteVolunteerParams} from '@libs/API/parameters'; +import {WRITE_COMMANDS} from '@libs/API/types'; import Navigation from '@libs/Navigation/Navigation'; import * as OptionsListUtils from '@libs/OptionsListUtils'; import * as ReportUtils from '@libs/ReportUtils'; @@ -51,13 +53,6 @@ function referTeachersUniteVolunteer(partnerUserID: string, firstName: string, l }, ]; - type ReferTeachersUniteVolunteerParams = { - reportID: string; - firstName: string; - lastName: string; - partnerUserID: string; - }; - const parameters: ReferTeachersUniteVolunteerParams = { reportID: publicRoomReportID, firstName, @@ -65,7 +60,7 @@ function referTeachersUniteVolunteer(partnerUserID: string, firstName: string, l partnerUserID, }; - API.write('ReferTeachersUniteVolunteer', parameters, {optimisticData}); + API.write(WRITE_COMMANDS.REFER_TEACHERS_UNITE_VOLUNTEER, parameters, {optimisticData}); Navigation.dismissModal(publicRoomReportID); } @@ -177,14 +172,6 @@ function addSchoolPrincipal(firstName: string, partnerUserID: string, lastName: }, ]; - type AddSchoolPrincipalParams = { - firstName: string; - lastName: string; - partnerUserID: string; - policyID: string; - reportCreationData: string; - }; - const parameters: AddSchoolPrincipalParams = { firstName, lastName, @@ -193,7 +180,7 @@ function addSchoolPrincipal(firstName: string, partnerUserID: string, lastName: reportCreationData: JSON.stringify(reportCreationData), }; - API.write('AddSchoolPrincipal', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.ADD_SCHOOL_PRINCIPAL, parameters, {optimisticData, successData, failureData}); Navigation.dismissModal(expenseChatReportID); } diff --git a/src/libs/actions/Timing.ts b/src/libs/actions/Timing.ts index 9e40f088f1c2..28ffdd92ffba 100644 --- a/src/libs/actions/Timing.ts +++ b/src/libs/actions/Timing.ts @@ -1,4 +1,6 @@ import * as API from '@libs/API'; +import type {SendPerformanceTimingParams} from '@libs/API/parameters'; +import {READ_COMMANDS} from '@libs/API/types'; import * as Environment from '@libs/Environment/Environment'; import Firebase from '@libs/Firebase'; import getPlatform from '@libs/getPlatform'; @@ -62,15 +64,13 @@ function end(eventName: string, secondaryName = '', maxExecutionTime = 0) { Log.warn(`${eventName} exceeded max execution time of ${maxExecutionTime}.`, {eventTime, eventName}); } - API.read( - 'SendPerformanceTiming', - { - name: grafanaEventName, - value: eventTime, - platform: `${getPlatform()}`, - }, - {}, - ); + const parameters: SendPerformanceTimingParams = { + name: grafanaEventName, + value: eventTime, + platform: `${getPlatform()}`, + }; + + API.read(READ_COMMANDS.SEND_PERFORMANCE_TIMING, parameters, {}); }); } diff --git a/src/libs/actions/Transaction.ts b/src/libs/actions/Transaction.ts index 430de0557674..8743da7abd06 100644 --- a/src/libs/actions/Transaction.ts +++ b/src/libs/actions/Transaction.ts @@ -3,6 +3,8 @@ import lodashClone from 'lodash/clone'; import lodashHas from 'lodash/has'; import Onyx from 'react-native-onyx'; import * as API from '@libs/API'; +import type {GetRouteForDraftParams, GetRouteParams} from '@libs/API/parameters'; +import {READ_COMMANDS} from '@libs/API/types'; import * as CollectionUtils from '@libs/CollectionUtils'; import * as TransactionUtils from '@libs/TransactionUtils'; import CONST from '@src/CONST'; @@ -209,14 +211,12 @@ function getOnyxDataForRouteRequest(transactionID: string, isDraft = false): Ony * Used so we can generate a map view of the provided waypoints */ function getRoute(transactionID: string, waypoints: WaypointCollection) { - API.read( - 'GetRoute', - { - transactionID, - waypoints: JSON.stringify(waypoints), - }, - getOnyxDataForRouteRequest(transactionID), - ); + const parameters: GetRouteParams = { + transactionID, + waypoints: JSON.stringify(waypoints), + }; + + API.read(READ_COMMANDS.GET_ROUTE, parameters, getOnyxDataForRouteRequest(transactionID)); } /** @@ -224,14 +224,12 @@ function getRoute(transactionID: string, waypoints: WaypointCollection) { * Used so we can generate a map view of the provided waypoints */ function getRouteForDraft(transactionID: string, waypoints: WaypointCollection) { - API.read( - 'GetRouteForDraft', - { - transactionID, - waypoints: JSON.stringify(waypoints), - }, - getOnyxDataForRouteRequest(transactionID, true), - ); + const parameters: GetRouteForDraftParams = { + transactionID, + waypoints: JSON.stringify(waypoints), + }; + + API.read(READ_COMMANDS.GET_ROUTE_FOR_DRAFT, parameters, getOnyxDataForRouteRequest(transactionID, true)); } /** diff --git a/src/libs/actions/User.ts b/src/libs/actions/User.ts index aaba02ecec1e..f118797fa659 100644 --- a/src/libs/actions/User.ts +++ b/src/libs/actions/User.ts @@ -4,6 +4,23 @@ import Onyx from 'react-native-onyx'; import type {OnyxEntry} from 'react-native-onyx/lib/types'; import type {ValueOf} from 'type-fest'; import * as API from '@libs/API'; +import type { + AddNewContactMethodParams, + CloseAccountParams, + DeleteContactMethodParams, + GetStatementPDFParams, + RequestContactMethodValidateCodeParams, + SetContactMethodAsDefaultParams, + UpdateChatPriorityModeParams, + UpdateFrequentlyUsedEmojisParams, + UpdateNewsletterSubscriptionParams, + UpdatePreferredEmojiSkinToneParams, + UpdateStatusParams, + UpdateThemeParams, + ValidateLoginParams, + ValidateSecondaryLoginParams, +} from '@libs/API/parameters'; +import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import * as ErrorUtils from '@libs/ErrorUtils'; import Log from '@libs/Log'; import Navigation from '@libs/Navigation/Navigation'; @@ -74,11 +91,9 @@ function closeAccount(reason: string) { }, ]; - type CloseAccountParams = {message: string}; - const parameters: CloseAccountParams = {message: reason}; - API.write('CloseAccount', parameters, { + API.write(WRITE_COMMANDS.CLOSE_ACCOUNT, parameters, { optimisticData, failureData, }); @@ -148,11 +163,9 @@ function requestContactMethodValidateCode(contactMethod: string) { }, ]; - type RequestContactMethodValidateCodeParams = {email: string}; - const parameters: RequestContactMethodValidateCodeParams = {email: contactMethod}; - API.write('RequestContactMethodValidateCode', parameters, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.REQUEST_CONTACT_METHOD_VALIDATE_CODE, parameters, {optimisticData, successData, failureData}); } /** @@ -174,11 +187,9 @@ function updateNewsletterSubscription(isSubscribed: boolean) { }, ]; - type UpdateNewsletterSubscriptionParams = {isSubscribed: boolean}; - const parameters: UpdateNewsletterSubscriptionParams = {isSubscribed}; - API.write('UpdateNewsletterSubscription', parameters, { + API.write(WRITE_COMMANDS.UPDATE_NEWSLETTER_SUBSCRIPTION, parameters, { optimisticData, failureData, }); @@ -235,11 +246,9 @@ function deleteContactMethod(contactMethod: string, loginList: Record, autom }); } - type UpdateChatPriorityModeParams = { - value: ValueOf; - automatic: boolean; - }; - const parameters: UpdateChatPriorityModeParams = { value: mode, automatic, }; - API.write('UpdateChatPriorityMode', parameters, {optimisticData}); + API.write(WRITE_COMMANDS.UPDATE_CHAT_PRIORITY_MODE, parameters, {optimisticData}); if (!autoSwitchedToFocusMode) { Navigation.goBack(ROUTES.SETTINGS_PREFERENCES); @@ -674,11 +664,9 @@ function generateStatementPDF(period: string) { }, ]; - type GetStatementPDFParams = {period: string}; - const parameters: GetStatementPDFParams = {period}; - API.read('GetStatementPDF', parameters, { + API.read(READ_COMMANDS.GET_STATEMENT_PDF, parameters, { optimisticData, successData, failureData, @@ -767,15 +755,11 @@ function setContactMethodAsDefault(newDefaultContactMethod: string) { }, ]; - type SetContactMethodAsDefaultParams = { - partnerUserID: string; - }; - const parameters: SetContactMethodAsDefaultParams = { partnerUserID: newDefaultContactMethod, }; - API.write('SetContactMethodAsDefault', parameters, { + API.write(WRITE_COMMANDS.SET_CONTACT_METHOD_AS_DEFAULT, parameters, { optimisticData, successData, failureData, @@ -792,15 +776,11 @@ function updateTheme(theme: ValueOf) { }, ]; - type UpdateThemeParams = { - value: string; - }; - const parameters: UpdateThemeParams = { value: theme, }; - API.write('UpdateTheme', parameters, {optimisticData}); + API.write(WRITE_COMMANDS.UPDATE_THEME, parameters, {optimisticData}); Navigation.navigate(ROUTES.SETTINGS_PREFERENCES); } @@ -821,15 +801,9 @@ function updateCustomStatus(status: Status) { }, ]; - type UpdateStatusParams = { - text?: string; - emojiCode: string; - clearAfter?: string; - }; - const parameters: UpdateStatusParams = {text: status.text, emojiCode: status.emojiCode, clearAfter: status.clearAfter}; - API.write('UpdateStatus', parameters, { + API.write(WRITE_COMMANDS.UPDATE_STATUS, parameters, { optimisticData, }); } @@ -849,9 +823,7 @@ function clearCustomStatus() { }, }, ]; - API.write('ClearStatus', undefined, { - optimisticData, - }); + API.write(WRITE_COMMANDS.CLEAR_STATUS, {}, {optimisticData}); } /** diff --git a/src/libs/actions/Wallet.ts b/src/libs/actions/Wallet.ts index e7a272343209..b03b5e8f6d3d 100644 --- a/src/libs/actions/Wallet.ts +++ b/src/libs/actions/Wallet.ts @@ -2,38 +2,25 @@ import type {OnyxUpdate} from 'react-native-onyx'; import Onyx from 'react-native-onyx'; import type {ValueOf} from 'type-fest'; import * as API from '@libs/API'; +import type { + AcceptWalletTermsParams, + AnswerQuestionsForWalletParams, + RequestPhysicalExpensifyCardParams, + UpdatePersonalDetailsForWalletParams, + VerifyIdentityParams, +} from '@libs/API/parameters'; +import {READ_COMMANDS, WRITE_COMMANDS} from '@libs/API/types'; import type {PrivatePersonalDetails} from '@libs/GetPhysicalCardUtils'; import type CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {WalletAdditionalQuestionDetails} from '@src/types/onyx'; import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; -type WalletTerms = { - hasAcceptedTerms: boolean; - reportID: string; -}; - type WalletQuestionAnswer = { question: string; answer: string; }; -type IdentityVerification = { - onfidoData: string; -}; - -type PersonalDetails = { - phoneNumber: string; - legalFirstName: string; - legalLastName: string; - addressStreet: string; - addressCity: string; - addressState: string; - addressZip: string; - dob: string; - ssn: string; -}; - /** * Fetch and save locally the Onfido SDK token and applicantID * - The sdkToken is used to initialize the Onfido SDK client @@ -62,14 +49,7 @@ function openOnfidoFlow() { }, ]; - API.read( - 'OpenOnfidoFlow', - {}, - { - optimisticData, - finallyData, - }, - ); + API.read(READ_COMMANDS.OPEN_ONFIDO_FLOW, {}, {optimisticData, finallyData}); } function setAdditionalDetailsQuestions(questions: WalletAdditionalQuestionDetails[], idNumber: string) { @@ -95,7 +75,7 @@ function setKYCWallSource(source?: ValueOf, chatRe /** * Validates a user's provided details against a series of checks */ -function updatePersonalDetails(personalDetails: PersonalDetails) { +function updatePersonalDetails(personalDetails: UpdatePersonalDetailsForWalletParams) { const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -118,7 +98,7 @@ function updatePersonalDetails(personalDetails: PersonalDetails) { }, ]; - API.write('UpdatePersonalDetailsForWallet', personalDetails, { + API.write(WRITE_COMMANDS.UPDATE_PERSONAL_DETAILS_FOR_WALLET, personalDetails, { optimisticData, finallyData, }); @@ -130,7 +110,7 @@ function updatePersonalDetails(personalDetails: PersonalDetails) { * The API will always return the updated userWallet in the response as a convenience so we can avoid an additional * API request to fetch the userWallet after we call VerifyIdentity */ -function verifyIdentity(parameters: IdentityVerification) { +function verifyIdentity(parameters: VerifyIdentityParams) { const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -171,7 +151,7 @@ function verifyIdentity(parameters: IdentityVerification) { }, }, ]; - API.write('VerifyIdentity', parameters, { + API.write(WRITE_COMMANDS.VERIFY_IDENTITY, parameters, { optimisticData, successData, failureData, @@ -183,7 +163,7 @@ function verifyIdentity(parameters: IdentityVerification) { * * @param parameters.chatReportID When accepting the terms of wallet to pay an IOU, indicates the parent chat ID of the IOU */ -function acceptWalletTerms(parameters: WalletTerms) { +function acceptWalletTerms(parameters: AcceptWalletTermsParams) { const optimisticData: OnyxUpdate[] = [ { onyxMethod: Onyx.METHOD.MERGE, @@ -223,23 +203,23 @@ function acceptWalletTerms(parameters: WalletTerms) { }, ]; - const requestParams: WalletTerms = {hasAcceptedTerms: parameters.hasAcceptedTerms, reportID: parameters.reportID}; + const requestParams: AcceptWalletTermsParams = {hasAcceptedTerms: parameters.hasAcceptedTerms, reportID: parameters.reportID}; - API.write('AcceptWalletTerms', requestParams, {optimisticData, successData, failureData}); + API.write(WRITE_COMMANDS.ACCEPT_WALLET_TERMS, requestParams, {optimisticData, successData, failureData}); } /** * Fetches data when the user opens the InitialSettingsPage */ function openInitialSettingsPage() { - API.read('OpenInitialSettingsPage', {}); + API.read(READ_COMMANDS.OPEN_INITIAL_SETTINGS_PAGE, {}); } /** * Fetches data when the user opens the EnablePaymentsPage */ function openEnablePaymentsPage() { - API.read('OpenEnablePaymentsPage', {}); + API.read(READ_COMMANDS.OPEN_ENABLE_PAYMENTS_PAGE, {}); } function updateCurrentStep(currentStep: ValueOf) { @@ -269,17 +249,12 @@ function answerQuestionsForWallet(answers: WalletQuestionAnswer[], idNumber: str }, ]; - type AnswerQuestionsForWallet = { - idologyAnswers: string; - idNumber: string; - }; - - const requestParams: AnswerQuestionsForWallet = { + const requestParams: AnswerQuestionsForWalletParams = { idologyAnswers, idNumber, }; - API.write('AnswerQuestionsForWallet', requestParams, { + API.write(WRITE_COMMANDS.ANSWER_QUESTIONS_FOR_WALLET, requestParams, { optimisticData, finallyData, }); @@ -293,18 +268,6 @@ function requestPhysicalExpensifyCard(cardID: number, authToken: string, private address: {city, country, state, street, zip}, } = privatePersonalDetails; - type RequestPhysicalExpensifyCardParams = { - authToken: string; - legalFirstName: string; - legalLastName: string; - phoneNumber: string; - addressCity: string; - addressCountry: string; - addressState: string; - addressStreet: string; - addressZip: string; - }; - const requestParams: RequestPhysicalExpensifyCardParams = { authToken, legalFirstName, @@ -334,7 +297,7 @@ function requestPhysicalExpensifyCard(cardID: number, authToken: string, private }, ]; - API.write('RequestPhysicalExpensifyCard', requestParams, {optimisticData}); + API.write(WRITE_COMMANDS.REQUEST_PHYSICAL_EXPENSIFY_CARD, requestParams, {optimisticData}); } export { diff --git a/src/libs/calculateAnchorPosition.ts b/src/libs/calculateAnchorPosition.ts index 3b6617aa3ed0..0f1e383522eb 100644 --- a/src/libs/calculateAnchorPosition.ts +++ b/src/libs/calculateAnchorPosition.ts @@ -1,5 +1,5 @@ -/* eslint-disable no-console */ -import type {View} from 'react-native'; +/* eslint-disable no-restricted-imports */ +import type {Text as RNText, View} from 'react-native'; import type {ValueOf} from 'type-fest'; import CONST from '@src/CONST'; import type {AnchorPosition} from '@src/styles'; @@ -13,7 +13,7 @@ type AnchorOrigin = { /** * Gets the x,y position of the passed in component for the purpose of anchoring another component to it. */ -export default function calculateAnchorPosition(anchorComponent: View, anchorOrigin?: AnchorOrigin): Promise { +export default function calculateAnchorPosition(anchorComponent: View | RNText, anchorOrigin?: AnchorOrigin): Promise { return new Promise((resolve) => { if (!anchorComponent) { return resolve({horizontal: 0, vertical: 0}); diff --git a/src/pages/RoomInvitePage.js b/src/pages/RoomInvitePage.js index 3f55ad6c0ff7..588a90e98649 100644 --- a/src/pages/RoomInvitePage.js +++ b/src/pages/RoomInvitePage.js @@ -77,7 +77,10 @@ function RoomInvitePage(props) { // Any existing participants and Expensify emails should not be eligible for invitation const excludedUsers = useMemo( - () => [...PersonalDetailsUtils.getLoginsByAccountIDs(lodashGet(props.report, 'visibleChatMemberAccountIDs', [])), ...CONST.EXPENSIFY_EMAILS], + () => + _.map([...PersonalDetailsUtils.getLoginsByAccountIDs(lodashGet(props.report, 'visibleChatMemberAccountIDs', [])), ...CONST.EXPENSIFY_EMAILS], (participant) => + OptionsListUtils.addSMSDomainIfPhoneNumber(participant), + ), [props.report], ); diff --git a/src/pages/TeachersUnite/IntroSchoolPrincipalPage.tsx b/src/pages/TeachersUnite/IntroSchoolPrincipalPage.tsx index 92645e18dfd5..ba1e3c1de6fb 100644 --- a/src/pages/TeachersUnite/IntroSchoolPrincipalPage.tsx +++ b/src/pages/TeachersUnite/IntroSchoolPrincipalPage.tsx @@ -50,14 +50,10 @@ function IntroSchoolPrincipalPage(props: IntroSchoolPrincipalPageProps) { (values: OnyxFormValuesFields) => { const errors: Errors = {}; - if (!ValidationUtils.isValidLegalName(values.firstName)) { - ErrorUtils.addErrorMessage(errors, 'firstName', 'privatePersonalDetails.error.hasInvalidCharacter'); - } else if (!values.firstName) { + if (!values.firstName || !ValidationUtils.isValidPersonName(values.firstName)) { ErrorUtils.addErrorMessage(errors, 'firstName', 'bankAccount.error.firstName'); } - if (!ValidationUtils.isValidLegalName(values.lastName)) { - ErrorUtils.addErrorMessage(errors, 'lastName', 'privatePersonalDetails.error.hasInvalidCharacter'); - } else if (!values.lastName) { + if (!values.lastName || !ValidationUtils.isValidPersonName(values.lastName)) { ErrorUtils.addErrorMessage(errors, 'lastName', 'bankAccount.error.lastName'); } if (!values.partnerUserID) { diff --git a/src/pages/TeachersUnite/KnowATeacherPage.tsx b/src/pages/TeachersUnite/KnowATeacherPage.tsx index 261c0cada3e8..4ff9da0f299c 100644 --- a/src/pages/TeachersUnite/KnowATeacherPage.tsx +++ b/src/pages/TeachersUnite/KnowATeacherPage.tsx @@ -56,25 +56,21 @@ function KnowATeacherPage(props: KnowATeacherPageProps) { (values: OnyxFormValuesFields) => { const errors = {}; const phoneLogin = LoginUtils.getPhoneLogin(values.partnerUserID); - const validateIfnumber = LoginUtils.validateNumber(phoneLogin); + const validateIfNumber = LoginUtils.validateNumber(phoneLogin); - if (!ValidationUtils.isValidLegalName(values.firstName)) { - ErrorUtils.addErrorMessage(errors, 'firstName', 'privatePersonalDetails.error.hasInvalidCharacter'); - } else if (!values.firstName) { + if (!values.firstName || !ValidationUtils.isValidPersonName(values.firstName)) { ErrorUtils.addErrorMessage(errors, 'firstName', 'bankAccount.error.firstName'); } - if (!ValidationUtils.isValidLegalName(values.lastName)) { - ErrorUtils.addErrorMessage(errors, 'lastName', 'privatePersonalDetails.error.hasInvalidCharacter'); - } else if (!values.lastName) { + if (!values.lastName || !ValidationUtils.isValidPersonName(values.lastName)) { ErrorUtils.addErrorMessage(errors, 'lastName', 'bankAccount.error.lastName'); } if (!values.partnerUserID) { ErrorUtils.addErrorMessage(errors, 'partnerUserID', 'teachersUnitePage.error.enterPhoneEmail'); } - if (values.partnerUserID && props.loginList?.[validateIfnumber || values.partnerUserID.toLowerCase()]) { + if (values.partnerUserID && props.loginList?.[validateIfNumber || values.partnerUserID.toLowerCase()]) { ErrorUtils.addErrorMessage(errors, 'partnerUserID', 'teachersUnitePage.error.tryDifferentEmail'); } - if (values.partnerUserID && !(validateIfnumber || Str.isValidEmail(values.partnerUserID))) { + if (values.partnerUserID && !(validateIfNumber || Str.isValidEmail(values.partnerUserID))) { ErrorUtils.addErrorMessage(errors, 'partnerUserID', 'contacts.genericFailureMessages.invalidContactMethod'); } diff --git a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx index 3eecb74a048a..213d94f51f81 100755 --- a/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx +++ b/src/pages/home/report/ContextMenu/BaseReportActionContextMenu.tsx @@ -2,6 +2,8 @@ import lodashIsEqual from 'lodash/isEqual'; import type {MutableRefObject, RefObject} from 'react'; import React, {memo, useMemo, useRef, useState} from 'react'; import {InteractionManager, View} from 'react-native'; +// eslint-disable-next-line no-restricted-imports +import type {GestureResponderEvent, Text as RNText, View as ViewType} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import {withOnyx} from 'react-native-onyx'; import type {ContextMenuItemHandle} from '@components/ContextMenuItem'; @@ -12,15 +14,16 @@ import useLocalize from '@hooks/useLocalize'; import useNetwork from '@hooks/useNetwork'; import useStyleUtils from '@hooks/useStyleUtils'; import useWindowDimensions from '@hooks/useWindowDimensions'; +import * as ReportUtils from '@libs/ReportUtils'; import * as Session from '@userActions/Session'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; import type {Beta, ReportAction, ReportActions} from '@src/types/onyx'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import type {ContextMenuActionPayload} from './ContextMenuActions'; +import type {ContextMenuAction, ContextMenuActionPayload} from './ContextMenuActions'; import ContextMenuActions from './ContextMenuActions'; import type {ContextMenuType} from './ReportActionContextMenu'; -import {hideContextMenu} from './ReportActionContextMenu'; +import {hideContextMenu, showContextMenu} from './ReportActionContextMenu'; type BaseReportActionContextMenuOnyxProps = { /** Beta features list */ @@ -78,7 +81,11 @@ type BaseReportActionContextMenuProps = BaseReportActionContextMenuOnyxProps & { /** Content Ref */ contentRef?: RefObject; + /** Function to check if context menu is active */ checkIfContextMenuActive?: () => void; + + /** List of disabled actions */ + disabledActions?: ContextMenuAction[]; }; type MenuItemRefs = Record; @@ -100,6 +107,7 @@ function BaseReportActionContextMenu({ betas, reportActions, checkIfContextMenuActive, + disabledActions = [], }: BaseReportActionContextMenuProps) { const StyleUtils = useStyleUtils(); const {translate} = useLocalize(); @@ -117,13 +125,22 @@ function BaseReportActionContextMenu({ }, [reportActions, reportActionID]); const shouldEnableArrowNavigation = !isMini && (isVisible || shouldKeepOpen); - let filteredContextMenuActions = ContextMenuActions.filter((contextAction) => - contextAction.shouldShow(type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID, isPinnedChat, isUnreadChat, !!isOffline, isMini), + let filteredContextMenuActions = ContextMenuActions.filter( + (contextAction) => + !disabledActions.includes(contextAction) && + contextAction.shouldShow(type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID, isPinnedChat, isUnreadChat, !!isOffline, isMini), ); - filteredContextMenuActions = - isMini && filteredContextMenuActions.length > CONST.MINI_CONTEXT_MENU_MAX_ITEMS - ? ([...filteredContextMenuActions.slice(0, CONST.MINI_CONTEXT_MENU_MAX_ITEMS - 1), filteredContextMenuActions.at(-1)] as typeof filteredContextMenuActions) - : filteredContextMenuActions; + + if (isMini) { + const menuAction = filteredContextMenuActions.at(-1); + const otherActions = filteredContextMenuActions.slice(0, -1); + if (otherActions.length > CONST.MINI_CONTEXT_MENU_MAX_ITEMS && menuAction) { + filteredContextMenuActions = otherActions.slice(0, CONST.MINI_CONTEXT_MENU_MAX_ITEMS - 1); + filteredContextMenuActions.push(menuAction); + } else { + filteredContextMenuActions = otherActions; + } + } // Context menu actions that are not rendered as menu items are excluded from arrow navigation const nonMenuItemActionIndexes = filteredContextMenuActions.map((contextAction, index) => @@ -172,6 +189,28 @@ function BaseReportActionContextMenu({ {isActive: shouldEnableArrowNavigation}, ); + const openOverflowMenu = (event: GestureResponderEvent | MouseEvent) => { + const originalReportID = ReportUtils.getOriginalReportID(reportID, reportAction); + const originalReport = ReportUtils.getReport(originalReportID); + showContextMenu( + CONST.CONTEXT_MENU_TYPES.REPORT_ACTION, + event, + selection, + anchor?.current as ViewType | RNText | null, + reportID, + reportAction?.reportActionID, + originalReportID, + draftMessage, + checkIfContextMenuActive, + checkIfContextMenuActive, + ReportUtils.isArchivedRoom(originalReport), + ReportUtils.chatIncludesChronos(originalReport), + undefined, + undefined, + filteredContextMenuActions, + ); + }; + return ( (isVisible || shouldKeepOpen) && ( setShouldKeepOpen(false), openContextMenu: () => setShouldKeepOpen(true), interceptAnonymousUser, - anchor, - checkIfContextMenuActive, + openOverflowMenu, }; if ('renderContent' in contextAction) { diff --git a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx index 7551e03b01ca..4724c9fe0617 100644 --- a/src/pages/home/report/ContextMenu/ContextMenuActions.tsx +++ b/src/pages/home/report/ContextMenu/ContextMenuActions.tsx @@ -1,8 +1,7 @@ import ExpensiMark from 'expensify-common/lib/ExpensiMark'; import type {MutableRefObject} from 'react'; import React from 'react'; -// eslint-disable-next-line no-restricted-imports -import type {GestureResponderEvent, Text as RNText, View} from 'react-native'; +import type {GestureResponderEvent} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import type {Emoji} from '@assets/emojis/types'; import * as Expensicons from '@components/Icon/Expensicons'; @@ -29,14 +28,19 @@ import type {TranslationPaths} from '@src/languages/types'; import ROUTES from '@src/ROUTES'; import type {Beta, ReportAction, ReportActionReactions} from '@src/types/onyx'; import type IconAsset from '@src/types/utils/IconAsset'; -import {hideContextMenu, showContextMenu, showDeleteModal} from './ReportActionContextMenu'; +import {hideContextMenu, showDeleteModal} from './ReportActionContextMenu'; /** Gets the HTML version of the message in an action */ -function getActionText(reportAction: OnyxEntry): string { +function getActionHtml(reportAction: OnyxEntry): string { const message = reportAction?.message?.at(-1) ?? null; return message?.html ?? ''; } +/** Gets the text version of the message in an action */ +function getActionText(reportAction: OnyxEntry): string { + return reportAction?.message?.reduce((acc, curr) => `${acc}${curr.text}`, '') ?? ''; +} + /** Sets the HTML string to Clipboard */ function setClipboardMessage(content: string) { const parser = new ExpensiMark(); @@ -70,8 +74,7 @@ type ContextMenuActionPayload = { close: () => void; openContextMenu: () => void; interceptAnonymousUser: (callback: () => void, isAnonymousAction?: boolean) => void; - anchor?: MutableRefObject; - checkIfContextMenuActive?: () => void; + openOverflowMenu: (event: GestureResponderEvent | MouseEvent) => void; event?: GestureResponderEvent | MouseEvent | KeyboardEvent; }; @@ -162,7 +165,7 @@ const ContextMenuActions: ContextMenuAction[] = [ ); }, onPress: (closePopover, {reportAction}) => { - const html = getActionText(reportAction); + const html = getActionHtml(reportAction); const {originalFileName, sourceURL} = getAttachmentDetails(html); const sourceURLWithAuth = addEncryptedAuthTokenToURL(sourceURL ?? ''); const sourceID = (sourceURL?.match(CONST.REGEX.ATTACHMENT_ID) ?? [])[1]; @@ -220,7 +223,7 @@ const ContextMenuActions: ContextMenuAction[] = [ } const editAction = () => { if (!draftMessage) { - Report.saveReportActionDraft(reportID, reportAction, getActionText(reportAction)); + Report.saveReportActionDraft(reportID, reportAction, getActionHtml(reportAction)); } else { Report.deleteReportActionDraft(reportID, reportAction); } @@ -240,7 +243,7 @@ const ContextMenuActions: ContextMenuAction[] = [ { isAnonymousAction: false, textTranslateKey: 'reportActionContextMenu.markAsUnread', - icon: Expensicons.Mail, + icon: Expensicons.ChatBubbleUnread, successIcon: Expensicons.Checkmark, shouldShow: (type, reportAction, isArchivedRoom, betas, menuTarget, isChronosReport, reportID, isPinnedChat, isUnreadChat) => type === CONST.CONTEXT_MENU_TYPES.REPORT_ACTION || (type === CONST.CONTEXT_MENU_TYPES.REPORT && !isUnreadChat), @@ -372,7 +375,8 @@ const ContextMenuActions: ContextMenuAction[] = [ onPress: (closePopover, {reportAction, selection}) => { const isTaskAction = ReportActionsUtils.isTaskAction(reportAction); const isReportPreviewAction = ReportActionsUtils.isReportPreviewAction(reportAction); - const messageHtml = isTaskAction ? TaskUtils.getTaskReportActionMessage(reportAction?.actionName) : getActionText(reportAction); + const messageHtml = isTaskAction ? TaskUtils.getTaskReportActionMessage(reportAction?.actionName) : getActionHtml(reportAction); + const messageText = getActionText(reportAction); const isAttachment = ReportActionsUtils.isReportActionAttachment(reportAction); if (!isAttachment) { @@ -393,11 +397,10 @@ const ContextMenuActions: ContextMenuAction[] = [ } else if (ReportActionsUtils.isMemberChangeAction(reportAction)) { const logMessage = ReportActionsUtils.getMemberChangeMessageFragment(reportAction).html ?? ''; setClipboardMessage(logMessage); - } else if (ReportActionsUtils.isSubmittedExpenseAction(reportAction)) { - const submittedMessage = reportAction?.message?.reduce((acc, curr) => `${acc}${curr.text}`, ''); - Clipboard.setString(submittedMessage ?? ''); } else if (content) { setClipboardMessage(content); + } else if (messageText) { + Clipboard.setString(messageText); } } @@ -503,27 +506,12 @@ const ContextMenuActions: ContextMenuAction[] = [ textTranslateKey: 'reportActionContextMenu.menu', icon: Expensicons.ThreeDots, shouldShow: (type, reportAction, isArchivedRoom, betas, anchor, isChronosReport, reportID, isPinnedChat, isUnreadChat, isOffline, isMini) => isMini, - onPress: (closePopover, {reportAction, reportID, event, anchor, selection, draftMessage, checkIfContextMenuActive}) => { - const originalReportID = ReportUtils.getOriginalReportID(reportID, reportAction); - const originalReport = ReportUtils.getReport(originalReportID); - showContextMenu( - CONST.CONTEXT_MENU_TYPES.REPORT_ACTION, - event as GestureResponderEvent | MouseEvent, - selection, - anchor?.current as View | RNText | null, - reportID, - reportAction.reportActionID, - originalReportID, - draftMessage, - checkIfContextMenuActive, - checkIfContextMenuActive, - ReportUtils.isArchivedRoom(originalReport), - ReportUtils.chatIncludesChronos(originalReport), - ); + onPress: (closePopover, {openOverflowMenu, event}) => { + openOverflowMenu(event as GestureResponderEvent | MouseEvent); }, getDescription: () => {}, }, ]; export default ContextMenuActions; -export type {ContextMenuActionPayload}; +export type {ContextMenuActionPayload, ContextMenuAction}; diff --git a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx index 46b783bca3f9..b28374fae04a 100644 --- a/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx +++ b/src/pages/home/report/ContextMenu/PopoverReportActionContextMenu.tsx @@ -1,23 +1,23 @@ import type {ForwardedRef} from 'react'; import React, {forwardRef, useCallback, useEffect, useImperativeHandle, useRef, useState} from 'react'; -import type {EmitterSubscription, GestureResponderEvent, NativeTouchEvent, View} from 'react-native'; + +/* eslint-disable no-restricted-imports */ +import type {EmitterSubscription, GestureResponderEvent, NativeTouchEvent, Text as RNText, View} from 'react-native'; import {Dimensions} from 'react-native'; import type {OnyxEntry} from 'react-native-onyx'; import ConfirmModal from '@components/ConfirmModal'; import PopoverWithMeasuredContent from '@components/PopoverWithMeasuredContent'; import useLocalize from '@hooks/useLocalize'; +import calculateAnchorPosition from '@libs/calculateAnchorPosition'; import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as IOU from '@userActions/IOU'; import * as Report from '@userActions/Report'; import CONST from '@src/CONST'; import type {ReportAction} from '@src/types/onyx'; import BaseReportActionContextMenu from './BaseReportActionContextMenu'; +import type {ContextMenuAction} from './ContextMenuActions'; import type {ContextMenuType, ReportActionContextMenu} from './ReportActionContextMenu'; -type ContextMenuAnchorCallback = (x: number, y: number) => void; - -type ContextMenuAnchor = {measureInWindow: (callback: ContextMenuAnchorCallback) => void}; - type Location = { x: number; y: number; @@ -62,11 +62,12 @@ function PopoverReportActionContextMenu(_props: never, ref: ForwardedRef([]); const contentRef = useRef(null); const anchorRef = useRef(null); const dimensionsEventListener = useRef(null); - const contextMenuAnchorRef = useRef(null); + const contextMenuAnchorRef = useRef(null); const contextMenuTargetNode = useRef(null); const onPopoverShow = useRef(() => {}); @@ -161,6 +162,7 @@ function PopoverReportActionContextMenu(_props: never, ref: ForwardedRef { const {pageX = 0, pageY = 0} = extractPointerEvent(event); contextMenuAnchorRef.current = contextMenuAnchor; @@ -171,16 +173,27 @@ function PopoverReportActionContextMenu(_props: never, ref: ForwardedRef { - popoverAnchorPosition.current = { - horizontal: pageX - x, - vertical: pageY - y, - }; - - popoverAnchorPosition.current = { - horizontal: pageX, - vertical: pageY, - }; + new Promise((resolve) => { + if (!pageX && !pageY && contextMenuAnchorRef.current) { + calculateAnchorPosition(contextMenuAnchorRef.current).then((position) => { + popoverAnchorPosition.current = position; + resolve(); + }); + } else { + getContextMenuMeasuredLocation().then(({x, y}) => { + cursorRelativePosition.current = { + horizontal: pageX - x, + vertical: pageY - y, + }; + popoverAnchorPosition.current = { + horizontal: pageX, + vertical: pageY, + }; + resolve(); + }); + } + }).then(() => { + setDisabledActions(disabledOptions); typeRef.current = type; reportIDRef.current = reportID ?? '0'; reportActionIDRef.current = reportActionID ?? '0'; @@ -310,6 +323,7 @@ function PopoverReportActionContextMenu(_props: never, ref: ForwardedRef void; @@ -30,6 +31,7 @@ type ShowContextMenu = ( isChronosReport?: boolean, isPinnedChat?: boolean, isUnreadChat?: boolean, + disabledOptions?: ContextMenuAction[], ) => void; type ReportActionContextMenu = { @@ -108,6 +110,7 @@ function showContextMenu( isChronosReport = false, isPinnedChat = false, isUnreadChat = false, + disabledActions: ContextMenuAction[] = [], ) { if (!contextMenuRef.current) { return; @@ -134,6 +137,7 @@ function showContextMenu( isChronosReport, isPinnedChat, isUnreadChat, + disabledActions, ); } diff --git a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js index a98a717e13d0..90c2ba0b42cf 100644 --- a/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js +++ b/src/pages/home/report/ReportActionCompose/ComposerWithSuggestions/ComposerWithSuggestions.js @@ -122,6 +122,7 @@ function ComposerWithSuggestions({ return draft; }); const commentRef = useRef(value); + const lastTextRef = useRef(value); const {isSmallScreenWidth} = useWindowDimensions(); const maxComposerLines = isSmallScreenWidth ? CONST.COMPOSER.MAX_LINES_SMALL_SCREEN : CONST.COMPOSER.MAX_LINES; @@ -189,6 +190,47 @@ function ComposerWithSuggestions({ [], ); + /** + * Find the newly added characters between the previous text and the new text based on the selection. + * + * @param {string} prevText - The previous text. + * @param {string} newText - The new text. + * @returns {object} An object containing information about the newly added characters. + * @property {number} startIndex - The start index of the newly added characters in the new text. + * @property {number} endIndex - The end index of the newly added characters in the new text. + * @property {string} diff - The newly added characters. + */ + const findNewlyAddedChars = useCallback( + (prevText, newText) => { + let startIndex = -1; + let endIndex = -1; + let currentIndex = 0; + + // Find the first character mismatch with newText + while (currentIndex < newText.length && prevText.charAt(currentIndex) === newText.charAt(currentIndex) && selection.start > currentIndex) { + currentIndex++; + } + + if (currentIndex < newText.length) { + startIndex = currentIndex; + const commonSuffixLength = ComposerUtils.findCommonSuffixLength(prevText, newText, selection.end); + // if text is getting pasted over find length of common suffix and subtract it from new text length + if (commonSuffixLength > 0 || selection.end - selection.start > 0) { + endIndex = newText.length - commonSuffixLength; + } else { + endIndex = currentIndex + newText.length; + } + } + + return { + startIndex, + endIndex, + diff: newText.substring(startIndex, endIndex), + }; + }, + [selection.start, selection.end], + ); + /** * Update the value of the comment in Onyx * @@ -198,7 +240,13 @@ function ComposerWithSuggestions({ const updateComment = useCallback( (commentValue, shouldDebounceSaveComment) => { raiseIsScrollLikelyLayoutTriggered(); - const {text: newComment, emojis, cursorPosition} = EmojiUtils.replaceAndExtractEmojis(commentValue, preferredSkinTone, preferredLocale); + const {startIndex, endIndex, diff} = findNewlyAddedChars(lastTextRef.current, commentValue); + const isEmojiInserted = diff.length && endIndex > startIndex && diff.trim() === diff && EmojiUtils.containsOnlyEmojis(diff); + const { + text: newComment, + emojis, + cursorPosition, + } = EmojiUtils.replaceAndExtractEmojis(isEmojiInserted ? ComposerUtils.insertWhiteSpaceAtIndex(commentValue, endIndex) : commentValue, preferredSkinTone, preferredLocale); if (!_.isEmpty(emojis)) { const newEmojis = EmojiUtils.getAddedEmojis(emojis, emojisPresentBefore.current); if (!_.isEmpty(newEmojis)) { @@ -255,6 +303,7 @@ function ComposerWithSuggestions({ }, [ debouncedUpdateFrequentlyUsedEmojis, + findNewlyAddedChars, preferredLocale, preferredSkinTone, reportID, @@ -309,17 +358,10 @@ function ComposerWithSuggestions({ /** * Callback to add whatever text is chosen into the main input (used f.e as callback for the emoji picker) * @param {String} text - * @param {Boolean} shouldAddTrailSpace */ const replaceSelectionWithText = useCallback( - (text, shouldAddTrailSpace = true) => { - const updatedText = shouldAddTrailSpace ? `${text} ` : text; - const selectionSpaceLength = shouldAddTrailSpace ? CONST.SPACE_LENGTH : 0; - updateComment(ComposerUtils.insertText(commentRef.current, selection, updatedText)); - setSelection((prevSelection) => ({ - start: prevSelection.start + text.length + selectionSpaceLength, - end: prevSelection.start + text.length + selectionSpaceLength, - })); + (text) => { + updateComment(ComposerUtils.insertText(commentRef.current, selection, text)); }, [selection, updateComment], ); @@ -524,6 +566,10 @@ function ComposerWithSuggestions({ [blur, focus, prepareCommentAndResetComposer, replaceSelectionWithText], ); + useEffect(() => { + lastTextRef.current = value; + }, [value]); + useEffect(() => { onValueChange(value); }, [onValueChange, value]); diff --git a/src/pages/home/report/ReportActionItemMessage.tsx b/src/pages/home/report/ReportActionItemMessage.tsx index d68fbf889f29..5f0e3ea4b72c 100644 --- a/src/pages/home/report/ReportActionItemMessage.tsx +++ b/src/pages/home/report/ReportActionItemMessage.tsx @@ -9,7 +9,7 @@ import * as ReportActionsUtils from '@libs/ReportActionsUtils'; import * as ReportUtils from '@libs/ReportUtils'; import CONST from '@src/CONST'; import type {ReportAction} from '@src/types/onyx'; -import type {OriginalMessageSource} from '@src/types/onyx/OriginalMessage'; +import type {OriginalMessageAddComment} from '@src/types/onyx/OriginalMessage'; import TextCommentFragment from './comment/TextCommentFragment'; import ReportActionItemFragment from './ReportActionItemFragment'; @@ -78,7 +78,7 @@ function ReportActionItemMessage({action, displayAsGroup, reportID, style, isHid iouMessage={iouMessage} isThreadParentMessage={ReportActionsUtils.isThreadParentMessage(action, reportID)} pendingAction={action.pendingAction} - source={action.originalMessage as OriginalMessageSource} + source={(action.originalMessage as OriginalMessageAddComment['originalMessage'])?.source} accountID={action.actorAccountID ?? 0} style={style} displayAsGroup={displayAsGroup} diff --git a/src/pages/home/report/ReportActionItemParentAction.tsx b/src/pages/home/report/ReportActionItemParentAction.tsx index dd279d5a1409..9031d4c24656 100644 --- a/src/pages/home/report/ReportActionItemParentAction.tsx +++ b/src/pages/home/report/ReportActionItemParentAction.tsx @@ -58,6 +58,7 @@ function ReportActionItemParentAction({allReportActions = {}, allReports = {}, i onClose={() => Report.navigateToConciergeChatAndDeleteReport(ancestor.report.reportID)} > Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(ancestor.report.reportID))} report={ancestor.report} diff --git a/src/pages/home/report/withReportAndPrivateNotesOrNotFound.js b/src/pages/home/report/withReportAndPrivateNotesOrNotFound.js index de5f7d36299c..6ca7b4b26f91 100644 --- a/src/pages/home/report/withReportAndPrivateNotesOrNotFound.js +++ b/src/pages/home/report/withReportAndPrivateNotesOrNotFound.js @@ -64,6 +64,7 @@ export default function (pageTitle) { const prevIsOffline = usePrevious(network.isOffline); const isReconnecting = prevIsOffline && !network.isOffline; const isOtherUserNote = accountID && Number(session.accountID) !== Number(accountID); + const isPrivateNotesFetchFinished = isPrivateNotesFetchTriggered && !report.isLoadingPrivateNotes; const isPrivateNotesEmpty = accountID ? _.has(lodashGet(report, ['privateNotes', accountID, 'note'], '')) : _.isEmpty(report.privateNotes); useEffect(() => { @@ -76,7 +77,7 @@ export default function (pageTitle) { // eslint-disable-next-line react-hooks/exhaustive-deps -- do not add report.isLoadingPrivateNotes to dependencies }, [report.reportID, network.isOffline, isPrivateNotesFetchTriggered, isReconnecting]); - const shouldShowFullScreenLoadingIndicator = !isPrivateNotesFetchTriggered || (isPrivateNotesEmpty && (report.isLoadingPrivateNotes || !isOtherUserNote)); + const shouldShowFullScreenLoadingIndicator = !isPrivateNotesFetchFinished || (isPrivateNotesEmpty && (report.isLoadingPrivateNotes || !isOtherUserNote)); // eslint-disable-next-line rulesdir/no-negated-variables const shouldShowNotFoundPage = useMemo(() => { diff --git a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js index be3d6ad50eeb..15f98205839e 100644 --- a/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js +++ b/src/pages/iou/request/MoneyTemporaryForRefactorRequestParticipantsSelector.js @@ -17,6 +17,7 @@ import useThemeStyles from '@hooks/useThemeStyles'; import * as Report from '@libs/actions/Report'; import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as OptionsListUtils from '@libs/OptionsListUtils'; +import * as ReportUtils from '@libs/ReportUtils'; import reportPropTypes from '@pages/reportPropTypes'; import CONST from '@src/CONST'; import ONYXKEYS from '@src/ONYXKEYS'; @@ -54,8 +55,8 @@ const propTypes = { /** The request type, ie. manual, scan, distance */ iouRequestType: PropTypes.oneOf(_.values(CONST.IOU.REQUEST_TYPE)).isRequired, - /** Whether we are searching for reports in the server */ - isSearchingForReports: PropTypes.bool, + /** Whether the parent screen transition has ended */ + didScreenTransitionEnd: PropTypes.bool, }; const defaultProps = { @@ -63,7 +64,7 @@ const defaultProps = { safeAreaPaddingBottomStyle: {}, reports: {}, betas: [], - isSearchingForReports: false, + didScreenTransitionEnd: false, }; function MoneyTemporaryForRefactorRequestParticipantsSelector({ @@ -75,7 +76,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ safeAreaPaddingBottomStyle, iouType, iouRequestType, - isSearchingForReports, + didScreenTransitionEnd, }) { const {translate} = useLocalize(); const styles = useThemeStyles(); @@ -95,6 +96,9 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ */ const [sections, newChatOptions] = useMemo(() => { const newSections = []; + if (!didScreenTransitionEnd) { + return [newSections, {}]; + } let indexOffset = 0; const chatOptions = OptionsListUtils.getFilteredOptions( @@ -169,7 +173,7 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ } return [newSections, chatOptions]; - }, [reports, personalDetails, betas, searchTerm, participants, iouType, iouRequestType, maxParticipantsReached, translate]); + }, [didScreenTransitionEnd, reports, personalDetails, betas, searchTerm, participants, iouType, iouRequestType, maxParticipantsReached, translate]); /** * Adds a single participant to the request @@ -328,11 +332,13 @@ function MoneyTemporaryForRefactorRequestParticipantsSelector({ [addParticipantToSelection, isAllowedToSplit, styles, translate], ); + const isOptionsDataReady = useMemo(() => ReportUtils.isReportDataReady() && OptionsListUtils.isPersonalDetailsReady(personalDetails), [personalDetails]); + return ( 0 ? safeAreaPaddingBottomStyle : {}]}> @@ -359,8 +365,4 @@ export default withOnyx({ betas: { key: ONYXKEYS.BETAS, }, - isSearchingForReports: { - key: ONYXKEYS.IS_SEARCHING_FOR_REPORTS, - initWithStoredValues: false, - }, })(MoneyTemporaryForRefactorRequestParticipantsSelector); diff --git a/src/pages/iou/request/step/IOURequestStepConfirmation.js b/src/pages/iou/request/step/IOURequestStepConfirmation.js index 801568b1c5b8..f867e57f9a13 100644 --- a/src/pages/iou/request/step/IOURequestStepConfirmation.js +++ b/src/pages/iou/request/step/IOURequestStepConfirmation.js @@ -140,7 +140,7 @@ function IOURequestStepConfirmation({ setReceiptFile(receipt); }; - IOUUtils.navigateToStartStepIfScanFileCannotBeRead(receiptFilename, receiptPath, onSuccess, requestType, iouType, transactionID, reportID); + IOU.navigateToStartStepIfScanFileCannotBeRead(receiptFilename, receiptPath, onSuccess, requestType, iouType, transactionID, reportID); }, [receiptPath, receiptFilename, requestType, iouType, transactionID, reportID]); useEffect(() => { diff --git a/src/pages/iou/request/step/IOURequestStepParticipants.js b/src/pages/iou/request/step/IOURequestStepParticipants.js index 730441035d08..0d1177e231c4 100644 --- a/src/pages/iou/request/step/IOURequestStepParticipants.js +++ b/src/pages/iou/request/step/IOURequestStepParticipants.js @@ -47,7 +47,7 @@ function IOURequestStepParticipants({ // This is because until the request is saved, the receipt file is only stored in the browsers memory as a blob:// and if the browser is refreshed, then // the image ceases to exist. The best way for the user to recover from this is to start over from the start of the request process. useEffect(() => { - IOUUtils.navigateToStartStepIfScanFileCannotBeRead(receiptFilename, receiptPath, () => {}, iouRequestType, iouType, transactionID, reportID); + IOU.navigateToStartStepIfScanFileCannotBeRead(receiptFilename, receiptPath, () => {}, iouRequestType, iouType, transactionID, reportID); }, [receiptPath, receiptFilename, iouRequestType, iouType, transactionID, reportID]); const addParticipant = useCallback( @@ -87,13 +87,16 @@ function IOURequestStepParticipants({ testID={IOURequestStepParticipants.displayName} includeSafeAreaPaddingBottom > - + {({didScreenTransitionEnd}) => ( + + )} ); } diff --git a/src/pages/workspace/WorkspaceNewRoomPage.js b/src/pages/workspace/WorkspaceNewRoomPage.js index 35fab36e5d41..b616b519ff32 100644 --- a/src/pages/workspace/WorkspaceNewRoomPage.js +++ b/src/pages/workspace/WorkspaceNewRoomPage.js @@ -100,10 +100,25 @@ function WorkspaceNewRoomPage(props) { const {isOffline} = useNetwork(); const {isSmallScreenWidth} = useWindowDimensions(); const [visibility, setVisibility] = useState(CONST.REPORT.VISIBILITY.RESTRICTED); - const [policyID, setPolicyID] = useState(props.activePolicyID); const [writeCapability, setWriteCapability] = useState(CONST.REPORT.WRITE_CAPABILITIES.ALL); const wasLoading = usePrevious(props.formState.isLoading); const visibilityDescription = useMemo(() => translate(`newRoomPage.${visibility}Description`), [translate, visibility]); + + const workspaceOptions = useMemo( + () => + _.map(PolicyUtils.getActivePolicies(props.policies), (policy) => ({ + label: policy.name, + key: policy.id, + value: policy.id, + })), + [props.policies], + ); + const [policyID, setPolicyID] = useState(() => { + if (_.some(workspaceOptions, (option) => option.value === props.activePolicyID)) { + return props.activePolicyID; + } + return ''; + }); const isPolicyAdmin = useMemo(() => { if (!policyID) { return false; @@ -144,10 +159,17 @@ function WorkspaceNewRoomPage(props) { useEffect(() => { if (policyID) { + if (!_.some(workspaceOptions, (opt) => opt.value === policyID)) { + setPolicyID(''); + } return; } - setPolicyID(props.activePolicyID); - }, [props.activePolicyID, policyID]); + if (_.some(workspaceOptions, (opt) => opt.value === props.activePolicyID)) { + setPolicyID(props.activePolicyID); + } else { + setPolicyID(''); + } + }, [props.activePolicyID, policyID, workspaceOptions]); useEffect(() => { if (!(((wasLoading && !props.formState.isLoading) || (isOffline && props.formState.isLoading)) && _.isEmpty(props.formState.errorFields))) { @@ -196,16 +218,6 @@ function WorkspaceNewRoomPage(props) { [props.reports], ); - const workspaceOptions = useMemo( - () => - _.map(PolicyUtils.getActivePolicies(props.policies), (policy) => ({ - label: policy.name, - key: policy.id, - value: policy.id, - })), - [props.policies], - ); - const writeCapabilityOptions = useMemo( () => _.map(CONST.REPORT.WRITE_CAPABILITIES, (value) => ({ diff --git a/src/types/onyx/Report.ts b/src/types/onyx/Report.ts index 90f25ab6a8cb..f3b20c68038e 100644 --- a/src/types/onyx/Report.ts +++ b/src/types/onyx/Report.ts @@ -13,6 +13,13 @@ type Note = { pendingAction?: OnyxCommon.PendingAction; }; +type Participant = { + hidden: boolean; + role?: 'admin' | 'member'; +}; + +type Participants = Record; + type Report = { /** The specific type of chat */ chatType?: ValueOf; @@ -117,6 +124,7 @@ type Report = { lastActorAccountID?: number; ownerAccountID?: number; ownerEmail?: string; + participants?: Participants; participantAccountIDs?: number[]; visibleChatMemberAccountIDs?: number[]; total?: number; diff --git a/tests/perf-test/ModifiedExpenseMessage.perf-test.ts b/tests/perf-test/ModifiedExpenseMessage.perf-test.ts index 5aa842155cb5..6e9ab5394cf9 100644 --- a/tests/perf-test/ModifiedExpenseMessage.perf-test.ts +++ b/tests/perf-test/ModifiedExpenseMessage.perf-test.ts @@ -11,8 +11,6 @@ import createRandomReportAction from '../utils/collections/reportActions'; import createRandomReport from '../utils/collections/reports'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; -const runs = CONST.PERFORMANCE_TESTS.RUNS; - beforeAll(() => Onyx.init({ keys: ONYXKEYS, @@ -39,10 +37,10 @@ const getMockedPolicies = (length = 500) => length, ); -const mockedReportsMap = getMockedReports(5000) as Record<`${typeof ONYXKEYS.COLLECTION.REPORT}`, Report>; -const mockedPoliciesMap = getMockedPolicies(5000) as Record<`${typeof ONYXKEYS.COLLECTION.POLICY}`, Policy>; +const mockedReportsMap = getMockedReports(1000) as Record<`${typeof ONYXKEYS.COLLECTION.REPORT}`, Report>; +const mockedPoliciesMap = getMockedPolicies(1000) as Record<`${typeof ONYXKEYS.COLLECTION.POLICY}`, Policy>; -test('[ModifiedExpenseMessage] getForReportAction on 5k reports and policies', async () => { +test('[ModifiedExpenseMessage] getForReportAction on 1k reports and policies', async () => { const reportAction = { ...createRandomReportAction(1), actionName: CONST.REPORT.ACTIONS.TYPE.MODIFIEDEXPENSE, @@ -60,5 +58,5 @@ test('[ModifiedExpenseMessage] getForReportAction on 5k reports and policies', a }); await waitForBatchedUpdates(); - await measureFunction(() => ModifiedExpenseMessage.getForReportAction(reportAction), {runs}); + await measureFunction(() => ModifiedExpenseMessage.getForReportAction(reportAction)); }); diff --git a/tests/perf-test/OptionsSelector.perf-test.js b/tests/perf-test/OptionsSelector.perf-test.js index b30169b8b53f..6104ded05c6a 100644 --- a/tests/perf-test/OptionsSelector.perf-test.js +++ b/tests/perf-test/OptionsSelector.perf-test.js @@ -3,7 +3,6 @@ import React from 'react'; import {measurePerformance} from 'reassure'; import _ from 'underscore'; import OptionsSelector from '@src/components/OptionsSelector'; -import CONST from '@src/CONST'; import variables from '@src/styles/variables'; jest.mock('../../src/components/withLocalize', () => (Component) => { @@ -65,8 +64,6 @@ function OptionsSelectorWrapper(args) { ); } -const runs = CONST.PERFORMANCE_TESTS.RUNS; - test('[OptionsSelector] should render text input with interactions', () => { const scenario = (screen) => { const textInput = screen.getByTestId('options-selector-input'); @@ -75,16 +72,16 @@ test('[OptionsSelector] should render text input with interactions', () => { fireEvent.changeText(textInput, 'test3'); }; - measurePerformance(, {scenario, runs}); + measurePerformance(, {scenario}); }); test('[OptionsSelector] should render 1 section', () => { - measurePerformance(, {runs}); + measurePerformance(); }); test('[OptionsSelector] should render multiple sections', () => { const sections = generateSections(mutlipleSectionsConfig); - measurePerformance(, {runs}); + measurePerformance(); }); test('[OptionsSelector] should press a list items', () => { @@ -94,7 +91,7 @@ test('[OptionsSelector] should press a list items', () => { fireEvent.press(screen.getByText('Item 10')); }; - measurePerformance(, {scenario, runs}); + measurePerformance(, {scenario}); }); test('[OptionsSelector] should scroll and press few items', () => { @@ -126,5 +123,5 @@ test('[OptionsSelector] should scroll and press few items', () => { fireEvent.press(screen.getByText('Item 200')); }; - measurePerformance(, {scenario, runs}); + measurePerformance(, {scenario}); }); diff --git a/tests/perf-test/ReportActionCompose.perf-test.js b/tests/perf-test/ReportActionCompose.perf-test.js index de34c139a361..27d83cb885da 100644 --- a/tests/perf-test/ReportActionCompose.perf-test.js +++ b/tests/perf-test/ReportActionCompose.perf-test.js @@ -7,7 +7,6 @@ import {LocaleContextProvider} from '../../src/components/LocaleContextProvider' import OnyxProvider from '../../src/components/OnyxProvider'; import {KeyboardStateProvider} from '../../src/components/withKeyboardState'; import {WindowDimensionsProvider} from '../../src/components/withWindowDimensions'; -import CONST from '../../src/CONST'; import * as Localize from '../../src/libs/Localize'; import ONYXKEYS from '../../src/ONYXKEYS'; import ReportActionCompose from '../../src/pages/home/report/ReportActionCompose/ReportActionCompose'; @@ -51,6 +50,22 @@ jest.mock('../../src/libs/actions/EmojiPickerAction', () => { }; }); +jest.mock('../../src/components/withNavigationFocus', () => (Component) => { + function WithNavigationFocus(props) { + return ( + + ); + } + + WithNavigationFocus.displayName = 'WithNavigationFocus'; + + return WithNavigationFocus; +}); + beforeAll(() => Onyx.init({ keys: ONYXKEYS, @@ -64,8 +79,6 @@ beforeEach(() => { Onyx.merge(ONYXKEYS.NETWORK, {isOffline: false}); }); -const runs = CONST.PERFORMANCE_TESTS.RUNS; - function ReportActionComposeWrapper() { return ( @@ -96,7 +109,7 @@ test('[ReportActionCompose] should render Composer with text input interactions' fireEvent.press(composer); }; - return waitForBatchedUpdates().then(() => measurePerformance(, {scenario, runs})); + return waitForBatchedUpdates().then(() => measurePerformance(, {scenario})); }); test('[ReportActionCompose] should press add attachemnt button', async () => { @@ -108,7 +121,7 @@ test('[ReportActionCompose] should press add attachemnt button', async () => { fireEvent.press(attachmentButton, mockEvent); }; - return waitForBatchedUpdates().then(() => measurePerformance(, {scenario, runs})); + return waitForBatchedUpdates().then(() => measurePerformance(, {scenario})); }); test('[ReportActionCompose] should press add emoji button', async () => { @@ -120,7 +133,7 @@ test('[ReportActionCompose] should press add emoji button', async () => { fireEvent.press(emojiButton); }; - return waitForBatchedUpdates().then(() => measurePerformance(, {scenario, runs})); + return waitForBatchedUpdates().then(() => measurePerformance(, {scenario})); }); test('[ReportActionCompose] should press send message button', async () => { @@ -132,7 +145,7 @@ test('[ReportActionCompose] should press send message button', async () => { fireEvent.press(sendButton); }; - return waitForBatchedUpdates().then(() => measurePerformance(, {scenario, runs})); + return waitForBatchedUpdates().then(() => measurePerformance(, {scenario})); }); test('[ReportActionCompose] render composer with attachement modal interactions', async () => { @@ -152,5 +165,5 @@ test('[ReportActionCompose] render composer with attachement modal interactions' fireEvent.press(assignTaskButton, mockEvent); }; - return waitForBatchedUpdates().then(() => measurePerformance(, {scenario, runs})); + return waitForBatchedUpdates().then(() => measurePerformance(, {scenario})); }); diff --git a/tests/perf-test/ReportActionsList.perf-test.js b/tests/perf-test/ReportActionsList.perf-test.js index 8e3312cfa4c7..34b127c217e4 100644 --- a/tests/perf-test/ReportActionsList.perf-test.js +++ b/tests/perf-test/ReportActionsList.perf-test.js @@ -5,7 +5,6 @@ import ComposeProviders from '../../src/components/ComposeProviders'; import {LocaleContextProvider} from '../../src/components/LocaleContextProvider'; import OnyxProvider from '../../src/components/OnyxProvider'; import {WindowDimensionsProvider} from '../../src/components/withWindowDimensions'; -import CONST from '../../src/CONST'; import * as Localize from '../../src/libs/Localize'; import ONYXKEYS from '../../src/ONYXKEYS'; import ReportActionsList from '../../src/pages/home/report/ReportActionsList'; @@ -97,8 +96,6 @@ function ReportActionsListWrapper() { ); } -const runs = CONST.PERFORMANCE_TESTS.RUNS; - test('[ReportActionsList] should render ReportActionsList with 500 reportActions stored', () => { const scenario = async () => { await screen.findByTestId('report-actions-list'); @@ -113,7 +110,7 @@ test('[ReportActionsList] should render ReportActionsList with 500 reportActions [ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails, }), ) - .then(() => measurePerformance(, {scenario, runs})); + .then(() => measurePerformance(, {scenario})); }); test('[ReportActionsList] should scroll and click some of the reports', () => { @@ -151,5 +148,5 @@ test('[ReportActionsList] should scroll and click some of the reports', () => { [ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails, }), ) - .then(() => measurePerformance(, {scenario, runs})); + .then(() => measurePerformance(, {scenario})); }); diff --git a/tests/perf-test/ReportActionsUtils.perf-test.ts b/tests/perf-test/ReportActionsUtils.perf-test.ts index 2a96a5959942..f194cd32bbf4 100644 --- a/tests/perf-test/ReportActionsUtils.perf-test.ts +++ b/tests/perf-test/ReportActionsUtils.perf-test.ts @@ -35,8 +35,6 @@ const reportActions = createCollection( const reportId = '1'; -const runs = CONST.PERFORMANCE_TESTS.RUNS; - describe('ReportActionsUtils', () => { beforeAll(() => { Onyx.init({ @@ -65,7 +63,7 @@ describe('ReportActionsUtils', () => { */ test('[ReportActionsUtils] getLastVisibleAction on 10k reportActions', async () => { await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId), {runs}); + await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId)); }); test('[ReportActionsUtils] getLastVisibleAction on 10k reportActions with actionsToMerge', async () => { @@ -91,19 +89,19 @@ describe('ReportActionsUtils', () => { } as unknown as ReportActions; await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId, actionsToMerge), {runs}); + await measureFunction(() => ReportActionsUtils.getLastVisibleAction(reportId, actionsToMerge)); }); test('[ReportActionsUtils] getMostRecentIOURequestActionID on 10k ReportActions', async () => { const reportActionsArray = ReportActionsUtils.getSortedReportActionsForDisplay(reportActions); await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray), {runs}); + await measureFunction(() => ReportActionsUtils.getMostRecentIOURequestActionID(reportActionsArray)); }); test('[ReportActionsUtils] getLastVisibleMessage on 10k ReportActions', async () => { await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId), {runs}); + await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId)); }); test('[ReportActionsUtils] getLastVisibleMessage on 10k ReportActions with actionsToMerge', async () => { @@ -129,21 +127,21 @@ describe('ReportActionsUtils', () => { } as unknown as ReportActions; await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId, actionsToMerge), {runs}); + await measureFunction(() => ReportActionsUtils.getLastVisibleMessage(reportId, actionsToMerge)); }); test('[ReportActionsUtils] getSortedReportActionsForDisplay on 10k ReportActions', async () => { await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions), {runs}); + await measureFunction(() => ReportActionsUtils.getSortedReportActionsForDisplay(reportActions)); }); test('[ReportActionsUtils] getLastClosedReportAction on 10k ReportActions', async () => { await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getLastClosedReportAction(reportActions), {runs}); + await measureFunction(() => ReportActionsUtils.getLastClosedReportAction(reportActions)); }); test('[ReportActionsUtils] getMostRecentReportActionLastModified', async () => { await waitForBatchedUpdates(); - await measureFunction(() => ReportActionsUtils.getMostRecentReportActionLastModified(), {runs}); + await measureFunction(() => ReportActionsUtils.getMostRecentReportActionLastModified()); }); }); diff --git a/tests/perf-test/ReportScreen.perf-test.js b/tests/perf-test/ReportScreen.perf-test.js index d58f71fa7ab4..5a144e715f5b 100644 --- a/tests/perf-test/ReportScreen.perf-test.js +++ b/tests/perf-test/ReportScreen.perf-test.js @@ -152,8 +152,6 @@ function ReportScreenWrapper(args) { ); } -const runs = CONST.PERFORMANCE_TESTS.RUNS; - test.skip('[ReportScreen] should render ReportScreen with composer interactions', () => { const {triggerTransitionEnd, addListener} = createAddListenerMock(); const scenario = async () => { @@ -222,7 +220,7 @@ test.skip('[ReportScreen] should render ReportScreen with composer interactions' navigation={navigation} route={mockRoute} />, - {scenario, runs}, + {scenario}, ), ); }); @@ -287,7 +285,7 @@ test.skip('[ReportScreen] should press of the report item', () => { navigation={navigation} route={mockRoute} />, - {scenario, runs}, + {scenario}, ), ); }); diff --git a/tests/perf-test/ReportUtils.perf-test.ts b/tests/perf-test/ReportUtils.perf-test.ts index 953fc88a99cf..ae3429bb9c01 100644 --- a/tests/perf-test/ReportUtils.perf-test.ts +++ b/tests/perf-test/ReportUtils.perf-test.ts @@ -12,7 +12,6 @@ import createRandomReport from '../utils/collections/reports'; import createRandomTransaction from '../utils/collections/transaction'; import waitForBatchedUpdates from '../utils/waitForBatchedUpdates'; -const runs = CONST.PERFORMANCE_TESTS.RUNS; const getMockedReports = (length = 500) => createCollection( (item) => `${ONYXKEYS.COLLECTION.REPORT}${item.reportID}`, @@ -33,8 +32,8 @@ const personalDetails = createCollection( 1000, ); -const mockedReportsMap = getMockedReports(5000) as Record<`${typeof ONYXKEYS.COLLECTION.REPORT}`, Report>; -const mockedPoliciesMap = getMockedPolicies(5000) as Record<`${typeof ONYXKEYS.COLLECTION.POLICY}`, Policy>; +const mockedReportsMap = getMockedReports(1000) as Record<`${typeof ONYXKEYS.COLLECTION.REPORT}`, Report>; +const mockedPoliciesMap = getMockedPolicies(1000) as Record<`${typeof ONYXKEYS.COLLECTION.POLICY}`, Policy>; const participantAccountIDs = Array.from({length: 1000}, (v, i) => i + 1); describe('ReportUtils', () => { @@ -62,15 +61,15 @@ describe('ReportUtils', () => { const openOnAdminRoom = true; await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.findLastAccessedReport(reports, ignoreDomainRooms, policies, isFirstTimeNewExpensifyUser, openOnAdminRoom), {runs}); + await measureFunction(() => ReportUtils.findLastAccessedReport(reports, ignoreDomainRooms, policies, isFirstTimeNewExpensifyUser, openOnAdminRoom)); }); - test('[ReportUtils] canDeleteReportAction on 5k reports and policies', async () => { + test('[ReportUtils] canDeleteReportAction on 1k reports and policies', async () => { const reportID = '1'; const reportAction = {...createRandomReportAction(1), actionName: CONST.REPORT.ACTIONS.TYPE.ADDCOMMENT} as unknown as ReportAction; await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.canDeleteReportAction(reportAction, reportID), {runs}); + await measureFunction(() => ReportUtils.canDeleteReportAction(reportAction, reportID)); }); test('[ReportUtils] getReportRecipientAccountID on 1k participants', async () => { @@ -78,14 +77,14 @@ describe('ReportUtils', () => { const currentLoginAccountID = 1; await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getReportRecipientAccountIDs(report, currentLoginAccountID), {runs}); + await measureFunction(() => ReportUtils.getReportRecipientAccountIDs(report, currentLoginAccountID)); }); test('[ReportUtils] getIconsForParticipants on 1k participants', async () => { const participants = Array.from({length: 1000}, (v, i) => i + 1); await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getIconsForParticipants(participants, personalDetails), {runs}); + await measureFunction(() => ReportUtils.getIconsForParticipants(participants, personalDetails)); }); test('[ReportUtils] getIcons on 1k participants', async () => { @@ -96,7 +95,7 @@ describe('ReportUtils', () => { const defaultIconId = -1; await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getIcons(report, personalDetails, defaultIcon, defaultName, defaultIconId, policy), {runs}); + await measureFunction(() => ReportUtils.getIcons(report, personalDetails, defaultIcon, defaultName, defaultIconId, policy)); }); test('[ReportUtils] getDisplayNamesWithTooltips 1k participants', async () => { @@ -104,10 +103,10 @@ describe('ReportUtils', () => { const shouldFallbackToHidden = true; await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getDisplayNamesWithTooltips(personalDetails, isMultipleParticipantReport, shouldFallbackToHidden), {runs}); + await measureFunction(() => ReportUtils.getDisplayNamesWithTooltips(personalDetails, isMultipleParticipantReport, shouldFallbackToHidden)); }); - test('[ReportUtils] getReportPreviewMessage on 5k policies', async () => { + test('[ReportUtils] getReportPreviewMessage on 1k policies', async () => { const reportAction = createRandomReportAction(1); const report = createRandomReport(1); const policy = createRandomPolicy(1); @@ -115,7 +114,7 @@ describe('ReportUtils', () => { const isPreviewMessageForParentChatReport = true; await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getReportPreviewMessage(report, reportAction, shouldConsiderReceiptBeingScanned, isPreviewMessageForParentChatReport, policy), {runs}); + await measureFunction(() => ReportUtils.getReportPreviewMessage(report, reportAction, shouldConsiderReceiptBeingScanned, isPreviewMessageForParentChatReport, policy)); }); test('[ReportUtils] getReportName on 1k participants', async () => { @@ -123,7 +122,7 @@ describe('ReportUtils', () => { const policy = createRandomPolicy(1); await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getReportName(report, policy), {runs}); + await measureFunction(() => ReportUtils.getReportName(report, policy)); }); test('[ReportUtils] canShowReportRecipientLocalTime on 1k participants', async () => { @@ -131,7 +130,7 @@ describe('ReportUtils', () => { const accountID = 1; await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.canShowReportRecipientLocalTime(personalDetails, report, accountID), {runs}); + await measureFunction(() => ReportUtils.canShowReportRecipientLocalTime(personalDetails, report, accountID)); }); test('[ReportUtils] shouldReportBeInOptionList on 1k participant', async () => { @@ -142,20 +141,17 @@ describe('ReportUtils', () => { const policies = getMockedPolicies(); await waitForBatchedUpdates(); - await measureFunction( - () => ReportUtils.shouldReportBeInOptionList({report, currentReportId, isInGSDMode, betas, policies, doesReportHaveViolations: false, excludeEmptyChats: false}), - { - runs, - }, + await measureFunction(() => + ReportUtils.shouldReportBeInOptionList({report, currentReportId, isInGSDMode, betas, policies, doesReportHaveViolations: false, excludeEmptyChats: false}), ); }); - test('[ReportUtils] getWorkspaceIcon on 5k policies', async () => { + test('[ReportUtils] getWorkspaceIcon on 1k policies', async () => { const report = createRandomReport(1); const policy = createRandomPolicy(1); await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getWorkspaceIcon(report, policy), {runs}); + await measureFunction(() => ReportUtils.getWorkspaceIcon(report, policy)); }); test('[ReportUtils] getMoneyRequestOptions on 1k participants', async () => { @@ -164,32 +160,32 @@ describe('ReportUtils', () => { const reportParticipants = Array.from({length: 1000}, (v, i) => i + 1); await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getMoneyRequestOptions(report, policy, reportParticipants), {runs}); + await measureFunction(() => ReportUtils.getMoneyRequestOptions(report, policy, reportParticipants)); }); - test('[ReportUtils] getWorkspaceAvatar on 5k policies', async () => { + test('[ReportUtils] getWorkspaceAvatar on 1k policies', async () => { const report = createRandomReport(1); await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getWorkspaceAvatar(report), {runs}); + await measureFunction(() => ReportUtils.getWorkspaceAvatar(report)); }); - test('[ReportUtils] getWorkspaceChat on 5k policies', async () => { + test('[ReportUtils] getWorkspaceChat on 1k policies', async () => { const policyID = '1'; const accountsID = Array.from({length: 20}, (v, i) => i + 1); await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getWorkspaceChats(policyID, accountsID), {runs}); + await measureFunction(() => ReportUtils.getWorkspaceChats(policyID, accountsID)); }); - test('[ReportUtils] getTransactionDetails on 5k reports', async () => { + test('[ReportUtils] getTransactionDetails on 1k reports', async () => { const transaction = createRandomTransaction(1); await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getTransactionDetails(transaction, 'yyyy-MM-dd'), {runs}); + await measureFunction(() => ReportUtils.getTransactionDetails(transaction, 'yyyy-MM-dd')); }); - test('[ReportUtils] getIOUReportActionDisplayMessage on 5k policies', async () => { + test('[ReportUtils] getIOUReportActionDisplayMessage on 1k policies', async () => { const reportAction = { ...createRandomReportAction(1), actionName: CONST.REPORT.ACTIONS.TYPE.IOU, @@ -205,6 +201,6 @@ describe('ReportUtils', () => { }; await waitForBatchedUpdates(); - await measureFunction(() => ReportUtils.getIOUReportActionDisplayMessage(reportAction), {runs}); + await measureFunction(() => ReportUtils.getIOUReportActionDisplayMessage(reportAction)); }); }); diff --git a/tests/perf-test/SearchPage.perf-test.js b/tests/perf-test/SearchPage.perf-test.js index e948ade014dc..b27a2e2115be 100644 --- a/tests/perf-test/SearchPage.perf-test.js +++ b/tests/perf-test/SearchPage.perf-test.js @@ -36,6 +36,22 @@ jest.mock('@react-navigation/native', () => { }; }); +jest.mock('../../src/components/withNavigationFocus', () => (Component) => { + function WithNavigationFocus(props) { + return ( + + ); + } + + WithNavigationFocus.displayName = 'WithNavigationFocus'; + + return WithNavigationFocus; +}); + const getMockedReports = (length = 100) => createCollection( (item) => `${ONYXKEYS.COLLECTION.REPORT}${item.reportID}`, @@ -87,8 +103,6 @@ function SearchPageWrapper(args) { ); } -const runs = CONST.PERFORMANCE_TESTS.RUNS; - test('[Search Page] should interact when text input changes', async () => { const {addListener} = TestHelper.createAddListenerMock(); @@ -113,7 +127,7 @@ test('[Search Page] should interact when text input changes', async () => { [ONYXKEYS.IS_SEARCHING_FOR_REPORTS]: true, }), ) - .then(() => measurePerformance(, {scenario, runs})); + .then(() => measurePerformance(, {scenario})); }); test('[Search Page] should render options list', async () => { @@ -139,7 +153,7 @@ test('[Search Page] should render options list', async () => { [ONYXKEYS.IS_SEARCHING_FOR_REPORTS]: true, }), ) - .then(() => measurePerformance(, {scenario, runs})); + .then(() => measurePerformance(, {scenario})); }); test('[Search Page] should search in options list', async () => { @@ -166,7 +180,7 @@ test('[Search Page] should search in options list', async () => { [ONYXKEYS.IS_SEARCHING_FOR_REPORTS]: true, }), ) - .then(() => measurePerformance(, {scenario, runs})); + .then(() => measurePerformance(, {scenario})); }); test('[Search Page] should click on list item', async () => { @@ -194,5 +208,5 @@ test('[Search Page] should click on list item', async () => { [ONYXKEYS.IS_SEARCHING_FOR_REPORTS]: true, }), ) - .then(() => measurePerformance(, {scenario, runs})); + .then(() => measurePerformance(, {scenario})); }); diff --git a/tests/perf-test/SelectionList.perf-test.js b/tests/perf-test/SelectionList.perf-test.js index b9f05c33e925..9decc4361612 100644 --- a/tests/perf-test/SelectionList.perf-test.js +++ b/tests/perf-test/SelectionList.perf-test.js @@ -3,7 +3,6 @@ import React, {useState} from 'react'; import {measurePerformance} from 'reassure'; import _ from 'underscore'; import SelectionList from '../../src/components/SelectionList'; -import CONST from '../../src/CONST'; import variables from '../../src/styles/variables'; jest.mock('../../src/components/Icon/Expensicons'); @@ -93,8 +92,6 @@ function SelectionListWrapper(args) { ); } -const runs = CONST.PERFORMANCE_TESTS.RUNS; - test('[SelectionList] should render 1 section and a thousand items', () => { measurePerformance(); }); @@ -104,7 +101,7 @@ test('[SelectionList] should press a list item', () => { fireEvent.press(screen.getByText('Item 5')); }; - measurePerformance(, {scenario, runs}); + measurePerformance(, {scenario}); }); test('[SelectionList] should render multiple selection and select 3 items', () => { @@ -114,7 +111,7 @@ test('[SelectionList] should render multiple selection and select 3 items', () = fireEvent.press(screen.getByText('Item 3')); }; - measurePerformance(, {scenario, runs}); + measurePerformance(, {scenario}); }); test('[SelectionList] should scroll and select a few items', () => { @@ -145,5 +142,5 @@ test('[SelectionList] should scroll and select a few items', () => { fireEvent.press(screen.getByText('Item 15')); }; - measurePerformance(, {scenario, runs}); + measurePerformance(, {scenario}); }); diff --git a/tests/perf-test/SidebarLinks.perf-test.js b/tests/perf-test/SidebarLinks.perf-test.js index 8109c00c0cea..0b10718fd0c4 100644 --- a/tests/perf-test/SidebarLinks.perf-test.js +++ b/tests/perf-test/SidebarLinks.perf-test.js @@ -31,8 +31,6 @@ const getMockedReportsMap = (length = 100) => { const mockedResponseMap = getMockedReportsMap(500); -const runs = CONST.PERFORMANCE_TESTS.RUNS; - describe('SidebarLinks', () => { beforeAll(() => { Onyx.init({ @@ -73,7 +71,7 @@ describe('SidebarLinks', () => { }; await waitForBatchedUpdates(); - await measurePerformance(, {scenario, runs}); + await measurePerformance(, {scenario}); }); test('[SidebarLinks] should scroll and click some of the items', async () => { @@ -108,6 +106,6 @@ describe('SidebarLinks', () => { await waitForBatchedUpdates(); - await measurePerformance(, {scenario, runs}); + await measurePerformance(, {scenario}); }); }); diff --git a/tests/perf-test/SidebarUtils.perf-test.ts b/tests/perf-test/SidebarUtils.perf-test.ts index 7b2fd873f3de..3aa65331b9c2 100644 --- a/tests/perf-test/SidebarUtils.perf-test.ts +++ b/tests/perf-test/SidebarUtils.perf-test.ts @@ -32,8 +32,7 @@ const personalDetails = createCollection( (index) => createPersonalDetails(index), ); -const mockedResponseMap = getMockedReports(5000) as Record<`${typeof ONYXKEYS.COLLECTION.REPORT}`, Report>; -const runs = CONST.PERFORMANCE_TESTS.RUNS; +const mockedResponseMap = getMockedReports(1000) as Record<`${typeof ONYXKEYS.COLLECTION.REPORT}`, Report>; describe('SidebarUtils', () => { beforeAll(() => { @@ -51,7 +50,7 @@ describe('SidebarUtils', () => { Onyx.clear(); }); - test('[SidebarUtils] getOptionData on 5k reports', async () => { + test('[SidebarUtils] getOptionData on 1k reports', async () => { const report = createRandomReport(1); const preferredLocale = 'en'; const policy = createRandomPolicy(1); @@ -59,22 +58,20 @@ describe('SidebarUtils', () => { await waitForBatchedUpdates(); - await measureFunction( - () => - SidebarUtils.getOptionData({ - report, - reportActions, - personalDetails, - preferredLocale, - policy, - parentReportAction, - hasViolations: false, - }), - {runs}, + await measureFunction(() => + SidebarUtils.getOptionData({ + report, + reportActions, + personalDetails, + preferredLocale, + policy, + parentReportAction, + hasViolations: false, + }), ); }); - test('[SidebarUtils] getOrderedReportIDs on 5k reports', async () => { + test('[SidebarUtils] getOrderedReportIDs on 1k reports', async () => { const currentReportId = '1'; const allReports = getMockedReports(); const betas = [CONST.BETAS.DEFAULT_ROOMS]; @@ -104,8 +101,6 @@ describe('SidebarUtils', () => { ) as unknown as OnyxCollection; await waitForBatchedUpdates(); - await measureFunction(() => SidebarUtils.getOrderedReportIDs(currentReportId, allReports, betas, policies, CONST.PRIORITY_MODE.DEFAULT, allReportActions, transactionViolations), { - runs, - }); + await measureFunction(() => SidebarUtils.getOrderedReportIDs(currentReportId, allReports, betas, policies, CONST.PRIORITY_MODE.DEFAULT, allReportActions, transactionViolations)); }); });